Merge "Let A11yIME use its own method name for systrace" into tm-dev
diff --git a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
index 53a3889..c572f82 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
@@ -32,8 +32,6 @@
import android.annotation.UserHandleAware;
import android.content.Context;
-import com.android.internal.util.FrameworkStatsLog;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
@@ -453,62 +451,6 @@
@Retention(RetentionPolicy.SOURCE)
public @interface ReasonCode {}
- private static final int EXEMPTION_REASON_SYSTEM_UID = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_SYSTEM_UID;
- private static final int EXEMPTION_REASON_ALLOWLISTED_PACKAGE = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_ALLOWLISTED_PACKAGE;
- private static final int EXEMPTION_REASON_COMPANION_DEVICE_MANAGER = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_COMPANION_DEVICE_MANAGER;
- private static final int EXEMPTION_REASON_DEVICE_DEMO_MODE = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_DEVICE_DEMO_MODE;
- private static final int EXEMPTION_REASON_DEVICE_OWNER = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_DEVICE_OWNER;
- private static final int EXEMPTION_REASON_PROFILE_OWNER = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_PROFILE_OWNER;
- private static final int EXEMPTION_REASON_PROC_STATE_PERSISTENT = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_PROC_STATE_PERSISTENT;
- private static final int EXEMPTION_REASON_PROC_STATE_PERSISTENT_UI = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_PROC_STATE_PERSISTENT_UI;
- private static final int EXEMPTION_REASON_OP_ACTIVATE_VPN = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_OP_ACTIVATE_VPN;
- private static final int EXEMPTION_REASON_OP_ACTIVATE_PLATFORM_VPN = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_OP_ACTIVATE_PLATFORM_VPN;
- private static final int EXEMPTION_REASON_SYSTEM_MODULE = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_SYSTEM_MODULE;
- private static final int EXEMPTION_REASON_CARRIER_PRIVILEGED_APP = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_CARRIER_PRIVILEGED_APP;
- private static final int EXEMPTION_REASON_SYSTEM_ALLOW_LISTED = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_SYSTEM_ALLOW_LISTED;
- private static final int EXEMPTION_REASON_ROLE_DIALER = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_ROLE_DIALER;
- private static final int EXEMPTION_REASON_ROLE_EMERGENCY = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_ROLE_EMERGENCY;
- private static final int EXEMPTION_REASON_DENIED = FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_DENIED;
- /**
- * List of exemption reason codes used for statsd logging in AppBackgroundRestrictionsInfo atom.
- * @hide
- */
- @IntDef(prefix = { "EXEMPTION_REASON_" }, value = {
- EXEMPTION_REASON_SYSTEM_UID,
- EXEMPTION_REASON_ALLOWLISTED_PACKAGE,
- EXEMPTION_REASON_COMPANION_DEVICE_MANAGER,
- EXEMPTION_REASON_DEVICE_DEMO_MODE,
- EXEMPTION_REASON_DEVICE_OWNER,
- EXEMPTION_REASON_PROFILE_OWNER,
- EXEMPTION_REASON_PROC_STATE_PERSISTENT,
- EXEMPTION_REASON_PROC_STATE_PERSISTENT_UI,
- EXEMPTION_REASON_OP_ACTIVATE_VPN,
- EXEMPTION_REASON_OP_ACTIVATE_PLATFORM_VPN,
- EXEMPTION_REASON_SYSTEM_MODULE,
- EXEMPTION_REASON_CARRIER_PRIVILEGED_APP,
- EXEMPTION_REASON_SYSTEM_ALLOW_LISTED,
- EXEMPTION_REASON_ROLE_DIALER,
- EXEMPTION_REASON_ROLE_EMERGENCY,
- EXEMPTION_REASON_DENIED,
- })
- public @interface ExemptionReason {}
-
/**
* @hide
*/
@@ -679,40 +621,40 @@
* @hide
* @return the reason code mapped to statsd for the AppBackgroundRestrictionsInfo atom.
*/
- public static @ExemptionReason int getExemptionReasonForStatsd(@ReasonCode int reasonCode) {
+ public static int getExemptionReasonForStatsd(@ReasonCode int reasonCode) {
switch (reasonCode) {
case REASON_SYSTEM_UID:
- return EXEMPTION_REASON_SYSTEM_UID;
+ return AppBackgroundRestrictionsInfo.REASON_SYSTEM_UID;
case REASON_ALLOWLISTED_PACKAGE:
- return EXEMPTION_REASON_ALLOWLISTED_PACKAGE;
+ return AppBackgroundRestrictionsInfo.REASON_ALLOWLISTED_PACKAGE;
case REASON_COMPANION_DEVICE_MANAGER:
- return EXEMPTION_REASON_COMPANION_DEVICE_MANAGER;
+ return AppBackgroundRestrictionsInfo.REASON_COMPANION_DEVICE_MANAGER;
case REASON_DEVICE_DEMO_MODE:
- return EXEMPTION_REASON_DEVICE_DEMO_MODE;
+ return AppBackgroundRestrictionsInfo.REASON_DEVICE_DEMO_MODE;
case REASON_DEVICE_OWNER:
- return EXEMPTION_REASON_DEVICE_OWNER;
+ return AppBackgroundRestrictionsInfo.REASON_DEVICE_OWNER;
case REASON_PROFILE_OWNER:
- return EXEMPTION_REASON_PROFILE_OWNER;
+ return AppBackgroundRestrictionsInfo.REASON_PROFILE_OWNER;
case REASON_PROC_STATE_PERSISTENT:
- return EXEMPTION_REASON_PROC_STATE_PERSISTENT;
+ return AppBackgroundRestrictionsInfo.REASON_PROC_STATE_PERSISTENT;
case REASON_PROC_STATE_PERSISTENT_UI:
- return EXEMPTION_REASON_PROC_STATE_PERSISTENT_UI;
+ return AppBackgroundRestrictionsInfo.REASON_PROC_STATE_PERSISTENT_UI;
case REASON_OP_ACTIVATE_VPN:
- return EXEMPTION_REASON_OP_ACTIVATE_VPN;
+ return AppBackgroundRestrictionsInfo.REASON_OP_ACTIVATE_VPN;
case REASON_OP_ACTIVATE_PLATFORM_VPN:
- return EXEMPTION_REASON_OP_ACTIVATE_PLATFORM_VPN;
+ return AppBackgroundRestrictionsInfo.REASON_OP_ACTIVATE_PLATFORM_VPN;
case REASON_SYSTEM_MODULE:
- return EXEMPTION_REASON_SYSTEM_MODULE;
+ return AppBackgroundRestrictionsInfo.REASON_SYSTEM_MODULE;
case REASON_CARRIER_PRIVILEGED_APP:
- return EXEMPTION_REASON_CARRIER_PRIVILEGED_APP;
+ return AppBackgroundRestrictionsInfo.REASON_CARRIER_PRIVILEGED_APP;
case REASON_SYSTEM_ALLOW_LISTED:
- return EXEMPTION_REASON_SYSTEM_ALLOW_LISTED;
+ return AppBackgroundRestrictionsInfo.REASON_SYSTEM_ALLOW_LISTED;
case REASON_ROLE_DIALER:
- return EXEMPTION_REASON_ROLE_DIALER;
+ return AppBackgroundRestrictionsInfo.REASON_ROLE_DIALER;
case REASON_ROLE_EMERGENCY:
- return EXEMPTION_REASON_ROLE_EMERGENCY;
+ return AppBackgroundRestrictionsInfo.REASON_ROLE_EMERGENCY;
default:
- return EXEMPTION_REASON_DENIED;
+ return AppBackgroundRestrictionsInfo.REASON_DENIED;
}
}
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 881453f..0e4887d 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -612,8 +612,7 @@
private static final boolean DEFAULT_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED = true;
- // TODO(b/226439802): Flip to true.
- private static final boolean DEFAULT_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = false;
+ private static final boolean DEFAULT_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = true;
// Minimum futurity of a new alarm
public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY;
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 aad8f9d..9e13133 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -1895,11 +1895,14 @@
// The job ran past its expected run window. Have it count towards the current window
// and schedule a new job for the next window.
if (DEBUG) {
- Slog.i(TAG, "Periodic job ran after its intended window.");
+ Slog.i(TAG, "Periodic job ran after its intended window by " + diffMs + " ms");
}
long numSkippedWindows = (diffMs / period) + 1; // +1 to include original window
- if (period != flex && diffMs > Math.min(PERIODIC_JOB_WINDOW_BUFFER,
- (period - flex) / 2)) {
+ // Determine how far into a single period the job ran, and determine if it's too close
+ // to the start of the next period. If the difference between the start of the execution
+ // window and the previous execution time inside of the period is less than the
+ // threshold, then we say that the job ran too close to the next period.
+ if (period != flex && (period - flex - (diffMs % period)) <= flex / 6) {
if (DEBUG) {
Slog.d(TAG, "Custom flex job ran too close to next window.");
}
diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
index 52f883b..d464e26 100644
--- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java
+++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
@@ -37,6 +37,8 @@
import com.android.internal.telecom.ITelecomService;
import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.stream.Collectors;
public final class Telecom extends BaseCommand {
@@ -90,6 +92,10 @@
private static final String COMMAND_GET_MAX_PHONES = "get-max-phones";
private static final String COMMAND_SET_TEST_EMERGENCY_PHONE_ACCOUNT_PACKAGE_FILTER =
"set-test-emergency-phone-account-package-filter";
+ /**
+ * Command used to emit a distinct "mark" in the logs.
+ */
+ private static final String COMMAND_LOG_MARK = "log-mark";
private ComponentName mComponent;
private String mAccountId;
@@ -161,6 +167,8 @@
+ " package name that will be used for test emergency calls. To clear,"
+ " send an empty package name. Real emergency calls will still be placed"
+ " over Telephony.\n"
+ + "telecom log-mark <MESSAGE>: emits a message into the telecom logs. Useful for "
+ + "testers to indicate where in the logs various test steps take place.\n"
);
}
@@ -265,6 +273,9 @@
case COMMAND_SET_TEST_EMERGENCY_PHONE_ACCOUNT_PACKAGE_FILTER:
runSetEmergencyPhoneAccountPackageFilter();
break;
+ case COMMAND_LOG_MARK:
+ runLogMark();
+ break;
default:
Log.w(this, "onRun: unknown command: %s", command);
throw new IllegalArgumentException ("unknown command '" + command + "'");
@@ -442,6 +453,11 @@
}
+ private void runLogMark() throws RemoteException {
+ String message = Arrays.stream(mArgs.peekRemainingArgs()).collect(Collectors.joining(" "));
+ mTelecomService.requestLogMark(message);
+ }
+
private PhoneAccountHandle getPhoneAccountHandleFromArgs() throws RemoteException {
if (TextUtils.isEmpty(mArgs.peekNextArg())) {
return null;
diff --git a/core/api/current.txt b/core/api/current.txt
index 2a6536e..e260ad0 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -335,15 +335,15 @@
field public static final int allowClearUserData = 16842757; // 0x1010005
field public static final int allowClickWhenDisabled = 16844312; // 0x1010618
field public static final int allowEmbedded = 16843765; // 0x10103f5
- field public static final int allowGameAngleDriver;
- field public static final int allowGameDownscaling;
- field public static final int allowGameFpsOverride;
+ field public static final int allowGameAngleDriver = 16844376; // 0x1010658
+ field public static final int allowGameDownscaling = 16844377; // 0x1010659
+ field public static final int allowGameFpsOverride = 16844378; // 0x101065a
field public static final int allowNativeHeapPointerTagging = 16844306; // 0x1010612
field public static final int allowParallelSyncs = 16843570; // 0x1010332
field public static final int allowSingleTap = 16843353; // 0x1010259
field public static final int allowTaskReparenting = 16843268; // 0x1010204
field public static final int allowUndo = 16843999; // 0x10104df
- field public static final int allowUntrustedActivityEmbedding;
+ field public static final int allowUntrustedActivityEmbedding = 16844393; // 0x1010669
field public static final int alpha = 16843551; // 0x101031f
field public static final int alphabeticModifiers = 16844110; // 0x101054e
field public static final int alphabeticShortcut = 16843235; // 0x10101e3
@@ -374,7 +374,7 @@
field public static final int authorities = 16842776; // 0x1010018
field public static final int autoAdvanceViewId = 16843535; // 0x101030f
field public static final int autoCompleteTextViewStyle = 16842859; // 0x101006b
- field public static final int autoHandwritingEnabled;
+ field public static final int autoHandwritingEnabled = 16844382; // 0x101065e
field public static final int autoLink = 16842928; // 0x10100b0
field public static final int autoMirrored = 16843754; // 0x10103ea
field public static final int autoRemoveFromRecents = 16843847; // 0x1010447
@@ -390,7 +390,7 @@
field public static final int autoVerify = 16844014; // 0x10104ee
field public static final int autofillHints = 16844118; // 0x1010556
field public static final int autofilledHighlight = 16844136; // 0x1010568
- field public static final int backdropColor;
+ field public static final int backdropColor = 16844402; // 0x1010672
field public static final int background = 16842964; // 0x10100d4
field public static final int backgroundDimAmount = 16842802; // 0x1010032
field public static final int backgroundDimEnabled = 16843295; // 0x101021f
@@ -437,7 +437,7 @@
field public static final int calendarViewShown = 16843596; // 0x101034c
field public static final int calendarViewStyle = 16843613; // 0x101035d
field public static final int canControlMagnification = 16844039; // 0x1010507
- field public static final int canDisplayOnRemoteDevices;
+ field public static final int canDisplayOnRemoteDevices = 16844368; // 0x1010650
field public static final int canPauseRecording = 16844314; // 0x101061a
field public static final int canPerformGestures = 16844045; // 0x101050d
field public static final int canRecord = 16844060; // 0x101051c
@@ -632,7 +632,7 @@
field public static final int elevation = 16843840; // 0x1010440
field public static final int ellipsize = 16842923; // 0x10100ab
field public static final int ems = 16843096; // 0x1010158
- field public static final int enableOnBackInvokedCallback;
+ field public static final int enableOnBackInvokedCallback = 16844396; // 0x101066c
field public static final int enableVrMode = 16844069; // 0x1010525
field public static final int enabled = 16842766; // 0x101000e
field public static final int end = 16843996; // 0x10104dc
@@ -744,10 +744,10 @@
field public static final int freezesText = 16843116; // 0x101016c
field public static final int fromAlpha = 16843210; // 0x10101ca
field public static final int fromDegrees = 16843187; // 0x10101b3
- field public static final int fromExtendBottom;
- field public static final int fromExtendLeft;
- field public static final int fromExtendRight;
- field public static final int fromExtendTop;
+ field public static final int fromExtendBottom = 16844386; // 0x1010662
+ field public static final int fromExtendLeft = 16844383; // 0x101065f
+ field public static final int fromExtendRight = 16844385; // 0x1010661
+ field public static final int fromExtendTop = 16844384; // 0x1010660
field public static final int fromId = 16843850; // 0x101044a
field public static final int fromScene = 16843741; // 0x10103dd
field public static final int fromXDelta = 16843206; // 0x10101c6
@@ -867,7 +867,7 @@
field public static final int installLocation = 16843447; // 0x10102b7
field public static final int interactiveUiTimeout = 16844181; // 0x1010595
field public static final int interpolator = 16843073; // 0x1010141
- field public static final int intro;
+ field public static final int intro = 16844395; // 0x101066b
field public static final int isAccessibilityTool = 16844353; // 0x1010641
field public static final int isAlwaysSyncable = 16843571; // 0x1010333
field public static final int isAsciiCapable = 16843753; // 0x10103e9
@@ -910,7 +910,7 @@
field public static final int keyboardNavigationCluster = 16844096; // 0x1010540
field public static final int keycode = 16842949; // 0x10100c5
field public static final int killAfterRestore = 16843420; // 0x101029c
- field public static final int knownActivityEmbeddingCerts;
+ field public static final int knownActivityEmbeddingCerts = 16844394; // 0x101066a
field public static final int knownCerts = 16844330; // 0x101062a
field public static final int lStar = 16844359; // 0x1010647
field public static final int label = 16842753; // 0x1010001
@@ -978,8 +978,8 @@
field public static final int left = 16843181; // 0x10101ad
field public static final int letterSpacing = 16843958; // 0x10104b6
field public static final int level = 16844032; // 0x1010500
- field public static final int lineBreakStyle;
- field public static final int lineBreakWordStyle;
+ field public static final int lineBreakStyle = 16844398; // 0x101066e
+ field public static final int lineBreakWordStyle = 16844399; // 0x101066f
field public static final int lineHeight = 16844159; // 0x101057f
field public static final int lineSpacingExtra = 16843287; // 0x1010217
field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
@@ -1003,7 +1003,7 @@
field public static final int listSeparatorTextViewStyle = 16843272; // 0x1010208
field public static final int listViewStyle = 16842868; // 0x1010074
field public static final int listViewWhiteStyle = 16842869; // 0x1010075
- field public static final int localeConfig;
+ field public static final int localeConfig = 16844379; // 0x101065b
field public static final int lockTaskMode = 16844013; // 0x10104ed
field public static final int logo = 16843454; // 0x10102be
field public static final int logoDescription = 16844009; // 0x10104e9
@@ -1162,7 +1162,7 @@
field public static final int popupWindowStyle = 16842870; // 0x1010076
field public static final int port = 16842793; // 0x1010029
field public static final int positiveButtonText = 16843253; // 0x10101f5
- field public static final int preferKeepClear;
+ field public static final int preferKeepClear = 16844381; // 0x101065d
field public static final int preferMinimalPostProcessing = 16844300; // 0x101060c
field public static final int preferenceCategoryStyle = 16842892; // 0x101008c
field public static final int preferenceFragmentStyle = 16844038; // 0x1010506
@@ -1238,10 +1238,10 @@
field public static final int requiredFeature = 16844116; // 0x1010554
field public static final int requiredForAllUsers = 16843728; // 0x10103d0
field public static final int requiredNotFeature = 16844117; // 0x1010555
- field public static final int requiredSplitTypes;
+ field public static final int requiredSplitTypes = 16844366; // 0x101064e
field public static final int requiresFadingEdge = 16843685; // 0x10103a5
field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364
- field public static final int resetEnabledSettingsOnAppDataCleared;
+ field public static final int resetEnabledSettingsOnAppDataCleared = 16844370; // 0x1010652
field public static final int resizeClip = 16843983; // 0x10104cf
field public static final int resizeMode = 16843619; // 0x1010363
field public static final int resizeable = 16843405; // 0x101028d
@@ -1337,7 +1337,7 @@
field public static final int shareInterpolator = 16843195; // 0x10101bb
field @Deprecated public static final int sharedUserId = 16842763; // 0x101000b
field @Deprecated public static final int sharedUserLabel = 16843361; // 0x1010261
- field public static final int sharedUserMaxSdkVersion;
+ field public static final int sharedUserMaxSdkVersion = 16844365; // 0x101064d
field public static final int shell = 16844180; // 0x1010594
field public static final int shortcutDisabledMessage = 16844075; // 0x101052b
field public static final int shortcutId = 16844072; // 0x1010528
@@ -1346,8 +1346,8 @@
field public static final int shouldDisableView = 16843246; // 0x10101ee
field public static final int shouldUseDefaultUnfoldTransition = 16844364; // 0x101064c
field public static final int showAsAction = 16843481; // 0x10102d9
- field public static final int showBackdrop;
- field public static final int showClockAndComplications;
+ field public static final int showBackdrop = 16844380; // 0x101065c
+ field public static final int showClockAndComplications = 16844372; // 0x1010654
field public static final int showDefault = 16843258; // 0x10101fa
field public static final int showDividers = 16843561; // 0x1010329
field public static final int showForAllUsers = 16844015; // 0x10104ef
@@ -1378,7 +1378,7 @@
field public static final int splitMotionEvents = 16843503; // 0x10102ef
field public static final int splitName = 16844105; // 0x1010549
field public static final int splitTrack = 16843852; // 0x101044c
- field public static final int splitTypes;
+ field public static final int splitTypes = 16844367; // 0x101064f
field public static final int spotShadowAlpha = 16843967; // 0x10104bf
field public static final int src = 16843033; // 0x1010119
field public static final int ssp = 16843747; // 0x10103e3
@@ -1449,18 +1449,18 @@
field public static final int summaryColumn = 16843426; // 0x10102a2
field public static final int summaryOff = 16843248; // 0x10101f0
field public static final int summaryOn = 16843247; // 0x10101ef
- field public static final int supportedTypes;
+ field public static final int supportedTypes = 16844369; // 0x1010651
field public static final int supportsAssist = 16844016; // 0x10104f0
- field public static final int supportsBatteryGameMode;
+ field public static final int supportsBatteryGameMode = 16844374; // 0x1010656
field public static final int supportsInlineSuggestions = 16844301; // 0x101060d
- field public static final int supportsInlineSuggestionsWithTouchExploration;
+ field public static final int supportsInlineSuggestionsWithTouchExploration = 16844397; // 0x101066d
field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1
field public static final int supportsLocalInteraction = 16844047; // 0x101050f
field public static final int supportsMultipleDisplays = 16844182; // 0x1010596
- field public static final int supportsPerformanceGameMode;
+ field public static final int supportsPerformanceGameMode = 16844375; // 0x1010657
field public static final int supportsPictureInPicture = 16844023; // 0x10104f7
field public static final int supportsRtl = 16843695; // 0x10103af
- field public static final int supportsStylusHandwriting;
+ field public static final int supportsStylusHandwriting = 16844371; // 0x1010653
field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
field public static final int supportsUploading = 16843419; // 0x101029b
field public static final int suppressesSpellChecker = 16844355; // 0x1010643
@@ -1579,7 +1579,7 @@
field public static final int tileMode = 16843265; // 0x1010201
field public static final int tileModeX = 16843895; // 0x1010477
field public static final int tileModeY = 16843896; // 0x1010478
- field public static final int tileService;
+ field public static final int tileService = 16844391; // 0x1010667
field public static final int timePickerDialogTheme = 16843934; // 0x101049e
field public static final int timePickerMode = 16843956; // 0x10104b4
field public static final int timePickerStyle = 16843933; // 0x101049d
@@ -1598,10 +1598,10 @@
field public static final int titleTextStyle = 16843512; // 0x10102f8
field public static final int toAlpha = 16843211; // 0x10101cb
field public static final int toDegrees = 16843188; // 0x10101b4
- field public static final int toExtendBottom;
- field public static final int toExtendLeft;
- field public static final int toExtendRight;
- field public static final int toExtendTop;
+ field public static final int toExtendBottom = 16844390; // 0x1010666
+ field public static final int toExtendLeft = 16844387; // 0x1010663
+ field public static final int toExtendRight = 16844389; // 0x1010665
+ field public static final int toExtendTop = 16844388; // 0x1010664
field public static final int toId = 16843849; // 0x1010449
field public static final int toScene = 16843742; // 0x10103de
field public static final int toXDelta = 16843207; // 0x10101c7
@@ -1753,7 +1753,7 @@
field public static final int windowSplashScreenAnimatedIcon = 16844333; // 0x101062d
field @Deprecated public static final int windowSplashScreenAnimationDuration = 16844334; // 0x101062e
field public static final int windowSplashScreenBackground = 16844332; // 0x101062c
- field public static final int windowSplashScreenBehavior;
+ field public static final int windowSplashScreenBehavior = 16844392; // 0x1010668
field public static final int windowSplashScreenBrandingImage = 16844335; // 0x101062f
field public static final int windowSplashScreenIconBackgroundColor = 16844336; // 0x1010630
field @Deprecated public static final int windowSplashscreenContent = 16844132; // 0x1010564
@@ -2092,7 +2092,7 @@
field public static final int accessibilityActionScrollUp = 16908344; // 0x1020038
field public static final int accessibilityActionSetProgress = 16908349; // 0x102003d
field public static final int accessibilityActionShowOnScreen = 16908342; // 0x1020036
- field public static final int accessibilityActionShowTextSuggestions;
+ field public static final int accessibilityActionShowTextSuggestions = 16908376; // 0x1020058
field public static final int accessibilityActionShowTooltip = 16908356; // 0x1020044
field public static final int accessibilitySystemActionBack = 16908363; // 0x102004b
field public static final int accessibilitySystemActionHome = 16908364; // 0x102004c
@@ -2128,8 +2128,8 @@
field public static final int icon_frame = 16908350; // 0x102003e
field public static final int input = 16908297; // 0x1020009
field public static final int inputArea = 16908318; // 0x102001e
- field public static final int inputExtractAccessories;
- field public static final int inputExtractAction;
+ field public static final int inputExtractAccessories = 16908378; // 0x102005a
+ field public static final int inputExtractAction = 16908377; // 0x1020059
field public static final int inputExtractEditText = 16908325; // 0x1020025
field @Deprecated public static final int keyboardView = 16908326; // 0x1020026
field public static final int list = 16908298; // 0x102000a
@@ -2301,7 +2301,7 @@
field public static final int TextAppearance = 16973886; // 0x103003e
field public static final int TextAppearance_DeviceDefault = 16974253; // 0x10301ad
field public static final int TextAppearance_DeviceDefault_DialogWindowTitle = 16974264; // 0x10301b8
- field public static final int TextAppearance_DeviceDefault_Headline;
+ field public static final int TextAppearance_DeviceDefault_Headline = 16974565; // 0x10302e5
field public static final int TextAppearance_DeviceDefault_Inverse = 16974254; // 0x10301ae
field public static final int TextAppearance_DeviceDefault_Large = 16974255; // 0x10301af
field public static final int TextAppearance_DeviceDefault_Large_Inverse = 16974256; // 0x10301b0
@@ -30977,7 +30977,7 @@
field public static final int R = 30; // 0x1e
field public static final int S = 31; // 0x1f
field public static final int S_V2 = 32; // 0x20
- field public static final int TIRAMISU = 10000; // 0x2710
+ field public static final int TIRAMISU = 33; // 0x21
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 66af50c..b25d1e3 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -367,12 +367,12 @@
public static final class R.array {
field public static final int config_keySystemUuidMapping = 17235973; // 0x1070005
- field public static final int config_optionalIpSecAlgorithms;
+ field public static final int config_optionalIpSecAlgorithms = 17235974; // 0x1070006
}
public static final class R.attr {
field public static final int allowClearUserDataOnFailedRestore = 16844288; // 0x1010600
- field public static final int gameSessionService;
+ field public static final int gameSessionService = 16844373; // 0x1010655
field public static final int hotwordDetectionService = 16844326; // 0x1010626
field public static final int isVrOnly = 16844152; // 0x1010578
field public static final int minExtensionVersion = 16844305; // 0x1010611
@@ -385,7 +385,7 @@
}
public static final class R.bool {
- field public static final int config_enableQrCodeScannerOnLockScreen;
+ field public static final int config_enableQrCodeScannerOnLockScreen = 17891336; // 0x1110008
field public static final int config_sendPackageName = 17891328; // 0x1110000
field public static final int config_showDefaultAssistant = 17891329; // 0x1110001
field public static final int config_showDefaultEmergency = 17891330; // 0x1110002
@@ -402,7 +402,7 @@
public static final class R.drawable {
field public static final int ic_info = 17301684; // 0x10800b4
- field public static final int ic_safety_protection;
+ field public static final int ic_safety_protection = 17301685; // 0x10800b5
}
public static final class R.raw {
@@ -414,13 +414,13 @@
field public static final int config_customMediaKeyDispatcher = 17039404; // 0x104002c
field public static final int config_customMediaSessionPolicyProvider = 17039405; // 0x104002d
field public static final int config_defaultAssistant = 17039393; // 0x1040021
- field public static final int config_defaultAutomotiveNavigation;
+ field public static final int config_defaultAutomotiveNavigation = 17039424; // 0x1040040
field public static final int config_defaultBrowser = 17039394; // 0x1040022
field public static final int config_defaultCallRedirection = 17039397; // 0x1040025
field public static final int config_defaultCallScreening = 17039398; // 0x1040026
field public static final int config_defaultDialer = 17039395; // 0x1040023
field public static final int config_defaultSms = 17039396; // 0x1040024
- field public static final int config_devicePolicyManagement;
+ field public static final int config_devicePolicyManagement = 17039421; // 0x104003d
field public static final int config_feedbackIntentExtraKey = 17039391; // 0x104001f
field public static final int config_feedbackIntentNameKey = 17039392; // 0x1040020
field public static final int config_helpIntentExtraKey = 17039389; // 0x104001d
@@ -429,19 +429,19 @@
field public static final int config_helpPackageNameValue = 17039388; // 0x104001c
field public static final int config_systemActivityRecognizer = 17039416; // 0x1040038
field public static final int config_systemAmbientAudioIntelligence = 17039411; // 0x1040033
- field public static final int config_systemAppProtectionService;
+ field public static final int config_systemAppProtectionService = 17039422; // 0x104003e
field public static final int config_systemAudioIntelligence = 17039412; // 0x1040034
- field public static final int config_systemAutomotiveCalendarSyncManager;
+ field public static final int config_systemAutomotiveCalendarSyncManager = 17039423; // 0x104003f
field public static final int config_systemAutomotiveCluster = 17039400; // 0x1040028
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_systemGallery = 17039399; // 0x1040027
field public static final int config_systemNotificationIntelligence = 17039413; // 0x1040035
- field public static final int config_systemSettingsIntelligence;
+ field public static final int config_systemSettingsIntelligence = 17039426; // 0x1040042
field public static final int config_systemShell = 17039402; // 0x104002a
field public static final int config_systemSpeechRecognizer = 17039406; // 0x104002e
- field public static final int config_systemSupervision;
+ field public static final int config_systemSupervision = 17039420; // 0x104003c
field public static final int config_systemTelevisionNotificationHandler = 17039409; // 0x1040031
field public static final int config_systemTextIntelligence = 17039414; // 0x1040036
field public static final int config_systemUi = 17039418; // 0x104003a
@@ -449,7 +449,7 @@
field public static final int config_systemVisualIntelligence = 17039415; // 0x1040037
field public static final int config_systemWellbeing = 17039408; // 0x1040030
field public static final int config_systemWifiCoexManager = 17039407; // 0x104002f
- field public static final int safety_protection_display_text;
+ field public static final int safety_protection_display_text = 17039425; // 0x1040041
}
public static final class R.style {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 27f5b92..f4a12a5 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -63,14 +63,14 @@
public static final class R.bool {
field public static final int config_assistantOnTopOfDream = 17891333; // 0x1110005
field public static final int config_perDisplayFocusEnabled = 17891332; // 0x1110004
- field public static final int config_preventImeStartupUnlessTextEditor;
+ field public static final int config_preventImeStartupUnlessTextEditor = 17891335; // 0x1110007
field public static final int config_remoteInsetsControllerControlsSystemBars = 17891334; // 0x1110006
}
public static final class R.string {
field public static final int config_defaultAssistant = 17039393; // 0x1040021
field public static final int config_defaultDialer = 17039395; // 0x1040023
- field public static final int config_systemAutomotiveCalendarSyncManager;
+ field public static final int config_systemAutomotiveCalendarSyncManager = 17039423; // 0x104003f
field public static final int config_systemAutomotiveCluster = 17039400; // 0x1040028
field public static final int config_systemAutomotiveProjection = 17039401; // 0x1040029
field public static final int config_systemGallery = 17039399; // 0x1040027
diff --git a/core/java/android/accessibilityservice/InputMethod.java b/core/java/android/accessibilityservice/InputMethod.java
index fa75713..79bac9b 100644
--- a/core/java/android/accessibilityservice/InputMethod.java
+++ b/core/java/android/accessibilityservice/InputMethod.java
@@ -62,7 +62,6 @@
private final AccessibilityService mService;
private InputBinding mInputBinding;
- private InputConnection mInputConnection;
private boolean mInputStarted;
private InputConnection mStartedInputConnection;
private EditorInfo mInputEditorInfo;
@@ -81,12 +80,8 @@
*/
@Nullable
public final AccessibilityInputConnection getCurrentInputConnection() {
- InputConnection ic = mStartedInputConnection;
- if (ic != null) {
- return new AccessibilityInputConnection(ic);
- }
- if (mInputConnection != null) {
- return new AccessibilityInputConnection(mInputConnection);
+ if (mStartedInputConnection != null) {
+ return new AccessibilityInputConnection(mStartedInputConnection);
}
return null;
}
@@ -136,10 +131,8 @@
* to perform whatever behavior you would like.
*/
public void onFinishInput() {
- InputConnection ic = mStartedInputConnection != null ? mStartedInputConnection
- : mInputConnection;
- if (ic != null) {
- ic.finishComposingText();
+ if (mStartedInputConnection != null) {
+ mStartedInputConnection.finishComposingText();
}
}
@@ -176,18 +169,14 @@
final void bindInput(@NonNull InputBinding binding) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "AccessibilityService.bindInput");
mInputBinding = binding;
- mInputConnection = binding.getConnection();
- Log.v(LOG_TAG, "bindInput(): binding=" + binding
- + " ic=" + mInputConnection);
+ Log.v(LOG_TAG, "bindInput(): binding=" + binding);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
final void unbindInput() {
- Log.v(LOG_TAG, "unbindInput(): binding=" + mInputBinding
- + " ic=" + mInputConnection);
+ Log.v(LOG_TAG, "unbindInput(): binding=" + mInputBinding);
// Unbind input is per process per display.
mInputBinding = null;
- mInputConnection = null;
}
final void startInput(@Nullable InputConnection ic, @NonNull EditorInfo attribute) {
@@ -206,8 +195,12 @@
final void doStartInput(InputConnection ic, EditorInfo attribute, boolean restarting) {
- if (!restarting && mInputStarted) {
+ if ((ic == null || !restarting) && mInputStarted) {
doFinishInput();
+ if (ic == null) {
+ // Unlike InputMethodService, A11y IME should not observe fallback InputConnection.
+ return;
+ }
}
mInputStarted = true;
mStartedInputConnection = ic;
@@ -224,6 +217,7 @@
}
mInputStarted = false;
mStartedInputConnection = null;
+ mInputEditorInfo = null;
}
private InputMethodSession onCreateInputMethodSessionInterface() {
@@ -624,7 +618,6 @@
@Override
public void invalidateInputInternal(EditorInfo editorInfo, IInputContext inputContext,
int sessionId) {
- // TODO(b/217788708): Add automated test.
if (mStartedInputConnection instanceof RemoteInputConnection) {
final RemoteInputConnection ric =
(RemoteInputConnection) mStartedInputConnection;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 852dd97..7d68eb9 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4114,8 +4114,8 @@
@NonNull SurfaceControl startingWindowLeash) {
final SplashScreenView.Builder builder = new SplashScreenView.Builder(r.activity);
final SplashScreenView view = builder.createFromParcel(parcelable).build();
+ view.attachHostWindow(r.window);
decorView.addView(view);
- view.attachHostActivityAndSetSystemUIColors(r.activity, r.window);
view.requestLayout();
view.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 6bb35db..56d655c 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -628,6 +628,9 @@
* Bit to be bitwise-ored into the {@link #flags} field that should be
* set if you would only like the sound, vibrate and ticker to be played
* if the notification was not already showing.
+ *
+ * Note that using this flag will stop any ongoing alerting behaviour such
+ * as sound, vibration or blinking notification LED.
*/
public static final int FLAG_ONLY_ALERT_ONCE = 0x00000008;
@@ -2810,8 +2813,8 @@
}
if (extras != null) {
- visitIconUri(visitor, extras.getParcelable(EXTRA_LARGE_ICON_BIG));
- visitIconUri(visitor, extras.getParcelable(EXTRA_PICTURE_ICON));
+ visitIconUri(visitor, extras.getParcelable(EXTRA_LARGE_ICON_BIG, Icon.class));
+ visitIconUri(visitor, extras.getParcelable(EXTRA_PICTURE_ICON, Icon.class));
// NOTE: The documentation of EXTRA_AUDIO_CONTENTS_URI explicitly says that it is a
// String representation of a Uri, but the previous implementation (and unit test) of
@@ -2835,7 +2838,7 @@
}
}
- final Person person = extras.getParcelable(EXTRA_MESSAGING_PERSON);
+ final Person person = extras.getParcelable(EXTRA_MESSAGING_PERSON, Person.class);
if (person != null) {
visitor.accept(person.getIconUri());
}
@@ -4633,6 +4636,9 @@
* Set this flag if you would only like the sound, vibrate
* and ticker to be played if the notification is not already showing.
*
+ * Note that using this flag will stop any ongoing alerting behaviour such
+ * as sound, vibration or blinking notification LED.
+ *
* @see Notification#FLAG_ONLY_ALERT_ONCE
*/
@NonNull
@@ -6467,7 +6473,7 @@
public static Notification.Builder recoverBuilder(Context context, Notification n) {
// Re-create notification context so we can access app resources.
ApplicationInfo applicationInfo = n.extras.getParcelable(
- EXTRA_BUILDER_APPLICATION_INFO);
+ EXTRA_BUILDER_APPLICATION_INFO, ApplicationInfo.class);
Context builderContext;
if (applicationInfo != null) {
try {
@@ -6919,9 +6925,8 @@
boolean isMediaStyle = (MediaStyle.class.equals(style)
|| DecoratedMediaCustomViewStyle.class.equals(style));
- boolean hasMediaSession = (extras.getParcelable(Notification.EXTRA_MEDIA_SESSION) != null
- && extras.getParcelable(Notification.EXTRA_MEDIA_SESSION)
- instanceof MediaSession.Token);
+ boolean hasMediaSession = extras.getParcelable(Notification.EXTRA_MEDIA_SESSION,
+ MediaSession.Token.class) != null;
return isMediaStyle && hasMediaSession;
}
@@ -7516,7 +7521,7 @@
if (extras.containsKey(EXTRA_LARGE_ICON_BIG)) {
mBigLargeIconSet = true;
- mBigLargeIcon = extras.getParcelable(EXTRA_LARGE_ICON_BIG);
+ mBigLargeIcon = extras.getParcelable(EXTRA_LARGE_ICON_BIG, Icon.class);
}
if (extras.containsKey(EXTRA_PICTURE_CONTENT_DESCRIPTION)) {
@@ -7536,11 +7541,11 @@
// When this style adds a picture, we only add one of the keys. If both were added,
// it would most likely be a legacy app trying to override the picture in some way.
// Because of that case it's better to give precedence to the legacy field.
- Bitmap bitmapPicture = extras.getParcelable(EXTRA_PICTURE);
+ Bitmap bitmapPicture = extras.getParcelable(EXTRA_PICTURE, Bitmap.class);
if (bitmapPicture != null) {
return Icon.createWithBitmap(bitmapPicture);
} else {
- return extras.getParcelable(EXTRA_PICTURE_ICON);
+ return extras.getParcelable(EXTRA_PICTURE_ICON, Icon.class);
}
}
@@ -8159,7 +8164,7 @@
protected void restoreFromExtras(Bundle extras) {
super.restoreFromExtras(extras);
- mUser = extras.getParcelable(EXTRA_MESSAGING_PERSON);
+ mUser = extras.getParcelable(EXTRA_MESSAGING_PERSON, Person.class);
if (mUser == null) {
CharSequence displayName = extras.getCharSequence(EXTRA_SELF_DISPLAY_NAME);
mUser = new Person.Builder().setName(displayName).build();
@@ -8171,7 +8176,7 @@
mHistoricMessages = Message.getMessagesFromBundleArray(histMessages);
mIsGroupConversation = extras.getBoolean(EXTRA_IS_GROUP_CONVERSATION);
mUnreadMessageCount = extras.getInt(EXTRA_CONVERSATION_UNREAD_MESSAGE_COUNT);
- mShortcutIcon = extras.getParcelable(EXTRA_CONVERSATION_ICON);
+ mShortcutIcon = extras.getParcelable(EXTRA_CONVERSATION_ICON, Icon.class);
}
/**
@@ -8725,7 +8730,7 @@
return null;
} else {
- Person senderPerson = bundle.getParcelable(KEY_SENDER_PERSON);
+ Person senderPerson = bundle.getParcelable(KEY_SENDER_PERSON, Person.class);
if (senderPerson == null) {
// Legacy apps that use compat don't actually provide the sender objects
// We need to fix the compat version to provide people / use
@@ -8742,7 +8747,7 @@
if (bundle.containsKey(KEY_DATA_MIME_TYPE) &&
bundle.containsKey(KEY_DATA_URI)) {
message.setData(bundle.getString(KEY_DATA_MIME_TYPE),
- (Uri) bundle.getParcelable(KEY_DATA_URI));
+ bundle.getParcelable(KEY_DATA_URI, Uri.class));
}
if (bundle.containsKey(KEY_EXTRAS_BUNDLE)) {
message.getExtras().putAll(bundle.getBundle(KEY_EXTRAS_BUNDLE));
@@ -9148,7 +9153,7 @@
super.restoreFromExtras(extras);
if (extras.containsKey(EXTRA_MEDIA_SESSION)) {
- mToken = extras.getParcelable(EXTRA_MEDIA_SESSION);
+ mToken = extras.getParcelable(EXTRA_MEDIA_SESSION, MediaSession.Token.class);
}
if (extras.containsKey(EXTRA_COMPACT_ACTIONS)) {
mActionsToShowInCompact = extras.getIntArray(EXTRA_COMPACT_ACTIONS);
@@ -9160,7 +9165,8 @@
mDeviceIcon = extras.getInt(EXTRA_MEDIA_REMOTE_ICON);
}
if (extras.containsKey(EXTRA_MEDIA_REMOTE_INTENT)) {
- mDeviceIntent = extras.getParcelable(EXTRA_MEDIA_REMOTE_INTENT);
+ mDeviceIntent = extras.getParcelable(
+ EXTRA_MEDIA_REMOTE_INTENT, PendingIntent.class);
}
}
@@ -9752,12 +9758,12 @@
super.restoreFromExtras(extras);
mCallType = extras.getInt(EXTRA_CALL_TYPE);
mIsVideo = extras.getBoolean(EXTRA_CALL_IS_VIDEO);
- mPerson = extras.getParcelable(EXTRA_CALL_PERSON);
+ mPerson = extras.getParcelable(EXTRA_CALL_PERSON, Person.class);
mVerificationIcon = extras.getParcelable(EXTRA_VERIFICATION_ICON);
mVerificationText = extras.getCharSequence(EXTRA_VERIFICATION_TEXT);
- mAnswerIntent = extras.getParcelable(EXTRA_ANSWER_INTENT);
- mDeclineIntent = extras.getParcelable(EXTRA_DECLINE_INTENT);
- mHangUpIntent = extras.getParcelable(EXTRA_HANG_UP_INTENT);
+ mAnswerIntent = extras.getParcelable(EXTRA_ANSWER_INTENT, PendingIntent.class);
+ mDeclineIntent = extras.getParcelable(EXTRA_DECLINE_INTENT, PendingIntent.class);
+ mHangUpIntent = extras.getParcelable(EXTRA_HANG_UP_INTENT, PendingIntent.class);
mAnswerButtonColor = extras.containsKey(EXTRA_ANSWER_COLOR)
? extras.getInt(EXTRA_ANSWER_COLOR) : null;
mDeclineButtonColor = extras.containsKey(EXTRA_DECLINE_COLOR)
@@ -10818,9 +10824,9 @@
// Keys within EXTRA_WEARABLE_EXTENSIONS for wearable options.
private static final String KEY_ACTIONS = "actions";
private static final String KEY_FLAGS = "flags";
- private static final String KEY_DISPLAY_INTENT = "displayIntent";
+ static final String KEY_DISPLAY_INTENT = "displayIntent";
private static final String KEY_PAGES = "pages";
- private static final String KEY_BACKGROUND = "background";
+ static final String KEY_BACKGROUND = "background";
private static final String KEY_CONTENT_ICON = "contentIcon";
private static final String KEY_CONTENT_ICON_GRAVITY = "contentIconGravity";
private static final String KEY_CONTENT_ACTION_INDEX = "contentActionIndex";
@@ -10877,7 +10883,8 @@
}
mFlags = wearableBundle.getInt(KEY_FLAGS, DEFAULT_FLAGS);
- mDisplayIntent = wearableBundle.getParcelable(KEY_DISPLAY_INTENT);
+ mDisplayIntent = wearableBundle.getParcelable(
+ KEY_DISPLAY_INTENT, PendingIntent.class);
Notification[] pages = getParcelableArrayFromBundle(
wearableBundle, KEY_PAGES, Notification.class);
@@ -10885,7 +10892,7 @@
Collections.addAll(mPages, pages);
}
- mBackground = wearableBundle.getParcelable(KEY_BACKGROUND);
+ mBackground = wearableBundle.getParcelable(KEY_BACKGROUND, Bitmap.class);
mContentIcon = wearableBundle.getInt(KEY_CONTENT_ICON);
mContentIconGravity = wearableBundle.getInt(KEY_CONTENT_ICON_GRAVITY,
DEFAULT_CONTENT_ICON_GRAVITY);
@@ -11598,7 +11605,7 @@
Bundle carBundle = notif.extras == null ?
null : notif.extras.getBundle(EXTRA_CAR_EXTENDER);
if (carBundle != null) {
- mLargeIcon = carBundle.getParcelable(EXTRA_LARGE_ICON);
+ mLargeIcon = carBundle.getParcelable(EXTRA_LARGE_ICON, Bitmap.class);
mColor = carBundle.getInt(EXTRA_COLOR, Notification.COLOR_DEFAULT);
Bundle b = carBundle.getBundle(EXTRA_CONVERSATION);
@@ -11704,9 +11711,9 @@
private static final String KEY_AUTHOR = "author";
private static final String KEY_TEXT = "text";
private static final String KEY_MESSAGES = "messages";
- private static final String KEY_REMOTE_INPUT = "remote_input";
- private static final String KEY_ON_REPLY = "on_reply";
- private static final String KEY_ON_READ = "on_read";
+ static final String KEY_REMOTE_INPUT = "remote_input";
+ static final String KEY_ON_REPLY = "on_reply";
+ static final String KEY_ON_READ = "on_read";
private static final String KEY_PARTICIPANTS = "participants";
private static final String KEY_TIMESTAMP = "timestamp";
@@ -11831,10 +11838,10 @@
}
}
- PendingIntent onRead = b.getParcelable(KEY_ON_READ);
- PendingIntent onReply = b.getParcelable(KEY_ON_REPLY);
+ PendingIntent onRead = b.getParcelable(KEY_ON_READ, PendingIntent.class);
+ PendingIntent onReply = b.getParcelable(KEY_ON_REPLY, PendingIntent.class);
- RemoteInput remoteInput = b.getParcelable(KEY_REMOTE_INPUT);
+ RemoteInput remoteInput = b.getParcelable(KEY_REMOTE_INPUT, RemoteInput.class);
String[] participants = b.getStringArray(KEY_PARTICIPANTS);
if (participants == null || participants.length != 1) {
@@ -11976,8 +11983,8 @@
private static final String EXTRA_TV_EXTENDER = "android.tv.EXTENSIONS";
private static final String EXTRA_FLAGS = "flags";
- private static final String EXTRA_CONTENT_INTENT = "content_intent";
- private static final String EXTRA_DELETE_INTENT = "delete_intent";
+ static final String EXTRA_CONTENT_INTENT = "content_intent";
+ static final String EXTRA_DELETE_INTENT = "delete_intent";
private static final String EXTRA_CHANNEL_ID = "channel_id";
private static final String EXTRA_SUPPRESS_SHOW_OVER_APPS = "suppressShowOverApps";
@@ -12009,8 +12016,8 @@
mFlags = bundle.getInt(EXTRA_FLAGS);
mChannelId = bundle.getString(EXTRA_CHANNEL_ID);
mSuppressShowOverApps = bundle.getBoolean(EXTRA_SUPPRESS_SHOW_OVER_APPS);
- mContentIntent = bundle.getParcelable(EXTRA_CONTENT_INTENT);
- mDeleteIntent = bundle.getParcelable(EXTRA_DELETE_INTENT);
+ mContentIntent = bundle.getParcelable(EXTRA_CONTENT_INTENT, PendingIntent.class);
+ mDeleteIntent = bundle.getParcelable(EXTRA_DELETE_INTENT, PendingIntent.class);
}
}
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 0a18588..e022ca3 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -67,7 +67,6 @@
import android.os.RemoteException;
import android.os.StrictMode;
import android.os.SystemProperties;
-import android.service.wallpaper.WallpaperService;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -559,23 +558,26 @@
}
mCachedWallpaper = null;
mCachedWallpaperUserId = 0;
- try {
- mCachedWallpaper = getCurrentWallpaperLocked(
- context, userId, hardware, cmProxy);
- mCachedWallpaperUserId = userId;
- } catch (OutOfMemoryError e) {
- Log.w(TAG, "Out of memory loading the current wallpaper: " + e);
- } catch (SecurityException e) {
- if (context.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.O_MR1) {
- Log.w(TAG, "No permission to access wallpaper, suppressing"
- + " exception to avoid crashing legacy app.");
- } else {
- // Post-O apps really most sincerely need the permission.
- throw e;
+ }
+ try {
+ Bitmap currentWallpaper = getCurrentWallpaperLocked(
+ context, userId, hardware, cmProxy);
+ if (currentWallpaper != null) {
+ synchronized (this) {
+ mCachedWallpaper = currentWallpaper;
+ mCachedWallpaperUserId = userId;
+ return mCachedWallpaper;
}
}
- if (mCachedWallpaper != null) {
- return mCachedWallpaper;
+ } catch (OutOfMemoryError e) {
+ Log.w(TAG, "Out of memory loading the current wallpaper: " + e);
+ } catch (SecurityException e) {
+ if (context.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.O_MR1) {
+ Log.w(TAG, "No permission to access wallpaper, suppressing"
+ + " exception to avoid crashing legacy app.");
+ } else {
+ // Post-O apps really most sincerely need the permission.
+ throw e;
}
}
if (returnDefault) {
@@ -2472,7 +2474,7 @@
*
* @param colors Wallpaper color info, {@code null} when not available.
* @param which A combination of {@link #FLAG_LOCK} and {@link #FLAG_SYSTEM}
- * @see WallpaperService.Engine#onComputeColors()
+ * @see android.service.wallpaper.WallpaperService.Engine#onComputeColors()
*/
void onColorsChanged(@Nullable WallpaperColors colors, int which);
@@ -2484,7 +2486,7 @@
* @param colors Wallpaper color info, {@code null} when not available.
* @param which A combination of {@link #FLAG_LOCK} and {@link #FLAG_SYSTEM}
* @param userId Owner of the wallpaper
- * @see WallpaperService.Engine#onComputeColors()
+ * @see android.service.wallpaper.WallpaperService.Engine#onComputeColors()
* @hide
*/
default void onColorsChanged(@Nullable WallpaperColors colors, int which, int userId) {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index f5cf73b..d11b23c 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2542,7 +2542,7 @@
* that has this delegation. If another app already had delegated security logging access, it
* will lose the delegation when a new app is delegated.
*
- * <p> Can only be granted by Device Owner or Profile Owner of an organnization owned and
+ * <p> Can only be granted by Device Owner or Profile Owner of an organization-owned
* managed profile.
*/
public static final String DELEGATION_SECURITY_LOGGING = "delegation-security-logging";
diff --git a/core/java/android/hardware/CameraSessionStats.java b/core/java/android/hardware/CameraSessionStats.java
index 698cc76..9ef6306 100644
--- a/core/java/android/hardware/CameraSessionStats.java
+++ b/core/java/android/hardware/CameraSessionStats.java
@@ -61,6 +61,7 @@
private boolean mDeviceError;
private float mMaxPreviewFps;
private ArrayList<CameraStreamStats> mStreamStats;
+ private String mUserTag;
public CameraSessionStats() {
mFacing = -1;
@@ -131,6 +132,7 @@
dest.writeLong(mResultErrorCount);
dest.writeBoolean(mDeviceError);
dest.writeTypedList(mStreamStats);
+ dest.writeString(mUserTag);
}
public void readFromParcel(Parcel in) {
@@ -151,6 +153,8 @@
ArrayList<CameraStreamStats> streamStats = new ArrayList<CameraStreamStats>();
in.readTypedList(streamStats, CameraStreamStats.CREATOR);
mStreamStats = streamStats;
+
+ mUserTag = in.readString();
}
public String getCameraId() {
@@ -208,4 +212,8 @@
public List<CameraStreamStats> getStreamStats() {
return mStreamStats;
}
+
+ public String getUserTag() {
+ return mUserTag;
+ }
}
diff --git a/core/java/android/hardware/fingerprint/FingerprintStateListener.java b/core/java/android/hardware/biometrics/BiometricStateListener.java
similarity index 79%
rename from core/java/android/hardware/fingerprint/FingerprintStateListener.java
rename to core/java/android/hardware/biometrics/BiometricStateListener.java
index 551f512..2ac0c1e 100644
--- a/core/java/android/hardware/fingerprint/FingerprintStateListener.java
+++ b/core/java/android/hardware/biometrics/BiometricStateListener.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.fingerprint;
+package android.hardware.biometrics;
import android.annotation.IntDef;
@@ -22,10 +22,10 @@
import java.lang.annotation.RetentionPolicy;
/**
- * Interface for handling state changes in fingerprint-related events.
+ * Interface for handling state changes in biometric sensors.
* @hide
*/
-public abstract class FingerprintStateListener extends IFingerprintStateListener.Stub {
+public abstract class BiometricStateListener extends IBiometricStateListener.Stub {
// Operation has not started yet.
public static final int STATE_IDLE = 0;
@@ -43,16 +43,19 @@
@IntDef({STATE_IDLE, STATE_ENROLLING, STATE_KEYGUARD_AUTH, STATE_BP_AUTH, STATE_AUTH_OTHER})
@Retention(RetentionPolicy.SOURCE)
- public @interface State {}
+ public @interface State {
+ }
/**
* Defines behavior in response to state update
- * @param newState new state of fingerprint sensor
+ * @param newState new state of the biometric sensor
*/
- public void onStateChanged(@FingerprintStateListener.State int newState) {}
+ public void onStateChanged(@BiometricStateListener.State int newState) {
+ }
/**
* Invoked when enrollment state changes for the specified user
*/
- public void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) {}
+ public void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) {
+ }
}
diff --git a/core/java/android/hardware/fingerprint/IFingerprintStateListener.aidl b/core/java/android/hardware/biometrics/IBiometricStateListener.aidl
similarity index 69%
rename from core/java/android/hardware/fingerprint/IFingerprintStateListener.aidl
rename to core/java/android/hardware/biometrics/IBiometricStateListener.aidl
index 1aa6fa1..5bdced0 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintStateListener.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricStateListener.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 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.
@@ -13,16 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.hardware.fingerprint;
-
-import android.hardware.fingerprint.Fingerprint;
+package android.hardware.biometrics;
/**
- * Communication channel for FingerprintManager to register the FingerprintStateListener
- * in FingerprintService.
+ * Communication channel between <Biometric>Manager and <Biometric>Service for passing the
+ * listener.
* @hide
*/
-oneway interface IFingerprintStateListener {
+oneway interface IBiometricStateListener {
void onStateChanged(int newState);
void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments);
}
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 9884c38..15e59e0 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -266,6 +266,8 @@
private int mRequestType = -1;
+ private static final String SET_TAG_STRING_PREFIX =
+ "android.hardware.camera2.CaptureRequest.setTag.";
/**
* Get the type of the capture request
*
@@ -614,6 +616,11 @@
throw new RuntimeException("Reading cached CaptureRequest is not supported");
}
}
+
+ boolean hasUserTagStr = (in.readInt() == 1) ? true : false;
+ if (hasUserTagStr) {
+ mUserTag = in.readString();
+ }
}
@Override
@@ -656,6 +663,19 @@
dest.writeInt(0);
}
}
+
+ // Write string for user tag if set to something in the same namespace
+ if (mUserTag != null) {
+ String userTagStr = mUserTag.toString();
+ if (userTagStr != null && userTagStr.startsWith(SET_TAG_STRING_PREFIX)) {
+ dest.writeInt(1);
+ dest.writeString(userTagStr.substring(SET_TAG_STRING_PREFIX.length()));
+ } else {
+ dest.writeInt(0);
+ }
+ } else {
+ dest.writeInt(0);
+ }
}
/**
@@ -938,7 +958,10 @@
* <p>This tag is not used for anything by the camera device, but can be
* used by an application to easily identify a CaptureRequest when it is
* returned by
- * {@link CameraCaptureSession.CaptureCallback#onCaptureCompleted CaptureCallback.onCaptureCompleted}
+ * {@link CameraCaptureSession.CaptureCallback#onCaptureCompleted CaptureCallback.onCaptureCompleted}.</p>
+ *
+ * <p>If the application overrides the tag object's {@link Object#toString} function, the
+ * returned string must not contain personal identifiable information.</p>
*
* @param tag an arbitrary Object to store with this request
* @see CaptureRequest#getTag
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 60c4b52..28f1f02 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -45,6 +45,7 @@
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricPrompt;
+import android.hardware.biometrics.BiometricStateListener;
import android.hardware.biometrics.BiometricTestSession;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.biometrics.SensorProperties;
@@ -918,13 +919,13 @@
/**
- * Forwards FingerprintStateListener to FingerprintService
- * @param listener new FingerprintStateListener being added
+ * Forwards BiometricStateListener to FingerprintService
+ * @param listener new BiometricStateListener being added
* @hide
*/
- public void registerFingerprintStateListener(@NonNull FingerprintStateListener listener) {
+ public void registerBiometricStateListener(@NonNull BiometricStateListener listener) {
try {
- mService.registerFingerprintStateListener(listener);
+ mService.registerBiometricStateListener(listener);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index d60bb6e..0b63446 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -17,13 +17,13 @@
import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
+import android.hardware.biometrics.IBiometricStateListener;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.fingerprint.IFingerprintClientActiveCallback;
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
-import android.hardware.fingerprint.IFingerprintStateListener;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.Fingerprint;
@@ -169,6 +169,6 @@
// Sets the controller for managing the SideFPS overlay.
void setSidefpsController(in ISidefpsController controller);
- // Registers FingerprintStateListener in list stored by FingerprintService.
- void registerFingerprintStateListener(IFingerprintStateListener listener);
+ // Registers BiometricStateListener.
+ void registerBiometricStateListener(IBiometricStateListener listener);
}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 4fdd534..6ece5ef 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -101,6 +101,7 @@
import android.view.Choreographer;
import android.view.Gravity;
import android.view.InputChannel;
+import android.view.InputDevice;
import android.view.InputEventReceiver;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
@@ -134,7 +135,10 @@
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
import android.window.WindowMetricsHelper;
+import android.window.WindowOnBackInvokedDispatcher;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.inputmethod.IInputContentUriToken;
@@ -345,6 +349,9 @@
**/
private RingBuffer<MotionEvent> mPendingEvents;
+ /** Callback to handle back invocation when IME window is shown. */
+ private OnBackInvokedCallback mBackCallback;
+
/**
* Returns whether {@link InputMethodService} is responsible for rendering the back button and
* the IME switcher button or not when the gestural navigation is enabled.
@@ -1605,6 +1612,7 @@
@Override public void onDestroy() {
mDestroyed = true;
super.onDestroy();
+ unregisterOnBackInvokedCallback();
mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
mInsetsComputer);
doFinishInput();
@@ -2579,6 +2587,7 @@
cancelImeSurfaceRemoval();
mInShowWindow = false;
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ registerOnBackInvokedCallback();
}
@@ -2625,6 +2634,56 @@
}
/**
+ * Registers an {@link OnBackInvokedCallback} to handle back invocation when ahead-of-time
+ * back dispatching is enabled. We keep the KEYCODE_BACK based legacy code around to handle
+ * back on older devices.
+ */
+ private void registerOnBackInvokedCallback() {
+ if (mBackCallback != null) {
+ // A back callback has already been registered.
+ return;
+ }
+ final ViewRootImpl viewRootImpl = mRootView == null ? null : mRootView.getViewRootImpl();
+ if (viewRootImpl != null && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(
+ viewRootImpl.mContext)) {
+ final OnBackInvokedCallback callback = () -> {
+ KeyEvent downEvent = createKeyEvent(
+ KeyEvent.ACTION_DOWN, false /* isTracking */);
+ onKeyDown(KeyEvent.KEYCODE_BACK, downEvent);
+ boolean hasStartedTracking =
+ (downEvent.getFlags() & KeyEvent.FLAG_START_TRACKING) != 0;
+ KeyEvent upEvent = createKeyEvent(KeyEvent.ACTION_UP, hasStartedTracking);
+ onKeyUp(KeyEvent.KEYCODE_BACK, upEvent);
+ };
+ viewRootImpl.getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
+ OnBackInvokedDispatcher.PRIORITY_DEFAULT, callback);
+ mBackCallback = callback;
+ }
+ }
+
+ private KeyEvent createKeyEvent(int action, boolean isTracking) {
+ final long when = SystemClock.uptimeMillis();
+ return new KeyEvent(when, when, action,
+ KeyEvent.KEYCODE_BACK, 0 /* repeat */, 0 /* metaState */,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */,
+ KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY
+ | (isTracking ? KeyEvent.FLAG_TRACKING : 0),
+ InputDevice.SOURCE_KEYBOARD);
+ }
+
+ private void unregisterOnBackInvokedCallback() {
+ final ViewRootImpl viewRootImpl = mRootView == null ? null : mRootView.getViewRootImpl();
+ if (viewRootImpl != null
+ && mBackCallback != null
+ && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(
+ viewRootImpl.mContext)) {
+ viewRootImpl.getOnBackInvokedDispatcher()
+ .unregisterOnBackInvokedCallback(mBackCallback);
+ }
+ mBackCallback = null;
+ }
+
+ /**
* Applies the IME visibility in {@link android.view.ImeInsetsSourceConsumer}.
*
* @param setVisible {@code true} to make it visible, false to hide it.
@@ -2669,6 +2728,7 @@
}
mLastWasInFullscreenMode = mIsFullscreen;
updateFullscreenMode();
+ unregisterOnBackInvokedCallback();
}
/**
diff --git a/core/java/android/net/vcn/VcnManager.java b/core/java/android/net/vcn/VcnManager.java
index 390c3b9..f1b110a 100644
--- a/core/java/android/net/vcn/VcnManager.java
+++ b/core/java/android/net/vcn/VcnManager.java
@@ -172,11 +172,11 @@
*
* <p>An app that has carrier privileges for any of the subscriptions in the given group may
* clear a VCN configuration. This API is ONLY permitted for callers running as the primary
- * user. Any active VCN will be torn down.
+ * user. Any active VCN associated with this configuration will be torn down.
*
* @param subscriptionGroup the subscription group that the configuration should be applied to
- * @throws SecurityException if the caller does not have carrier privileges, or is not running
- * as the primary user
+ * @throws SecurityException if the caller does not have carrier privileges, is not the owner of
+ * the associated configuration, or is not running as the primary user
* @throws IOException if the configuration failed to be cleared from disk. This may occur due
* to temporary disk errors, or more permanent conditions such as a full disk.
*/
@@ -196,8 +196,13 @@
/**
* Retrieves the list of Subscription Groups for which a VCN Configuration has been set.
*
- * <p>The returned list will include only subscription groups for which the carrier app is
- * privileged, and which have an associated {@link VcnConfig}.
+ * <p>The returned list will include only subscription groups for which an associated {@link
+ * VcnConfig} exists, and the app is either:
+ *
+ * <ul>
+ * <li>Carrier privileged for that subscription group, or
+ * <li>Is the provisioning package of the config
+ * </ul>
*
* @throws SecurityException if the caller is not running as the primary user
*/
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 42e6ac4..0b956f8 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1166,7 +1166,7 @@
/**
* Tiramisu.
*/
- public static final int TIRAMISU = CUR_DEVELOPMENT;
+ public static final int TIRAMISU = 33;
}
/** The type of build, like "user" or "eng". */
diff --git a/core/java/android/service/dreams/DreamActivity.java b/core/java/android/service/dreams/DreamActivity.java
index 96bbf8e..cf4e6a6 100644
--- a/core/java/android/service/dreams/DreamActivity.java
+++ b/core/java/android/service/dreams/DreamActivity.java
@@ -19,6 +19,7 @@
import android.annotation.Nullable;
import android.app.Activity;
import android.os.Bundle;
+import android.text.TextUtils;
import com.android.internal.R;
@@ -44,6 +45,7 @@
*/
public class DreamActivity extends Activity {
static final String EXTRA_CALLBACK = "binder";
+ static final String EXTRA_DREAM_TITLE = "title";
public DreamActivity() {}
@@ -51,6 +53,11 @@
public void onCreate(@Nullable Bundle bundle) {
super.onCreate(bundle);
+ final String title = getIntent().getStringExtra(EXTRA_DREAM_TITLE);
+ if (!TextUtils.isEmpty(title)) {
+ setTitle(title);
+ }
+
DreamService.DreamServiceWrapper callback =
(DreamService.DreamServiceWrapper) getIntent().getIBinderExtra(EXTRA_CALLBACK);
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index d4f8a3b..95eae6c 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -1280,6 +1280,9 @@
i.setPackage(getApplicationContext().getPackageName());
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra(DreamActivity.EXTRA_CALLBACK, mDreamServiceWrapper);
+ final ServiceInfo serviceInfo = fetchServiceInfo(this,
+ new ComponentName(this, getClass()));
+ i.putExtra(DreamActivity.EXTRA_DREAM_TITLE, fetchDreamLabel(this, serviceInfo));
try {
if (!ActivityTaskManager.getService().startDreamActivity(i)) {
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 5131e4e..425dbb9 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -1685,13 +1685,12 @@
void updatePage(EngineWindowPage currentPage, int pageIndx, int numPages,
float xOffsetStep) {
- // to save creating a runnable, check twice
- long current = System.currentTimeMillis();
+ // in case the clock is zero, we start with negative time
+ long current = SystemClock.elapsedRealtime() - DEFAULT_UPDATE_SCREENSHOT_DURATION;
long lapsed = current - currentPage.getLastUpdateTime();
// Always update the page when the last update time is <= 0
// This is important especially when the device first boots
- if (lapsed < DEFAULT_UPDATE_SCREENSHOT_DURATION
- && currentPage.getLastUpdateTime() > 0) {
+ if (lapsed < DEFAULT_UPDATE_SCREENSHOT_DURATION) {
return;
}
Surface surface = mSurfaceHolder.getSurface();
diff --git a/core/java/android/transparency/OWNERS b/core/java/android/transparency/OWNERS
index 75bf84c..ed0e5e5 100644
--- a/core/java/android/transparency/OWNERS
+++ b/core/java/android/transparency/OWNERS
@@ -1,4 +1,5 @@
-# Bug component: 36824
+# Bug component: 1164579
billylau@google.com
-vishwath@google.com
mpgroover@google.com
+vishwath@google.com
+wenhaowang@google.com
diff --git a/core/java/android/view/AccessibilityEmbeddedConnection.java b/core/java/android/view/AccessibilityEmbeddedConnection.java
index de895d9..a7d3164 100644
--- a/core/java/android/view/AccessibilityEmbeddedConnection.java
+++ b/core/java/android/view/AccessibilityEmbeddedConnection.java
@@ -33,7 +33,7 @@
*/
final class AccessibilityEmbeddedConnection extends IAccessibilityEmbeddedConnection.Stub {
private final WeakReference<ViewRootImpl> mViewRootImpl;
- private final Matrix mTmpScreenMatrix = new Matrix();
+ private final Matrix mTmpWindowMatrix = new Matrix();
AccessibilityEmbeddedConnection(ViewRootImpl viewRootImpl) {
mViewRootImpl = new WeakReference<>(viewRootImpl);
@@ -70,14 +70,14 @@
}
@Override
- public void setScreenMatrix(float[] matrixValues) {
+ public void setWindowMatrix(float[] matrixValues) {
final ViewRootImpl viewRootImpl = mViewRootImpl.get();
if (viewRootImpl != null) {
- mTmpScreenMatrix.setValues(matrixValues);
- if (viewRootImpl.mAttachInfo.mScreenMatrixInEmbeddedHierarchy == null) {
- viewRootImpl.mAttachInfo.mScreenMatrixInEmbeddedHierarchy = new Matrix();
+ mTmpWindowMatrix.setValues(matrixValues);
+ if (viewRootImpl.mAttachInfo.mWindowMatrixInEmbeddedHierarchy == null) {
+ viewRootImpl.mAttachInfo.mWindowMatrixInEmbeddedHierarchy = new Matrix();
}
- viewRootImpl.mAttachInfo.mScreenMatrixInEmbeddedHierarchy.set(mTmpScreenMatrix);
+ viewRootImpl.mAttachInfo.mWindowMatrixInEmbeddedHierarchy.set(mTmpWindowMatrix);
}
}
}
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 7e0b794..23e1505 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -22,7 +22,6 @@
import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY;
import android.graphics.Matrix;
-import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
@@ -112,10 +111,7 @@
private final ArrayList<View> mTempArrayList = new ArrayList<View>();
- private final Point mTempPoint = new Point();
private final Rect mTempRect = new Rect();
- private final Rect mTempRect1 = new Rect();
- private final Rect mTempRect2 = new Rect();
private final RectF mTempRectF = new RectF();
private AddNodeInfosForViewId mAddNodeInfosForViewId;
@@ -131,7 +127,7 @@
private int mActiveRequestPreparerId;
public AccessibilityInteractionController(ViewRootImpl viewRootImpl) {
- Looper looper = viewRootImpl.mHandler.getLooper();
+ Looper looper = viewRootImpl.mHandler.getLooper();
mMyLooperThreadId = looper.getThread().getId();
mMyProcessId = Process.myPid();
mHandler = new PrivateHandler(looper);
@@ -173,7 +169,8 @@
public void findAccessibilityNodeInfoByAccessibilityIdClientThread(
long accessibilityNodeId, Region interactiveRegion, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
- long interrogatingTid, MagnificationSpec spec, Bundle arguments) {
+ long interrogatingTid, MagnificationSpec spec, float[] matrixValues,
+ Bundle arguments) {
final Message message = mHandler.obtainMessage();
message.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID;
message.arg1 = flags;
@@ -186,6 +183,7 @@
args.arg2 = spec;
args.arg3 = interactiveRegion;
args.arg4 = arguments;
+ args.arg5 = matrixValues;
message.obj = args;
synchronized (mLock) {
@@ -344,6 +342,7 @@
final MagnificationSpec spec = (MagnificationSpec) args.arg2;
final Region interactiveRegion = (Region) args.arg3;
final Bundle arguments = (Bundle) args.arg4;
+ final float[] matrixValues = (float[]) args.arg5;
args.recycle();
@@ -378,7 +377,7 @@
if (!interruptPrefetch) {
// Return found node and prefetched nodes in one IPC.
updateInfosForViewportAndReturnFindNodeResult(infos, callback, interactionId, spec,
- interactiveRegion);
+ matrixValues, interactiveRegion);
final SatisfiedFindAccessibilityNodeByAccessibilityIdRequest satisfiedRequest =
getSatisfiedRequestInPrefetch(requestedNode == null ? null : requestedNode,
@@ -391,13 +390,13 @@
// Return found node.
updateInfoForViewportAndReturnFindNodeResult(
requestedNode == null ? null : new AccessibilityNodeInfo(requestedNode),
- callback, interactionId, spec, interactiveRegion);
+ callback, interactionId, spec, matrixValues, interactiveRegion);
}
}
mPrefetcher.prefetchAccessibilityNodeInfos(requestedView,
requestedNode == null ? null : new AccessibilityNodeInfo(requestedNode), infos);
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
- updateInfosForViewPort(infos, spec, interactiveRegion);
+ updateInfosForViewPort(infos, spec, matrixValues, interactiveRegion);
final SatisfiedFindAccessibilityNodeByAccessibilityIdRequest satisfiedRequest =
getSatisfiedRequestInPrefetch(requestedNode == null ? null : requestedNode, infos,
flags);
@@ -439,7 +438,7 @@
public void findAccessibilityNodeInfosByViewIdClientThread(long accessibilityNodeId,
String viewId, Region interactiveRegion, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
- long interrogatingTid, MagnificationSpec spec) {
+ long interrogatingTid, MagnificationSpec spec, float[] matrixValues) {
Message message = mHandler.obtainMessage();
message.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID;
message.arg1 = flags;
@@ -451,6 +450,7 @@
args.arg2 = spec;
args.arg3 = viewId;
args.arg4 = interactiveRegion;
+ args.arg5 = matrixValues;
message.obj = args;
scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
@@ -467,6 +467,7 @@
final MagnificationSpec spec = (MagnificationSpec) args.arg2;
final String viewId = (String) args.arg3;
final Region interactiveRegion = (Region) args.arg4;
+ final float[] matrixValues = (float[]) args.arg5;
args.recycle();
final List<AccessibilityNodeInfo> infos = mTempAccessibilityNodeInfoList;
@@ -494,14 +495,14 @@
} finally {
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
updateInfosForViewportAndReturnFindNodeResult(
- infos, callback, interactionId, spec, interactiveRegion);
+ infos, callback, interactionId, spec, matrixValues, interactiveRegion);
}
}
public void findAccessibilityNodeInfosByTextClientThread(long accessibilityNodeId,
String text, Region interactiveRegion, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
- long interrogatingTid, MagnificationSpec spec) {
+ long interrogatingTid, MagnificationSpec spec, float[] matrixValues) {
Message message = mHandler.obtainMessage();
message.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT;
message.arg1 = flags;
@@ -514,6 +515,7 @@
args.argi2 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId);
args.argi3 = interactionId;
args.arg4 = interactiveRegion;
+ args.arg5 = matrixValues;
message.obj = args;
scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
@@ -531,6 +533,7 @@
final int virtualDescendantId = args.argi2;
final int interactionId = args.argi3;
final Region interactiveRegion = (Region) args.arg4;
+ final float[] matrixValues = (float[]) args.arg5;
args.recycle();
List<AccessibilityNodeInfo> infos = null;
@@ -577,14 +580,14 @@
} finally {
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
updateInfosForViewportAndReturnFindNodeResult(
- infos, callback, interactionId, spec, interactiveRegion);
+ infos, callback, interactionId, spec, matrixValues, interactiveRegion);
}
}
public void findFocusClientThread(long accessibilityNodeId, int focusType,
Region interactiveRegion, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
- long interrogatingTid, MagnificationSpec spec) {
+ long interrogatingTid, MagnificationSpec spec, float[] matrixValues) {
Message message = mHandler.obtainMessage();
message.what = PrivateHandler.MSG_FIND_FOCUS;
message.arg1 = flags;
@@ -597,7 +600,7 @@
args.arg1 = callback;
args.arg2 = spec;
args.arg3 = interactiveRegion;
-
+ args.arg4 = matrixValues;
message.obj = args;
scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
@@ -615,6 +618,7 @@
(IAccessibilityInteractionConnectionCallback) args.arg1;
final MagnificationSpec spec = (MagnificationSpec) args.arg2;
final Region interactiveRegion = (Region) args.arg3;
+ final float[] matrixValues = (float[]) args.arg4;
args.recycle();
AccessibilityNodeInfo focused = null;
@@ -672,14 +676,14 @@
} finally {
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
updateInfoForViewportAndReturnFindNodeResult(
- focused, callback, interactionId, spec, interactiveRegion);
+ focused, callback, interactionId, spec, matrixValues, interactiveRegion);
}
}
public void focusSearchClientThread(long accessibilityNodeId, int direction,
Region interactiveRegion, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
- long interrogatingTid, MagnificationSpec spec) {
+ long interrogatingTid, MagnificationSpec spec, float[] matrixValues) {
Message message = mHandler.obtainMessage();
message.what = PrivateHandler.MSG_FOCUS_SEARCH;
message.arg1 = flags;
@@ -691,6 +695,7 @@
args.arg1 = callback;
args.arg2 = spec;
args.arg3 = interactiveRegion;
+ args.arg4 = matrixValues;
message.obj = args;
@@ -708,7 +713,7 @@
(IAccessibilityInteractionConnectionCallback) args.arg1;
final MagnificationSpec spec = (MagnificationSpec) args.arg2;
final Region interactiveRegion = (Region) args.arg3;
-
+ final float[] matrixValues = (float[]) args.arg4;
args.recycle();
AccessibilityNodeInfo next = null;
@@ -727,7 +732,7 @@
} finally {
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
updateInfoForViewportAndReturnFindNodeResult(
- next, callback, interactionId, spec, interactiveRegion);
+ next, callback, interactionId, spec, matrixValues, interactiveRegion);
}
}
@@ -882,13 +887,20 @@
}
}
+ // The boundInScreen includes magnification effect, so we need to normalize it before
+ // determine the visibility.
private void adjustIsVisibleToUserIfNeeded(AccessibilityNodeInfo info,
- Region interactiveRegion) {
+ Region interactiveRegion, MagnificationSpec spec) {
if (interactiveRegion == null || info == null) {
return;
}
Rect boundsInScreen = mTempRect;
info.getBoundsInScreen(boundsInScreen);
+ if (spec != null && !spec.isNop()) {
+ boundsInScreen.offset((int) -spec.offsetX, (int) -spec.offsetY);
+ boundsInScreen.scale(1 / spec.scale);
+ }
+
if (interactiveRegion.quickReject(boundsInScreen) && !shouldBypassAdjustIsVisible()) {
info.setVisibleToUser(false);
}
@@ -902,36 +914,30 @@
return false;
}
- private void applyScreenMatrixIfNeeded(List<AccessibilityNodeInfo> infos) {
- if (infos == null || shouldBypassApplyScreenMatrix()) {
- return;
- }
- final int infoCount = infos.size();
- for (int i = 0; i < infoCount; i++) {
- final AccessibilityNodeInfo info = infos.get(i);
- applyScreenMatrixIfNeeded(info);
- }
- }
-
- private void applyScreenMatrixIfNeeded(AccessibilityNodeInfo info) {
- if (info == null || shouldBypassApplyScreenMatrix()) {
+ /**
+ * Applies the host-window matrix to the embedded node. After this transform, The node bounds
+ * will be transformed from embedded window coordinates to host-window coordinates.
+ *
+ */
+ private void applyHostWindowMatrixIfNeeded(AccessibilityNodeInfo info) {
+ if (info == null || shouldBypassApplyWindowMatrix()) {
return;
}
final Rect boundsInScreen = mTempRect;
final RectF transformedBounds = mTempRectF;
- final Matrix screenMatrix = mViewRootImpl.mAttachInfo.mScreenMatrixInEmbeddedHierarchy;
+ final Matrix windowMatrix = mViewRootImpl.mAttachInfo.mWindowMatrixInEmbeddedHierarchy;
info.getBoundsInScreen(boundsInScreen);
transformedBounds.set(boundsInScreen);
- screenMatrix.mapRect(transformedBounds);
+ windowMatrix.mapRect(transformedBounds);
boundsInScreen.set((int) transformedBounds.left, (int) transformedBounds.top,
(int) transformedBounds.right, (int) transformedBounds.bottom);
info.setBoundsInScreen(boundsInScreen);
}
- private boolean shouldBypassApplyScreenMatrix() {
- final Matrix screenMatrix = mViewRootImpl.mAttachInfo.mScreenMatrixInEmbeddedHierarchy;
- return screenMatrix == null || screenMatrix.isIdentity();
+ private boolean shouldBypassApplyWindowMatrix() {
+ final Matrix windowMatrix = mViewRootImpl.mAttachInfo.mWindowMatrixInEmbeddedHierarchy;
+ return windowMatrix == null || windowMatrix.isIdentity();
}
private void associateLeashedParentIfNeeded(AccessibilityNodeInfo info) {
@@ -963,46 +969,17 @@
if (!shouldApplyAppScaleAndMagnificationSpec(applicationScale, spec)) {
return;
}
-
Rect boundsInParent = mTempRect;
- Rect boundsInScreen = mTempRect1;
info.getBoundsInParent(boundsInParent);
- info.getBoundsInScreen(boundsInScreen);
if (applicationScale != 1.0f) {
boundsInParent.scale(applicationScale);
- boundsInScreen.scale(applicationScale);
}
if (spec != null) {
boundsInParent.scale(spec.scale);
// boundsInParent must not be offset.
- boundsInScreen.scale(spec.scale);
- boundsInScreen.offset((int) spec.offsetX, (int) spec.offsetY);
}
info.setBoundsInParent(boundsInParent);
- info.setBoundsInScreen(boundsInScreen);
-
- // Scale text locations if they are present
- if (info.hasExtras()) {
- Bundle extras = info.getExtras();
- Parcelable[] textLocations =
- extras.getParcelableArray(EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY);
- if (textLocations != null) {
- for (int i = 0; i < textLocations.length; i++) {
- // Unchecked cast - an app that puts other objects in this bundle with this
- // key will crash.
- RectF textLocation = ((RectF) textLocations[i]);
- if (textLocation == null) {
- continue;
- }
- textLocation.scale(applicationScale);
- if (spec != null) {
- textLocation.scale(spec.scale);
- textLocation.offset(spec.offsetX, spec.offsetY);
- }
- }
- }
- }
}
private boolean shouldApplyAppScaleAndMagnificationSpec(float appScale,
@@ -1011,27 +988,88 @@
}
private void updateInfosForViewPort(List<AccessibilityNodeInfo> infos, MagnificationSpec spec,
- Region interactiveRegion) {
+ float[] matrixValues, Region interactiveRegion) {
for (int i = 0; i < infos.size(); i++) {
- updateInfoForViewPort(infos.get(i), spec, interactiveRegion);
+ updateInfoForViewPort(infos.get(i), spec, matrixValues, interactiveRegion);
}
}
private void updateInfoForViewPort(AccessibilityNodeInfo info, MagnificationSpec spec,
- Region interactiveRegion) {
+ float[] matrixValues, Region interactiveRegion) {
associateLeashedParentIfNeeded(info);
- applyScreenMatrixIfNeeded(info);
- // To avoid applyAppScaleAndMagnificationSpecIfNeeded changing the bounds of node,
- // then impact the visibility result, we need to adjust visibility before apply scale.
- adjustIsVisibleToUserIfNeeded(info, interactiveRegion);
+
+ applyHostWindowMatrixIfNeeded(info);
+ // Transform view bounds from window coordinates to screen coordinates.
+ transformBoundsWithScreenMatrix(info, matrixValues);
+ adjustIsVisibleToUserIfNeeded(info, interactiveRegion, spec);
applyAppScaleAndMagnificationSpecIfNeeded(info, spec);
}
+
+ /**
+ * Transforms the regions from local screen coordinate to global screen coordinate with the
+ * given transform matrix used in on-screen coordinate.
+ *
+ * @param info the AccessibilityNodeInfo that has the region in application screen coordinate
+ * @param matrixValues the matrix to be applied
+ */
+ private void transformBoundsWithScreenMatrix(AccessibilityNodeInfo info,
+ float[] matrixValues) {
+ if (info == null || matrixValues == null) {
+ return;
+ }
+ final Rect boundInScreen = mTempRect;
+ final RectF transformedBounds = mTempRectF;
+
+ info.getBoundsInScreen(boundInScreen);
+ transformedBounds.set(boundInScreen);
+
+ final Matrix transformMatrix = new Matrix();
+ transformMatrix.setValues(matrixValues);
+ final float applicationScale = mViewRootImpl.mAttachInfo.mApplicationScale;
+ if (applicationScale != 1f) {
+ transformMatrix.preScale(applicationScale, applicationScale);
+ }
+ // Transform the bounds from application screen coordinates to global window coordinates.
+ // For the embedded node, the bounds we get is already in window coordinates, so we don't
+ // need to do it.
+ if (mViewRootImpl.mAttachInfo.mWindowMatrixInEmbeddedHierarchy == null) {
+ transformMatrix.preTranslate(-mViewRootImpl.mAttachInfo.mWindowLeft,
+ -mViewRootImpl.mAttachInfo.mWindowTop);
+ }
+
+ if (transformMatrix.isIdentity()) {
+ return;
+ }
+ transformMatrix.mapRect(transformedBounds);
+ // Offset 0.5f to round after casting.
+ transformedBounds.offset(0.5f, 0.5f);
+ boundInScreen.set((int) (transformedBounds.left), (int) transformedBounds.top,
+ (int) transformedBounds.right, (int) transformedBounds.bottom);
+ info.setBoundsInScreen(boundInScreen);
+ // Scale text locations if they are present
+ if (info.hasExtras()) {
+ final Bundle extras = info.getExtras();
+ final RectF[] textLocations =
+ extras.getParcelableArray(EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY, RectF.class);
+ if (textLocations != null) {
+ for (int i = 0; i < textLocations.length; i++) {
+ // Unchecked cast - an app that puts other objects in this bundle with this
+ // key will crash.
+ final RectF textLocation = textLocations[i];
+ if (textLocation != null) {
+ transformMatrix.mapRect(textLocation);
+ }
+ }
+ }
+ }
+ }
+
private void updateInfosForViewportAndReturnFindNodeResult(List<AccessibilityNodeInfo> infos,
IAccessibilityInteractionConnectionCallback callback, int interactionId,
- MagnificationSpec spec, Region interactiveRegion) {
+ MagnificationSpec spec, float[] matrixValues, Region interactiveRegion) {
if (infos != null) {
- updateInfosForViewPort(infos, spec, interactiveRegion);
+ updateInfosForViewPort(infos, spec, matrixValues, interactiveRegion);
}
returnFindNodesResult(infos, callback, interactionId);
}
@@ -1141,8 +1179,8 @@
private void updateInfoForViewportAndReturnFindNodeResult(AccessibilityNodeInfo info,
IAccessibilityInteractionConnectionCallback callback, int interactionId,
- MagnificationSpec spec, Region interactiveRegion) {
- updateInfoForViewPort(info, spec, interactiveRegion);
+ MagnificationSpec spec, float[] matrixValues, Region interactiveRegion) {
+ updateInfoForViewPort(info, spec, matrixValues, interactiveRegion);
returnFindNodeResult(info, callback, interactionId);
}
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 7b6a0d6..cce3e8c 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -833,10 +833,12 @@
}
/**
- * @see InsetsState#calculateVisibleInsets(Rect, int)
+ * @see InsetsState#calculateVisibleInsets(Rect, int, int, int, int)
*/
- public Insets calculateVisibleInsets(@SoftInputModeFlags int softInputMode) {
- return mState.calculateVisibleInsets(mFrame, softInputMode);
+ public Insets calculateVisibleInsets(int windowType, int windowingMode,
+ @SoftInputModeFlags int softInputMode, int windowFlags) {
+ return mState.calculateVisibleInsets(mFrame, windowType, windowingMode, softInputMode,
+ windowFlags);
}
/**
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index b1b630e..eb74608 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -23,11 +23,11 @@
import static android.view.WindowInsets.Type.displayCutout;
import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.indexOf;
-import static android.view.WindowInsets.Type.isVisibleInsetsType;
import static android.view.WindowInsets.Type.statusBars;
import static android.view.WindowInsets.Type.systemBars;
import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
@@ -257,7 +257,7 @@
if ((legacyWindowFlags & FLAG_FULLSCREEN) != 0) {
compatInsetsTypes &= ~statusBars();
}
- if (clearCompatInsets(windowType, legacyWindowFlags, windowingMode)) {
+ if (clearsCompatInsets(windowType, legacyWindowFlags, windowingMode)) {
compatInsetsTypes = 0;
}
@@ -358,17 +358,23 @@
return insets;
}
- public Insets calculateVisibleInsets(Rect frame, @SoftInputModeFlags int softInputMode) {
+ public Insets calculateVisibleInsets(Rect frame, int windowType, int windowingMode,
+ @SoftInputModeFlags int softInputMode, int windowFlags) {
+ if (clearsCompatInsets(windowType, windowFlags, windowingMode)) {
+ return Insets.NONE;
+ }
+ final int softInputAdjustMode = softInputMode & SOFT_INPUT_MASK_ADJUST;
+ final int visibleInsetsTypes = softInputAdjustMode != SOFT_INPUT_ADJUST_NOTHING
+ ? systemBars() | ime()
+ : systemBars();
Insets insets = Insets.NONE;
for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
InsetsSource source = mSources[type];
if (source == null) {
continue;
}
-
- // Ignore everything that's not a system bar or IME.
- int publicType = InsetsState.toPublicType(type);
- if (!isVisibleInsetsType(publicType, softInputMode)) {
+ final int publicType = InsetsState.toPublicType(type);
+ if ((publicType & visibleInsetsTypes) == 0) {
continue;
}
insets = Insets.max(source.calculateVisibleInsets(frame), insets);
@@ -676,7 +682,7 @@
mSources[source.getType()] = source;
}
- public static boolean clearCompatInsets(int windowType, int windowFlags, int windowingMode) {
+ public static boolean clearsCompatInsets(int windowType, int windowFlags, int windowingMode) {
return (windowFlags & FLAG_LAYOUT_NO_LIMITS) != 0
&& windowType != TYPE_WALLPAPER && windowType != TYPE_SYSTEM_ERROR
&& !WindowConfiguration.inMultiWindowMode(windowingMode);
diff --git a/core/java/android/view/RemoteAccessibilityController.java b/core/java/android/view/RemoteAccessibilityController.java
index bc0fab1b..8855fb5 100644
--- a/core/java/android/view/RemoteAccessibilityController.java
+++ b/core/java/android/view/RemoteAccessibilityController.java
@@ -28,7 +28,7 @@
private static final String TAG = "RemoteAccessibilityController";
private int mHostId;
private RemoteAccessibilityEmbeddedConnection mConnectionWrapper;
- private Matrix mScreenMatrixForEmbeddedHierarchy = new Matrix();
+ private Matrix mWindowMatrixForEmbeddedHierarchy = new Matrix();
private final float[] mMatrixValues = new float[9];
private View mHostView;
@@ -140,9 +140,9 @@
return mConnectionWrapper;
}
- void setScreenMatrix(Matrix m) {
- // If the screen matrix is identity or doesn't change, do nothing.
- if (m.isIdentity() || m.equals(mScreenMatrixForEmbeddedHierarchy)) {
+ void setWindowMatrix(Matrix m) {
+ // If the window matrix is identity or doesn't change, do nothing.
+ if (m.isIdentity() || m.equals(mWindowMatrixForEmbeddedHierarchy)) {
return;
}
@@ -153,8 +153,8 @@
return;
}
m.getValues(mMatrixValues);
- wrapper.getConnection().setScreenMatrix(mMatrixValues);
- mScreenMatrixForEmbeddedHierarchy.set(m);
+ wrapper.getConnection().setWindowMatrix(mMatrixValues);
+ mWindowMatrixForEmbeddedHierarchy.set(m);
} catch (RemoteException e) {
Log.d(TAG, "Error while setScreenMatrix " + e);
}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index ed57136..96b1abb 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -967,7 +967,7 @@
final boolean redrawNeeded = sizeChanged || creating || hintChanged
|| (mVisible && !mDrawFinished);
boolean shouldSyncBuffer =
- redrawNeeded && viewRoot.wasRelayoutRequested() && viewRoot.isInSync();
+ redrawNeeded && viewRoot.wasRelayoutRequested() && viewRoot.isInLocalSync();
SyncBufferTransactionCallback syncBufferTransactionCallback = null;
if (shouldSyncBuffer) {
syncBufferTransactionCallback = new SyncBufferTransactionCallback();
@@ -1274,6 +1274,7 @@
private class SurfaceViewPositionUpdateListener implements RenderNode.PositionUpdateListener {
private final int mRtSurfaceWidth;
private final int mRtSurfaceHeight;
+ private boolean mRtFirst = true;
private final SurfaceControl.Transaction mPositionChangedTransaction =
new SurfaceControl.Transaction();
@@ -1284,14 +1285,15 @@
@Override
public void positionChanged(long frameNumber, int left, int top, int right, int bottom) {
- if (mRTLastReportedPosition.left == left
+ if (!mRtFirst && (mRTLastReportedPosition.left == left
&& mRTLastReportedPosition.top == top
&& mRTLastReportedPosition.right == right
&& mRTLastReportedPosition.bottom == bottom
&& mRTLastReportedSurfaceSize.x == mRtSurfaceWidth
- && mRTLastReportedSurfaceSize.y == mRtSurfaceHeight) {
+ && mRTLastReportedSurfaceSize.y == mRtSurfaceHeight)) {
return;
}
+ mRtFirst = false;
try {
if (DEBUG_POSITION) {
Log.d(TAG, String.format(
@@ -1781,11 +1783,16 @@
return;
}
getBoundsOnScreen(mTmpRect);
+
+ // To compute the node bounds of the node on the embedded window,
+ // apply this matrix to get the bounds in host window-relative coordinates,
+ // then using the global transform to get the actual bounds on screen.
+ mTmpRect.offset(-mAttachInfo.mWindowLeft, -mAttachInfo.mWindowTop);
mTmpMatrix.reset();
mTmpMatrix.setTranslate(mTmpRect.left, mTmpRect.top);
mTmpMatrix.postScale(mScreenRect.width() / (float) mSurfaceWidth,
mScreenRect.height() / (float) mSurfaceHeight);
- mRemoteAccessibilityController.setScreenMatrix(mTmpMatrix);
+ mRemoteAccessibilityController.setWindowMatrix(mTmpMatrix);
}
@Override
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 8b9a86b9..569461e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -29938,10 +29938,10 @@
boolean mHandlingPointerEvent;
/**
- * The screen matrix of this view when it's on a {@link SurfaceControlViewHost} that is
+ * The window matrix of this view when it's on a {@link SurfaceControlViewHost} that is
* embedded within a SurfaceView.
*/
- Matrix mScreenMatrixInEmbeddedHierarchy;
+ Matrix mWindowMatrixInEmbeddedHierarchy;
/**
* Global to the view hierarchy used as a temporary for dealing with
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index a3d0bf7..27ce711 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -319,6 +319,8 @@
*/
private static final int SCROLL_CAPTURE_REQUEST_TIMEOUT_MILLIS = 2500;
+ private static final int UNSET_SYNC_ID = -1;
+
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
static final ThreadLocal<HandlerActionQueue> sRunQueues = new ThreadLocal<HandlerActionQueue>();
@@ -815,7 +817,7 @@
}
private final SurfaceSyncer mSurfaceSyncer = new SurfaceSyncer();
- private int mLastSyncId = -1;
+ private int mSyncId = UNSET_SYNC_ID;
private SurfaceSyncer.SyncBufferCallback mSyncBufferCallback;
private int mNumSyncsInProgress = 0;
@@ -2570,7 +2572,8 @@
mAttachInfo.mContentInsets.set(mLastWindowInsets.getSystemWindowInsets().toRect());
mAttachInfo.mStableInsets.set(mLastWindowInsets.getStableInsets().toRect());
mAttachInfo.mVisibleInsets.set(mInsetsController.calculateVisibleInsets(
- mWindowAttributes.softInputMode).toRect());
+ mWindowAttributes.type, config.windowConfiguration.getWindowingMode(),
+ mWindowAttributes.softInputMode, mWindowAttributes.flags).toRect());
}
return mLastWindowInsets;
}
@@ -3462,21 +3465,21 @@
mReportNextDraw = false;
mSyncBufferCallback = null;
mSyncBuffer = false;
- if (mLastSyncId != -1) {
- mSurfaceSyncer.markSyncReady(mLastSyncId);
- mLastSyncId = -1;
+ if (isInLocalSync()) {
+ mSurfaceSyncer.markSyncReady(mSyncId);
+ mSyncId = UNSET_SYNC_ID;
}
}
}
private void createSyncIfNeeded() {
// Started a sync already or there's nothing needing to sync
- if (mLastSyncId != -1 || !mReportNextDraw) {
+ if (isInLocalSync() || !mReportNextDraw) {
return;
}
final int seqId = mSyncSeqId;
- mLastSyncId = mSurfaceSyncer.setupSync(transaction -> {
+ mSyncId = mSurfaceSyncer.setupSync(transaction -> {
// Callback will be invoked on executor thread so post to main thread.
mHandler.postAtFrontOfQueue(() -> {
mSurfaceChangedTransaction.merge(transaction);
@@ -3484,9 +3487,9 @@
});
});
if (DEBUG_BLAST) {
- Log.d(mTag, "Setup new sync id=" + mLastSyncId);
+ Log.d(mTag, "Setup new sync id=" + mSyncId);
}
- mSurfaceSyncer.addToSync(mLastSyncId, mSyncTarget);
+ mSurfaceSyncer.addToSync(mSyncId, mSyncTarget);
}
private void notifyContentCatpureEvents() {
@@ -4122,17 +4125,19 @@
return mAttachInfo.mThreadedRenderer != null && mAttachInfo.mThreadedRenderer.isEnabled();
}
- boolean addToSync(SurfaceSyncer.SyncTarget syncable) {
- if (mLastSyncId == -1) {
- return false;
+ void addToSync(SurfaceSyncer.SyncTarget syncable) {
+ if (!isInLocalSync()) {
+ return;
}
- mSurfaceSyncer.addToSync(mLastSyncId, syncable);
- return true;
+ mSurfaceSyncer.addToSync(mSyncId, syncable);
}
-
- public boolean isInSync() {
- return mLastSyncId != -1;
+ /**
+ * This VRI is currently in the middle of a sync request, but specifically one initiated from
+ * within VRI.
+ */
+ public boolean isInLocalSync() {
+ return mSyncId != UNSET_SYNC_ID;
}
private void addFrameCommitCallbackIfNeeded() {
@@ -10249,13 +10254,14 @@
public void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId,
Region interactiveRegion, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags,
- int interrogatingPid, long interrogatingTid, MagnificationSpec spec, Bundle args) {
+ int interrogatingPid, long interrogatingTid, MagnificationSpec spec, float[] matrix,
+ Bundle args) {
ViewRootImpl viewRootImpl = mViewRootImpl.get();
if (viewRootImpl != null && viewRootImpl.mView != null) {
viewRootImpl.getAccessibilityInteractionController()
.findAccessibilityNodeInfoByAccessibilityIdClientThread(accessibilityNodeId,
interactiveRegion, interactionId, callback, flags, interrogatingPid,
- interrogatingTid, spec, args);
+ interrogatingTid, spec, matrix, args);
} else {
// We cannot make the call and notify the caller so it does not wait.
try {
@@ -10290,13 +10296,14 @@
public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId,
String viewId, Region interactiveRegion, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags,
- int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+ int interrogatingPid, long interrogatingTid, MagnificationSpec spec,
+ float[] matrix) {
ViewRootImpl viewRootImpl = mViewRootImpl.get();
if (viewRootImpl != null && viewRootImpl.mView != null) {
viewRootImpl.getAccessibilityInteractionController()
.findAccessibilityNodeInfosByViewIdClientThread(accessibilityNodeId,
viewId, interactiveRegion, interactionId, callback, flags,
- interrogatingPid, interrogatingTid, spec);
+ interrogatingPid, interrogatingTid, spec, matrix);
} else {
// We cannot make the call and notify the caller so it does not wait.
try {
@@ -10311,13 +10318,14 @@
public void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text,
Region interactiveRegion, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags,
- int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+ int interrogatingPid, long interrogatingTid, MagnificationSpec spec,
+ float[] matrix) {
ViewRootImpl viewRootImpl = mViewRootImpl.get();
if (viewRootImpl != null && viewRootImpl.mView != null) {
viewRootImpl.getAccessibilityInteractionController()
.findAccessibilityNodeInfosByTextClientThread(accessibilityNodeId, text,
interactiveRegion, interactionId, callback, flags, interrogatingPid,
- interrogatingTid, spec);
+ interrogatingTid, spec, matrix);
} else {
// We cannot make the call and notify the caller so it does not wait.
try {
@@ -10331,13 +10339,14 @@
@Override
public void findFocus(long accessibilityNodeId, int focusType, Region interactiveRegion,
int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
- int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+ int interrogatingPid, long interrogatingTid, MagnificationSpec spec,
+ float[] matrix) {
ViewRootImpl viewRootImpl = mViewRootImpl.get();
if (viewRootImpl != null && viewRootImpl.mView != null) {
viewRootImpl.getAccessibilityInteractionController()
.findFocusClientThread(accessibilityNodeId, focusType, interactiveRegion,
interactionId, callback, flags, interrogatingPid, interrogatingTid,
- spec);
+ spec, matrix);
} else {
// We cannot make the call and notify the caller so it does not wait.
try {
@@ -10351,13 +10360,14 @@
@Override
public void focusSearch(long accessibilityNodeId, int direction, Region interactiveRegion,
int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
- int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+ int interrogatingPid, long interrogatingTid, MagnificationSpec spec,
+ float[] matrix) {
ViewRootImpl viewRootImpl = mViewRootImpl.get();
if (viewRootImpl != null && viewRootImpl.mView != null) {
viewRootImpl.getAccessibilityInteractionController()
.focusSearchClientThread(accessibilityNodeId, direction, interactiveRegion,
interactionId, callback, flags, interrogatingPid, interrogatingTid,
- spec);
+ spec, matrix);
} else {
// We cannot make the call and notify the caller so it does not wait.
try {
@@ -10889,6 +10899,10 @@
private void readyToSync(SurfaceSyncer.SyncBufferCallback syncBufferCallback) {
mNumSyncsInProgress++;
+ if (!isInLocalSync()) {
+ // Always sync the buffer if the sync request did not come from VRI.
+ mSyncBuffer = true;
+ }
if (mAttachInfo.mThreadedRenderer != null) {
HardwareRenderer.setRtAnimationsEnabled(false);
}
diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java
index 1edbbba..a5b8720 100644
--- a/core/java/android/view/WindowInfo.java
+++ b/core/java/android/view/WindowInfo.java
@@ -17,6 +17,7 @@
package android.view;
import android.app.ActivityTaskManager;
+import android.graphics.Matrix;
import android.graphics.Region;
import android.os.IBinder;
import android.os.Parcel;
@@ -53,6 +54,11 @@
public boolean hasFlagWatchOutsideTouch;
public int displayId = Display.INVALID_DISPLAY;
public int taskId = ActivityTaskManager.INVALID_TASK_ID;
+ // The matrix applied to the bounds in window coordinate to get the corresponding values in
+ // screen coordinates.
+ public float[] mTransformMatrix = new float[9];
+
+ public MagnificationSpec mMagnificationSpec = new MagnificationSpec();
private WindowInfo() {
/* do nothing - hide constructor */
@@ -81,6 +87,9 @@
window.accessibilityIdOfAnchor = other.accessibilityIdOfAnchor;
window.inPictureInPicture = other.inPictureInPicture;
window.hasFlagWatchOutsideTouch = other.hasFlagWatchOutsideTouch;
+ for (int i = 0; i < window.mTransformMatrix.length; i++) {
+ window.mTransformMatrix[i] = other.mTransformMatrix[i];
+ }
if (other.childTokens != null && !other.childTokens.isEmpty()) {
if (window.childTokens == null) {
@@ -89,7 +98,7 @@
window.childTokens.addAll(other.childTokens);
}
}
-
+ window.mMagnificationSpec.setTo(other.mMagnificationSpec);
return window;
}
@@ -118,6 +127,7 @@
parcel.writeLong(accessibilityIdOfAnchor);
parcel.writeInt(inPictureInPicture ? 1 : 0);
parcel.writeInt(hasFlagWatchOutsideTouch ? 1 : 0);
+ parcel.writeFloatArray(mTransformMatrix);
if (childTokens != null && !childTokens.isEmpty()) {
parcel.writeInt(1);
@@ -125,6 +135,7 @@
} else {
parcel.writeInt(0);
}
+ mMagnificationSpec.writeToParcel(parcel, flags);
}
@Override
@@ -145,6 +156,10 @@
builder.append(", accessibility anchor=").append(accessibilityIdOfAnchor);
builder.append(", pictureInPicture=").append(inPictureInPicture);
builder.append(", watchOutsideTouch=").append(hasFlagWatchOutsideTouch);
+ Matrix matrix = new Matrix();
+ matrix.setValues(mTransformMatrix);
+ builder.append(", mTransformMatrix=").append(matrix);
+ builder.append(", mMagnificationSpec=").append(mMagnificationSpec);
builder.append(']');
return builder.toString();
}
@@ -163,7 +178,7 @@
accessibilityIdOfAnchor = parcel.readLong();
inPictureInPicture = (parcel.readInt() == 1);
hasFlagWatchOutsideTouch = (parcel.readInt() == 1);
-
+ parcel.readFloatArray(mTransformMatrix);
final boolean hasChildren = (parcel.readInt() == 1);
if (hasChildren) {
if (childTokens == null) {
@@ -171,6 +186,7 @@
}
parcel.readBinderList(childTokens);
}
+ mMagnificationSpec = MagnificationSpec.CREATOR.createFromParcel(parcel);
}
private void clear() {
@@ -188,6 +204,10 @@
}
inPictureInPicture = false;
hasFlagWatchOutsideTouch = false;
+ for (int i = 0; i < mTransformMatrix.length; i++) {
+ mTransformMatrix[i] = 0;
+ }
+ mMagnificationSpec.clear();
}
public static final @android.annotation.NonNull Parcelable.Creator<WindowInfo> CREATOR =
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index 1c6d93d..c846175 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -32,8 +32,6 @@
import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.indexOf;
import static android.view.WindowInsets.Type.systemBars;
-import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
-import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
import android.annotation.IntDef;
import android.annotation.IntRange;
@@ -46,7 +44,6 @@
import android.util.SparseArray;
import android.view.View.OnApplyWindowInsetsListener;
import android.view.WindowInsets.Type.InsetsType;
-import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethod;
@@ -1600,17 +1597,6 @@
public static @InsetsType int all() {
return 0xFFFFFFFF;
}
-
- /**
- * Checks whether the specified type is considered to be part of visible insets.
- * @hide
- */
- public static boolean isVisibleInsetsType(int type,
- @SoftInputModeFlags int softInputModeFlags) {
- int softInputMode = softInputModeFlags & SOFT_INPUT_MASK_ADJUST;
- return (type & Type.systemBars()) != 0
- || (softInputMode != SOFT_INPUT_ADJUST_NOTHING && (type & Type.ime()) != 0);
- }
}
/**
diff --git a/core/java/android/view/accessibility/IAccessibilityEmbeddedConnection.aidl b/core/java/android/view/accessibility/IAccessibilityEmbeddedConnection.aidl
index 707099e..75d81ed 100644
--- a/core/java/android/view/accessibility/IAccessibilityEmbeddedConnection.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityEmbeddedConnection.aidl
@@ -28,5 +28,5 @@
void disassociateEmbeddedHierarchy();
- oneway void setScreenMatrix(in float[] matrixValues);
+ oneway void setWindowMatrix(in float[] matrixValues);
}
diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
index deb0d2a..472a363 100644
--- a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
@@ -34,23 +34,24 @@
void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId, in Region bounds,
int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
int interrogatingPid, long interrogatingTid, in MagnificationSpec spec,
- in Bundle arguments);
+ in float[] matrixValues, in Bundle arguments);
void findAccessibilityNodeInfosByViewId(long accessibilityNodeId, String viewId,
in Region bounds, int interactionId, IAccessibilityInteractionConnectionCallback callback,
- int flags, int interrogatingPid, long interrogatingTid, in MagnificationSpec spec);
+ int flags, int interrogatingPid, long interrogatingTid, in MagnificationSpec spec,
+ in float[] matrix);
void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text, in Region bounds,
int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
- int interrogatingPid, long interrogatingTid, in MagnificationSpec spec);
+ int interrogatingPid, long interrogatingTid, in MagnificationSpec spec, in float[] matrixValues);
void findFocus(long accessibilityNodeId, int focusType, in Region bounds, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
- long interrogatingTid, in MagnificationSpec spec);
+ long interrogatingTid, in MagnificationSpec spec, in float[] matrixValues);
void focusSearch(long accessibilityNodeId, int direction, in Region bounds, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
- long interrogatingTid, in MagnificationSpec spec);
+ long interrogatingTid, in MagnificationSpec spec, in float[] matrixValues);
void performAccessibilityAction(long accessibilityNodeId, int action, in Bundle arguments,
int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java
index 2d1deb2..bc9f74e 100644
--- a/core/java/android/window/SplashScreenView.java
+++ b/core/java/android/window/SplashScreenView.java
@@ -16,9 +16,6 @@
package android.window;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
-import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
-import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
-import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_SPLASHSCREEN_AVD;
@@ -29,11 +26,9 @@
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.annotation.UiThread;
-import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
@@ -52,15 +47,12 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
-import android.view.WindowInsetsController;
-import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.android.internal.R;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.policy.DecorView;
-import com.android.internal.util.ContrastColorUtil;
import java.time.Duration;
import java.time.Instant;
@@ -87,12 +79,6 @@
private static final String TAG = SplashScreenView.class.getSimpleName();
private static final boolean DEBUG = Build.IS_DEBUGGABLE;
- private static final int LIGHT_BARS_MASK =
- WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
- | WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
- private static final int WINDOW_FLAG_MASK = FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
- | FLAG_TRANSLUCENT_NAVIGATION | FLAG_TRANSLUCENT_STATUS;
-
private boolean mNotCopyable;
private boolean mIsCopied;
private int mInitBackgroundColor;
@@ -107,9 +93,6 @@
private final Rect mTmpRect = new Rect();
private final int[] mTmpPos = new int[2];
- // The host activity when transfer view to it.
- private Activity mHostActivity;
-
@Nullable
private SurfaceControlViewHost.SurfacePackage mSurfacePackageCopy;
@Nullable
@@ -123,14 +106,7 @@
// cache original window and status
private Window mWindow;
- private int mAppWindowFlags;
- private int mStatusBarColor;
- private int mNavigationBarColor;
- private int mSystemBarsAppearance;
private boolean mHasRemoved;
- private boolean mNavigationContrastEnforced;
- private boolean mStatusContrastEnforced;
- private boolean mDecorFitsSystemWindows;
/**
* Internal builder to create a SplashScreenView object.
@@ -570,7 +546,6 @@
if (decorView != null) {
decorView.removeView(this);
}
- restoreSystemUIColors();
mWindow = null;
}
mHasRemoved = true;
@@ -651,56 +626,12 @@
}
/**
- * Called when this view is attached to an activity. This also makes SystemUI colors
- * transparent so the content of splash screen view can draw fully.
+ * Called when this view is attached to a window of an activity.
*
* @hide
*/
- public void attachHostActivityAndSetSystemUIColors(Activity activity, Window window) {
- mHostActivity = activity;
+ public void attachHostWindow(Window window) {
mWindow = window;
- final WindowManager.LayoutParams attr = window.getAttributes();
- mAppWindowFlags = attr.flags;
- mStatusBarColor = window.getStatusBarColor();
- mNavigationBarColor = window.getNavigationBarColor();
- mSystemBarsAppearance = window.getInsetsController().getSystemBarsAppearance();
- mNavigationContrastEnforced = window.isNavigationBarContrastEnforced();
- mStatusContrastEnforced = window.isStatusBarContrastEnforced();
- mDecorFitsSystemWindows = window.decorFitsSystemWindows();
-
- applySystemBarsContrastColor(window.getInsetsController(), mInitBackgroundColor);
- // Let app draw the background of bars.
- window.addFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
- // Use specified bar colors instead of window background.
- window.clearFlags(FLAG_TRANSLUCENT_STATUS | FLAG_TRANSLUCENT_NAVIGATION);
- window.setStatusBarColor(Color.TRANSPARENT);
- window.setNavigationBarColor(Color.TRANSPARENT);
- window.setDecorFitsSystemWindows(false);
- window.setStatusBarContrastEnforced(false);
- window.setNavigationBarContrastEnforced(false);
- }
-
- /** Called when this view is removed from the host activity. */
- private void restoreSystemUIColors() {
- mWindow.setFlags(mAppWindowFlags, WINDOW_FLAG_MASK);
- mWindow.setStatusBarColor(mStatusBarColor);
- mWindow.setNavigationBarColor(mNavigationBarColor);
- mWindow.getInsetsController().setSystemBarsAppearance(mSystemBarsAppearance,
- LIGHT_BARS_MASK);
- mWindow.setDecorFitsSystemWindows(mDecorFitsSystemWindows);
- mWindow.setStatusBarContrastEnforced(mStatusContrastEnforced);
- mWindow.setNavigationBarContrastEnforced(mNavigationContrastEnforced);
- }
-
- /**
- * Makes the icon color of system bars contrast.
- * @hide
- */
- public static void applySystemBarsContrastColor(WindowInsetsController windowInsetsController,
- int backgroundColor) {
- final int lightBarAppearance = ContrastColorUtil.isColorLight(backgroundColor)
- ? LIGHT_BARS_MASK : 0;
- windowInsetsController.setSystemBarsAppearance(lightBarAppearance, LIGHT_BARS_MASK);
}
/**
diff --git a/core/java/android/window/TaskFragmentInfo.java b/core/java/android/window/TaskFragmentInfo.java
index a118f9a..f72164e 100644
--- a/core/java/android/window/TaskFragmentInfo.java
+++ b/core/java/android/window/TaskFragmentInfo.java
@@ -52,9 +52,6 @@
@NonNull
private final Configuration mConfiguration = new Configuration();
- /** Whether the TaskFragment contains any child Window Container. */
- private final boolean mIsEmpty;
-
/** The number of the running activities in the TaskFragment. */
private final int mRunningActivityCount;
@@ -77,21 +74,27 @@
*/
private final boolean mIsTaskClearedForReuse;
+ /**
+ * Whether the last running activity in the TaskFragment was reparented to a different Task
+ * because it is entering PiP.
+ */
+ private final boolean mIsTaskFragmentClearedForPip;
+
/** @hide */
public TaskFragmentInfo(
@NonNull IBinder fragmentToken, @NonNull WindowContainerToken token,
- @NonNull Configuration configuration, boolean isEmpty, int runningActivityCount,
+ @NonNull Configuration configuration, int runningActivityCount,
boolean isVisible, @NonNull List<IBinder> activities, @NonNull Point positionInParent,
- boolean isTaskClearedForReuse) {
+ boolean isTaskClearedForReuse, boolean isTaskFragmentClearedForPip) {
mFragmentToken = requireNonNull(fragmentToken);
mToken = requireNonNull(token);
mConfiguration.setTo(configuration);
- mIsEmpty = isEmpty;
mRunningActivityCount = runningActivityCount;
mIsVisible = isVisible;
mActivities.addAll(activities);
mPositionInParent = requireNonNull(positionInParent);
mIsTaskClearedForReuse = isTaskClearedForReuse;
+ mIsTaskFragmentClearedForPip = isTaskFragmentClearedForPip;
}
@NonNull
@@ -110,7 +113,7 @@
}
public boolean isEmpty() {
- return mIsEmpty;
+ return mRunningActivityCount == 0;
}
public boolean hasRunningActivity() {
@@ -140,6 +143,11 @@
return mIsTaskClearedForReuse;
}
+ /** @hide */
+ public boolean isTaskFragmentClearedForPip() {
+ return mIsTaskFragmentClearedForPip;
+ }
+
@WindowingMode
public int getWindowingMode() {
return mConfiguration.windowConfiguration.getWindowingMode();
@@ -156,25 +164,25 @@
return mFragmentToken.equals(that.mFragmentToken)
&& mToken.equals(that.mToken)
- && mIsEmpty == that.mIsEmpty
&& mRunningActivityCount == that.mRunningActivityCount
&& mIsVisible == that.mIsVisible
&& getWindowingMode() == that.getWindowingMode()
&& mActivities.equals(that.mActivities)
&& mPositionInParent.equals(that.mPositionInParent)
- && mIsTaskClearedForReuse == that.mIsTaskClearedForReuse;
+ && mIsTaskClearedForReuse == that.mIsTaskClearedForReuse
+ && mIsTaskFragmentClearedForPip == that.mIsTaskFragmentClearedForPip;
}
private TaskFragmentInfo(Parcel in) {
mFragmentToken = in.readStrongBinder();
mToken = in.readTypedObject(WindowContainerToken.CREATOR);
mConfiguration.readFromParcel(in);
- mIsEmpty = in.readBoolean();
mRunningActivityCount = in.readInt();
mIsVisible = in.readBoolean();
in.readBinderList(mActivities);
mPositionInParent = requireNonNull(in.readTypedObject(Point.CREATOR));
mIsTaskClearedForReuse = in.readBoolean();
+ mIsTaskFragmentClearedForPip = in.readBoolean();
}
/** @hide */
@@ -183,12 +191,12 @@
dest.writeStrongBinder(mFragmentToken);
dest.writeTypedObject(mToken, flags);
mConfiguration.writeToParcel(dest, flags);
- dest.writeBoolean(mIsEmpty);
dest.writeInt(mRunningActivityCount);
dest.writeBoolean(mIsVisible);
dest.writeBinderList(mActivities);
dest.writeTypedObject(mPositionInParent, flags);
dest.writeBoolean(mIsTaskClearedForReuse);
+ dest.writeBoolean(mIsTaskFragmentClearedForPip);
}
@NonNull
@@ -210,12 +218,12 @@
return "TaskFragmentInfo{"
+ " fragmentToken=" + mFragmentToken
+ " token=" + mToken
- + " isEmpty=" + mIsEmpty
+ " runningActivityCount=" + mRunningActivityCount
+ " isVisible=" + mIsVisible
+ " activities=" + mActivities
+ " positionInParent=" + mPositionInParent
+ " isTaskClearedForReuse=" + mIsTaskClearedForReuse
+ + " isTaskFragmentClearedForPip" + mIsTaskFragmentClearedForPip
+ "}";
}
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 2f7c015..1db4bbb 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -22,7 +22,7 @@
import static android.os.Build.VERSION_CODES.N;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
-import static android.view.InsetsState.clearCompatInsets;
+import static android.view.InsetsState.clearsCompatInsets;
import static android.view.View.MeasureSpec.AT_MOST;
import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.getMode;
@@ -1120,11 +1120,11 @@
: controller.getSystemBarsAppearance();
if (insets != null) {
- final boolean clearCompatInsets = clearCompatInsets(attrs.type, attrs.flags,
+ final boolean clearsCompatInsets = clearsCompatInsets(attrs.type, attrs.flags,
getResources().getConfiguration().windowConfiguration.getWindowingMode());
final Insets stableBarInsets = insets.getInsetsIgnoringVisibility(
WindowInsets.Type.systemBars());
- final Insets systemInsets = clearCompatInsets
+ final Insets systemInsets = clearsCompatInsets
? Insets.NONE
: Insets.min(insets.getInsets(WindowInsets.Type.systemBars()
| WindowInsets.Type.displayCutout()), stableBarInsets);
diff --git a/core/java/com/android/internal/security/OWNERS b/core/java/com/android/internal/security/OWNERS
index 41d1d66..b702df8 100644
--- a/core/java/com/android/internal/security/OWNERS
+++ b/core/java/com/android/internal/security/OWNERS
@@ -1,3 +1,3 @@
# Bug component: 36824
-per-file VerityUtils.java = victorhsieh@google.com
+per-file VerityUtils.java = file:platform/system/security:/fsverity/OWNERS
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index 3f7c4d5..2f707a7 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -48,7 +48,7 @@
*/
public class LatencyTracker {
private static final String TAG = "LatencyTracker";
- private static final String SETTINGS_ENABLED_KEY = "enabled";
+ public static final String SETTINGS_ENABLED_KEY = "enabled";
private static final String SETTINGS_SAMPLING_INTERVAL_KEY = "sampling_interval";
private static final boolean DEBUG = false;
/** Default to being enabled on debug builds. */
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 9e5f6ea..ac6b80f 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -84,7 +84,7 @@
per-file LayoutlibLoader.cpp = diegoperez@google.com, jgaillard@google.com
# Verity
-per-file com_android_internal_security_Verity* = ebiggers@google.com, victorhsieh@google.com
+per-file com_android_internal_security_Verity* = file:platform/system/security:/fsverity/OWNERS
# VINTF
per-file android_os_VintfObject* = file:platform/system/libvintf:/OWNERS
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index bce4ed7..8012e0c 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -33,12 +33,13 @@
#include <nativehelper/ScopedUtfChars.h>
+#include "android_media_AudioAttributes.h"
#include "android_media_AudioFormat.h"
#include "android_media_AudioErrors.h"
#include "android_media_DeviceCallback.h"
+#include "android_media_JNIUtils.h"
#include "android_media_MediaMetricsJNI.h"
#include "android_media_MicrophoneInfo.h"
-#include "android_media_AudioAttributes.h"
// ----------------------------------------------------------------------------
@@ -57,8 +58,7 @@
// these fields provide access from C++ to the...
jmethodID postNativeEventInJava; //... event post callback method
jfieldID nativeRecorderInJavaObj; // provides access to the C++ AudioRecord object
- jfieldID nativeCallbackCookie; // provides access to the AudioRecord callback data
- jfieldID nativeDeviceCallback; // provides access to the JNIDeviceCallback instance
+ jfieldID jniData; // provides access to AudioRecord JNI Handle
};
static audio_record_fields_t javaAudioRecordFields;
static struct {
@@ -66,15 +66,68 @@
jfieldID fieldNanoTime; // AudioTimestamp.nanoTime
} javaAudioTimestampFields;
-struct audiorecord_callback_cookie {
- jclass audioRecord_class;
- jobject audioRecord_ref;
- bool busy;
- Condition cond;
-};
-static Mutex sLock;
-static SortedVector <audiorecord_callback_cookie *> sAudioRecordCallBackCookies;
+class AudioRecordJNIStorage : public AudioRecord::IAudioRecordCallback {
+ private:
+ // Keep in sync with frameworks/base/media/java/android/media/AudioRecord.java NATIVE_EVENT_*.
+ enum class EventType {
+ EVENT_MORE_DATA = 0, // Request to read available data from buffer.
+ // If this event is delivered but the callback handler
+ // does not want to read the available data, the handler must
+ // explicitly ignore the event by setting frameCount to zero.
+ EVENT_OVERRUN = 1, // Buffer overrun occurred.
+ EVENT_MARKER = 2, // Record head is at the specified marker position
+ // (See setMarkerPosition()).
+ EVENT_NEW_POS = 3, // Record head is at a new position
+ // (See setPositionUpdatePeriod()).
+ EVENT_NEW_IAUDIORECORD = 4, // IAudioRecord was re-created, either due to re-routing and
+ // voluntary invalidation by mediaserver, or mediaserver crash.
+ };
+
+ public:
+ AudioRecordJNIStorage(jclass audioRecordClass, jobject audioRecordWeakRef)
+ : mAudioRecordClass(audioRecordClass), mAudioRecordWeakRef(audioRecordWeakRef) {}
+ AudioRecordJNIStorage(const AudioRecordJNIStorage &) = delete;
+ AudioRecordJNIStorage& operator=(const AudioRecordJNIStorage &) = delete;
+
+ void onMarker(uint32_t) override {
+ postEvent(EventType::EVENT_MARKER);
+ }
+
+ void onNewPos(uint32_t) override {
+ postEvent(EventType::EVENT_NEW_POS);
+ }
+
+ void setDeviceCallback(const sp<JNIDeviceCallback>& callback) {
+ mDeviceCallback = callback;
+ }
+
+ sp<JNIDeviceCallback> getDeviceCallback() const { return mDeviceCallback; }
+
+ jobject getAudioTrackWeakRef() const & { return mAudioRecordWeakRef.get(); }
+
+ // If we attempt to get a jobject from a rvalue, it will soon go out of
+ // scope, and the reference count can drop to zero, which is unsafe.
+ jobject getAudioTrackWeakRef() const && = delete;
+
+ private:
+ void postEvent(EventType event, int arg = 0) const {
+ JNIEnv *env = getJNIEnvOrDie();
+ env->CallStaticVoidMethod(
+ static_cast<jclass>(mAudioRecordClass.get()),
+ javaAudioRecordFields.postNativeEventInJava,
+ mAudioRecordWeakRef.get(), static_cast<int>(event), arg, 0, nullptr);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+ }
+
+ // Mutation of this object is protected using Java concurrency constructs
+ sp<JNIDeviceCallback> mDeviceCallback;
+ const GlobalRef mAudioRecordClass;
+ const GlobalRef mAudioRecordWeakRef;
+};
// ----------------------------------------------------------------------------
@@ -85,103 +138,9 @@
#define AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED (-20)
// ----------------------------------------------------------------------------
-static void recorderCallback(int event, void* user, void *info) {
-
- audiorecord_callback_cookie *callbackInfo = (audiorecord_callback_cookie *)user;
- {
- Mutex::Autolock l(sLock);
- if (sAudioRecordCallBackCookies.indexOf(callbackInfo) < 0) {
- return;
- }
- callbackInfo->busy = true;
- }
-
- switch (event) {
- case AudioRecord::EVENT_MARKER: {
- JNIEnv *env = AndroidRuntime::getJNIEnv();
- if (user != NULL && env != NULL) {
- env->CallStaticVoidMethod(
- callbackInfo->audioRecord_class,
- javaAudioRecordFields.postNativeEventInJava,
- callbackInfo->audioRecord_ref, event, 0,0, NULL);
- if (env->ExceptionCheck()) {
- env->ExceptionDescribe();
- env->ExceptionClear();
- }
- }
- } break;
-
- case AudioRecord::EVENT_NEW_POS: {
- JNIEnv *env = AndroidRuntime::getJNIEnv();
- if (user != NULL && env != NULL) {
- env->CallStaticVoidMethod(
- callbackInfo->audioRecord_class,
- javaAudioRecordFields.postNativeEventInJava,
- callbackInfo->audioRecord_ref, event, 0,0, NULL);
- if (env->ExceptionCheck()) {
- env->ExceptionDescribe();
- env->ExceptionClear();
- }
- }
- } break;
- }
-
- {
- Mutex::Autolock l(sLock);
- callbackInfo->busy = false;
- callbackInfo->cond.broadcast();
- }
-}
-
-static sp<JNIDeviceCallback> getJniDeviceCallback(JNIEnv* env, jobject thiz)
-{
- Mutex::Autolock l(sLock);
- JNIDeviceCallback* const cb =
- (JNIDeviceCallback*)env->GetLongField(thiz,
- javaAudioRecordFields.nativeDeviceCallback);
- return sp<JNIDeviceCallback>(cb);
-}
-
-static sp<JNIDeviceCallback> setJniDeviceCallback(JNIEnv* env,
- jobject thiz,
- const sp<JNIDeviceCallback>& cb)
-{
- Mutex::Autolock l(sLock);
- sp<JNIDeviceCallback> old =
- (JNIDeviceCallback*)env->GetLongField(thiz,
- javaAudioRecordFields.nativeDeviceCallback);
- if (cb.get()) {
- cb->incStrong((void*)setJniDeviceCallback);
- }
- if (old != 0) {
- old->decStrong((void*)setJniDeviceCallback);
- }
- env->SetLongField(thiz, javaAudioRecordFields.nativeDeviceCallback, (jlong)cb.get());
- return old;
-}
-
-// ----------------------------------------------------------------------------
static sp<AudioRecord> getAudioRecord(JNIEnv* env, jobject thiz)
{
- Mutex::Autolock l(sLock);
- AudioRecord* const ar =
- (AudioRecord*)env->GetLongField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
- return sp<AudioRecord>(ar);
-}
-
-static sp<AudioRecord> setAudioRecord(JNIEnv* env, jobject thiz, const sp<AudioRecord>& ar)
-{
- Mutex::Autolock l(sLock);
- sp<AudioRecord> old =
- (AudioRecord*)env->GetLongField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
- if (ar.get()) {
- ar->incStrong((void*)setAudioRecord);
- }
- if (old != 0) {
- old->decStrong((void*)setAudioRecord);
- }
- env->SetLongField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, (jlong)ar.get());
- return old;
+ return getFieldSp<AudioRecord>(env, thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
}
// ----------------------------------------------------------------------------
@@ -211,9 +170,8 @@
env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
nSession = NULL;
- sp<AudioRecord> lpRecorder = 0;
- audiorecord_callback_cookie *lpCallbackData = NULL;
-
+ sp<AudioRecord> lpRecorder;
+ sp<AudioRecordJNIStorage> callbackData;
jclass clazz = env->GetObjectClass(thiz);
if (clazz == NULL) {
ALOGE("Can't find %s when setting up callback.", kClassPathName);
@@ -287,18 +245,14 @@
}
// create the callback information:
// this data will be passed with every AudioRecord callback
- lpCallbackData = new audiorecord_callback_cookie;
- lpCallbackData->audioRecord_class = (jclass)env->NewGlobalRef(clazz);
// we use a weak reference so the AudioRecord object can be garbage collected.
- lpCallbackData->audioRecord_ref = env->NewGlobalRef(weak_this);
- lpCallbackData->busy = false;
+ callbackData = sp<AudioRecordJNIStorage>::make(clazz, weak_this);
const status_t status =
lpRecorder->set(paa->source, sampleRateInHertz,
format, // word length, PCM
localChanMask, frameCount,
- recorderCallback, // callback_t
- lpCallbackData, // void* user
+ callbackData, // callback
0, // notificationFrames,
true, // threadCanCallJava
sessionId, AudioRecord::TRANSFER_DEFAULT, flags, -1,
@@ -330,11 +284,8 @@
// create the callback information:
// this data will be passed with every AudioRecord callback
- lpCallbackData = new audiorecord_callback_cookie;
- lpCallbackData->audioRecord_class = (jclass)env->NewGlobalRef(clazz);
- // we use a weak reference so the AudioRecord object can be garbage collected.
- lpCallbackData->audioRecord_ref = env->NewGlobalRef(weak_this);
- lpCallbackData->busy = false;
+ // This next line makes little sense
+ // callbackData = sp<AudioRecordJNIStorage>::make(clazz, weak_this);
}
nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL);
@@ -352,26 +303,20 @@
env->SetIntArrayRegion(jSampleRate, 0, 1, elements);
}
- { // scope for the lock
- Mutex::Autolock l(sLock);
- sAudioRecordCallBackCookies.add(lpCallbackData);
- }
// save our newly created C++ AudioRecord in the "nativeRecorderInJavaObj" field
// of the Java object
- setAudioRecord(env, thiz, lpRecorder);
+ setFieldSp(env, thiz, lpRecorder, javaAudioRecordFields.nativeRecorderInJavaObj);
- // save our newly created callback information in the "nativeCallbackCookie" field
- // of the Java object (in mNativeCallbackCookie) so we can free the memory in finalize()
- env->SetLongField(thiz, javaAudioRecordFields.nativeCallbackCookie, (jlong)lpCallbackData);
+ // save our newly created callback information in the "jniData" field
+ // of the Java object (in mNativeJNIDataHandle) so we can free the memory in finalize()
+ setFieldSp(env, thiz, callbackData, javaAudioRecordFields.jniData);
return (jint) AUDIO_JAVA_SUCCESS;
// failure:
native_init_failure:
- env->DeleteGlobalRef(lpCallbackData->audioRecord_class);
- env->DeleteGlobalRef(lpCallbackData->audioRecord_ref);
- delete lpCallbackData;
- env->SetLongField(thiz, javaAudioRecordFields.nativeCallbackCookie, 0);
+ setFieldSp(env, thiz, sp<AudioRecord>{}, javaAudioRecordFields.nativeRecorderInJavaObj);
+ setFieldSp(env, thiz, sp<AudioRecordJNIStorage>{}, javaAudioRecordFields.jniData);
// lpRecorder goes out of scope, so reference count drops to zero
return (jint) AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED;
@@ -411,36 +356,9 @@
#define CALLBACK_COND_WAIT_TIMEOUT_MS 1000
static void android_media_AudioRecord_release(JNIEnv *env, jobject thiz) {
- sp<AudioRecord> lpRecorder = setAudioRecord(env, thiz, 0);
- if (lpRecorder == NULL) {
- return;
- }
- ALOGV("About to delete lpRecorder: %p", lpRecorder.get());
- lpRecorder->stop();
- audiorecord_callback_cookie *lpCookie = (audiorecord_callback_cookie *)env->GetLongField(
- thiz, javaAudioRecordFields.nativeCallbackCookie);
-
- // reset the native resources in the Java object so any attempt to access
- // them after a call to release fails.
- env->SetLongField(thiz, javaAudioRecordFields.nativeCallbackCookie, 0);
-
- // delete the callback information
- if (lpCookie) {
- Mutex::Autolock l(sLock);
- ALOGV("deleting lpCookie: %p", lpCookie);
- while (lpCookie->busy) {
- if (lpCookie->cond.waitRelative(sLock,
- milliseconds(CALLBACK_COND_WAIT_TIMEOUT_MS)) !=
- NO_ERROR) {
- break;
- }
- }
- sAudioRecordCallBackCookies.remove(lpCookie);
- env->DeleteGlobalRef(lpCookie->audioRecord_class);
- env->DeleteGlobalRef(lpCookie->audioRecord_ref);
- delete lpCookie;
- }
+ setFieldSp(env, thiz, sp<AudioRecord>{}, javaAudioRecordFields.nativeRecorderInJavaObj);
+ setFieldSp(env, thiz, sp<AudioRecordJNIStorage>{}, javaAudioRecordFields.jniData);
}
@@ -685,43 +603,40 @@
return (jint)lpRecorder->getRoutedDeviceId();
}
+// Enable and Disable Callback methods are synchronized on the Java side
static void android_media_AudioRecord_enableDeviceCallback(
JNIEnv *env, jobject thiz) {
sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
- if (lpRecorder == 0) {
+ if (lpRecorder == nullptr) {
return;
}
- sp<JNIDeviceCallback> cb = getJniDeviceCallback(env, thiz);
- if (cb != 0) {
- return;
- }
- audiorecord_callback_cookie *cookie =
- (audiorecord_callback_cookie *)env->GetLongField(thiz,
- javaAudioRecordFields.nativeCallbackCookie);
- if (cookie == NULL) {
+ const auto pJniStorage =
+ getFieldSp<AudioRecordJNIStorage>(env, thiz, javaAudioRecordFields.jniData);
+ if (pJniStorage == nullptr || pJniStorage->getDeviceCallback() != nullptr) {
return;
}
- cb = new JNIDeviceCallback(env, thiz, cookie->audioRecord_ref,
- javaAudioRecordFields.postNativeEventInJava);
- status_t status = lpRecorder->addAudioDeviceCallback(cb);
- if (status == NO_ERROR) {
- setJniDeviceCallback(env, thiz, cb);
- }
+ pJniStorage->setDeviceCallback(
+ sp<JNIDeviceCallback>::make(env, thiz, pJniStorage->getAudioTrackWeakRef(),
+ javaAudioRecordFields.postNativeEventInJava));
+ lpRecorder->addAudioDeviceCallback(pJniStorage->getDeviceCallback());
}
static void android_media_AudioRecord_disableDeviceCallback(
JNIEnv *env, jobject thiz) {
-
sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
- if (lpRecorder == 0) {
+ if (lpRecorder == nullptr) {
return;
}
- sp<JNIDeviceCallback> cb = setJniDeviceCallback(env, thiz, 0);
- if (cb != 0) {
- lpRecorder->removeAudioDeviceCallback(cb);
+ const auto pJniStorage =
+ getFieldSp<AudioRecordJNIStorage>(env, thiz, javaAudioRecordFields.jniData);
+
+ if (pJniStorage == nullptr || pJniStorage->getDeviceCallback() == nullptr) {
+ return;
}
+ lpRecorder->removeAudioDeviceCallback(pJniStorage->getDeviceCallback());
+ pJniStorage->setDeviceCallback(nullptr);
}
// ----------------------------------------------------------------------------
@@ -962,17 +877,15 @@
// field names found in android/media/AudioRecord.java
#define JAVA_POSTEVENT_CALLBACK_NAME "postEventFromNative"
-#define JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME "mNativeRecorderInJavaObj"
-#define JAVA_NATIVECALLBACKINFO_FIELD_NAME "mNativeCallbackCookie"
-#define JAVA_NATIVEDEVICECALLBACK_FIELD_NAME "mNativeDeviceCallback"
+#define JAVA_NATIVEAUDIORECORDERHANDLE_FIELD_NAME "mNativeAudioRecordHandle"
+#define JAVA_NATIVEJNIDATAHANDLE_FIELD_NAME "mNativeJNIDataHandle"
// ----------------------------------------------------------------------------
int register_android_media_AudioRecord(JNIEnv *env)
{
javaAudioRecordFields.postNativeEventInJava = NULL;
javaAudioRecordFields.nativeRecorderInJavaObj = NULL;
- javaAudioRecordFields.nativeCallbackCookie = NULL;
- javaAudioRecordFields.nativeDeviceCallback = NULL;
+ javaAudioRecordFields.jniData = NULL;
// Get the AudioRecord class
@@ -983,15 +896,12 @@
"(Ljava/lang/Object;IIILjava/lang/Object;)V");
// Get the variables
- // mNativeRecorderInJavaObj
+ // mNativeAudioRecordHandle
javaAudioRecordFields.nativeRecorderInJavaObj = GetFieldIDOrDie(env,
- audioRecordClass, JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME, "J");
- // mNativeCallbackCookie
- javaAudioRecordFields.nativeCallbackCookie = GetFieldIDOrDie(env,
- audioRecordClass, JAVA_NATIVECALLBACKINFO_FIELD_NAME, "J");
-
- javaAudioRecordFields.nativeDeviceCallback = GetFieldIDOrDie(env,
- audioRecordClass, JAVA_NATIVEDEVICECALLBACK_FIELD_NAME, "J");
+ audioRecordClass, JAVA_NATIVEAUDIORECORDERHANDLE_FIELD_NAME, "J");
+ // mNativeJNIDataHandle
+ javaAudioRecordFields.jniData = GetFieldIDOrDie(env,
+ audioRecordClass, JAVA_NATIVEJNIDATAHANDLE_FIELD_NAME, "J");
// Get the RecordTimestamp class and fields
jclass audioTimestampClass = FindClassOrDie(env, "android/media/AudioTimestamp");
diff --git a/core/jni/android_media_JNIUtils.h b/core/jni/android_media_JNIUtils.h
index 9da5fa3..a413d09 100644
--- a/core/jni/android_media_JNIUtils.h
+++ b/core/jni/android_media_JNIUtils.h
@@ -64,5 +64,39 @@
return env;
}
+class GlobalRef {
+ public:
+ GlobalRef(jobject object) : GlobalRef(object, AndroidRuntime::getJNIEnv()) {}
+
+ GlobalRef(jobject object, JNIEnv* env) {
+ LOG_ALWAYS_FATAL_IF(env == nullptr, "Invalid JNIEnv when attempting to create a GlobalRef");
+ mGlobalRef = env->NewGlobalRef(object);
+ LOG_ALWAYS_FATAL_IF(env->IsSameObject(object, nullptr) == JNI_TRUE,
+ "Creating GlobalRef from null object");
+ }
+
+ GlobalRef(const GlobalRef& other) : GlobalRef(other.mGlobalRef) {}
+
+ GlobalRef(GlobalRef&& other) : mGlobalRef(other.mGlobalRef) { other.mGlobalRef = nullptr; }
+
+ // Logically const
+ GlobalRef& operator=(const GlobalRef& other) = delete;
+
+ GlobalRef& operator=(GlobalRef&& other) = delete;
+
+ ~GlobalRef() {
+ if (mGlobalRef == nullptr) return; // No reference to decrement
+ getJNIEnvOrDie()->DeleteGlobalRef(mGlobalRef);
+ }
+
+ // Valid as long as this wrapper is in scope.
+ jobject get() const {
+ return mGlobalRef;
+ }
+
+ private:
+ // Logically const. Not actually const so we can move from GlobalRef
+ jobject mGlobalRef;
+};
} // namespace android
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 518fc09..51a708b 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -24,7 +24,9 @@
#include <memory>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
#include <android-base/chrono_utils.h>
+#include <android/graphics/properties.h>
#include <android/graphics/region.h>
#include <android/gui/BnScreenCaptureListener.h>
#include <android/hardware/display/IDeviceProductInfoConstants.h>
@@ -1888,6 +1890,11 @@
return nullptr;
}
+ using aidl::android::hardware::graphics::common::PixelFormat;
+ if (support.value().format == PixelFormat::R_8 && !hwui_uses_vulkan()) {
+ return nullptr;
+ }
+
jobject jDisplayDecorationSupport =
env->NewObject(gDisplayDecorationSupportInfo.clazz, gDisplayDecorationSupportInfo.ctor);
if (jDisplayDecorationSupport == nullptr) {
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 3a063a5..084b109 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -2067,14 +2067,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Tik om meer te wete te kom en te verander."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Moenie Steur Nie het verander"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tik om te kyk wat geblokkeer word."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Gaan kennisgewinginstellings na"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"In Android 13 het programme wat jy installeer jou toestemming nodig om kennisgewings te stuur. Tik om hierdie toestemming vir bestaande programme te verander."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Herinner my later"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Maak toe"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Stelsel"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Instellings"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Kamera"</string>
@@ -2293,9 +2289,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> is vertaal."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Boodskap is vertaal uit <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> in <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Agtergrondaktiwiteit"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"’n Program gebruik tans batterykrag"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"’n Program is nog aktief"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> gebruik tans batterykrag op die agtergrond. Tik om na te gaan."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> kan batterylewe beïnvloed. Tik om aktiewe programme na te gaan."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Gaan aktiewe programme na"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Kan nie toegang tot die foon se kamera op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index ba53134..3e22089 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -2067,14 +2067,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"የበለጠ ለመረዳት እና ለመለወጥ መታ ያድርጉ።"</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"አትረብሽ ተቀይሯል"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"ምን እንደታገደ ለመፈተሽ መታ ያድርጉ።"</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"የማሳወቂያ ቅንብሮችን ይገምግሙ"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"በAndroid 13 ላይ የሚጭኗቸው መተግበሪያዎች ማሳወቂያዎችን ለመላክ የእርስዎ ፈቃድ ያስፈልጋቸዋል። ይህን ፈቃድ ለነባር መተግበሪያዎች ለመቀየር መታ ያድርጉ።"</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"በኋላ አስታውሰኝ"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"አሰናብት"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"ሥርዓት"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"ቅንብሮች"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"ካሜራ"</string>
@@ -2293,9 +2289,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> ተተርጉሟል።"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"መልዕክት ከ<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> ወደ <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> ተተርጉሟል።"</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"የበስተጀርባ እንቅስቃሴ"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"አንድ መተግበሪያ ባትሪን እየተጠቀመ ነው"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"አንድ መተግበሪያ አሁንም ገቢር ነው"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> በበስተጀርባ ውስጥ ባትሪን እየተጠቀመ ነው። ለመገምገም መታ ያድርጉ።"</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> የባትሪ ዕድሜ ላይ ተጽዕኖ ሊያሳድር ይችላል። ንቁ መተግበሪያዎችን ለመገምገም መታ ያድርጉ።"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ንቁ መተግበሪያዎችን ይፈትሹ"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"የስልኩን ካሜራ ከእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> መድረስ አይቻልም"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 5b2343f..63eb6aa 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -2297,9 +2297,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> (مُترجَم)."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"الرسالة مُترجَمة من <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> إلى <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"النشاط في الخلفية"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"تطبيق يستخدم طاقة البطارية"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"ثمة تطبيق لا يزال نشطًا"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"يستخدم التطبيق <xliff:g id="APP">%1$s</xliff:g> طاقة البطارية أثناء عمله في الخلفية. انقر لمراجعة نشاط التطبيق."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"قد يؤثر استخدام التطبيق <xliff:g id="APP">%1$s</xliff:g> على عمر البطارية. انقر للاطّلاع على التطبيقات النشطة."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"التحقّق من التطبيقات النشطة"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"يتعذّر الوصول إلى كاميرا الهاتف من على جهاز <xliff:g id="DEVICE">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index fc9601e..1fbeed8 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -439,7 +439,7 @@
<string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"এই এপে আপোনাৰ ফ\'নৰ কেলেণ্ডাৰত কার্যক্ৰম যোগ দিব, আঁতৰাব বা সলনি কৰিব পাৰে। ই এনে বাৰ্তা পঠিয়াব পাৰে যিবোৰ কেলেণ্ডাৰৰ গৰাকীৰ পৰা অহা যেন লাগে বা ই গৰাকীক নজনোৱাকৈ কাৰ্যক্ৰম সলনি কৰিব পাৰে৷"</string>
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"অতিৰিক্ত অৱস্থান দেখুওৱা নির্দেশত প্ৰৱেশ কৰক"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"অৱস্থানৰ অতিৰিক্ত নির্দেশনাসমূহত প্ৰৱেশ কৰিবলৈ এপক অনুমতি দিয়ে। ইয়ে এপটোক জিপিএছ বা অন্য অৱস্থান উৎসসমূহৰ কাৰ্যকলাপত হস্তক্ষেপ কৰাৰ সুযোগ দিব পাৰে।"</string>
- <string name="permlab_accessFineLocation" msgid="6426318438195622966">"কেৱল অগ্ৰভূমিত অৱস্থানৰ সঠিক তথ্য় পাওক"</string>
+ <string name="permlab_accessFineLocation" msgid="6426318438195622966">"কেৱল অগ্ৰভূমিত অৱস্থানৰ সঠিক তথ্য পাওক"</string>
<string name="permdesc_accessFineLocation" msgid="6732174080240016335">"এই এপ্টো ব্যৱহাৰ হৈ থকা অৱস্থাত ই অৱস্থান সেৱাসমূহৰ পৰা আপোনাৰ সঠিক অৱস্থান লাভ কৰিব পাৰে। এপ্টোৱে অৱস্থান লাভ কৰিবলৈ হ’লে আপোনাৰ ডিভাইচৰ অৱস্থান সেৱাসমূহ অন কৰি ৰাখিবই লাগিব। ইয়াৰ ফলত বেটাৰীৰ ব্যৱহাৰ বাঢ়িব পাৰে।"</string>
<string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"কেৱল অগ্ৰভূমিত আনুমানিক অৱস্থান এক্সেছ কৰক"</string>
<string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"এই এপ্টো ব্যৱহাৰ হৈ থকা অৱস্থাত ই অৱস্থান সেৱাসমূহৰ পৰা আপোনাৰ আনুমানিক অৱস্থান লাভ কৰিব পাৰে। এপ্টোৱে অৱস্থান লাভ কৰিবলৈ হ’লে আপোনাৰ ডিভাইচৰ অৱস্থান সেৱাসমূহ অন কৰি ৰাখিবই লাগিব।"</string>
@@ -471,7 +471,7 @@
<string name="permlab_accessImsCallService" msgid="442192920714863782">"আইএমএছ কল সেৱা ব্যৱহাৰ কৰিব পাৰে"</string>
<string name="permdesc_accessImsCallService" msgid="6328551241649687162">"আপোনাৰ হস্তক্ষেপৰ অবিহনে আইএমএছ সেৱা ব্যৱহাৰ কৰি কল কৰিবলৈ এপক অনুমতি দিয়ে।"</string>
<string name="permlab_readPhoneState" msgid="8138526903259297969">"ফ\'নৰ স্থিতি আৰু পৰিচয় পঢ়ক"</string>
- <string name="permdesc_readPhoneState" msgid="7229063553502788058">"ডিভাইচত থকা ফ\'নৰ সুবিধাসমূহ ব্য়ৱহাৰ কৰিবলৈ এপটোক অনুমতি দিয়ে৷ এই অনুমতিয়ে কোনো কল সক্ৰিয় হৈ থাককেই বা নাথাকক আৰু দূৰবৰ্তী নম্বৰটো কলৰ দ্বাৰা সংযোজিত হওকেই বা নহওক এপটোক ফ\'ন নম্বৰ আৰু ডিভাইচৰ পৰিচয় নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ে৷"</string>
+ <string name="permdesc_readPhoneState" msgid="7229063553502788058">"ডিভাইচত থকা ফ\'নৰ সুবিধাসমূহ ব্যৱহাৰ কৰিবলৈ এপটোক অনুমতি দিয়ে৷ এই অনুমতিয়ে কোনো কল সক্ৰিয় হৈ থাককেই বা নাথাকক আৰু দূৰবৰ্তী নম্বৰটো কলৰ দ্বাৰা সংযোজিত হওকেই বা নহওক এপটোক ফ\'ন নম্বৰ আৰু ডিভাইচৰ পৰিচয় নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ে৷"</string>
<string name="permlab_readBasicPhoneState" msgid="3214853233263871347">"প্ৰাথমিক টেলিফ\'নী স্থিতি আৰু পৰিচয় পঢ়ক"</string>
<string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"এপ্টোক ডিভাইচটোৰ প্ৰাথমিক টেলিফ’নী সুবিধাসমূহ এক্সেছ কৰাৰ অনুমতি দিয়ে।"</string>
<string name="permlab_manageOwnCalls" msgid="9033349060307561370">"ছিষ্টেমৰ জৰিয়তে কল কৰিব পাৰে"</string>
@@ -525,20 +525,20 @@
<string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"কেৱল আপোনাৰ Android TV ডিভাইচটোৱেই নহয়, মাল্টিকাষ্ট ঠিকনাবোৰ ব্যৱহাৰ কৰি এটা ৱাই-ফাই নেটৱর্কত থকা আটাইবোৰ ডিভাইচলৈ পঠিওৱা পেকেট লাভ কৰিবলৈ এপ্টোক অনুমতি দিয়ে। এই কার্যই নন-মাল্টিকাষ্ট ম’ডতকৈ অধিক পাৱাৰ ব্যৱহাৰ কৰে।"</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"আপোনাৰ ফ\'নৰ লগতে ৱাই-ফাই নেটৱর্কত থকা আটাইবোৰ ডিভাইচলৈ মাল্টিকাষ্ট ঠিকনা ব্যৱহাৰ কৰি পঠিওৱা পেকেট লাভ কৰিবলৈ এপক অনুমতি দিয়ে। এই কার্যই নন-মাল্টিকাষ্ট ম\'ডতকৈ বেটাৰীৰ অধিক চাৰ্জ ব্যৱহাৰ কৰে।"</string>
<string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"ব্লুটুথ ছেটিং এক্সেছ কৰক"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"স্থানীয় ব্লুটুথ টে\'বলেট কনফিগাৰ কৰিবলৈ আৰু দূৰৱৰ্তী ডিভাইচসমূহৰ সৈতে যোৰা লগাবলৈ আৰু বিচাৰি উলিয়াবলৈ এপটোক অনুমতি দিয়ে।"</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"স্থানীয় ব্লুটুথ টেবলেট কনফিগাৰ কৰিবলৈ আৰু দূৰৱৰ্তী ডিভাইচসমূহৰ সৈতে পেয়াৰ কৰিবলৈ আৰু বিচাৰি উলিয়াবলৈ এপ্টোক অনুমতি দিয়ে।"</string>
<string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"এপ্টোক আপোনাৰ Android TV ডিভাইচটোত ব্লুটুথ কনফিগাৰ কৰিবলৈ আৰু ৰিম’ট ডিভাইচসমূহ বিচাৰি উলিয়াবলৈ আৰু পেয়াৰ কৰিবলৈ অনুমতি দিয়ে।"</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"স্থানীয় ব্লুটুথ ফ\'ন কনফিগাৰ কৰিবলৈ আৰু দূৰৱৰ্তী ডিভাইচসমূহৰ সৈতে যোৰা লগাবলৈ আৰু বিচাৰি উলিয়াবলৈ এপটোক অনুমতি দিয়ে।"</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"স্থানীয় ব্লুটুথ ফ’ন কনফিগাৰ কৰিবলৈ আৰু দূৰৱৰ্তী ডিভাইচসমূহৰ সৈতে পেয়াৰ কৰিবলৈ আৰু বিচাৰি উলিয়াবলৈ এপ্টোক অনুমতি দিয়ে।"</string>
<string name="permlab_accessWimaxState" msgid="7029563339012437434">"WiMAXৰ লগত সংযোগ কৰক আৰু ইয়াৰ পৰা সংযোগ বিচ্ছিন্ন কৰক"</string>
<string name="permdesc_accessWimaxState" msgid="5372734776802067708">"WiMAX সক্ষম হৈ আছেনে নাই আৰু সংযোজিত যিকোনো WiMAX নেটৱৰ্কৰ বিষয়ে তথ্য নিৰ্ধাৰণ কৰিবলৈ এপটোক অনুমতি দিয়ে৷"</string>
<string name="permlab_changeWimaxState" msgid="6223305780806267462">"WiMAXৰ স্থিতি সলনি কৰক"</string>
<string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"এপটোক টেবলেটলৈ সংযোগ কৰিবলৈ আৰু WiMAX নেটৱৰ্কসমূহৰ পৰা টেবলেটৰ সংযোগ বিচ্ছিন্ন কৰিবলৈ অনুমতি দিয়ে৷"</string>
<string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"এপ্টোক আপোনাৰ Android TV ডিভাইচৰ সৈতে সংযোগ কৰিবলৈ আৰু WiMAX নেটৱৰ্কসমূহৰ পৰা আপোনাৰ Android TV ডিভাইচৰ সংযোগ বিচ্ছিন্ন কৰিবলৈ অনুমতি দিয়ে।"</string>
<string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"এপটোক ফ\'নলৈ সংযোগ কৰিবলৈ আৰু WiMAX নেটৱৰ্কসমূহৰ পৰা ফ\'নৰ সংযোগ বিচ্ছিন্ন কৰিবলৈ অনুমতি দিয়ে৷"</string>
- <string name="permlab_bluetooth" msgid="586333280736937209">"ব্লুটুথ ডিভাইচবোৰৰ সৈতে যোৰা লগাওক"</string>
+ <string name="permlab_bluetooth" msgid="586333280736937209">"ব্লুটুথ ডিভাইচবোৰৰ সৈতে পেয়াৰ কৰক"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"টেবলেটত ব্লুটুথৰ কনফিগাৰেশ্বন চাবলৈ আৰু যোৰা লগোৱা ডিভাইচসমূহৰ জৰিয়তে সংযোগ কৰিবলৈ আৰু সংযোগৰ অনুৰোধ স্বীকাৰ কৰিবলৈ এপটোক অনুমতি দিয়ে৷"</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"এপ্টোক আপোনাৰ Android TV ডিভাইচটোত ব্লুটুথৰ কনফিগাৰেশ্বন চাবলৈ আৰু পেয়াৰ কৰি থোৱা ডিভাইচসমূহৰ সৈতে সংযোগ কৰিবলৈ আৰু গ্ৰহণ কৰিবলৈ অনুমতি দিয়ে।"</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"ফ\'নটোত ব্লুটুথৰ কনফিগাৰেশ্বন চাবলৈ আৰু যোৰা লগোৱা ডিভাইচসমূহৰ জৰিয়তে সংযোগ কৰিবলৈ আৰু সংযোগৰ অনুৰোধ স্বীকাৰ কৰিবলৈ এপটোক অনুমতি দিয়ে৷"</string>
- <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"নিকটৱৰ্তী ব্লুটুথ ডিভাইচ বিচাৰক আৰু তাৰ সৈতে সংযোগ কৰক"</string>
+ <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"নিকটৱৰ্তী ব্লুটুথ ডিভাইচ বিচাৰক আৰু তাৰ সৈতে পেয়াৰ কৰক"</string>
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"এপ্টোক নিকটৱৰ্তী ব্লুটুথ ডিভাইচ বিচাৰি উলিয়াবলৈ আৰু সেইসমূহৰ সৈতে পেয়াৰ কৰিবলৈ অনুমতি দিয়ে"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"পেয়াৰ কৰা ব্লুটুথ ডিভাইচৰ সৈতে সংযোগ কৰক"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"এপ্টোক পেয়াৰ কৰা ব্লুটুথ ডিভাইচৰ সৈতে সংযোগ কৰিবলৈ অনুমতি দিয়ে"</string>
@@ -558,12 +558,12 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"এপ্টোক স্ক্ৰীন লকৰ জটিলতাৰ স্তৰ (উচ্চ, মধ্যম, নিম্ন বা একেবাৰে নাই)ৰ বিষয়ে জানিবলৈ অনুমতি দিয়ে, যিয়ে স্ক্ৰীন লকৰ সম্ভাব্য দৈৰ্ঘ্য বা স্ক্ৰীন লকৰ প্ৰকাৰ দৰ্শায়। লগতে এপ্টোৱে ব্যৱহাৰকাৰীক স্ক্ৰীন লকটো এটা নিৰ্দিষ্ট স্তৰলৈ আপডে’ট কৰিবলৈ পৰামৰ্শ দিব পাৰে যিটো ব্যৱহাৰকাৰীয়ে অৱজ্ঞা কৰি পৰৱর্তী পৃষ্ঠালৈ যাব পাৰে। মনত ৰাখিব যে স্ক্ৰীন লকটো সাধাৰণ পাঠ হিচাপে ষ্ট\'ৰ কৰা নহয়; সেয়েহে, এপ্টোৱে সঠিক পাছৱৰ্ডটো জানিব নোৱাৰে।"</string>
<string name="permlab_postNotification" msgid="4875401198597803658">"জাননী দেখুৱাওক"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"এপ্টোক জাননী দেখুৱাবলৈ দিয়ে"</string>
- <string name="permlab_useBiometric" msgid="6314741124749633786">"বায়োমেট্ৰিক হাৰ্ডৱেৰ ব্য়ৱহাৰ কৰক"</string>
- <string name="permdesc_useBiometric" msgid="7502858732677143410">"বিশ্বাসযোগ্য়তা প্ৰমাণীকৰণৰ বাবে এপক বায়োমেট্ৰিক হাৰ্ডৱেৰ ব্য়ৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string>
+ <string name="permlab_useBiometric" msgid="6314741124749633786">"বায়োমেট্ৰিক হাৰ্ডৱেৰ ব্যৱহাৰ কৰক"</string>
+ <string name="permdesc_useBiometric" msgid="7502858732677143410">"বিশ্বাসযোগ্য়তা প্ৰমাণীকৰণৰ বাবে এপক বায়োমেট্ৰিক হাৰ্ডৱেৰ ব্যৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"ফিংগাৰপ্ৰিণ্ট হাৰ্ডৱেৰ পৰিচালনা কৰিব পাৰে"</string>
<string name="permdesc_manageFingerprint" msgid="2025616816437339865">"ফিংগাৰপ্ৰিণ্ট টেম্প্লেটসমূহ যোগ কৰা বা মচাৰ পদ্ধতিসমূহ কামত লগাবলৈ নিৰ্দেশ দিবলৈ এপটোক অনুমতি দিয়ে।"</string>
<string name="permlab_useFingerprint" msgid="1001421069766751922">"ফিংগাৰপ্ৰিণ্ট হাৰ্ডৱেৰ ব্যৱহাৰ কৰিব পাৰে"</string>
- <string name="permdesc_useFingerprint" msgid="412463055059323742">"প্ৰমাণীকৰণৰ বাবে ফিংগাৰপ্ৰিণ্ট হাৰ্ডৱেৰ ব্য়ৱহাৰ কৰিবলৈ এপটোক অনুমতি দিয়ে"</string>
+ <string name="permdesc_useFingerprint" msgid="412463055059323742">"প্ৰমাণীকৰণৰ বাবে ফিংগাৰপ্ৰিণ্ট হাৰ্ডৱেৰ ব্যৱহাৰ কৰিবলৈ এপটোক অনুমতি দিয়ে"</string>
<string name="permlab_audioWrite" msgid="8501705294265669405">"আপোনাৰ সংগীত সংগ্ৰহ সালসলনি কৰিবলৈ"</string>
<string name="permdesc_audioWrite" msgid="8057399517013412431">"এপক আপোনাৰ সংগীত সংগ্ৰহ সালসলনি কৰিবলৈ দিয়ে।"</string>
<string name="permlab_videoWrite" msgid="5940738769586451318">"আপোনাৰ ভিডিঅ’ সংগ্ৰহ সালসলনি কৰিবলৈ"</string>
@@ -768,13 +768,13 @@
<string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"সর্তকবাণী নিদিয়াকৈয়ে ফেক্টৰী ডেটা ৰিছেট কৰি ইনফ’টেইনমেণ্ট ছিষ্টেমৰ ডেটা মোহাৰক।"</string>
<string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"সতৰ্কবাণী প্ৰেৰণ নকৰাকৈয়ে ফেক্টৰী ডেটা ৰিছেট কৰি ফ\'নৰ ডেটা মচক।"</string>
<string name="policylab_wipeData_secondaryUser" product="automotive" msgid="115034358520328373">"প্ৰ’ফাইলৰ ডেটা মোহাৰক"</string>
- <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"ব্য়ৱহাৰকাৰীৰ তথ্য় মচক"</string>
+ <string name="policylab_wipeData_secondaryUser" product="default" msgid="413813645323433166">"ব্য়ৱহাৰকাৰীৰ তথ্য মচক"</string>
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="2336676480090926470">"এই টেবলেটটোত থকা এই ব্যৱহাৰকাৰীৰ তথ্য কোনো সর্তকবাণী নিদিয়াকৈ মচি পেলাওক।"</string>
<string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"কোনো সতর্কবার্তা নপঠিওৱাকৈ এই Android TV ডিভাইচটোত এই ব্যৱহাৰকাৰীৰ ডেটা মচক।"</string>
<string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"সর্তকবাণী নিদিয়াকৈয়ে এই ইনফ’টেইনমেণ্ট ছিষ্টেমত এই প্ৰ’ফাইলটোৰ ডেটা মোহাৰক।"</string>
<string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"এই ফ\'নটোত থকা এই ব্যৱহাৰকাৰীৰ তথ্য কোনো সর্তকবাণী নিদিয়াকৈ মচি পেলাওক।"</string>
<string name="policylab_setGlobalProxy" msgid="215332221188670221">"ডিভাইচৰ বাবে গ্ল\'বেল প্ৰক্সী ছেট কৰক"</string>
- <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"নীতি সক্ষম কৰি থোৱা অৱস্থাত ব্য়ৱহাৰ কৰিবৰ বাবে ডিভাইচৰ বাবে গ্ল\'বেল প্ৰক্সী ছেট কৰক। কেৱল ডিভাইচৰ গৰাকীয়েহে গ্ল\'বেল প্ৰক্সী ছেট কৰিব পাৰে।"</string>
+ <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"নীতি সক্ষম কৰি থোৱা অৱস্থাত ব্যৱহাৰ কৰিবৰ বাবে ডিভাইচৰ বাবে গ্ল\'বেল প্ৰক্সী ছেট কৰক। কেৱল ডিভাইচৰ গৰাকীয়েহে গ্ল\'বেল প্ৰক্সী ছেট কৰিব পাৰে।"</string>
<string name="policylab_expirePassword" msgid="6015404400532459169">"স্ক্ৰীন লক পাছৱৰ্ডৰ ম্যাদ ওকলাৰ দিন ছেট কৰক"</string>
<string name="policydesc_expirePassword" msgid="9136524319325960675">"স্ক্ৰীন লকৰ পাছৱৰ্ড, পিন বা আর্হি কিমান ঘনাই সলনি কৰিব লাগিব তাক সলনি কৰক।"</string>
<string name="policylab_encryptedStorage" msgid="9012936958126670110">"ষ্ট’ৰেজৰ এনক্ৰিপশ্বন ছেট কৰক"</string>
@@ -1181,7 +1181,7 @@
<string name="whichSendApplicationNamed" msgid="4470386782693183461">"%1$sৰ জৰিয়তে শ্বেয়াৰ কৰক"</string>
<string name="whichSendApplicationLabel" msgid="7467813004769188515">"শ্বেয়াৰ কৰক"</string>
<string name="whichSendToApplication" msgid="77101541959464018">"ইয়াৰ মাধ্য়মেৰে প্ৰেৰণ কৰক"</string>
- <string name="whichSendToApplicationNamed" msgid="3385686512014670003">"%1$s ব্য়ৱহাৰ কৰি প্ৰেৰণ কৰক"</string>
+ <string name="whichSendToApplicationNamed" msgid="3385686512014670003">"%1$s ব্যৱহাৰ কৰি প্ৰেৰণ কৰক"</string>
<string name="whichSendToApplicationLabel" msgid="3543240188816513303">"প্রেৰণ কৰক"</string>
<string name="whichHomeApplication" msgid="8276350727038396616">"এটা হ\'ম এপ্ বাছনি কৰক"</string>
<string name="whichHomeApplicationNamed" msgid="5855990024847433794">"হ\'ম ৰূপে %1$s ব্যৱহাৰ কৰক"</string>
@@ -1464,7 +1464,7 @@
<string name="create_contact_using" msgid="6200708808003692594">"<xliff:g id="NUMBER">%s</xliff:g> ব্যৱহাৰ কৰি সম্পৰ্ক \n সৃষ্টি কৰক"</string>
<string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"বৰ্তমান আৰু ভৱিষ্যতে আপোনাৰ একাউণ্টত প্ৰৱেশ কৰিবলৈ তলৰ এটা বা অধিক এপে অনুমতি লাভৰ বাবে অনুৰোধ কৰিছে৷"</string>
<string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"আপুনি এই অনুৰোধক সন্মতি দিব বিচাৰেনে?"</string>
- <string name="grant_permissions_header_text" msgid="3420736827804657201">"ব্য়ৱহাৰ কৰাৰ অনুমতি বিচাৰি কৰা অনুৰোধ"</string>
+ <string name="grant_permissions_header_text" msgid="3420736827804657201">"ব্যৱহাৰ কৰাৰ অনুমতি বিচাৰি কৰা অনুৰোধ"</string>
<string name="allow" msgid="6195617008611933762">"অনুমতি দিয়ক"</string>
<string name="deny" msgid="6632259981847676572">"প্ৰত্যাখ্যান কৰক"</string>
<string name="permission_request_notification_title" msgid="1810025922441048273">"অনুমতি বিচাৰি অনুৰোধ কৰা হৈছে"</string>
@@ -1851,7 +1851,7 @@
<string name="confirm_battery_saver" msgid="5247976246208245754">"ঠিক আছে"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"বেটাৰী সঞ্চয়কাৰীয়ে গাঢ় ৰঙৰ থীম অন কৰে আৰু নেপথ্যৰ কাৰ্যকলাপ, কিছুমান ভিজুৱেল ইফেক্ট, নিৰ্দিষ্ট কিছুমান সুবিধা আৰু নেটৱৰ্কৰ সংযোগ সীমিত অথবা অফ কৰে।"</string>
<string name="battery_saver_description" msgid="8518809702138617167">"বেটাৰী সঞ্চয়কাৰীয়ে গাঢ় ৰঙৰ থীম অন কৰে আৰু নেপথ্যৰ কাৰ্যকলাপ, কিছুমান ভিজুৱেল ইফেক্ট, নিৰ্দিষ্ট কিছুমান সুবিধা আৰু নেটৱৰ্কৰ সংযোগ অফ কৰে অথবা সীমাবদ্ধ কৰে।"</string>
- <string name="data_saver_description" msgid="4995164271550590517">"ডেটা ব্য়ৱহাৰ হ্ৰাস কৰিবলৈ ডেটা সঞ্চয়কাৰীয়ে কিছুমান এপক নেপথ্য়ত ডেটা প্ৰেৰণ বা সংগ্ৰহ কৰাত বাধা প্ৰদান কৰে। আপুনি বৰ্তমান ব্য়ৱহাৰ কৰি থকা এটা এপে ডেটা এক্সেছ কৰিব পাৰে, কিন্তু সঘনাই এক্সেছ কৰিব নোৱাৰিব পাৰে। ইয়াৰ অৰ্থ উদাহৰণস্বৰূপে এয়া হ\'ব পাৰে যে, আপুনি নিটিপা পর্যন্ত প্ৰতিচ্ছবিসমূহ দেখুওৱা নহ’ব।"</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"ডেটা ব্যৱহাৰ হ্ৰাস কৰিবলৈ ডেটা সঞ্চয়কাৰীয়ে কিছুমান এপক নেপথ্য়ত ডেটা প্ৰেৰণ বা সংগ্ৰহ কৰাত বাধা প্ৰদান কৰে। আপুনি বৰ্তমান ব্যৱহাৰ কৰি থকা এটা এপে ডেটা এক্সেছ কৰিব পাৰে, কিন্তু সঘনাই এক্সেছ কৰিব নোৱাৰিব পাৰে। ইয়াৰ অৰ্থ উদাহৰণস্বৰূপে এয়া হ\'ব পাৰে যে, আপুনি নিটিপা পর্যন্ত প্ৰতিচ্ছবিসমূহ দেখুওৱা নহ’ব।"</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"ডেটা সঞ্চয়কাৰী অন কৰিবনে?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"অন কৰক"</string>
<string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{এক মিনিটৰ বাবে ({formattedTime} পৰ্যন্ত)}one{# মিনিটৰ বাবে ({formattedTime} পৰ্যন্ত)}other{# মিনিটৰ বাবে ({formattedTime} পৰ্যন্ত)}}"</string>
@@ -1933,36 +1933,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"এই মুহূৰ্তত <xliff:g id="APP_NAME">%1$s</xliff:g> উপলব্ধ নহয়।"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> উপলব্ধ নহয়"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"অনুমতিৰ প্ৰয়োজন"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"কেমেৰা উপলব্ধ নহয়"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ফ’নতে অব্যাহত ৰাখক"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"মাইক্ৰ’ফ’ন উপলব্ধ নহয়"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Android TVৰ ছেটিং উপলব্ধ নহয়"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"টেবলেটৰ ছেটিং উপলব্ধ নহয়"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"ফ’নৰ ছেটিং উপলব্ধ নহয়"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"এইটো আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ত এক্সেছ কৰিব নোৱৰি। তাৰ পৰিৱৰ্তে আপোনাৰ Android TV ডিভাইচত চেষ্টা কৰি চাওক।"</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"এইটো আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ত এক্সেছ কৰিব নোৱৰি। তাৰ পৰিৱৰ্তে আপোনাৰ টেবলেটত চেষ্টা কৰি চাওক।"</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"এইটো আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ত এক্সেছ কৰিব নোৱৰি। তাৰ পৰিৱৰ্তে আপোনাৰ ফ’নত চেষ্টা কৰি চাওক।"</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"এইটো এই মুহূৰ্তত আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ত এক্সেছ কৰিব নোৱাৰি। তাৰ পৰিৱৰ্তে আপোনাৰ Android TV ডিভাইচত চেষ্টা কৰি চাওক।"</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"এইটো এই মুহূৰ্তত আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ত এক্সেছ কৰিব নোৱাৰি। তাৰ পৰিৱৰ্তে আপোনাৰ টেবলেটত চেষ্টা কৰি চাওক।"</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"এইটো এই মুহূৰ্তত আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ত এক্সেছ কৰিব নোৱাৰি। তাৰ পৰিৱৰ্তে আপোনাৰ ফ’নত চেষ্টা কৰি চাওক।"</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"এই এপ্টোৱে অতিৰিক্ত সুৰক্ষাৰ বাবে অনুৰোধ কৰিছে। তাৰ পৰিৱৰ্তে আপোনাৰ Android TV ডিভাইচত চেষ্টা কৰি চাওক।"</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"এই এপ্টোৱে অতিৰিক্ত সুৰক্ষাৰ বাবে অনুৰোধ কৰিছে। তাৰ পৰিৱৰ্তে আপোনাৰ টেবলেটত চেষ্টা কৰি চাওক।"</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"এই এপ্টোৱে অতিৰিক্ত সুৰক্ষাৰ বাবে অনুৰোধ কৰিছে। তাৰ পৰিৱৰ্তে আপোনাৰ ফ’নত চেষ্টা কৰি চাওক।"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"এই এপটো Androidৰ এটা পুৰণা সংস্কৰণৰ বাবে প্ৰস্তুত কৰা হৈছিল, আৰু ই বিচৰাধৰণে কাম নকৰিবও পাৰে। ইয়াৰ আপডে’ট আছে নেকি চাওক, বা বিকাশকৰ্তাৰ সৈতে যোগাযোগ কৰক।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"আপডে’ট আছে নেকি চাওক"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"আপুনি নতুন বার্তা লাভ কৰিছে"</string>
@@ -2067,14 +2052,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"অধিক জানিবলৈ আৰু সলনি কৰিবলৈ টিপক।"</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"অসুবিধা নিদিব সলনি হৈছে"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"কি কি অৱৰোধ কৰা হৈছে জানিবলৈ টিপক।"</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"জাননীৰ ছেটিং পৰ্যালোচনা কৰক"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"আপুনি Android 13ত ইনষ্টল কৰা এপক জাননী পঠিয়াবলৈ আপোনাৰ অনুমতিৰ প্ৰয়োজন। আগৰে পৰা থকা এপৰ বাবে এই অনুমতিটো সলনি কৰিবলৈ টিপক।"</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"পাছত মনত পেলাই দিব"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"অগ্ৰাহ্য কৰক"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"ছিষ্টেম"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"ছেটিং"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"কেমেৰা"</string>
@@ -2293,9 +2274,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> অনুবাদ কৰা হ’ল।"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"বাৰ্তাটো <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>ৰ পৰা <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>লৈ অনুবাদ কৰা হ’ল।"</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"নেপথ্যত চলি থকা কাৰ্যকলাপ"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"এটা এপে বেটাৰী ব্যৱহাৰ কৰি আছে"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"এটা এপ্ এতিয়াও সক্ৰিয় হৈ আছে"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g>এ নেপথ্যত বেটাৰী ব্যৱহাৰ কৰি আছে। পৰ্যালোচনা কৰিবলৈ টিপক।"</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g>এ বেটাৰীৰ জীৱনকালৰ ওপৰত প্ৰভাৱ পেলাব পাৰে। সক্ৰিয় এপ্ পৰ্যালোচনা কৰিবলৈ টিপক।"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"সক্ৰিয় এপ্সমূহ পৰীক্ষা কৰক"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ৰ পৰা ফ’নটোৰ কেমেৰা এক্সেছ কৰিব নোৱাৰি"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 07f8239..b6c903a 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -2067,14 +2067,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Ətraflı məıumat əldə edərək dəyişmək üçün klikləyin."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\"Narahat Etməyin\" rejimi dəyişdirildi"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Nəyin blok edildiyini yoxlamaq üçün klikləyin."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Bildiriş ayarlarını nəzərdən keçirin"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"Android 13-də quraşdırdığınız tətbiqlər bildiriş göndərmək üçün icazənizi tələb edir. Mövcud tətbiqlər üçün bu icazəni dəyişmək üçün toxunun."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Sonra xatırladın"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Qapadın"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Ayarlar"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Kamera"</string>
@@ -2293,9 +2289,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> Tərcümə edildi."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Mesaj <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> dilindən <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> dilinə tərcümə edilib."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Arxa Fonda Fəaliyyət"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Tətbiq batareyadan istifadə edir"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Tətbiq hələ də aktivdir"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> arxa fonda batareyadan istifadə edir. Nəzərdən keçirmək üçün toxunun."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> batareyanın ömrünə təsir edə bilər. Aktiv tətbiqləri nəzərdən keçirmək üçün toxunun."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Aktiv tətbiqləri yoxlayın"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan telefonun kamerasına giriş etmək olmur"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 9d645e9..41e306f 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -2068,14 +2068,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Dodirnite da biste saznali više i promenili podešavanje."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Režim Ne uznemiravaj je promenjen"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Dodirnite da biste proverili šta je blokirano."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Pregledajte podešavanja obaveštenja"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"U Android-u 13 aplikacije koje instalirate moraju da imaju dozvolu za slanje obaveštenja. Dodirnite da biste promenili ovu dozvolu za postojeće aplikacije."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Podseti me kasnije"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Odbaci"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Podešavanja"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Kamera"</string>
@@ -2294,9 +2290,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> Prevedeno."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Poruka je prevedena sa jezika <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> na <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktivnost u pozadini"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Aplikacija koristi bateriju"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Aplikacija je i dalje aktivna"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> koristi bateriju u pozadini. Dodirnite da biste pregledali."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> može da utiče na trajanje baterije. Dodirnite da biste pregledali aktivne aplikacije."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Proverite aktivne aplikacije"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ne može da se pristupi kameri telefona sa <xliff:g id="DEVICE">%1$s</xliff:g> uređaja"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 66327b5..7fd5f2f 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -2295,9 +2295,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Паведамленне \"<xliff:g id="MESSAGE">%1$s</xliff:g>\" перакладзена."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Паведамленне перакладзена з мовы \"<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>\" на мову \"<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>\"."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Фонавая дзейнасць"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Праграма выкарыстоўвае зарад акумулятара"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Праграма па-ранейшаму актыўная"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> выкарыстоўвае зарад акумулятара ў фонавым рэжыме. Націсніце, каб праглядзець."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> можа скараціць час працы прылады ад акумулятара. Націсніце, каб праглядзець актыўныя праграмы."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Праверце актыўныя праграмы"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не ўдалося атрымаць доступ да камеры тэлефона з прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\""</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 7cab71d..28243e3 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1707,7 +1707,7 @@
<string name="accessibility_button_instructional_text" msgid="8853928358872550500">"За превключване между функциите докоснете и задръжте бутона за достъпност."</string>
<string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"За превключване между функциите прекарайте два пръста нагоре и задръжте."</string>
<string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"За превключване между функциите прекарайте три пръста нагоре и задръжте."</string>
- <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ниво на мащаба"</string>
+ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увеличение"</string>
<string name="user_switched" msgid="7249833311585228097">"Текущ потребител <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"Превключва се към: <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> излиза…"</string>
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Съобщението <xliff:g id="MESSAGE">%1$s</xliff:g> бе преведено."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Съобщението бе преведено от <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> на <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Активност на заден план"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Приложение използва батерията"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Приложение е все още активно"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> използва батерията на заден план. Докоснете за преглед."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> може да засегне живота на батерията. Докоснете за преглед на активните приложения."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверете активните приложения"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Няма достъп до камерата на телефона от вашия <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 7b6f770..8bbfa3a 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> অনুবাদ করা হয়েছে।"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"মেসেজ <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> থেকে <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> ভাষাতে অনুবাদ করা হয়েছে।"</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"ব্যাকগ্রাউন্ড অ্যাক্টিভিটি"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"কোনও একটি অ্যাপ ব্যাটারি ব্যবহার করছে"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"কোনও একটি অ্যাপ এখনও চালু আছে"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> ব্যাকগ্রাউন্ডে ব্যাটারি ব্যবহার করছে। পর্যালোচনা করতে ট্যাপ করুন।"</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ব্যাটারির আয়ুকে প্রভাবিত করতে পারে। চালু থাকা অ্যাপ পর্যালোচনা করতে ট্যাপ করুন।"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"অ্যাক্টিভ অ্যাপ চেক করুন"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"আপনার <xliff:g id="DEVICE">%1$s</xliff:g> থেকে ফোনের ক্যামেরা অ্যাক্সেস করা যাচ্ছে না"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index ad9b770..b628d5b 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1680,7 +1680,7 @@
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"UKLJUČENO"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ISKLJUČENO"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"Dozvoliti da usluga <xliff:g id="SERVICE">%1$s</xliff:g> ima punu kontrolu nad vašim uređajem?"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"Puna kontrola je prikladna za aplikacije koje vam pomažu kod potreba za pristupačnosti, ali nije za većinu aplikacija."</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"Puna kontrola je prikladna za aplikacije koje vam pomažu kod potreba pristupačnosti, ali nije za većinu aplikacija."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Prikaz i kontrola ekrana"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Može čitati sav sadržaj na ekranu i prikazivati sadržaj u drugim aplikacijama."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Prikaz i izvršavanje radnji"</string>
@@ -1934,36 +1934,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno nije dostupna."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"Nedostupno: <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Potrebno je odobrenje"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera nije dostupna"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Nastavite na telefonu"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon nije dostupan"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Postavke Android TV-a nisu dostupne"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Postavke tableta nisu dostupne"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Postavke telefona nisu dostupne"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"Toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na Android TV uređaju."</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"Toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na tabletu."</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"Toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na telefonu."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"Trenutačno toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na Android TV uređaju."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"Trenutačno toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na tabletu."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"Trenutačno toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na telefonu."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ta aplikacija zahtijeva dodatnu sigurnost. Pokušajte joj pristupiti na Android TV uređaju."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ta aplikacija zahtijeva dodatnu sigurnost. Pokušajte joj pristupiti na tabletu."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ta aplikacija zahtijeva dodatnu sigurnost. Pokušajte joj pristupiti na telefonu."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ova aplikacija je pravljena za stariju verziju Androida i možda neće ispravno raditi. Provjerite jesu li dostupna ažuriranja ili kontaktirajte programera."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Provjeri je li dostupno ažuriranje"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
@@ -2068,14 +2053,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Dodirnite da saznate više i izvršite promjene."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Način rada Ne ometaj je promijenjen"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Dodirnite da provjerite šta je blokirano."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Pregledajte postavke obavijesti"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"U Androidu 13 aplikacije koje instalirate trebaju vaše dopuštenje za slanje obavijesti. Dodirnite da biste promijenili to dopuštenje za postojeće aplikacije."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Podsjeti me kasnije"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Odbaci"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Postavke"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Kamera"</string>
@@ -2294,9 +2275,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> – prevedeno."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Poruka je prevedena s jezika <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> na <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktivnost u pozadini"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Aplikacija koristi bateriju"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Aplikacija je i dalje aktivna"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> koristi bateriju u pozadini. Dodirnite da pregledate."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> može uticati na vijek trajanja baterije. Dodirnite da pregledate aktivne aplikacije."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Provjerite aktivne aplikacije"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nije moguće pristupiti kameri telefona s uređaja <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index a318064..1a8328d 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"S\'ha traduït <xliff:g id="MESSAGE">%1$s</xliff:g>."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Missatge traduït de <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> a <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Activitat en segon pla"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Una aplicació està utilitzant la bateria"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Una aplicació encara està activa"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> està utilitzant la bateria en segon pla. Toca per revisar-ho."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> pot afectar la durada de la bateria. Toca per revisar les aplicacions actives."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Consulta les aplicacions actives"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No es pot accedir a la càmera del telèfon des del teu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 067ba2a..d078712 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -2295,9 +2295,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Překlad textu <xliff:g id="MESSAGE">%1$s</xliff:g>."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Zpráva byla přeložena z jazyka <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> do jazyka <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktivita na pozadí"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Nějaká aplikace spotřebovává baterii"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Nějaká aplikace je stále aktivní"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"Aplikace <xliff:g id="APP">%1$s</xliff:g> spotřebovává baterii na pozadí. Klepnutím to zkontrolujete."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"Aplikace <xliff:g id="APP">%1$s</xliff:g> může ovlivňovat výdrž baterie. Klepnutím zkontrolujete aktivní aplikace."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Zkontrolujte aktivní aplikace"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ze zařízení <xliff:g id="DEVICE">%1$s</xliff:g> nelze získat přístup k fotoaparátu telefonu"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 63d24e5..5545a73 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> er oversat."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Meddelelsen er oversat fra <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> til <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktivitet i baggrunden"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"En app bruger batteri"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"En app er stadig aktiv"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> bruger batteriet i baggrunden. Tryk for at gennemgå."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> kan påvirke batteritiden. Tryk for at gennemgå nye apps."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Tjek aktive apps"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Kameraet på din telefon kan ikke tilgås via din <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 1cb98c3..baed0a85 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"„<xliff:g id="MESSAGE">%1$s</xliff:g>“ wurde übersetzt."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Nachricht wurde von <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> auf <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> übersetzt."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Hintergrundaktivität"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Eine App verbraucht Strom"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Eine App ist immer noch aktiv"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> verwendet im Hintergrund den Akku. Tippe, um die App zu prüfen."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> kann die Akkulaufzeit beeinträchtigen. Tippe, um die aktiven Apps zu prüfen."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Aktive Apps prüfen"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Zugriff auf die Kamera des Smartphones über dein Gerät (<xliff:g id="DEVICE">%1$s</xliff:g>) nicht möglich"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 8bc79b7..c545ee8 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Μεταφράστηκε το μήνυμα <xliff:g id="MESSAGE">%1$s</xliff:g>."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Μήνυμα που έχει μεταφραστεί από τα <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> στα <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Δραστηριότητα στο παρασκήνιο"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Μια εφαρμογή χρησιμοποιεί την μπαταρία"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Μια εφαρμογή είναι ακόμα ενεργή"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"Η εφαρμογή <xliff:g id="APP">%1$s</xliff:g> χρησιμοποιεί την μπαταρία στο παρασκήνιο. Πατήστε για έλεγχο."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"Η εφαρμογή <xliff:g id="APP">%1$s</xliff:g> μπορεί να επηρεάσει τη διάρκεια ζωής μπαταρίας. Πατήστε για έλεγχο των ενεργών εφαρμογών."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Έλεγχος ενεργών εφαρμογών"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Δεν είναι δυνατή η πρόσβαση στην κάμερα του τηλεφώνου από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 8374b6a..6f8505a 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1933,36 +1933,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> unavailable"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permission needed"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Camera unavailable"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continue on phone"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microphone unavailable"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Android TV settings unavailable"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Tablet settings unavailable"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Phone settings unavailable"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your Android TV device instead."</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your tablet instead."</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your phone instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your Android TV device instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your tablet instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your phone instead."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"This app is requesting additional security. Try on your Android TV device instead."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"This app is requesting additional security. Try on your tablet instead."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"This app is requesting additional security. Try on your phone instead."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"This app was built for an older version of Android and may not work properly. Try checking for updates or contact the developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
@@ -2289,9 +2274,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> translated."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Message translated from <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> to <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Background activity"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"An app is using battery"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"An app is still active"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> is using battery in the background. Tap to review."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> might affect battery life. Tap to review active apps."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 523d0d3..954aad9 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1933,36 +1933,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> unavailable"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permission needed"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Camera unavailable"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continue on phone"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microphone unavailable"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Android TV settings unavailable"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Tablet settings unavailable"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Phone settings unavailable"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your Android TV device instead."</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your tablet instead."</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your phone instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your Android TV device instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your tablet instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your phone instead."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"This app is requesting additional security. Try on your Android TV device instead."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"This app is requesting additional security. Try on your tablet instead."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"This app is requesting additional security. Try on your phone instead."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"This app was built for an older version of Android and may not work properly. Try checking for updates or contact the developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
@@ -2289,9 +2274,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> translated."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Message translated from <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> to <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Background activity"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"An app is using battery"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"An app is still active"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> is using battery in the background. Tap to review."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> might affect battery life. Tap to review active apps."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index c3a6ae9..587a38b 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1933,36 +1933,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> unavailable"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permission needed"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Camera unavailable"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continue on phone"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microphone unavailable"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Android TV settings unavailable"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Tablet settings unavailable"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Phone settings unavailable"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your Android TV device instead."</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your tablet instead."</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your phone instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your Android TV device instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your tablet instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your phone instead."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"This app is requesting additional security. Try on your Android TV device instead."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"This app is requesting additional security. Try on your tablet instead."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"This app is requesting additional security. Try on your phone instead."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"This app was built for an older version of Android and may not work properly. Try checking for updates or contact the developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
@@ -2289,9 +2274,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> translated."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Message translated from <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> to <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Background activity"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"An app is using battery"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"An app is still active"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> is using battery in the background. Tap to review."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> might affect battery life. Tap to review active apps."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index f1241ad..1c66ee6 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1933,36 +1933,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> unavailable"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permission needed"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Camera unavailable"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continue on phone"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microphone unavailable"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Android TV settings unavailable"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Tablet settings unavailable"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Phone settings unavailable"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your Android TV device instead."</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your tablet instead."</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your phone instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your Android TV device instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your tablet instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your phone instead."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"This app is requesting additional security. Try on your Android TV device instead."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"This app is requesting additional security. Try on your tablet instead."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"This app is requesting additional security. Try on your phone instead."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"This app was built for an older version of Android and may not work properly. Try checking for updates or contact the developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
@@ -2289,9 +2274,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> translated."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Message translated from <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> to <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Background activity"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"An app is using battery"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"An app is still active"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> is using battery in the background. Tap to review."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> might affect battery life. Tap to review active apps."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 03511cc..05565ae 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1933,36 +1933,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> unavailable"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permission needed"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Camera unavailable"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continue on phone"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microphone unavailable"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Android TV settings unavailable"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Tablet settings unavailable"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Phone settings unavailable"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your Android TV device instead."</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your tablet instead."</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your phone instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your Android TV device instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your tablet instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your phone instead."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"This app is requesting additional security. Try on your Android TV device instead."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"This app is requesting additional security. Try on your tablet instead."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"This app is requesting additional security. Try on your phone instead."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"This app was built for an older version of Android and may not work properly. Try checking for updates, or contact the developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
@@ -2289,9 +2274,9 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> Translated."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Message translated from <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> to <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Background Activity"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"An app is using battery"</string>
+ <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"An app is draining battery"</string>
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"An app is still active"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> is using battery in the background. Tap to review."</string>
+ <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> is running in the background. Tap to manage battery usage."</string>
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> might affect battery life. Tap to review active apps."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Can’t access the phone’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 8c21052..7658f56 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Se tradujo: <xliff:g id="MESSAGE">%1$s</xliff:g>."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Se tradujo el mensaje del <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> al <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Actividad en segundo plano"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Una app está consumiendo batería"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Hay una app que sigue activa"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> está consumiendo batería en segundo plano. Presiona para revisar esta actividad."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> podría afectar la duración de la batería. Presiona para revisar las apps activas."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Consulta las apps activas"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No se puede acceder a la cámara del dispositivo desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 5eaaec0..6acde1b 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -2067,14 +2067,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Toca para obtener más información y hacer cambios."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Ha cambiado el modo No molestar"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Toca para consultar lo que se está bloqueando."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Consulta los ajustes de notificaciones"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"En Android 13, las aplicaciones que instales necesitan tu permiso para enviar notificaciones. Toca para cambiar este permiso en las aplicaciones que ya tengas."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Recordar más tarde"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Cerrar"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Ajustes"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Cámara"</string>
@@ -2293,9 +2289,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> traducido."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Mensaje traducido del <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> al <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Actividad en segundo plano"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Una aplicación está gastando batería"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Una aplicación sigue activa"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> está gastando batería en segundo plano. Toca para ver más detalles."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> podría afectar a la duración de la batería. Toca para ver las aplicaciones activas."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Consultar aplicaciones activas"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No se puede acceder a la cámara del teléfono desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 99e7ba3..8cefd0a 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Sõnum „<xliff:g id="MESSAGE">%1$s</xliff:g>” on tõlgitud."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Sõnum on tõlgitud <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> keelest <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> keelde."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Tegevus taustal"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Rakendus kasutab akutoidet"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Rakendus on ikka aktiivne"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> kasutab taustal akutoidet. Puudutage ülevaatamiseks."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> võib aku tööiga mõjutada. Puudutage aktiivsete rakenduste ülevaatamiseks."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vaadake aktiivseid rakendusi"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Teie seadmest <xliff:g id="DEVICE">%1$s</xliff:g> ei pääse telefoni kaamerale juurde"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index a7412ba..a495ee1 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -54,7 +54,7 @@
<item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> saiakera geratzen zaizkizu SIM txartela blokeatu aurretik.</item>
<item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> saiakera geratzen zaizu SIM txartela blokeatu aurretik.</item>
</plurals>
- <string name="imei" msgid="2157082351232630390">"IMEI zk."</string>
+ <string name="imei" msgid="2157082351232630390">"IMEIa"</string>
<string name="meid" msgid="3291227361605924674">"MEID"</string>
<string name="ClipMmi" msgid="4110549342447630629">"Sarrerako deien identifikazio-zerbitzua"</string>
<string name="ClirMmi" msgid="6752346475055446417">"Ezkutatu irteerako deitzailearen IDa"</string>
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Itzuli da <xliff:g id="MESSAGE">%1$s</xliff:g>."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> hizkuntzatik <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> hizkuntzara itzuli da mezua."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Atzeko planoko jarduerak"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Aplikazio bat bateria erabiltzen ari da"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Aplikazio bat aktibo dago oraindik"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> atzeko planoan bateria erabiltzen ari da. Sakatu berrikusteko."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"Baliteke <xliff:g id="APP">%1$s</xliff:g> aplikazioak bateriaren iraupenean eragina izatea. Sakatu hau aplikazio aktiboak ikusteko."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Ikusi zer aplikazio dauden aktibo"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ezin da atzitu telefonoaren kamera <xliff:g id="DEVICE">%1$s</xliff:g> gailutik"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 8519c43..0946552 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -2067,14 +2067,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"برای اطلاعات بیشتر و تغییر دادن، ضربه بزنید."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"«مزاحم نشوید» تغییر کرده است"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"برای بررسی موارد مسدودشده ضربه بزنید."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"مرور تنظیمات اعلان"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"در Android نسخه ۱۳، برنامههایی که نصب میکنید برای ارسال اعلان به اجازه شما نیاز دارند. برای تغییر دادن این اجازه برای برنامههای موجود، ضربه بزنید."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"بعداً یادآوری شود"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"رد شدن"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"سیستم"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"تنظیمات"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"دوربین"</string>
@@ -2293,9 +2289,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> ترجمه شد."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"پیام از <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> به <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> ترجمه شد."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"فعالیت در پسزمینه"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"یکی از برنامهها درحال مصرف شارژ باتری است"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"یکی از برنامهها همچنان فعال است"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> در پسزمینه از شارژ باتری استفاده میکند. برای مرور، ضربه بزنید."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ممکن است بر عمر باتری تأثیر بگذارد. برای مرور برنامههای فعال، ضربه بزنید."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"بررسی برنامههای فعال"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"نمیتوان از <xliff:g id="DEVICE">%1$s</xliff:g> شما به دوربین تلفن دسترسی داشت"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 7039858..0899c77 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1679,7 +1679,7 @@
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"PÄÄLLÄ"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"EI PÄÄLLÄ"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"Saako <xliff:g id="SERVICE">%1$s</xliff:g> laitteesi täyden käyttöoikeuden?"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"Täysi käyttöoikeus sopii esteettömyyssovelluksille, mutta ei useimmille sovelluksille."</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"Täysi käyttöoikeus sopii saavutettavuussovelluksille, mutta ei useimmille sovelluksille."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Näytön katselu ja ohjaus"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Se voi lukea kaiken näytön sisällön ja näyttää sisältöä kaikista sovelluksista."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Toimintojen näkeminen ja suorittaminen"</string>
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> käännettiin."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Viesti käännettiin kielestä <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> kielelle <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Taustatoiminta"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Sovellus käyttää akkua"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Sovellus on edelleen aktiivinen"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> käyttää akkua taustalla. Tarkista napauttamalla."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> saattaa vaikuttaa akunkestoon. Tarkista aktiiviset sovellukset napauttamalla."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Tarkista aktiiviset sovellukset"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> ei pääse puhelimen kameraan"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index cb41aab..d6b0b8c 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Message <xliff:g id="MESSAGE">%1$s</xliff:g> traduit."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Message traduit : <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> vers <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Activité en arrière-plan"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Une application consomme de l\'énergie"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Une application est toujours active"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> consomme de l\'énergie en arrière-plan. Touchez pour examiner."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> peut avoir une incidence sur l\'autonomie de la pile. Touchez pour examiner les applications actives."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vérifier les applications actives"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossible d\'accéder à l\'appareil photo du téléphone à partir de votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 14134b8..0b22e9e 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> traduit."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Message en <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> traduit en <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Activité en arrière-plan"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Une appli utilise la batterie"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Une appli est encore active"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> utilise la batterie en arrière-plan. Appuyez pour en savoir plus."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> peut affecter l\'autonomie de la batterie. Appuyez pour consulter les applis actives."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vérifier les applis actives"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossible d\'accéder à l\'appareil photo du téléphone depuis votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 8641fc1..0f32543 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Mensaxe <xliff:g id="MESSAGE">%1$s</xliff:g> traducida."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Mensaxe traducida do <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> ao <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Actividade en segundo plano"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Hai unha aplicación consumindo batería"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Hai unha aplicación que aínda está activa"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> está consumindo batería en segundo plano. Toca para revisalo."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> podería estar minguando a duración da batería. Toca para revisar as aplicacións activas."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Comprobar aplicacións activas"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Non se puido acceder á cámara do teléfono desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>)"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 2d34b8ee..8e328bd 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g>નો અનુવાદ કર્યો."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>થી <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>માં સંદેશનો અનુવાદ કરવામાં આવ્યો."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"બૅકગ્રાઉન્ડ પ્રવૃત્તિ"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"કોઈ ઍપ બૅટરીનો વપરાશ કરી રહી છે"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"કોઈ ઍપ હજી પણ સક્રિય છે"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> દ્વારા બૅકગ્રાઉન્ડમાં બૅટરીનો વપરાશ કરવામાં આવી રહ્યો છે. રિવ્યૂ કરવા માટે ટૅપ કરો."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g>, બૅટરીની આવરદાને અસર કરી શકે છે. બધી સક્રિય ઍપનો રિવ્યૂ કરવા માટે ટૅપ કરો."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"સક્રિય ઍપ ચેક કરો"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"તમારા <xliff:g id="DEVICE">%1$s</xliff:g> પરથી ફોનના કૅમેરાનો ઍક્સેસ કરી શકતાં નથી"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index a88cf03..86e90c1 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> का अनुवाद किया गया."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"मैसेज का <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> से <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> में अनुवाद किया गया."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"बैकग्राउंड में हो रही गतिविधि"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"कोई ऐप्लिकेशन, बैटरी का इस्तेमाल कर रहा है"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"कोई ऐप्लिकेशन अब भी चालू है"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g>, बैकग्राउंड में बैटरी का इस्तेमाल कर रहा है. समीक्षा करने के लिए टैप करें."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> से, आपके डिवाइस की बैटरी लाइफ़ पर असर पड़ सकता है. चालू ऐप्लिकेशन देखने के लिए टैप करें."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"चालू ऐप्लिकेशन देखें"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"आपके <xliff:g id="DEVICE">%1$s</xliff:g> से फ़ोन के कैमरे को ऐक्सेस नहीं किया जा सकता"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index cedb915..a11252198 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1934,36 +1934,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutačno nije dostupna."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – nije dostupno"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Potrebno je dopuštenje"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera nije dostupna"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Nastavite na telefonu"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon nije dostupan"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Postavke Android TV-a nisu dostupne"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Postavke tableta nisu dostupne"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Postavke telefona nisu dostupne"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"Toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na Android TV uređaju."</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"Toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na tabletu."</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"Toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na telefonu."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"Trenutačno toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na Android TV uređaju."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"Trenutačno toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na tabletu."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"Trenutačno toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na telefonu."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ta aplikacija zahtijeva dodatnu sigurnost. Pokušajte joj pristupiti na Android TV uređaju."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ta aplikacija zahtijeva dodatnu sigurnost. Pokušajte joj pristupiti na tabletu."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ta aplikacija zahtijeva dodatnu sigurnost. Pokušajte joj pristupiti na telefonu."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ova je aplikacija razvijena za stariju verziju Androida i možda neće funkcionirati pravilno. Potražite ažuriranja ili se obratite razvojnom programeru."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Provjeri ažuriranja"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
@@ -2068,14 +2053,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Dodirnite da biste saznali više i promijenili postavke."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Promijenjena je postavka Ne uznemiravaj"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Dodirnite da biste provjerili što je blokirano."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Pregledajte postavke obavijesti"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"U Androidu 13 aplikacije koje instalirate trebaju vaše dopuštenje za slanje obavijesti. Dodirnite da biste promijenili to dopuštenje za postojeće aplikacije."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Podsjeti me kasnije"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Odbaci"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sustav"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Postavke"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Fotoaparat"</string>
@@ -2294,9 +2275,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Preveden je tekst <xliff:g id="MESSAGE">%1$s</xliff:g>."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Poruka je prevedena: <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> na <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktivnost u pozadini"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Aplikacija koristi bateriju"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Aplikacija je i dalje aktivna"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> koristi bateriju u pozadini. Dodirnite za pregled."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> može utjecati na trajanje baterije. Dodirnite da biste pregledali aktivne aplikacije."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Provjera aktivnih aplikacija"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"S vašeg uređaja <xliff:g id="DEVICE">%1$s</xliff:g> nije moguće pristupiti fotoaparatu telefona"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index ba3c66c..a227b7c 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"A következő lefordítása sikeresen megtörtént: <xliff:g id="MESSAGE">%1$s</xliff:g>."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Sikerült lefordítani az üzenetet <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> nyelvről <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> nyelvre."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Háttértevékenység"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Az egyik alkalmazás használja az akkumulátort"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Az egyik alkalmazás még aktív"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"A(z) <xliff:g id="APP">%1$s</xliff:g> a háttérben használja az akkumulátort. Koppintson az áttekintéshez."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"A(z) <xliff:g id="APP">%1$s</xliff:g> befolyásolhatja az akkumulátor üzemidejét. Koppintson az aktív alkalmazások áttekintéséhez."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Aktív alkalmazások ellenőrzése"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nem lehet hozzáférni a telefon kamerájához a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 395c78b..c2aa0fb 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"«<xliff:g id="MESSAGE">%1$s</xliff:g>» հաղորդագրությունը թարգմանված է։"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Հաղորդագրությունը <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>ից թարգմանվել է <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>։"</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Ակտիվ հավելվածներ ֆոնային ռեժիմում"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Հավելվածն օգտագործում է մարտկոցի լիցքը"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Հավելվածը դեռ ակտիվ է"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> հավելվածն օգտագործում է մարտկոցի լիցքը ֆոնային ռեժիմում։ Հպեք՝ մանրամասները տեսնելու համար։"</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> հավելվածը կարող է ազդել մարտկոցի աշխատաժամանակի վրա։ Հպեք՝ ակտիվ հավելվածները տեսնելու համար։"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Ստուգել ակտիվ հավելվածները"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Հնարավոր չէ օգտագործել հեռախոսի տեսախցիկը ձեր <xliff:g id="DEVICE">%1$s</xliff:g> սարքից"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 3ab2263..17e9f61 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1014,7 +1014,7 @@
<string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nYakin ingin beranjak dari halaman ini?"</string>
<string name="save_password_label" msgid="9161712335355510035">"Konfirmasi"</string>
<string name="double_tap_toast" msgid="7065519579174882778">"Kiat: Ketuk dua kali untuk memperbesar dan memperkecil."</string>
- <string name="autofill_this_form" msgid="3187132440451621492">"IsiOtomatis"</string>
+ <string name="autofill_this_form" msgid="3187132440451621492">"Isi Otomatis"</string>
<string name="setup_autofill" msgid="5431369130866618567">"Siapkan Pengisian Otomatis"</string>
<string name="autofill_window_title" msgid="4379134104008111961">"IsiOtomatis dengan <xliff:g id="SERVICENAME">%1$s</xliff:g>"</string>
<string name="autofill_address_name_separator" msgid="8190155636149596125">" "</string>
@@ -1137,7 +1137,7 @@
<string name="selectTextMode" msgid="3225108910999318778">"Pilih teks"</string>
<string name="undo" msgid="3175318090002654673">"Urungkan"</string>
<string name="redo" msgid="7231448494008532233">"Ulangi"</string>
- <string name="autofill" msgid="511224882647795296">"IsiOtomatis"</string>
+ <string name="autofill" msgid="511224882647795296">"Isi Otomatis"</string>
<string name="textSelectionCABTitle" msgid="5151441579532476940">"Pemilihan teks"</string>
<string name="addToDictionary" msgid="8041821113480950096">"Tambahkan ke kamus"</string>
<string name="deleteText" msgid="4200807474529938112">"Hapus"</string>
@@ -1679,11 +1679,11 @@
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AKTIF"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"NONAKTIF"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"Izinkan <xliff:g id="SERVICE">%1$s</xliff:g> memiliki kontrol penuh atas perangkat Anda?"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"Kontrol penuh sesuai untuk aplikasi yang membantu Anda terkait kebutuhan aksesibilitas, tetapi tidak untuk sebagian besar aplikasi."</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"Kontrol penuh sesuai untuk aplikasi yang mendukung kebutuhan aksesibilitas Anda, tetapi tidak untuk sebagian besar aplikasi."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Melihat dan mengontrol layar"</string>
- <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Aplikasi dapat membaca semua konten di layar dan menampilkan konten di atas aplikasi lain."</string>
+ <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Voice Access dapat membaca semua konten di layar dan menampilkan konten di atas aplikasi lain."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Menampilkan dan melakukan tindakan"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Aplikasi dapat melacak interaksi Anda dengan aplikasi atau sensor hardware, dan melakukan interaksi dengan aplikasi untuk Anda."</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Voice Access dapat melacak interaksi Anda dengan aplikasi atau sensor hardware, dan berinteraksi dengan aplikasi untuk Anda."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Izinkan"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Tolak"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Ketuk fitur untuk mulai menggunakannya:"</string>
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> Diterjemahkan."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Pesan diterjemahkan dari bahasa <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> ke <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktivitas Latar Belakang"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Aplikasi sedang menggunakan daya baterai"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Aplikasi masih aktif"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> sedang menggunakan daya baterai di latar belakang. Ketuk untuk meninjau."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> mungkin memengaruhi masa pakai baterai. Ketuk untuk meninjau aplikasi aktif."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Periksa aplikasi aktif"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Tidak dapat mengakses kamera ponsel dari <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 60b571d..3a2a293 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> var þýtt."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Skilaboð þýdd úr <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> á <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Bakgrunnsvirkni"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Forrit notar rafhlöðuorku"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Forrit er enn virkt"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> notar rafhlöðuorku í bakgrunni. Ýttu til að skoða."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> gæti haft áhrif á rafhlöðuendingu. Ýttu til að skoða virk forrit."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Skoða virk forrit"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ekki er hægt að opna myndavél símans úr <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index f1771aa..e07f93c5 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1851,7 +1851,7 @@
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Il risparmio energetico attiva il tema scuro e limita o disattiva l\'attività in background, nonché alcuni effetti visivi, funzionalità e connessioni di rete."</string>
<string name="battery_saver_description" msgid="8518809702138617167">"Il risparmio energetico attiva il tema scuro e limita o disattiva l\'attività in background, nonché alcuni effetti visivi, funzionalità e connessioni di rete."</string>
- <string name="data_saver_description" msgid="4995164271550590517">"Per contribuire a ridurre l\'utilizzo dei dati, la funzione Risparmio dati impedisce ad alcune app di inviare o ricevere dati in background. Un\'app in uso può accedere ai dati, ma potrebbe farlo con meno frequenza. Esempio: le immagini non vengono visualizzate finché non le tocchi."</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"Per contribuire a ridurre l\'utilizzo dei dati, la funzionalità Risparmio dati impedisce ad alcune app di inviare o ricevere dati in background. Un\'app in uso può accedere ai dati, ma potrebbe farlo con meno frequenza. Per esempio, è possibile che le immagini non vengano visualizzate finché non le tocchi."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Attivare Risparmio dati?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Attiva"</string>
<string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Per un minuto (fino alle ore {formattedTime})}other{Per # minuti (fino alle ore {formattedTime})}}"</string>
@@ -2067,14 +2067,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Tocca per avere ulteriori informazioni e modificare."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"L\'impostazione Non disturbare è cambiata"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tocca per controllare le notifiche bloccate."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Controlla le impostazioni di notifica"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"In Android 13, le app che installi devono avere la tua autorizzazione per poter inviare notifiche. Tocca per cambiare questa autorizzazione per le app esistenti."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Ricordamelo dopo"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Ignora"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Impostazioni"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Fotocamera"</string>
@@ -2293,9 +2289,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Messaggio <xliff:g id="MESSAGE">%1$s</xliff:g> tradotto."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Messaggio tradotto dalla lingua <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> alla lingua <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Attività in background"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Un\'app sta usando la batteria"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"C\'è un\'app ancora attiva"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> sta usando la batteria in background. Tocca per controllare."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> potrebbe influire sulla durata della batteria. Tocca per controllare le app attive."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verifica le app attive"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Impossibile accedere alla fotocamera del telefono dal tuo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 44e66589..1761788 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -2295,9 +2295,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"ההודעה <xliff:g id="MESSAGE">%1$s</xliff:g> תורגמה."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"ההודעה תורגמה מ<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> ל<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"פעילות ברקע"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"אפליקציה כלשהי צורכת סוללה"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"אפליקציה כלשהי עדיין פעילה"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"האפליקציה <xliff:g id="APP">%1$s</xliff:g> צורכת סוללה ברקע. אפשר להקיש כדי לבדוק."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"האפליקציה <xliff:g id="APP">%1$s</xliff:g> עלולה להשפיע על חיי הסוללה. אפשר להקיש כדי לבדוק את האפליקציות הפעילות."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"כדאי לבדוק את האפליקציות הפעילות"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"לא ניתן לגשת למצלמה של הטלפון מה‑<xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index c3b84bf..bed3479 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> に翻訳しました。"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"メッセージを<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>から<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>に翻訳しました。"</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"バックグラウンド アクティビティ"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"アプリがバッテリーを使用しています"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"アプリがまだアクティブです"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> がバックグラウンドでバッテリーを使用しています。タップしてご確認ください。"</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> がバッテリー駆動時間に影響を与えている可能性があります。タップして、実行中のアプリをご確認ください。"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"実行中のアプリをチェック"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> からスマートフォンのカメラにアクセスできません"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 82e02f8..9fcde9c 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -2067,14 +2067,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"შეეხეთ მეტის გასაგებად და შესაცვლელად."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"„არ შემაწუხოთ“ რეჟიმი შეცვლილია"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"შეეხეთ იმის სანახავად, თუ რა არის დაბლოკილი."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"შეტყობინების პარამეტრების შემოწმება"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"Android 13-ზე შეტყობინებების გასაგზავნად საჭიროა თქვენ მიერ დაინსტალირებული აპებისთვის ნებართვის მინიჭება. არსებული აპებისთვის ამ ნებართვის შესაცვლელად შეეხეთ."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"შემახსენე მოგვიან."</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"უარყოფა"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"სისტემა"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"პარამეტრები"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"კამერა"</string>
@@ -2293,9 +2289,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> ნათარგმნია."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"შეტყობინება ნათარგმნია <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>-დან შემდეგ ენაზე: <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"აქტივობა ფონურ რეჟიმში"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"აპი იყენებს ბატარეას"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"აპი კვლავ აქტიურია"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> იყენებს ბატარეას ფონში შეეხეთ გადასახედად."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> იმოქმედებს ბატარეის მუშაობის ხანგრძლივობაზე. შეეხეთ აქტიური აპების მიმოხილვისთვის."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"აქტიური აპების შემოწმება"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ტელეფონის კამერაზე წვდომა ვერ მოხერხდა თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 7fd0beb..afc2d29 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"\"<xliff:g id="MESSAGE">%1$s</xliff:g>\" хабары аударылды."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Хабар мына тілге аударылды: <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>. Түпнұсқаның тілі: <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Фондық режимдегі әрекет"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Қолданба батареяны пайдаланып жатыр"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Қолданба әлі белсенді"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> қолданбасы батареяны фондық режимде пайдаланып жатыр. Көру үшін түртіңіз."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> қолданбасы батарея жұмысының ұзақтығына әсер етуі мүмкін. Белсенді қолданбаларды қарап шығу үшін түртіңіз."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Белсенді қолданбаларды тексеру"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан телефон камерасын пайдалану мүмкін емес."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 8705715..eeb62ca 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1141,7 +1141,7 @@
<string name="textSelectionCABTitle" msgid="5151441579532476940">"ការជ្រើសអត្ថបទ"</string>
<string name="addToDictionary" msgid="8041821113480950096">"បន្ថែមទៅវចនានុក្រម"</string>
<string name="deleteText" msgid="4200807474529938112">"លុប"</string>
- <string name="inputMethod" msgid="1784759500516314751">"វិធីសាស្ត្របញ្ចូល"</string>
+ <string name="inputMethod" msgid="1784759500516314751">"វិធីបញ្ចូល"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"សកម្មភាពអត្ថបទ"</string>
<string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"ថយក្រោយ"</string>
<string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"ប្ដូរវិធីសាស្ត្របញ្ចូល"</string>
@@ -1472,7 +1472,7 @@
<string name="permission_request_notification_for_app_with_subtitle" msgid="1298704005732851350">"ការអនុញ្ញាតដែលស្នើដោយ <xliff:g id="APP">%1$s</xliff:g>\nសម្រាប់គណនី <xliff:g id="ACCOUNT">%2$s</xliff:g>។"</string>
<string name="forward_intent_to_owner" msgid="4620359037192871015">"អ្នកកំពុងប្រើកម្មវិធីនេះនៅខាងក្រៅប្រវត្តិរូបការងាររបស់អ្នក"</string>
<string name="forward_intent_to_work" msgid="3620262405636021151">"អ្នកកំពុងប្រើកម្មវិធីនេះក្នុងប្រវត្តិរូបការងាររបស់អ្នក"</string>
- <string name="input_method_binding_label" msgid="1166731601721983656">"វិធីសាស្ត្របញ្ចូល"</string>
+ <string name="input_method_binding_label" msgid="1166731601721983656">"វិធីបញ្ចូល"</string>
<string name="sync_binding_label" msgid="469249309424662147">"ធ្វើសមកាលកម្ម"</string>
<string name="accessibility_binding_label" msgid="1974602776545801715">"ភាពងាយស្រួល"</string>
<string name="wallpaper_binding_label" msgid="1197440498000786738">"ផ្ទាំងរូបភាព"</string>
@@ -1695,7 +1695,7 @@
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"បិទផ្លូវកាត់"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ប្រើប្រាស់ផ្លូវកាត់"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"បញ្ច្រាសពណ៌"</string>
- <string name="color_correction_feature_name" msgid="3655077237805422597">"ការកែពណ៌"</string>
+ <string name="color_correction_feature_name" msgid="3655077237805422597">"ការកែតម្រូវពណ៌"</string>
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"មុខងារប្រើដៃម្ខាង"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ពន្លឺតិចខ្លាំង"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"បានសង្កត់គ្រាប់ចុចកម្រិតសំឡេងជាប់។ បានបើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string>
@@ -1851,7 +1851,7 @@
<string name="confirm_battery_saver" msgid="5247976246208245754">"យល់ព្រម"</string>
<string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"មុខងារសន្សំថ្មបើករចនាប័ទ្មងងឹត និងដាក់កំហិត ឬបិទសកម្មភាពផ្ទៃខាងក្រោយ ឥទ្ធិពលរូបភាពមួយចំនួន មុខងារជាក់លាក់ និងការតភ្ជាប់បណ្ដាញមួយចំនួន។"</string>
<string name="battery_saver_description" msgid="8518809702138617167">"មុខងារសន្សំថ្មបើករចនាប័ទ្មងងឹត និងដាក់កំហិត ឬបិទសកម្មភាពផ្ទៃខាងក្រោយ ឥទ្ធិពលរូបភាពមួយចំនួន មុខងារជាក់លាក់ និងការតភ្ជាប់បណ្ដាញមួយចំនួន។"</string>
- <string name="data_saver_description" msgid="4995164271550590517">"ដើម្បីជួយកាត់បន្ថយការប្រើប្រាស់ទិន្នន័យ កម្មវិធីសន្សំសំចៃទិន្នន័យរារាំងកម្មវិធីមួយចំនួនមិនឲ្យបញ្ជូន ឬទទួលទិន្នន័យនៅផ្ទៃខាងក្រោយទេ។ កម្មវិធីដែលអ្នកកំពុងប្រើនាពេលបច្ចុប្បន្នអាចចូលប្រើប្រាស់ទិន្នន័យបាន ប៉ុន្តែអាចនឹងមិនញឹកញាប់ដូចមុនទេ។ ឧទាហរណ៍ រូបភាពមិនបង្ហាញទេ លុះត្រាតែអ្នកប៉ះរូបភាពទាំងនោះ។"</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"ដើម្បីជួយកាត់បន្ថយការប្រើប្រាស់ទិន្នន័យ មុខងារសន្សំសំចៃទិន្នន័យរារាំងកម្មវិធីមួយចំនួនមិនឲ្យបញ្ជូន ឬទទួលទិន្នន័យនៅផ្ទៃខាងក្រោយទេ។ កម្មវិធីដែលអ្នកកំពុងប្រើនាពេលបច្ចុប្បន្នអាចចូលប្រើប្រាស់ទិន្នន័យបាន ប៉ុន្តែអាចនឹងមិនញឹកញាប់ដូចមុនទេ។ ឧទាហរណ៍ រូបភាពមិនបង្ហាញទេ លុះត្រាតែអ្នកប៉ះរូបភាពទាំងនោះ។"</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"បើកកម្មវិធីសន្សំសំចៃទិន្នន័យ?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"បើក"</string>
<string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{រយៈពេលមួយនាទី (រហូតដល់ {formattedTime})}other{រយៈពេល # នាទី (រហូតដល់ {formattedTime})}}"</string>
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"បានបកប្រែ <xliff:g id="MESSAGE">%1$s</xliff:g>។"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"បានបកប្រែសារពីភាសា<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>ទៅភាសា<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>។"</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"សកម្មភាពនៅផ្ទៃខាងក្រោយ"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"កម្មវិធីកំពុងប្រើថ្ម"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"កម្មវិធីនៅតែសកម្មដដែល"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> កំពុងប្រើថ្មនៅផ្ទៃខាងក្រោយ។ សូមចុច ដើម្បីពិនិត្យមើល។"</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> អាចប៉ះពាល់ដល់កម្រិតថាមពលថ្ម។ សូមចុច ដើម្បីពិនិត្យមើលកម្មវិធីដែលសកម្ម។"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ពិនិត្យមើលកម្មវិធីសកម្ម"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"មិនអាចចូលប្រើកាមេរ៉ាទូរសព្ទពី <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នកបានទេ"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index a6148d9..6fd3039 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> ಅನ್ನು ಅನುವಾದಿಸಲಾಗಿದೆ."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> ಭಾಷೆಯಿಂದ <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> ಭಾಷೆಗೆ ಸಂದೇಶವನ್ನು ಅನುವಾದಿಸಲಾಗಿದೆ."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"ಹಿನ್ನೆಲೆ ಚಟುವಟಿಕೆ"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"ಒಂದು ಆ್ಯಪ್ ಬ್ಯಾಟರಿಯನ್ನು ಬಳಸುತ್ತಿದೆ"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"ಒಂದು ಆ್ಯಪ್ ಈಗಲೂ ಸಕ್ರಿಯವಾಗಿದೆ"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಬ್ಯಾಟರಿಯನ್ನು ಬಳಸುತ್ತಿದೆ. ಪರಿಶೀಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ಬ್ಯಾಟರಿ ಬಾಳಿಕೆಯ ಮೇಲೆ ಪ್ರಭಾವ ಬೀರಬಹುದು. ಸಕ್ರಿಯ ಆ್ಯಪ್ಗಳನ್ನು ಪರಿಶೀಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ಸಕ್ರಿಯ ಆ್ಯಪ್ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ನಿಮ್ಮ <xliff:g id="DEVICE">%1$s</xliff:g> ಮೂಲಕ ಫೋನ್ನ ಕ್ಯಾಮರಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 3b5518a..0268a13 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"다음 메시지가 번역되었습니다. <xliff:g id="MESSAGE">%1$s</xliff:g>"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"메시지가 <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>에서 <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>로 번역되었습니다."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"백그라운드 활동"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"앱이 배터리를 사용 중임"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"앱이 여전히 활성 상태임"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> 앱이 백그라운드에서 배터리를 사용하고 있습니다. 확인하려면 탭하세요."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> 앱은 배터리 수명에 영향을 미칠 수 있습니다. 활성 상태인 앱을 확인하려면 탭하세요."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"활성 상태의 앱 확인"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"사용자의 <xliff:g id="DEVICE">%1$s</xliff:g>에서 휴대전화 카메라에 액세스할 수 없습니다."</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index f56abd5..0a60461 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -425,10 +425,10 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Колдонмого планшетиңиздин чалуулар тизмегин, анын ичинде, чыгыш жана кириш чалууларына тиешелүү берилиштерди өзгөртүү уруксатын берет. Зыяндуу колдонмолор муну колдонуп чалуулар тизмегин өзгөртө же жок кыла алышат."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Колдонмого Android TV түзмөгүңүздүн чалуулар тизмесин, анын ичинде кирүүчү жана чыгуучу чалуулар тууралуу маалыматтарды өзгөртүүгө уруксат берет. Зыянкеч колдонмолор ал уруксатты колдонуп чалуулар тизмеңизди тазалап же өзгөртүп коюшу мүмкүн."</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Колдонмого телефонуңуздун чалуулар тизмегин, анын ичинде, чыгыш жана кириш чалууларына тиешелүү берилиштерди өзгөртүү уруксатын берет. Зыяндуу колдонмолор муну колдонуп чалуулар тизмегин өзгөртө же жок кыла алышат."</string>
- <string name="permlab_bodySensors" msgid="662918578601619569">"Иштеп жатканда дене сенсорлорунун дайындарын, мисалы, жүрөктүн согушун көрүү"</string>
- <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Иштеп жатканда колдонмо дене сенсорлорунун дайындарын, мисалы, жүрөктүн согушу, температура жана кандагы кычкылтектин пайызын көрө алат."</string>
- <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Фондо дене сенсорлорунун дайындарын, мисалы, жүрөктүн согушун көрүү"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Колдонмо фондо дене сенсорлорунун дайындарын, мисалы, жүрөктүн согушу, температура жана кандагы кычкылтектин пайызын көрө алат."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Иштеп жатканда дене сенсорлорунун көрсөткүчтөрүн, мисалы, жүрөктүн согушун көрүү"</string>
+ <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Иштеп жатканда колдонмо дене сенсорлорунун көрсөткүчтөрүн, мисалы, жүрөктүн согушу, температура жана кандагы кычкылтектин пайызын көрө алат."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Фондо дене сенсорлорунун көрсөткүчтөрүн, мисалы, жүрөктүн согушун көрүү"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Колдонмо фондо дене сенсорлорунун көрсөткүчтөрүн, мисалы, жүрөктүн согушу, температура жана кандагы кычкылтектин пайызын көрө алат."</string>
<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>
@@ -1933,36 +1933,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> учурда жеткиликсиз"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> жеткиликсиз"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Уруксат керек"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Камера жеткиликсиз"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Телефондон улантуу"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Микрофон жеткиликсиз"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Android TV параметрлери жеткиликсиз"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Планшеттин параметрлери жеткиликсиз"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Телефондун параметрлери жеткиликсиз"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"Буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Android TV түзмөгүңүздөн аракет кылып көрүңүз."</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"Буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Планшетиңизден кирип көрүңүз."</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"Буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Анын ордуна телефондон кирип көрүңүз."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"Учурда буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Android TV түзмөгүңүздөн аракет кылып көрүңүз."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"Учурда буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Планшетиңизден кирип көрүңүз."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"Учурда буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Анын ордуна телефондон кирип көрүңүз."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Бул колдонмо кошумча коопсуздукту иштетүүнү суранып жатат. Android TV түзмөгүңүздөн аракет кылып көрүңүз."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Бул колдонмо кошумча коопсуздукту иштетүүнү суранып жатат. Планшетиңизден кирип көрүңүз."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Бул колдонмо кошумча коопсуздукту иштетүүнү суранып жатат. Анын ордуна телефондон кирип көрүңүз."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Бул колдонмо Android\'дин эски версиясы үчүн иштеп чыгарылган, андыктан туура эмес иштеши мүмкүн. Жаңыртууларды издеп көрүңүз же иштеп чыгуучуга кайрылыңыз."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Жаңыртууларды текшерүү"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Сизге жаңы билдирүүлөр келди"</string>
@@ -2289,9 +2274,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Билдирүү (<xliff:g id="MESSAGE">%1$s</xliff:g>) которулду."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Билдирүү <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> тилинен <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> тилине которулду."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Фондогу активдүүлүк"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Колдонмо батареяны сарптоодо"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Колдонмо дагы эле иштеп жатат"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> батареяны фондо колдонуп жатат. Көрүү үчүн таптап коюңуз."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> батареянын кубатынын мөөнөтүн азайтышы мүмкүн. Жигердүү колдонмолорду көрүү үчүн таптап коюңуз."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Жигердүү колдонмолорду карап чыгуу"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн телефондун камерасына мүмкүнчүлүк жок"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 545b2dc..ba227d6 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -2067,14 +2067,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"ແຕະເພື່ອສຶກສາເພີ່ມເຕີມ ແລະ ປ່ຽນແປງ."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"ປ່ຽນໂໝດຫ້າມລົບກວນແລ້ວ"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"ແຕະເພື່ອກວດສອບວ່າມີຫຍັງຖືກບລັອກໄວ້ແດ່."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"ກວດສອບການຕັ້ງຄ່າການແຈ້ງເຕືອນ"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"ໃນ Android 13, ແອັບຕ່າງໆທີ່ທ່ານຕິດຕັ້ງຈະຕ້ອງໃຊ້ການອະນຸຍາດຂອງທ່ານເພື່ອສົ່ງການແຈ້ງເຕືອນ. ແຕະເພື່ອປ່ຽນການອະນຸຍາດນີ້ສຳລັບແອັບທີ່ມີຢູ່ກ່ອນແລ້ວ."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"ແຈ້ງເຕືອນຂ້ອຍພາຍຫຼັງ"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ປິດໄວ້"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"ລະບົບ"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"ການຕັ້ງຄ່າ"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"ກ້ອງ"</string>
@@ -2293,9 +2289,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"ແປ <xliff:g id="MESSAGE">%1$s</xliff:g> ແລ້ວ."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"ແປຂໍ້ຄວາມຈາກ <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> ເປັນ <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> ແລ້ວ."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"ການເຄື່ອນໄຫວໃນພື້ນຫຼັງ"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"ມີແອັບກຳລັງໃຊ້ແບັດເຕີຣີ"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"ມີແອັບທີ່ຍັງຄົງນຳໃຊ້ຢູ່"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> ກຳລັງໃຊ້ແບັດເຕີຣີໃນພື້ນຫຼັງ. ແຕະເພື່ອກວດສອບ."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ອາດສົ່ງຜົນກະທົບຕໍ່ອາຍຸແບັດເຕີຣີ. ແຕະເພື່ອກວດສອບແອັບທີ່ນຳໃຊ້ຢູ່."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ກວດສອບແອັບທີ່ເຄື່ອນໄຫວ"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ບໍ່ສາມາດເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຂອງໂທລະສັບຈາກ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໄດ້"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f0a6a0f..f2fb7ba 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1935,36 +1935,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ šiuo metu nepasiekiama."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"„<xliff:g id="ACTIVITY">%1$s</xliff:g>“ nepasiekiama"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Reikalingas leidimas"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera nepasiekiama"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Tęsti telefone"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofonas nepasiekiamas"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"„Android TV“ nustatymai nepasiekiami"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Planšetinio kompiuterio nustatymai nepasiekiami"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Telefono nustatymai nepasiekiami"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"Nepavyksta pasiekti programos iš jūsų „<xliff:g id="DEVICE">%1$s</xliff:g>“. Pabandykite naudoti „Android TV“ įrenginį."</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"Nepavyksta pasiekti programos iš jūsų „<xliff:g id="DEVICE">%1$s</xliff:g>“. Pabandykite naudoti planšetinį kompiuterį."</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"Nepavyksta pasiekti programos iš jūsų „<xliff:g id="DEVICE">%1$s</xliff:g>“. Pabandykite naudoti telefoną."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"Šįkart nepavyksta pasiekti programos iš jūsų „<xliff:g id="DEVICE">%1$s</xliff:g>“. Pabandykite naudoti „Android TV“ įrenginį."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"Šįkart nepavyksta pasiekti programos iš jūsų „<xliff:g id="DEVICE">%1$s</xliff:g>“. Pabandykite naudoti planšetinį kompiuterį."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"Šįkart nepavyksta pasiekti programos iš jūsų „<xliff:g id="DEVICE">%1$s</xliff:g>“. Pabandykite naudoti telefoną."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ši programa prašo papildomų saugos funkcijų. Pabandykite naudoti „Android TV“ įrenginį."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ši programa prašo papildomų saugos funkcijų. Pabandykite naudoti planšetinį kompiuterį."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ši programa prašo papildomų saugos funkcijų. Pabandykite naudoti telefoną."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ši programa sukurta naudoti senesnės versijos sistemoje „Android“ ir gali tinkamai neveikti. Pabandykite patikrinti, ar yra naujinių, arba susisiekite su kūrėju."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Tikrinti, ar yra naujinių"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Turite naujų pranešimų"</string>
@@ -2295,9 +2280,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Pranešimas „<xliff:g id="MESSAGE">%1$s</xliff:g>“ išverstas."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Pranešimas išverstas iš <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> į <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Veikla fone"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Programa eikvoja akumuliatoriaus energiją"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Programa vis dar aktyvi"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"Programa „<xliff:g id="APP">%1$s</xliff:g>“ eikvoja akumuliatoriaus energiją fone. Palieskite ir peržiūrėkite."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"Programa „<xliff:g id="APP">%1$s</xliff:g>“ gali turėti įtakos akumuliatoriaus veikimo laikui. Palieskite ir peržiūrėkite aktyvias programas."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Peržiūrėkite aktyvias programas"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nepavyko pasiekti telefono fotoaparato iš „<xliff:g id="DEVICE">%1$s</xliff:g>“"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 086af66..b3de654 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1689,7 +1689,7 @@
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Neatļaut"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Pieskarieties funkcijai, lai sāktu to izmantot"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Izvēlieties funkcijas, ko izmantot ar pieejamības pogu"</string>
- <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Izvēlieties funkcijas, ko izmantot ar skaļuma pogu īsinājumtaustiņu"</string>
+ <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Izvēlieties funkcijas, ko izmantot ar skaļuma pogu saīsni"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Pakalpojums <xliff:g id="SERVICE_NAME">%s</xliff:g> ir izslēgts."</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Rediģēt īsinājumtaustiņus"</string>
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Gatavs"</string>
@@ -2294,9 +2294,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Iztulkots: <xliff:g id="MESSAGE">%1$s</xliff:g>."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Ziņojums ir iztulkots no šādas valodas: <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> šādā valodā: <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Darbība fonā"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Lietotne patērē akumulatora enerģiju"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Lietotne joprojām ir aktīva"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"Lietotne <xliff:g id="APP">%1$s</xliff:g> patērē akumulatora enerģiju fonā. Pieskarieties, lai pārskatītu."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"Lietotne <xliff:g id="APP">%1$s</xliff:g> var ietekmēt akumulatora darbības ilgumu. Pieskarieties, lai pārskatītu aktīvās lietotnes."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Pārbaudiet aktīvās lietotnes"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nevar piekļūt tālruņa kamerai no jūsu ierīces (<xliff:g id="DEVICE">%1$s</xliff:g>)."</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 81ecb7e..c753c66 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1849,8 +1849,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Ажурирано од администраторот"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Избришано од администраторот"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Во ред"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"„Штедачот на батерија“ вклучува темна тема и ја ограничува или исклучува активноста во заднина, некои визуелни ефекти, одредени функции и некои мрежни врски."</string>
- <string name="battery_saver_description" msgid="8518809702138617167">"„Штедачот на батерија“ вклучува темна тема и ја ограничува или исклучува активноста во заднина, некои визуелни ефекти, одредени функции и некои мрежни врски."</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"„Штедачот на батерија“ вклучува „Темна тема“ и ограничува или исклучува активност во заднина, некои визуелни ефекти, одредени функции и некои мрежни врски."</string>
+ <string name="battery_saver_description" msgid="8518809702138617167">"„Штедачот на батерија“ вклучува „Темна тема“ и ограничува или исклучува активност во заднина, некои визуелни ефекти, одредени функции и некои мрежни врски."</string>
<string name="data_saver_description" msgid="4995164271550590517">"За да се намали користењето интернет, „Штедачот на интернет“ спречува дел од апликациите да испраќаат или да примаат податоци во заднина. Одредена апликација што ја користите ќе може да користи интернет, но можеби тоа ќе го прави поретко. Ова значи, на пример, дека сликите нема да се прикажуваат додека не ги допрете."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Да се вклучи „Штедач на интернет“?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Вклучи"</string>
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g>, преведено."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Пораката е преведена од <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> на <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Активност во заднина"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Апликација троши батерија"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Апликација сѐ уште е активна"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> троши батерија во заднина. Допрете за да прегледате."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> може да влијае врз траење на батеријата. Допрете за да ги прегледате активните апликации."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверете ги активните апликации"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не може да се пристапи до камерата на вашиот телефон од <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 34e5116..3ccdefaf 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -2067,14 +2067,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"കൂടുതലറിയാനും മാറ്റാനും ടാപ്പ് ചെയ്യുക."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'ശല്യപ്പെടുത്തരുത്\' മാറ്റി"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"എന്തിനെയാണ് ബ്ലോക്ക് ചെയ്തതെന്ന് പരിശോധിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"അറിയിപ്പ് ക്രമീകരണം അവലോകനം ചെയ്യുക"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"Android 13-ൽ നിങ്ങൾ ഇൻസ്റ്റാൾ ചെയ്യുന്ന ആപ്പുകൾക്ക് അറിയിപ്പുകൾ അയയ്ക്കാൻ നിങ്ങളുടെ അനുമതി വേണം. നിലവിലുള്ള ആപ്പുകൾക്ക് ഈ അനുമതി മാറ്റാൻ ടാപ്പ് ചെയ്യുക."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"പിന്നീട് ഓർമ്മിപ്പിക്കൂ"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ഡിസ്മിസ് ചെയ്യുക"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"സിസ്റ്റം"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"ക്രമീകരണം"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"ക്യാമറ"</string>
@@ -2293,9 +2289,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> വിവർത്തനം ചെയ്തു."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> എന്നതിൽ നിന്ന് <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> എന്നതിലേക്ക് സന്ദേശം വിവർത്തനം ചെയ്തു."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"പശ്ചാത്തല ആക്റ്റിവിറ്റി"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"ഒരു ആപ്പ് ബാറ്ററി ഉപയോഗിക്കുന്നു"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"ഒരു ആപ്പ് ഇപ്പോഴും സജീവമാണ്"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> പശ്ചാത്തലത്തിൽ ബാറ്ററി ഉപയോഗിക്കുന്നു. അവലോകനം ചെയ്യാൻ ടാപ്പ് ചെയ്യുക."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ബാറ്ററി ലൈഫിനെ ബാധിച്ചേക്കാം. സജീവ ആപ്പുകൾ അവലോകനം ചെയ്യാൻ ടാപ്പ് ചെയ്യുക."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"സജീവമായ ആപ്പുകൾ പരിശോധിക്കുക"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"നിങ്ങളുടെ <xliff:g id="DEVICE">%1$s</xliff:g> എന്നതിൽ നിന്ന് ഫോണിന്റെ ക്യാമറ ആക്സസ് ചെയ്യാനാകില്ല"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index ecc1a76..d3ddc5c 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1933,36 +1933,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> яг одоо боломжгүй байна."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> боломжгүй байна"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Зөвшөөрөл шаардлагатай"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Камер боломжгүй байна"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Утсан дээр үргэлжлүүлэх"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Микрофон боломжгүй байна"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Android TV-н тохиргоо боломжгүй байна"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Таблетын тохиргоо боломжгүй байна"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Утасны тохиргоо боломжгүй байна"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"Үүнд таны <xliff:g id="DEVICE">%1$s</xliff:g>-с хандах боломжгүй. Оронд нь Android TV төхөөрөмж дээрээ туршиж үзнэ үү."</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"Үүнд таны <xliff:g id="DEVICE">%1$s</xliff:g>-с хандах боломжгүй. Оронд нь таблет дээрээ туршиж үзнэ үү."</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"Үүнд таны <xliff:g id="DEVICE">%1$s</xliff:g>-с хандах боломжгүй. Оронд нь утсан дээрээ туршиж үзнэ үү."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"Одоогоор үүнд таны <xliff:g id="DEVICE">%1$s</xliff:g> дээрээс хандах боломжгүй. Оронд нь Android TV төхөөрөмж дээрээ туршиж үзнэ үү."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"Одоогоор үүнд таны <xliff:g id="DEVICE">%1$s</xliff:g> дээрээс хандах боломжгүй. Оронд нь таблет дээрээ туршиж үзнэ үү."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"Одоогоор үүнд таны <xliff:g id="DEVICE">%1$s</xliff:g> дээрээс хандах боломжгүй. Оронд нь утсан дээрээ туршиж үзнэ үү."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Энэ апп нэмэлт аюулгүй байдал хүсэж байна. Оронд нь Android TV төхөөрөмж дээрээ туршиж үзнэ үү."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Энэ апп нэмэлт аюулгүй байдал хүсэж байна. Оронд нь таблет дээрээ туршиж үзнэ үү."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Энэ апп нэмэлт аюулгүй байдал хүсэж байна. Оронд нь утсан дээрээ туршиж үзнэ үү."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Энэ аппыг Андройдын хуучин хувилбарт зориулсан бөгөөд буруу ажиллаж болзошгүй. Шинэчлэлтийг шалгаж эсвэл хөгжүүлэгчтэй холбогдоно уу."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Шинэчлэлтийг шалгах"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Танд шинэ мессежүүд байна"</string>
@@ -2067,14 +2052,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Илүү ихийг мэдэж, өөрчлөхийн тулд товшино уу."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Бүү саад бол горимыг өөрчилсөн"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Блоклосон зүйлийг шалгахын тулд товшино уу."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Мэдэгдлийн тохиргоог шалгах"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"Android 13-т таны суулгасан аппууд мэдэгдэл илгээхийн тулд тэдгээрт таны зөвшөөрөл шаардлагатай. Одоо байгаа аппуудын уг зөвшөөрлийг өөрчлөхийн тулд товшино уу."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Надад дараа сануул"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Хаах"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Систем"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Тохиргоо"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Камер"</string>
@@ -2293,9 +2274,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> Орчуулсан."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Мессежийг <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>-с <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> руу орчуулсан."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Дэвсгэрийн үйл ажиллагаа"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Апп батарейг ашиглаж байна"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Апп идэвхтэй хэвээр байна"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"Ард <xliff:g id="APP">%1$s</xliff:g> батарейг ашиглаж байна. Хянахын тулд товшино уу."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> батарейн ажиллах хугацаанд нөлөөлж болзошгүй. Идэвхтэй аппыг хянахын тулд товшино уу."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Идэвхтэй аппуудыг шалгах"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Таны <xliff:g id="DEVICE">%1$s</xliff:g>-с утасны камерт хандах боломжгүй"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 6741330..46d89b2 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -2289,9 +2289,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> चे भाषांतर केले."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"मेसेजचे <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> मधून <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> मध्ये भाषांतर केले."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"बॅकग्राउंड अॅक्टिव्हिटी"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"अॅप बॅटरी वापरत आहे"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"अॅप अजूनही अॅक्टिव्ह आहे"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> हे बॅकग्राउंडमध्ये बॅटरी वापरत आहे. पुनरावलोकन करण्यासाठी टॅप करा."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> कदाचित बॅटरी लाइफवर परिणाम करेल. अॅक्टिव्ह अॅप्सचे पुनरावलोकन करण्यासाठी टॅप करा."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ॲक्टिव्ह ॲप्स पहा"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वरून फोनचा कॅमेरा अॅक्सेस करू शकत नाही"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 5a12e05..8f66982 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -2067,14 +2067,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Ketik untuk mengetahui lebih lanjut dan menukar tetapan."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Jangan Ganggu telah berubah"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Ketik untuk menyemak item yang disekat."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Semak tetapan pemberitahuan"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"Dalam Android 13, apl yang anda pasang memerlukan kebenaran anda untuk menghantar pemberitahuan. Ketik untuk menukar kebenaran ini bagi apl sedia ada."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Ingatkan saya nanti"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Ketepikan"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Tetapan"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Kamera"</string>
@@ -2293,9 +2289,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> Diterjemahkan."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Mesej diterjemahkan daripada <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> kepada <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktiviti Latar Belakang"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Apl sedang menggunakan bateri"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Apl masih aktif"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> sedang menggunakan bateri pada latar. Ketik untuk menyemak."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> mungkin menjejaskan hayat bateri. Ketik untuk menyemak apl aktif."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Semak apl aktif"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Tidak dapat mengakses kamera telefon daripada <xliff:g id="DEVICE">%1$s</xliff:g> anda"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 3cf9bf0..db01211 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1337,7 +1337,7 @@
<string name="carrier_app_notification_text" msgid="6567057546341958637">"၎င်းကိုတပ်ဆင်ရန် တို့ပါ"</string>
<string name="time_picker_dialog_title" msgid="9053376764985220821">"အချိန်သတ်မှတ်ရန်"</string>
<string name="date_picker_dialog_title" msgid="5030520449243071926">"ရက်စွဲ အတည်ပြုရန်"</string>
- <string name="date_time_set" msgid="4603445265164486816">"အတည်ပြုရန်"</string>
+ <string name="date_time_set" msgid="4603445265164486816">"သတ်မှတ်ရန်"</string>
<string name="date_time_done" msgid="8363155889402873463">"ပြီးပါပြီ"</string>
<string name="perms_new_perm_prefix" msgid="6984556020395757087"><font size="12" fgcolor="#ff33b5e5">"အသစ်: "</font></string>
<string name="perms_description_app" msgid="2747752389870161996">"<xliff:g id="APP_NAME">%1$s</xliff:g> မှ ထောက်ပံ့သည်"</string>
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> ကို ဘာသာပြန်ထားသည်။"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"မက်ဆေ့ဂျ်ကို <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> မှ <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> သို့ ဘာသာပြန်ထားသည်။"</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"နောက်ခံလုပ်ဆောင်ချက်"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"အက်ပ်က ဘက်ထရီသုံးနေသည်"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"အက်ပ်က ပွင့်နေဆဲဖြစ်သည်"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> က နောက်ခံတွင် ဘက်ထရီသုံးနေသည်။ ပြန်ကြည့်ရန် တို့ပါ။"</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> က ဘက်ထရီ သက်တမ်းကို ထိခိုက်နိုင်သည်။ ပွင့်နေသောအက်ပ်များ ပြန်ကြည့်ရန် တို့ပါ။"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ပွင့်နေသည့်အက်ပ်များ စစ်ဆေးရန်"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"သင်၏ <xliff:g id="DEVICE">%1$s</xliff:g> မှ ဖုန်းကင်မရာကို သုံး၍မရပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 8e4c080..ce59cc5 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> er oversatt."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Meldingen er oversatt fra <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> til <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktivitet i bakgrunnen"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"En app bruker batteri"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"En app er fremdeles aktiv"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> bruker batteri i bakgrunnen. Trykk for å gjennomgå."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> kan påvirke batterilevetiden. Trykk for å gjennomgå aktive apper."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Sjekk aktive apper"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Det er ikke mulig å få tilgang til telefonkameraet fra <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 66e0909..b179c36 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1695,7 +1695,7 @@
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"सर्टकटलाई निष्क्रिय पार्नुहोस्"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"सर्टकट प्रयोग गर्नुहोस्"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"कलर इन्भर्सन"</string>
- <string name="color_correction_feature_name" msgid="3655077237805422597">"रङ्ग सच्याउने सुविधा"</string>
+ <string name="color_correction_feature_name" msgid="3655077237805422597">"कलर करेक्सन"</string>
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"एक हाते मोड"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"अझै मधुरो"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन भयो।"</string>
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> अनुवाद गरिएको छ।"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"म्यासेज <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> भाषाबाट <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> भाषामा अनुवाद गरिएको छ।"</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"ब्याकग्राउन्डमा गरिएको क्रियाकलाप"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"कुनै एपले ब्याट्री खपत गरिरहेको छ"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"कुनै एप अझै पनि चलिरहेको छ"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> ले ब्याकग्राउन्डमा ब्याट्री खपत गरिरहेको छ। समीक्षा गर्न ट्याप गर्नुहोस्।"</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ले ब्याट्रीको आयु घटाउन सक्छ। सक्रिय एपहरू हेर्न ट्याप गर्नुहोस्।"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"कुन कुन एप सक्रिय छ भन्ने कुरा जाँच्नुहोस्"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मार्फत फोनको क्यामेरा प्रयोग गर्न मिल्दैन"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index f7f6d670..f882663 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> vertaald."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Bericht vertaald vanuit het <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> naar het <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Achtergrondactiviteit"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Een app gebruikt de batterij"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Een app is nog actief"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> gebruikt de batterij op de achtergrond. Tik om te bekijken."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> kan van invloed zijn op de batterijduur. Tik om actieve apps te bekijken."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Actieve apps checken"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Kan geen toegang tot de camera van de telefoon krijgen vanaf je <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 4bd1dfb..5ac97af 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1697,7 +1697,7 @@
<string name="color_inversion_feature_name" msgid="326050048927789012">"ରଙ୍ଗ ବଦଳାଇବାର ସୁବିଧା"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"ରଙ୍ଗ ସଂଶୋଧନ"</string>
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ଏକ-ହାତ ମୋଡ୍"</string>
- <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ଅତିରିକ୍ତ ଡିମ୍"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ଅତ୍ୟଧିକ ଡିମ"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ଚାଲୁ ହୋଇଛି।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ବନ୍ଦ ହୋଇଛି।"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ବ୍ୟବହାର କରିବାକୁ ତିନି ସେକେଣ୍ଡ ପାଇଁ ଉଭୟ ଭଲ୍ୟୁମ୍ କୀ ଦବାଇ ଧରି ରଖନ୍ତୁ"</string>
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> ଅନୁବାଦ କରାଯାଇଛି।"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"ମେସେଜ୍, <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>ରୁ <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>କୁ ଅନୁବାଦ କରାଯାଇଛି।"</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"ପୃଷ୍ଠପଟ କାର୍ଯ୍ୟକଳାପ"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"ଏକ ଆପ ବ୍ୟାଟେରୀ ବ୍ୟବହାର କରୁଛି"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"ଏକ ଆପ ଏବେ ବି ସକ୍ରିୟ ଅଛି"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> ପୃଷ୍ଠପଟରେ ବ୍ୟାଟେରୀ ବ୍ୟବହାର କରୁଛି। ସମୀକ୍ଷା କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ବ୍ୟାଟେରୀ ଲାଇଫକୁ ପ୍ରଭାବିତ କରିପାରେ। ସକ୍ରିୟ ଆପ୍ସକୁ ସମୀକ୍ଷା କରିବା ପାଇଁ ଟାପ କରନ୍ତୁ।"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ସକ୍ରିୟ ଆପଗୁଡ଼ିକୁ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରୁ ଫୋନର କ୍ୟାମେରାକୁ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index d8503ae..fe515b0 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -425,9 +425,9 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ ਦਾ ਕਾਲ ਲੌਗ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਇਨਕਮਿੰਗ ਅਤੇ ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਬਾਰੇ ਡਾਟਾ ਸਮੇਤ। ਖਰਾਬ ਐਪਾਂ ਇਸਦੀ ਵਰਤੋਂ ਤੁਹਾਡੇ ਕਾਲ ਲੌਗ ਨੂੰ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਲਈ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
<string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ Android TV ਡੀਵਾਈਸ ਦਾ ਕਾਲ ਲੌਗ ਸੋਧਣ ਦਿੰਦੀ ਹੈ, ਇਸ ਵਿੱਚ ਇਨਕਮਿੰਗ ਅਤੇ ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਬਾਰੇ ਡਾਟਾ ਵੀ ਸ਼ਾਮਲ ਹੈ। ਭੈੜੀਆਂ ਐਪਾਂ ਤੁਹਾਡੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਕਾਲ ਲੌਗ ਡਾਟਾ ਮਿਟਾ ਜਾਂ ਸੋਧ ਸਕਦੀਆਂ ਹਨ।"</string>
<string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦਾ ਕਾਲ ਲੌਗ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਇਨਕਮਿੰਗ ਅਤੇ ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ ਬਾਰੇ ਡਾਟਾ ਸਮੇਤ। ਖਰਾਬ ਐਪਾਂ ਇਸਦੀ ਵਰਤੋਂ ਤੁਹਾਡੇ ਕਾਲ ਲੌਗ ਨੂੰ ਮਿਟਾਉਣ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਲਈ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string>
- <string name="permlab_bodySensors" msgid="662918578601619569">"ਵਰਤੋਂ ਵਿੱਚ ਹੋਣ \'ਤੇ ਦਿਲ ਦੀ ਧੜਕਣ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"ਵਰਤੋਂ ਵਿੱਚ ਹੋਣ \'ਤੇ ਦਿਲ ਦੀ ਧੜਕਣ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਦੇ ਡਾਟਾ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
<string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ਜਦੋਂ ਐਪ ਵਰਤੋਂ ਵਿੱਚ ਹੋਵੇ, ਤਾਂ ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਦਿਲ ਦੀ ਧੜਕਣ, ਤਾਪਮਾਨ, ਖੂਨ ਵਿੱਚ ਮੌਜੂਦ ਆਕਸੀਜਨ ਦੀ ਫ਼ੀਸਦ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਦੇ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਮਿਲਦੀ ਹੈ।"</string>
- <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਣ \'ਤੇ ਦਿਲ ਦੀ ਧੜਕਣ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਣ \'ਤੇ ਦਿਲ ਦੀ ਧੜਕਣ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਦੇ ਡਾਟਾ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
<string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ਜਦੋਂ ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀ ਹੋਵੇ, ਤਾਂ ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਦਿਲ ਦੀ ਧੜਕਣ, ਤਾਪਮਾਨ, ਖੂਨ ਵਿੱਚ ਮੌਜੂਦ ਆਕਸੀਜਨ ਦੀ ਫ਼ੀਸਦ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਦੇ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਮਿਲਦੀ ਹੈ।"</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"ਕੈਲੰਡਰ ਵਰਤਾਰਿਆਂ ਅਤੇ ਵੇਰਵਿਆਂ ਨੂੰ ਪੜ੍ਹੋ"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਡਾਟੇ ਨੂੰ ਸਾਂਝਾ ਜਾਂ ਰੱਖਿਅਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
@@ -1679,7 +1679,7 @@
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ਚਾਲੂ"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ਬੰਦ"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"ਕੀ <xliff:g id="SERVICE">%1$s</xliff:g> ਨੂੰ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ ਪੂਰਾ ਕੰਟਰੋਲ ਦੇਣਾ ਹੈ?"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"ਪੂਰਾ ਕੰਟਰੋਲ ਉਹਨਾਂ ਐਪਾਂ ਲਈ ਢੁਕਵਾਂ ਹੈ ਜੋ ਪਹੁੰਚਯੋਗਤਾ ਸੰਬੰਧੀ ਲੋੜਾਂ ਵਿੱਚ ਤੁਹਾਡੀ ਮਦਦ ਕਰਦੀਆਂ ਹਨ, ਪਰ ਜ਼ਿਆਦਾਤਰ ਐਪਾਂ ਲਈ ਢੁਕਵਾਂ ਨਹੀਂ ਹੁੰਦਾ।"</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"ਪੂਰਾ ਕੰਟਰੋਲ ਉਨ੍ਹਾਂ ਐਪਾਂ ਲਈ ਢੁਕਵਾਂ ਹੈ ਜੋ ਪਹੁੰਚਯੋਗਤਾ ਸੰਬੰਧੀ ਲੋੜਾਂ ਵਿੱਚ ਤੁਹਾਡੀ ਮਦਦ ਕਰਦੀਆਂ ਹਨ, ਪਰ ਜ਼ਿਆਦਾਤਰ ਐਪਾਂ ਲਈ ਢੁਕਵਾਂ ਨਹੀਂ ਹੁੰਦਾ।"</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"ਸਕ੍ਰੀਨ ਨੂੰ ਦੇਖੋ ਅਤੇ ਕੰਟਰੋਲ ਕਰੋ"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"ਇਹ ਸਕ੍ਰੀਨ \'ਤੇ ਸਾਰੀ ਸਮੱਗਰੀ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਸਮੱਗਰੀ ਨੂੰ ਦੂਜੀਆਂ ਐਪਾਂ ਦੇ ਉੱਪਰ ਦਿਖਾ ਸਕਦੀ ਹੈ।"</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"ਕਾਰਵਾਈਆਂ ਦੇਖੋ ਅਤੇ ਕਰੋ"</string>
@@ -1933,36 +1933,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ ਇਸ ਵੇਲੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਹੈ"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"ਕੈਮਰਾ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ਫ਼ੋਨ \'ਤੇ ਜਾਰੀ ਰੱਖੋ"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਅਣਉਪਲਬਧ ਹੈ"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Android TV ਸੈਟਿੰਗਾਂ ਅਣਉਪਲਬਧ ਹਨ"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"ਟੈਬਲੈੱਟ ਸੈਟਿੰਗਾਂ ਅਣਉਪਲਬਧ ਹਨ"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"ਫ਼ੋਨ ਸੈਟਿੰਗਾਂ ਅਣਉਪਲਬਧ ਹਨ"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ Android TV ਡੀਵਾਈਸ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਟੈਬਲੈੱਟ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਫ਼ੋਨ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"ਇਸ ਸਮੇਂ ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ Android TV ਡੀਵਾਈਸ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"ਇਸ ਸਮੇਂ ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਟੈਬਲੈੱਟ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"ਇਸ ਸਮੇਂ ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਫ਼ੋਨ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"ਇਹ ਐਪ ਵਧੀਕ ਸੁਰੱਖਿਆ ਦੀ ਬੇਨਤੀ ਕਰ ਰਹੀ ਹੈ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ Android TV ਡੀਵਾਈਸ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"ਇਹ ਐਪ ਵਧੀਕ ਸੁਰੱਖਿਆ ਦੀ ਬੇਨਤੀ ਕਰ ਰਹੀ ਹੈ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਟੈਬਲੈੱਟ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"ਇਹ ਐਪ ਵਧੀਕ ਸੁਰੱਖਿਆ ਦੀ ਬੇਨਤੀ ਕਰ ਰਹੀ ਹੈ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਫ਼ੋਨ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ਇਹ ਐਪ Android ਦੇ ਕਿਸੇ ਵਧੇਰੇ ਪੁਰਾਣੇ ਵਰਜਨ ਲਈ ਬਣਾਈ ਗਈ ਸੀ ਅਤੇ ਸ਼ਾਇਦ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ। ਅੱਪਡੇਟਾਂ ਲਈ ਜਾਂਚ ਕਰੋ ਜਾਂ ਵਿਕਾਸਕਾਰ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ਅੱਪਡੇਟ ਲਈ ਜਾਂਚ ਕਰੋ"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"ਤੁਹਾਨੂੰ ਨਵੇਂ ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਹੋਏ ਹਨ"</string>
@@ -2067,14 +2052,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"ਹੋਰ ਜਾਣਨ ਲਈ ਅਤੇ ਬਦਲਾਅ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵਿਕਲਪ ਬਦਲ ਗਿਆ ਹੈ"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"ਟੈਪ ਕਰਕੇ ਦੋਖੋ ਕਿ ਕਿਹੜੀਆਂ ਚੀਜ਼ਾਂ ਬਲਾਕ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ।"</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"ਸੂਚਨਾ ਸੈਟਿੰਗਾਂ ਦੀ ਸਮੀਖਿਆ ਕਰੋ"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"Android 13 ਵਿੱਚ, ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਥਾਪਤ ਕੀਤੀਆਂ ਜਾਣ ਵਾਲੀਆਂ ਐਪਾਂ ਨੂੰ ਸੂਚਨਾਵਾਂ ਭੇਜਣ ਲਈ ਤੁਹਾਡੀ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ। ਮੌਜੂਦਾ ਐਪਾਂ ਲਈ ਇਸ ਇਜਾਜ਼ਤ ਨੂੰ ਬਦਲਣ ਵਾਸਤੇ ਟੈਪ ਕਰੋ।"</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"ਬਾਅਦ ਵਿੱਚ ਯਾਦ ਕਰਵਾਓ"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ਖਾਰਜ ਕਰੋ"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"ਸਿਸਟਮ"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"ਸੈਟਿੰਗਾਂ"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"ਕੈਮਰਾ"</string>
@@ -2293,9 +2274,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> ਦਾ ਅਨੁਵਾਦ ਕੀਤਾ ਗਿਆ।"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"ਸੁਨੇਹੇ ਦਾ <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> ਤੋਂ <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> ਵਿੱਚ ਅਨੁਵਾਦ ਕੀਤਾ ਗਿਆ।"</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"ਬੈਕਗ੍ਰਾਊਂਡ ਸਰਗਰਮੀ"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"ਇੱਕ ਐਪ ਬੈਟਰੀ ਵਰਤ ਰਹੀ ਹੈ"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"ਇੱਕ ਐਪ ਹਾਲੇ ਵੀ ਕਿਰਿਆਸ਼ੀਲ ਹੈ"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> ਵੱਲੋਂ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਬੈਟਰੀ ਵਰਤੀ ਜਾ ਰਹੀ ਹੈ। ਸਮੀਖਿਆ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ਵੱਲੋਂ ਬੈਟਰੀ ਲਾਈਫ਼ ਨੂੰ ਪ੍ਰਭਾਵਿਤ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ। ਕਿਰਿਆਸ਼ੀਲ ਐਪਾਂ ਦੀ ਸਮੀਖਿਆ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ਕਿਰਿਆਸ਼ੀਲ ਐਪਾਂ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> ਤੋਂ ਫ਼ੋਨ ਦੇ ਕੈਮਰੇ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 6d9c4b6..2cd8a6d 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -2069,14 +2069,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Kliknij, by dowiedzieć się więcej i zmienić ustawienia."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Zmiany w trybie Nie przeszkadzać"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Kliknij, by sprawdzić, co jest zablokowane."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Sprawdź ustawienia powiadomień"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"Na Androidzie 13 aplikacje, które zainstalujesz, będą potrzebowały zezwolenia na wysyłanie powiadomień. Kliknij, aby zmienić uprawnienia dla istniejących aplikacji."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Przypomnij później"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Odrzuć"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Ustawienia"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Aparat"</string>
@@ -2295,9 +2291,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Przetłumaczono wiadomość: <xliff:g id="MESSAGE">%1$s</xliff:g>."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Wiadomość przetłumaczono z języka: <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> na język: <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktywność w tle"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Aplikacja używa baterii"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Aplikacja jest wciąż aktywna"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"Aplikacja <xliff:g id="APP">%1$s</xliff:g> używa baterii w tle. Kliknij, aby to sprawdzić."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"Aplikacja <xliff:g id="APP">%1$s</xliff:g> może mieć wpływ na czas pracy na baterii. Kliknij, aby sprawdzić aktywne aplikacje."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Sprawdź aktywne aplikacje"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nie można korzystać z aparatu telefonu na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 4c25913..e6eab2b 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Mensagem \"<xliff:g id="MESSAGE">%1$s</xliff:g>\" traduzida."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Mensagem traduzida do <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> para o <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Atividade em segundo plano"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Um app está consumindo bateria"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Um app ainda está ativo"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"O app <xliff:g id="APP">%1$s</xliff:g> está consumindo a bateria em segundo plano. Toque para revisar."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"O app <xliff:g id="APP">%1$s</xliff:g> pode afetar a duração da bateria. Toque para revisar os apps ativos."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificar apps ativos"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível acessar a câmera do smartphone pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 8908518..0b0e69a 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -422,9 +422,9 @@
<string name="permlab_readCallLog" msgid="1739990210293505948">"ler registo de chamadas"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Esta app pode ler o seu histórico de chamadas."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"escrever registo de chamadas"</string>
- <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permite à app modificar o registo de chamadas do tablet, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar esta funcionalidade para apagar ou modificar o registo de chamadas."</string>
- <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permite à app modificar o registo de chamadas do seu dispositivo Android TV, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar esta funcionalidade para apagar ou modificar o seu registo de chamadas."</string>
- <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permite à app modificar o registo de chamadas do telemóvel, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar esta funcionalidade para apagar ou modificar o seu registo de chamadas."</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permite à app modificar o registo de chamadas do tablet, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem usar esta funcionalidade para apagar ou modificar o registo de chamadas."</string>
+ <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permite à app modificar o registo de chamadas do seu dispositivo Android TV, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem usar esta funcionalidade para apagar ou modificar o seu registo de chamadas."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permite à app modificar o registo de chamadas do telemóvel, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem usar esta funcionalidade para apagar ou modificar o seu registo de chamadas."</string>
<string name="permlab_bodySensors" msgid="662918578601619569">"Aceder a dados de sensores de corpo, como ritmo cardíaco, durante a utilização"</string>
<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>
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Mensagem <xliff:g id="MESSAGE">%1$s</xliff:g> traduzida."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Mensagem traduzida de <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> para <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Atividade em segundo plano"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Uma app está a consumir bateria"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Uma app ainda está ativa"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"A app <xliff:g id="APP">%1$s</xliff:g> está a consumir bateria em segundo plano. Toque para rever."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"A app <xliff:g id="APP">%1$s</xliff:g> pode afetar a autonomia da bateria. Toque para rever as apps ativas."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificar apps ativas"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível aceder à câmara do telemóvel a partir do dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 4c25913..e6eab2b 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Mensagem \"<xliff:g id="MESSAGE">%1$s</xliff:g>\" traduzida."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Mensagem traduzida do <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> para o <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Atividade em segundo plano"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Um app está consumindo bateria"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Um app ainda está ativo"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"O app <xliff:g id="APP">%1$s</xliff:g> está consumindo a bateria em segundo plano. Toque para revisar."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"O app <xliff:g id="APP">%1$s</xliff:g> pode afetar a duração da bateria. Toque para revisar os apps ativos."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificar apps ativos"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível acessar a câmera do smartphone pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index a4ecb25..938cf84 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -2068,14 +2068,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Atingeți ca să aflați mai multe și să modificați"</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Funcția Nu deranja s-a schimbat"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Atingeți pentru a verifica ce este blocat."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Examinați setările pentru notificări"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"Pe Android 13, aplicațiile pe care le instalați necesită permisiunea de a trimite notificări. Atingeți ca să modificați permisiunea pentru aplicațiile existente."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Mai târziu"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Închideți"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Setări"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Cameră foto"</string>
@@ -2294,9 +2290,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> a fost tradus."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Mesaj tradus din <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> în <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Activitate de fundal"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"O aplicație folosește bateria"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"O aplicație este încă activă"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> folosește bateria în fundal. Atingeți pentru a examina."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> poate afecta autonomia bateriei. Atingeți pentru a examina aplicațiile active."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificați aplicațiile active"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nu se poate accesa camera foto a telefonului de pe <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 7c6b043..4786f58 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -2295,9 +2295,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Сообщение \"<xliff:g id="MESSAGE">%1$s</xliff:g>\" переведено."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Сообщение переведено на <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>. Язык оригинала: <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Работа в фоновом режиме"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Приложение расходует заряд батареи"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Приложение все ещё активно"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"Приложение \"<xliff:g id="APP">%1$s</xliff:g>\" расходует заряд батареи в фоновом режиме. Нажмите, чтобы узнать подробности."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"Приложение \"<xliff:g id="APP">%1$s</xliff:g>\" может влиять на время работы батареи. Нажмите, чтобы увидеть активные приложения."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверить активные приложения"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"У устройства \"<xliff:g id="DEVICE">%1$s</xliff:g>\" нет доступа к камере телефона."</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 37223e9..9430302 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> පරිවර්තනය කරන ලදි."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"පණිවිඩය <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> සිට <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> භාෂාවට පරිවර්තනය කරන ලදි."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"පසුබිම් ක්රියාකාරකම"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"යෙදුමක් බැටරිය භාවිත කරමින් ඇත"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"යෙදුමක් තවම සක්රියයි"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> පසුබිමේ බැටරිය භාවිත කරමින් ඇත. සමාලෝචනය කිරීමට තට්ටු කරන්න."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> බැටරි ආයු කාලය සඳහා බලපෑමට ඉඩ ඇත. සක්රිය යෙදුම් සමාලෝචනය කිරීමට තට්ටු කරන්න."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"සක්රිය යෙදුම් පරීක්ෂා කරන්න"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> වෙතින් දුරකථනයේ කැමරාවට ප්රවේශ විය නොහැකිය"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index b9edd9a..2652be0 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -2069,14 +2069,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Klepnutím získate ďalšie informácie a budete môcť vykonať zmeny."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Režim bez vyrušení sa zmenil"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Klepnutím skontrolujete, čo je blokované."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Kontrola nastavení upozornení"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"V Androide 13 vyžadujú nainštalované aplikácie povolenie, aby mohli odosielať upozornenia. Klepnutím môžete zmeniť toto povolenie pre existujúce aplikácie."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Pripomenúť neskôr"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Zavrieť"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Systém"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Nastavenia"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Fotoaparát"</string>
@@ -2295,9 +2291,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Správa <xliff:g id="MESSAGE">%1$s</xliff:g> bola preložená."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Správa bola preložená z jazyka <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> do jazyka <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktivita na pozadí"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Aplikácia používa batériu"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Aplikácia je stále aktívna"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> používa batériu na pozadí. Skontrolujte to klepnutím."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> môže mať vplyv na výdrž batérie. Klepnutím si zobrazte aktívne aplikácie."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Skontrolovať aktívne aplikácie"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> nemáte prístup ku kamere telefónu"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index f7020ae..d704c29 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1935,36 +1935,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno ni na voljo."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"»<xliff:g id="ACTIVITY">%1$s</xliff:g>« ni na voljo"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Potrebno je dovoljenje"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Fotoaparat ni na voljo"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Nadaljevanje v telefonu"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon ni na voljo"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Nastavitve naprave Android TV niso na voljo"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Nastavitve tabličnega računalnika niso na voljo"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Nastavitve telefona niso na voljo"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"V napravi <xliff:g id="DEVICE">%1$s</xliff:g> ni mogoče dostopati do te vsebine. Poskusite z napravo Android TV."</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"V napravi <xliff:g id="DEVICE">%1$s</xliff:g> ni mogoče dostopati do te vsebine. Poskusite s tabličnim računalnikom."</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"V napravi <xliff:g id="DEVICE">%1$s</xliff:g> ni mogoče dostopati do te vsebine. Poskusite s telefonom."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"V napravi <xliff:g id="DEVICE">%1$s</xliff:g> trenutno ni mogoče dostopati do te vsebine. Poskusite z napravo Android TV."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"V napravi <xliff:g id="DEVICE">%1$s</xliff:g> trenutno ni mogoče dostopati do te vsebine. Poskusite s tabličnim računalnikom."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"V napravi <xliff:g id="DEVICE">%1$s</xliff:g> trenutno ni mogoče dostopati do te vsebine. Poskusite s telefonom."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ta aplikacija zahteva dodatno varnost. Poskusite z napravo Android TV."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ta aplikacija zahteva dodatno varnost. Poskusite s tabličnim računalnikom."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ta aplikacija zahteva dodatno varnost. Poskusite s telefonom."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ta aplikacija je bila zasnovana za starejšo različico Androida in morda ne bo delovala pravilno. Preverite, ali so na voljo posodobitve, ali pa se obrnite na razvijalca."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Preveri, ali je na voljo posodobitev"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nova sporočila."</string>
@@ -2069,14 +2054,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Dotaknite se, če želite izvedeti več in spremeniti."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Način »ne moti« je spremenjen"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Dotaknite se, da preverite, kaj je blokirano."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Preglejte nastavitve obvestil"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"V Androidu 13 bodo aplikacije, ki jih namestite, za pošiljanje obvestil potrebovale vaše dovoljenje. Dotaknite se, če želite spremeniti to dovoljenje za obstoječe aplikacije."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Opomni me pozneje"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Opusti"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Nastavitve"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Fotoaparat"</string>
@@ -2295,9 +2276,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Sporočilo »<xliff:g id="MESSAGE">%1$s</xliff:g>« je prevedeno."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Sporočilo je prevedeno iz jezika »<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>« v jezik »<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>«."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Dejavnost v ozadju"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Aplikacija porablja energijo baterije"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Aplikacija je še vedno aktivna"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> porablja energijo baterije v ozadju. Dotaknite se za pregled."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> morda vpliva na čas delovanja baterije. Dotaknite se za pregled aktivnih aplikacij."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Preverite aktivne aplikacije"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ni mogoče dostopati do fotoaparata telefona prek naprave <xliff:g id="DEVICE">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 9d4cd999..b02544c 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> i përkthyer."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Mesazhi u përkthye nga <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> në <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktiviteti në sfond"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Një aplikacion po përdor baterinë"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Një aplikacion është ende aktiv"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> po përdor baterinë në sfond. Trokit për ta rishikuar."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> mund të kenë ndikim në kohëzgjatjen e baterisë. Trokit për të rishikuar aplikacionet aktive."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Kontrollo aplikacionet aktive"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Nuk mund të qasesh në kamerën e telefonit tënd nga <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index fa4cafb..bba0d13 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -2068,14 +2068,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Додирните да бисте сазнали више и променили подешавање."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Режим Не узнемиравај је промењен"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Додирните да бисте проверили шта је блокирано."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Прегледајте подешавања обавештења"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"У Android-у 13 апликације које инсталирате морају да имају дозволу за слање обавештења. Додирните да бисте променили ову дозволу за постојеће апликације."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Подсети ме касније"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Одбаци"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Систем"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Подешавања"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Камера"</string>
@@ -2294,9 +2290,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> Преведено."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Порука је преведена са језика <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> на <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Активност у позадини"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Апликација користи батерију"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Апликација је и даље активна"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> користи батерију у позадини. Додирните да бисте прегледали."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> може да утиче на трајање батерије. Додирните да бисте прегледали активне апликације."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверите активне апликације"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не може да се приступи камери телефона са <xliff:g id="DEVICE">%1$s</xliff:g> уређаја"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 13b1fcd..9b98329 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> har översatts."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Meddelandet har översatts från <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> till<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Bakgrundsaktivitet"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"En app använder batteriet"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"En app är fortfarande aktiv"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> använder batteriet i bakgrunden. Tryck för att granska."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> kan påverka batteritiden. Tryck för att granska de aktiva apparna."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Kontrollera aktiva appar"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Telefonens kamera kan inte användas från <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 031fad5..5b62726 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> Imetafsiriwa."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Ujumbe umetafsiriwa kwa <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> kutoka <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Shughuli za Chinichini"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Programu inatumia betri"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Programu bado inatumika"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> inatumia betri chinichini. Gusa ili ukague."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> inaweza kuathiri muda wa matumizi ya betri. Gusa ili ukague programu zinazotumika."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Angalia programu zinazotumika"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Haiwezi kufikia kamera ya simu kutoka kwenye <xliff:g id="DEVICE">%1$s</xliff:g> yako"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 4ddfccba..7c4a794 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -2067,14 +2067,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"மேலும் அறிந்து மாற்ற, தட்டவும்."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"தொந்தரவு செய்ய வேண்டாம் அமைப்புகள் மாற்றப்பட்டன"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"எவற்றையெல்லாம் தடுக்கிறது என்பதைப் பார்க்க, தட்டவும்."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"அறிவிப்பு அமைப்புகளை மதிப்பாய்வு செய்யுங்கள்"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"Android 13ல், நீங்கள் நிறுவுகின்ற ஆப்ஸ் உங்களுக்கு அறிவிப்புகளை அனுப்ப உங்கள் அனுமதி தேவை. ஏற்கெனவே உள்ள ஆப்ஸுக்கு இந்த அனுமதியை மாற்ற தட்டவும்."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"பின்னர் நினைவூட்டு"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"நிராகரி"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"சிஸ்டம்"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"அமைப்புகள்"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"கேமரா"</string>
@@ -2293,9 +2289,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> மொழிபெயர்க்கப்பட்டது."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> மொழியிலிருந்து <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> மொழிக்கு மெசேஜ் மொழிபெயர்க்கப்பட்டது."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"பின்னணிச் செயல்பாடு"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"ஆப்ஸ் பேட்டரியைப் பயன்படுத்துகிறது"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"ஆப்ஸ் செயல்பாட்டில் உள்ளது"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> ஆப்ஸ் பேட்டரியைப் பின்னணியில் பயன்படுத்துகிறது. பார்க்க தட்டவும்."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> பேட்டரியின் ஆயுளைப் பாதிக்கலாம். செயலிலுள்ள ஆப்ஸைப் பார்க்க தட்டவும்."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"செயலிலுள்ள ஆப்ஸைப் பாருங்கள்"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்திலிருந்து மொபைலின் கேமராவை அணுக முடியாது"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 851d17e..242749c 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1933,36 +1933,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ప్రస్తుతం అందుబాటులో లేదు."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> అందుబాటులో లేదు"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"అనుమతి అవసరం"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"కెమెరా అందుబాటులో లేదు"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ఫోన్లో కొనసాగించండి"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"మైక్రోఫోన్ అందుబాటులో లేదు"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Android TV సెట్టింగ్లు అందుబాటులో లేవు"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"టాబ్లెట్ సెట్టింగ్లు అందుబాటులో లేవు"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"ఫోన్ సెట్టింగ్లు అందుబాటులో లేవు"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"మీ <xliff:g id="DEVICE">%1$s</xliff:g>లో దీన్ని యాక్సెస్ చేయడం సాధ్యపడదు. బదులుగా మీ Android TV పరికరంలో ట్రై చేయండి."</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"మీ <xliff:g id="DEVICE">%1$s</xliff:g>లో దీన్ని యాక్సెస్ చేయడం సాధ్యపడదు. బదులుగా మీ టాబ్లెట్లో ట్రై చేయండి."</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"మీ <xliff:g id="DEVICE">%1$s</xliff:g>లో దీన్ని యాక్సెస్ చేయడం సాధ్యపడదు. బదులుగా మీ ఫోన్లో ట్రై చేయండి."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"ఈ సమయంలో మీ <xliff:g id="DEVICE">%1$s</xliff:g>లో దీన్ని యాక్సెస్ చేయడం సాధ్యపడదు. బదులుగా మీ Android TV పరికరంలో ట్రై చేయండి."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"ఈ సమయంలో మీ <xliff:g id="DEVICE">%1$s</xliff:g>లో దీన్ని యాక్సెస్ చేయడం సాధ్యపడదు. బదులుగా మీ టాబ్లెట్లో ట్రై చేయండి."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"ఈ సమయంలో మీ <xliff:g id="DEVICE">%1$s</xliff:g>లో దీన్ని యాక్సెస్ చేయడం సాధ్యపడదు. బదులుగా మీ ఫోన్లో ట్రై చేయండి."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ Android TV పరికరంలో ట్రై చేయండి."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ టాబ్లెట్లో ట్రై చేయండి."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ ఫోన్లో ట్రై చేయండి."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"ఈ యాప్ పాత వెర్షన్ Android కోసం రూపొందించబడింది మరియు అది సరిగ్గా పని చేయకపోవచ్చు. అప్డేట్ల కోసం తనిఖీ చేయడానికి ప్రయత్నించండి లేదా డెవలపర్ని సంప్రదించండి."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"అప్డేట్ కోసం తనిఖీ చేయండి"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"మీకు కొత్త మెసేజ్లు ఉన్నాయి"</string>
@@ -2067,14 +2052,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"మరింత తెలుసుకోవడానికి మరియు మార్చడానికి నొక్కండి."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"అంతరాయం కలిగించవద్దు మార్చబడింది"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"బ్లాక్ చేయబడిన దాన్ని తనిఖీ చేయడానికి నొక్కండి."</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"నోటిఫికేషన్ సెట్టింగ్లను రివ్యూ చేయండి"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"Android 13లో, మీరు ఇన్స్టాల్ చేసే యాప్లకు నోటిఫికేషన్లను పంపడానికి మీ అనుమతి అవసరం. ఇప్పటికే ఉన్న యాప్ల కోసం ఈ అనుమతిని మార్చడానికి ట్యాప్ చేయండి."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"తర్వాత గుర్తు చేయి"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"విస్మరించండి"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"సిస్టమ్"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"సెట్టింగ్లు"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"కెమెరా"</string>
@@ -2293,9 +2274,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> అనువదించబడింది."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"మెసేజ్ <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> నుండి <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>కు అనువదించబడింది."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"బ్యాక్గ్రౌండ్ యాక్టివిటీ"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"యాప్ బ్యాటరీని ఉపయోగిస్తోంది"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"యాప్ ఇప్పటికీ యాక్టివ్గా ఉంది"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"బ్యాక్గ్రౌండ్లో <xliff:g id="APP">%1$s</xliff:g> బ్యాటరీని ఉపయోగిస్తోంది. రివ్యూ చేయడానికి ట్యాప్ చేయండి."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> బ్యాటరీ జీవితకాలాన్ని ప్రభావితం చేయవచ్చు. యాక్టివ్ యాప్లను రివ్యూ చేయడానికి ట్యాప్ చేయండి."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"యాక్టివ్గా ఉన్న యాప్లను చెక్ చేయండి"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"మీ <xliff:g id="DEVICE">%1$s</xliff:g> నుండి ఫోన్ కెమెరాను యాక్సెస్ చేయడం సాధ్యపడదు"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index adf04ed..e565608 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1681,9 +1681,9 @@
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"อนุญาตให้ <xliff:g id="SERVICE">%1$s</xliff:g> ควบคุมอุปกรณ์อย่างเต็มที่ไหม"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"การควบคุมอย่างเต็มที่เหมาะสำหรับแอปที่ช่วยคุณในเรื่องความต้องการความช่วยเหลือพิเศษแต่ไม่เหมาะสำหรับแอปส่วนใหญ่"</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"ดูและควบคุมหน้าจอ"</string>
- <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"การควบคุมนี้อ่านเนื้อหาทั้งหมดบนหน้าจอและแสดงเนื้อหาทับแอปอื่นๆ"</string>
+ <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"การควบคุมนี้สามารถอ่านเนื้อหาทั้งหมดบนหน้าจอและแสดงเนื้อหาทับแอปอื่นๆ"</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"ดูและดำเนินการ"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"การกระทำนี้ติดตามการโต้ตอบของคุณกับแอปหรือกับเซ็นเซอร์ของฮาร์ดแวร์ และจะโต้ตอบกับแอปต่างๆ แทนคุณ"</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"การควบคุมนี้สามารถติดตามการโต้ตอบของคุณกับแอปหรือกับเซ็นเซอร์ของฮาร์ดแวร์ และโต้ตอบกับแอปต่างๆ แทนคุณ"</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"อนุญาต"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"ปฏิเสธ"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"แตะฟีเจอร์เพื่อเริ่มใช้"</string>
@@ -1933,36 +1933,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ไม่พร้อมใช้งานในขณะนี้"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ไม่พร้อมใช้งาน"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"ต้องการสิทธิ์"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"กล้องไม่พร้อมใช้งาน"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ดำเนินการต่อบนโทรศัพท์"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"ไมโครโฟนไม่พร้อมใช้งาน"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"การตั้งค่า Android TV ไม่พร้อมใช้งาน"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"การตั้งค่าแท็บเล็ตไม่พร้อมใช้งาน"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"การตั้งค่าโทรศัพท์ไม่พร้อมใช้งาน"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"เข้าถึงแอปนี้ใน <xliff:g id="DEVICE">%1$s</xliff:g> ของคุณไม่ได้ โปรดลองเข้าถึงในอุปกรณ์ Android TV แทน"</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"เข้าถึงแอปนี้ใน <xliff:g id="DEVICE">%1$s</xliff:g> ของคุณไม่ได้ โปรดลองเข้าถึงในแท็บเล็ตแทน"</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"เข้าถึงแอปนี้ใน <xliff:g id="DEVICE">%1$s</xliff:g> ของคุณไม่ได้ โปรดลองเข้าถึงในโทรศัพท์แทน"</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"เข้าถึงแอปนี้ใน <xliff:g id="DEVICE">%1$s</xliff:g> ของคุณไม่ได้ในขณะนี้ โปรดลองเข้าถึงในอุปกรณ์ Android TV แทน"</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"เข้าถึงแอปนี้ใน <xliff:g id="DEVICE">%1$s</xliff:g> ของคุณไม่ได้ในขณะนี้ โปรดลองเข้าถึงในแท็บเล็ตแทน"</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"เข้าถึงแอปนี้ใน <xliff:g id="DEVICE">%1$s</xliff:g> ของคุณไม่ได้ในขณะนี้ โปรดลองเข้าถึงในโทรศัพท์แทน"</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"แอปนี้มีการขอการรักษาความปลอดภัยเพิ่มเติม โปรดลองเข้าถึงในอุปกรณ์ Android TV แทน"</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"แอปนี้มีการขอการรักษาความปลอดภัยเพิ่มเติม โปรดลองเข้าถึงในแท็บเล็ตแทน"</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"แอปนี้มีการขอการรักษาความปลอดภัยเพิ่มเติม โปรดลองเข้าถึงในโทรศัพท์แทน"</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"แอปนี้สร้างขึ้นเพื่อ Android เวอร์ชันเก่าและอาจทำงานผิดปกติ โปรดลองตรวจหาการอัปเดตหรือติดต่อนักพัฒนาซอฟต์แวร์"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ตรวจสอบอัปเดต"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"คุณมีข้อความใหม่"</string>
@@ -2293,9 +2278,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> แปลแล้ว"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"แปลข้อความจากภาษา<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>เป็นภาษา<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>แล้ว"</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"กิจกรรมในเบื้องหลัง"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"แอปกำลังใช้แบตเตอรี่"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"แอปยังทำงานอยู่"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> กำลังใช้แบตเตอรี่ในเบื้องหลัง แตะเพื่อตรวจสอบ"</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> อาจส่งผลต่ออายุการใช้งานแบตเตอรี่ แตะเพื่อตรวจสอบแอปที่ทำงานอยู่"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ตรวจสอบแอปที่ใช้งานอยู่"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"เข้าถึงกล้องของโทรศัพท์จาก <xliff:g id="DEVICE">%1$s</xliff:g> ไม่ได้"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index a195c88..6c95f3f 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1933,36 +1933,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"Hindi available sa ngayon ang <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"Hindi available ang <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Kailangan ng pahintulot"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Hindi available ang camera"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Magpatuloy sa telepono"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Hindi available ang mikropono"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Hindi available ang mga setting ng Android TV"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Hindi available ang mga setting ng tablet"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Hindi available ang mga setting ng telepono"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"Hindi ito maa-access sa iyong <xliff:g id="DEVICE">%1$s</xliff:g>. Subukan na lang sa iyong Android TV device."</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"Hindi ito maa-access sa iyong <xliff:g id="DEVICE">%1$s</xliff:g>. Subukan na lang sa iyong tablet."</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"Hindi ito maa-access sa iyong <xliff:g id="DEVICE">%1$s</xliff:g>. Subukan na lang sa iyong telepono."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"Hindi ito maa-access sa iyong <xliff:g id="DEVICE">%1$s</xliff:g> sa ngayon. Subukan na lang sa iyong Android TV device."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"Hindi ito maa-access sa iyong <xliff:g id="DEVICE">%1$s</xliff:g> sa ngayon. Subukan na lang sa iyong tablet."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"Hindi ito maa-access sa iyong <xliff:g id="DEVICE">%1$s</xliff:g> sa ngayon. Subukan na lang sa iyong telepono."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Humihiling ng karagdagang seguridad ang app na ito. Subukan na lang sa iyong Android TV device."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Humihiling ng karagdagang seguridad ang app na ito. Subukan na lang sa iyong tablet."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Humihiling ng karagdagang seguridad ang app na ito. Subukan na lang sa iyong telepono."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Ang app na ito ay ginawa para sa mas lumang bersyon ng Android at maaaring hindi gumana nang maayos. Subukang tingnan kung may mga update, o makipag-ugnayan sa developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Tingnan kung may update"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Mayroon kang mga bagong mensahe"</string>
@@ -2293,9 +2278,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Naisalin ang <xliff:g id="MESSAGE">%1$s</xliff:g>."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Naisalin ang mensahe sa <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> mula sa <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktibidad sa Background"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"May app na gumagamit ng baterya"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"May app na aktibo pa rin"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"Gumagamit ng baterya ang <xliff:g id="APP">%1$s</xliff:g> sa background. I-tap para suriin."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"Posibleng maapektuhan ng <xliff:g id="APP">%1$s</xliff:g> ang tagal ng baterya. I-tap para suriin ang mga aktibong app."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Tingnan ang mga aktibong app"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Hindi ma-access ang camera ng telepono mula sa iyong <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 1313b96..580e5d85 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> Çevrildi."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Mesajın, <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>-<xliff:g id="TO_LANGUAGE">%2$s</xliff:g> çevirisi yapıldı."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Arka Plan Etkinliği"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Pil kullanan bir uygulama var"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Hâlâ etkin olan bir uygulama var"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> uygulaması arka planda pil kullanıyor. İncelemek için dokunun."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> uygulaması pil ömrünü etkileyebilir. Etkin uygulamaları incelemek için dokunun."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Etkin uygulamaları kontrol edin"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan telefonun kamerasına erişilemiyor"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 29d5c5e..9f20cf2 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -2295,9 +2295,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> (перекладене повідомлення)."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Повідомлення перекладено (мова оригіналу: <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>, мова перекладу: <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>)."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Робота у фоновому режимі"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Додаток споживає заряд акумулятора"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Додаток досі активний"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"Додаток <xliff:g id="APP">%1$s</xliff:g> споживає заряд акумулятора у фоновому режимі. Натисніть, щоб переглянути."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"Додаток <xliff:g id="APP">%1$s</xliff:g> може вплинути на час роботи акумулятора. Натисніть, щоб переглянути активні додатки."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Перевірте активні додатки"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Не вдається отримати доступ до камери телефона з пристрою <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index fb69ba3..e0aa778 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> کا ترجمہ کیا گیا۔"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"پیغام کا ترجمہ <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> سے<xliff:g id="TO_LANGUAGE">%2$s</xliff:g> میں کیا گیا۔"</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"پس منظر کی سرگرمی"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"ایک ایپ بیٹری کا استعمال کر رہی ہے"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"ایک ایپ اب بھی فعال ہے"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> ایپ پس منظر میں بیٹری استعمال کر رہی ہے۔ جائزے کے لیے تھپتھپائیں۔"</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ایپ بیٹری لائف کو متاثر کر سکتی ہے۔ فعال ایپس کا جائزہ لینے کے لیے تھپتھپائیں۔"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"فعال ایپس چیک کریں"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> سے فون کے کیمرا تک رسائی حاصل نہیں کی جا سکتی"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index afea585..e5e006f 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1933,36 +1933,21 @@
<string name="app_blocked_message" msgid="542972921087873023">"Ayni vaqtda <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi ishlamayapti."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> kanali ish faoliyatida emas"</string>
<string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Ruxsat zarur"</string>
- <!-- no translation found for app_streaming_blocked_title_for_camera_dialog (3935701653713853065) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_fingerprint_dialog (3516853717714141951) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_microphone_dialog (544822455127171206) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (196994247017450357) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (8222710146267948647) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_title_for_settings_dialog (6895719984375299791) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (5024599278277957935) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (7491114163056552686) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message (1245180131667647277) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6306583663205997979) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (6545624942642129664) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_permission_dialog (8462740631707923000) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (3470977315395784567) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (698460091901465092) -->
- <skip />
- <!-- no translation found for app_streaming_blocked_message_for_fingerprint_dialog (8552691971910603907) -->
- <skip />
+ <string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera ishlamayapti"</string>
+ <string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Telefonda davom ettirish"</string>
+ <string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon ishlamayapti"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tv" msgid="196994247017450357">"Android TV sozlamalari ishlamayapti"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="tablet" msgid="8222710146267948647">"Planshet sozlamalari ishlamayapti"</string>
+ <string name="app_streaming_blocked_title_for_settings_dialog" product="default" msgid="6895719984375299791">"Telefon sozlamalari ishlamayapti"</string>
+ <string name="app_streaming_blocked_message" product="tv" msgid="5024599278277957935">"Bu <xliff:g id="DEVICE">%1$s</xliff:g> qurilmangizda ochilmaydi. Android TV qurilmasi orqali urinib koʻring."</string>
+ <string name="app_streaming_blocked_message" product="tablet" msgid="7491114163056552686">"Bu <xliff:g id="DEVICE">%1$s</xliff:g> qurilmangizda ochilmaydi. Planshet orqali urinib koʻring."</string>
+ <string name="app_streaming_blocked_message" product="default" msgid="1245180131667647277">"Bu <xliff:g id="DEVICE">%1$s</xliff:g> qurilmangizda ochilmaydi. Telefon orqali urininb koʻring."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tv" msgid="6306583663205997979">"Ayni vaqtda bu translatsiya <xliff:g id="DEVICE">%1$s</xliff:g> qurilmangizda ishlamaydi. Android TV qurilmasi orqali urinib koʻring."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="tablet" msgid="6545624942642129664">"Ayni vaqtda bu translatsiya <xliff:g id="DEVICE">%1$s</xliff:g> qurilmangizda ishlamaydi. Planshet orqali urinib koʻring."</string>
+ <string name="app_streaming_blocked_message_for_permission_dialog" product="default" msgid="8462740631707923000">"Ayni vaqtda bu translatsiya <xliff:g id="DEVICE">%1$s</xliff:g> qurilmangizda ishlamaydi. Telefon orqali urininb koʻring."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Bu ilova qoʻshimcha himoyani talab qilmoqda. Android TV qurilmasi orqali urinib koʻring."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Bu ilova qoʻshimcha himoyani talab qilmoqda. Planshet orqali urinib koʻring."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Bu ilova qoʻshimcha himoyani talab qilmoqda. Telefon orqali urininb koʻring."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Bu ilova eskiroq Android versiyalariga chiqarilgan va xato ishlashi mumkin. Yangilanishlarini tekshiring yoki dasturchi bilan bog‘laning."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Yangilanish borligini tekshirish"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Sizga yangi SMS keldi"</string>
@@ -2067,14 +2052,10 @@
<string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Batafsil axborot olish va o‘zgartirish uchun bosing."</string>
<string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Bezovta qilinmasin rejimi sozlamalari o‘zgartirildi"</string>
<string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Nimalar bloklanganini tekshirish uchun bosing"</string>
- <!-- no translation found for review_notification_settings_title (5102557424459810820) -->
- <skip />
- <!-- no translation found for review_notification_settings_text (5696497037817525074) -->
- <skip />
- <!-- no translation found for review_notification_settings_remind_me_action (1081081018678480907) -->
- <skip />
- <!-- no translation found for review_notification_settings_dismiss (4160916504616428294) -->
- <skip />
+ <string name="review_notification_settings_title" msgid="5102557424459810820">"Bildirishnoma sozlamalarini tekshiring"</string>
+ <string name="review_notification_settings_text" msgid="5696497037817525074">"Android 13 versiyasida oʻrnatiladigan ilovalar bildirishnoma yuborishiga ruxsat talab etiladi. Mavjud ilovalar uchun bu ruxsatni oʻzgartirish uchun bosing."</string>
+ <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Keyinroq eslatilsin"</string>
+ <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Yopish"</string>
<string name="notification_app_name_system" msgid="3045196791746735601">"Tizim"</string>
<string name="notification_app_name_settings" msgid="9088548800899952531">"Sozlamalar"</string>
<string name="notification_appops_camera_active" msgid="8177643089272352083">"Kamera"</string>
@@ -2293,9 +2274,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> tarjima qilindi."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Xabar <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> tilidan <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> tiliga tarjima qilindi."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Fondagi harakatlar"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Ilova batareyadan foydalanmoqda"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Ilova hali ham faol"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> orqa fonda batareyadan foydalanmoqda. Tekshirish uchun bosing."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> batareya quvvatiga taʼsir qiladi. Faol ilovalarni koʻrib chiqish uchun bosing."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Faol ilovalarni tekshiring"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"<xliff:g id="DEVICE">%1$s</xliff:g> qurilmasidan telefonning kamerasiga kirish imkonsiz"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index db2855c..14de1b9 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Đã dịch <xliff:g id="MESSAGE">%1$s</xliff:g>."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Đã dịch thông báo từ <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> sang <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Hoạt động trong nền"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"Một ứng dụng đang sử dụng pin"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Một ứng dụng vẫn đang hoạt động"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"<xliff:g id="APP">%1$s</xliff:g> đang sử dụng pin trong nền. Hãy nhấn để xem."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> có thể ảnh hưởng đến thời lượng pin. Hãy nhấn để xem các ứng dụng đang hoạt động."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Xem các ứng dụng đang hoạt động"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Không truy cập được vào máy ảnh trên điện thoại từ <xliff:g id="DEVICE">%1$s</xliff:g> 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 c049efc..002896e 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"已翻译“<xliff:g id="MESSAGE">%1$s</xliff:g>”。"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"已将消息内容从<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>翻译成<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>。"</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"后台活动"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"某个应用正在消耗电量"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"某个应用仍在使用中"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"“<xliff:g id="APP">%1$s</xliff:g>”正在后台消耗电量。点按即可查看。"</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"“<xliff:g id="APP">%1$s</xliff:g>”可能会影响电池续航时间。点按即可查看使用中的应用。"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"查看使用中的应用"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"无法从<xliff:g id="DEVICE">%1$s</xliff:g>上访问手机的摄像头"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 732faa0..e1c4ce3 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"翻譯咗「<xliff:g id="MESSAGE">%1$s</xliff:g>」。"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"已經將訊息由<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>翻譯成<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>。"</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"背景活動"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"某個應用程式正在使用電量"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"某個應用程式目前仍在運作"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"「<xliff:g id="APP">%1$s</xliff:g>」正在背景使用電量。輕按即可查看。"</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"「<xliff:g id="APP">%1$s</xliff:g>」可能會影響電池壽命。輕按即可查看使用中的應用程式。"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"查看使用中的應用程式"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取手機的相機"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 403bf1a..cc752cd 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"已翻譯<xliff:g id="MESSAGE">%1$s</xliff:g>。"</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"訊息內容已從<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>翻成<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>。"</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"背景活動"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"某個應用程式正在消耗電池電力"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"某個應用程式目前仍在運作"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"「<xliff:g id="APP">%1$s</xliff:g>」應用程式正在背景消耗電池電力。輕觸即可查看。"</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"「<xliff:g id="APP">%1$s</xliff:g>」應用程式可能會影響電池續航力。輕觸即可查看使用中的應用程式。"</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"查看使用中的應用程式"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取手機的相機"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index cf9e05f..88a184b 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -2293,9 +2293,11 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> Uhunyushiwe."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Umlayezo uhunyushwe kusuka ku-<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> kuya ku-<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Umsebenzi Wangemuva"</string>
- <string name="notification_title_abusive_bg_apps" msgid="3258460527676573815">"I-app isebenzisa ibhethri"</string>
+ <!-- no translation found for notification_title_abusive_bg_apps (994230770856147656) -->
+ <skip />
<string name="notification_title_long_running_fgs" msgid="8170284286477131587">"I-app isasebenza"</string>
- <string name="notification_content_abusive_bg_apps" msgid="9180610713603474720">"I-<xliff:g id="APP">%1$s</xliff:g> isebenzisa ibhethri kungemuva. Thepha ukuze ubuyekeze."</string>
+ <!-- no translation found for notification_content_abusive_bg_apps (5296898075922695259) -->
+ <skip />
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"I-<xliff:g id="APP">%1$s</xliff:g> ingase ithinte impilo yebhethri. Thepha ukuze ubuyekeze ama-app asebenzayo."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Hlola ama-app asebenzayo"</string>
<string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Ayikwazi ukufinyelela ikhamera yefoni kusuka ku-<xliff:g id="DEVICE">%1$s</xliff:g> yakho"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index cd3ba1e..757f409 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -674,6 +674,10 @@
<!-- Indicates whether to enable hinge angle sensor when using unfold animation -->
<bool name="config_unfoldTransitionHingeAngle">false</bool>
+ <!-- Indicates the time needed to time out the fold animation if the device stops in half folded
+ mode. -->
+ <integer name="config_unfoldTransitionHalfFoldedTimeout">600</integer>
+
<!-- Indicates that the device supports having more than one internal display on at the same
time. Only applicable to devices with more than one internal display. If this option is
set to false, DisplayManager will make additional effort to ensure no more than 1 internal
@@ -5740,6 +5744,12 @@
-->
<bool name="config_bg_prompt_fgs_with_noti_to_bg_restricted">false</bool>
+ <!-- The behavior when the system detects it's abusive, should the system prompt the user
+ to put it into the bg restricted level.
+ True - we'll show the prompt to user, False - we'll not show it.
+ -->
+ <bool name="config_bg_prompt_abusive_apps_to_bg_restricted">false</bool>
+
<!-- The types of state where we'll exempt its battery usage during that state.
The state here must be one or a combination of STATE_TYPE_* in BaseAppStateTracker.
-->
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index cd3578c..77500c4 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -17,9 +17,9 @@
<resources>
<!-- This file defines Android telephony related resources -->
- <!-- Whether force to enable telephony new data stack or not -->
- <bool name="config_force_enable_telephony_new_data_stack">true</bool>
- <java-symbol type="bool" name="config_force_enable_telephony_new_data_stack" />
+ <!-- Whether force disabling telephony new data stack or not -->
+ <bool name="config_force_disable_telephony_new_data_stack">false</bool>
+ <java-symbol type="bool" name="config_force_disable_telephony_new_data_stack" />
<!-- Configure tcp buffer sizes per network type in the form:
network-type:rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max
diff --git a/core/res/res/values/public-final.xml b/core/res/res/values/public-final.xml
index 19a4842..85325fe 100644
--- a/core/res/res/values/public-final.xml
+++ b/core/res/res/values/public-final.xml
@@ -3222,4 +3222,184 @@
<public type="id" name="accessibilityActionDragDrop" id="0x01020056" />
<public type="id" name="accessibilityActionDragCancel" id="0x01020057" />
+ <!-- ===============================================================
+ Resources added in version T of the platform
+
+ NOTE: After this version of the platform is forked, changes cannot be made to the root
+ branch's groups for that release. Only merge changes to the forked platform branch.
+ =============================================================== -->
+ <eat-comment/>
+
+ <staging-public-group-final type="attr" first-id="0x01df0000">
+ <public name="sharedUserMaxSdkVersion" />
+ <public name="requiredSplitTypes" />
+ <public name="splitTypes" />
+ <public name="canDisplayOnRemoteDevices" />
+ <public name="supportedTypes" />
+ <public name="resetEnabledSettingsOnAppDataCleared" />
+ <public name="supportsStylusHandwriting" />
+ <public name="showClockAndComplications" />
+ <!-- @hide @SystemApi -->
+ <public name="gameSessionService" />
+ <public name="supportsBatteryGameMode" />
+ <public name="supportsPerformanceGameMode" />
+ <public name="allowGameAngleDriver" />
+ <public name="allowGameDownscaling" />
+ <public name="allowGameFpsOverride" />
+ <public name="localeConfig" />
+ <public name="showBackdrop" />
+ <public name="removed_useTargetActivityForQuickAccess"/>
+ <public name="removed_inheritKeyStoreKeys" />
+ <public name="preferKeepClear" />
+ <public name="autoHandwritingEnabled" />
+ <public name="fromExtendLeft" />
+ <public name="fromExtendTop" />
+ <public name="fromExtendRight" />
+ <public name="fromExtendBottom" />
+ <public name="toExtendLeft" />
+ <public name="toExtendTop" />
+ <public name="toExtendRight" />
+ <public name="toExtendBottom" />
+ <public name="tileService" />
+ <public name="windowSplashScreenBehavior" />
+ <public name="allowUntrustedActivityEmbedding" />
+ <public name="knownActivityEmbeddingCerts" />
+ <public name="intro" />
+ <public name="enableOnBackInvokedCallback" />
+ <public name="supportsInlineSuggestionsWithTouchExploration" />
+ <public name="lineBreakStyle" />
+ <public name="lineBreakWordStyle" />
+ <!-- @hide -->
+ <public name="maxDrawableWidth" />
+ <!-- @hide -->
+ <public name="maxDrawableHeight" />
+ <public name="backdropColor" />
+ </staging-public-group-final>
+
+ <public type="attr" name="sharedUserMaxSdkVersion" id="0x0101064d" />
+ <public type="attr" name="requiredSplitTypes" id="0x0101064e" />
+ <public type="attr" name="splitTypes" id="0x0101064f" />
+ <public type="attr" name="canDisplayOnRemoteDevices" id="0x01010650" />
+ <public type="attr" name="supportedTypes" id="0x01010651" />
+ <public type="attr" name="resetEnabledSettingsOnAppDataCleared" id="0x01010652" />
+ <public type="attr" name="supportsStylusHandwriting" id="0x01010653" />
+ <public type="attr" name="showClockAndComplications" id="0x01010654" />
+ <!-- @hide @SystemApi -->
+ <public type="attr" name="gameSessionService" id="0x01010655" />
+ <public type="attr" name="supportsBatteryGameMode" id="0x01010656" />
+ <public type="attr" name="supportsPerformanceGameMode" id="0x01010657" />
+ <public type="attr" name="allowGameAngleDriver" id="0x01010658" />
+ <public type="attr" name="allowGameDownscaling" id="0x01010659" />
+ <public type="attr" name="allowGameFpsOverride" id="0x0101065a" />
+ <public type="attr" name="localeConfig" id="0x0101065b" />
+ <public type="attr" name="showBackdrop" id="0x0101065c" />
+ <public type="attr" name="preferKeepClear" id="0x0101065d" />
+ <public type="attr" name="autoHandwritingEnabled" id="0x0101065e" />
+ <public type="attr" name="fromExtendLeft" id="0x0101065f" />
+ <public type="attr" name="fromExtendTop" id="0x01010660" />
+ <public type="attr" name="fromExtendRight" id="0x01010661" />
+ <public type="attr" name="fromExtendBottom" id="0x01010662" />
+ <public type="attr" name="toExtendLeft" id="0x01010663" />
+ <public type="attr" name="toExtendTop" id="0x01010664" />
+ <public type="attr" name="toExtendRight" id="0x01010665" />
+ <public type="attr" name="toExtendBottom" id="0x01010666" />
+ <public type="attr" name="tileService" id="0x01010667" />
+ <public type="attr" name="windowSplashScreenBehavior" id="0x01010668" />
+ <public type="attr" name="allowUntrustedActivityEmbedding" id="0x01010669" />
+ <public type="attr" name="knownActivityEmbeddingCerts" id="0x0101066a" />
+ <public type="attr" name="intro" id="0x0101066b" />
+ <public type="attr" name="enableOnBackInvokedCallback" id="0x0101066c" />
+ <public type="attr" name="supportsInlineSuggestionsWithTouchExploration" id="0x0101066d" />
+ <public type="attr" name="lineBreakStyle" id="0x0101066e" />
+ <public type="attr" name="lineBreakWordStyle" id="0x0101066f" />
+ <!-- @hide -->
+ <public type="attr" name="maxDrawableWidth" id="0x01010670" />
+ <!-- @hide -->
+ <public type="attr" name="maxDrawableHeight" id="0x01010671" />
+ <public type="attr" name="backdropColor" id="0x01010672" />
+
+ <staging-public-group-final type="id" first-id="0x01de0000">
+ <public name="removed_accessibilityActionSwipeLeft" />
+ <public name="removed_accessibilityActionSwipeRight" />
+ <public name="removed_accessibilityActionSwipeUp" />
+ <public name="removed_accessibilityActionSwipeDown" />
+ <public name="accessibilityActionShowTextSuggestions" />
+ <public name="inputExtractAction" />
+ <public name="inputExtractAccessories" />
+ </staging-public-group-final>
+
+ <public type="id" name="accessibilityActionShowTextSuggestions" id="0x01020058" />
+ <public type="id" name="inputExtractAction" id="0x01020059" />
+ <public type="id" name="inputExtractAccessories" id="0x0102005a" />
+
+ <staging-public-group-final type="style" first-id="0x01dd0000">
+ <public name="TextAppearance.DeviceDefault.Headline" />
+ </staging-public-group-final>
+
+ <public type="style" name="TextAppearance.DeviceDefault.Headline" id="0x010302e5" />
+
+ <staging-public-group-final type="string" first-id="0x01dc0000">
+ <!-- @hide @SystemApi -->
+ <public name="config_systemSupervision" />
+ <!-- @hide @SystemApi -->
+ <public name="config_devicePolicyManagement" />
+ <!-- @hide @SystemApi -->
+ <public name="config_systemAppProtectionService" />
+ <!-- @hide @SystemApi @TestApi -->
+ <public name="config_systemAutomotiveCalendarSyncManager" />
+ <!-- @hide @SystemApi -->
+ <public name="config_defaultAutomotiveNavigation" />
+ <!-- @hide @SystemApi -->
+ <public name="safety_protection_display_text" />
+ <!-- @hide @SystemApi -->
+ <public name="config_systemSettingsIntelligence" />
+ <!-- @hide -->
+ <public name="config_systemBluetoothStack" />
+ </staging-public-group-final>
+
+ <!-- @hide @SystemApi -->
+ <public type="string" name="config_systemSupervision" id="0x0104003c" />
+ <!-- @hide @SystemApi -->
+ <public type="string" name="config_devicePolicyManagement" id="0x0104003d" />
+ <!-- @hide @SystemApi -->
+ <public type="string" name="config_systemAppProtectionService" id="0x0104003e" />
+ <!-- @hide @SystemApi @TestApi -->
+ <public type="string" name="config_systemAutomotiveCalendarSyncManager" id="0x0104003f" />
+ <!-- @hide @SystemApi -->
+ <public type="string" name="config_defaultAutomotiveNavigation" id="0x01040040" />
+ <!-- @hide @SystemApi -->
+ <public type="string" name="safety_protection_display_text" id="0x01040041" />
+ <!-- @hide @SystemApi -->
+ <public type="string" name="config_systemSettingsIntelligence" id="0x01040042" />
+ <!-- @hide -->
+ <public type="string" name="config_systemBluetoothStack" id="0x01040043" />
+
+ <staging-public-group-final type="array" first-id="0x01d90000">
+ <!-- @hide @SystemApi -->
+ <public name="config_optionalIpSecAlgorithms" />
+ </staging-public-group-final>
+
+ <!-- @hide @SystemApi -->
+ <public type="array" name="config_optionalIpSecAlgorithms" id="0x01070006" />
+
+ <staging-public-group-final type="drawable" first-id="0x01d80000">
+ <!-- @hide @SystemApi -->
+ <public name="ic_safety_protection" />
+ </staging-public-group-final>
+
+ <!-- @hide @SystemApi -->
+ <public type="drawable" name="ic_safety_protection" id="0x010800b5" />
+
+ <staging-public-group-final type="bool" first-id="0x01cf0000">
+ <!-- @hide @TestApi -->
+ <public name="config_preventImeStartupUnlessTextEditor" />
+ <!-- @hide @SystemApi -->
+ <public name="config_enableQrCodeScannerOnLockScreen" />
+ </staging-public-group-final>
+
+ <!-- @hide @TestApi -->
+ <public type="bool" name="config_preventImeStartupUnlessTextEditor" id="0x01110007" />
+ <!-- @hide @SystemApi -->
+ <public type="bool" name="config_enableQrCodeScannerOnLockScreen" id="0x01110008" />
+
</resources>
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index 86bad7f..f09ffbe 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -102,140 +102,65 @@
<resources>
<!-- ===============================================================
- Resources added in version T of the platform
+ Resources added in version U of the platform
NOTE: After this version of the platform is forked, changes cannot be made to the root
branch's groups for that release. Only merge changes to the forked platform branch.
=============================================================== -->
<eat-comment/>
- <staging-public-group type="attr" first-id="0x01df0000">
- <public name="sharedUserMaxSdkVersion" />
- <public name="requiredSplitTypes" />
- <public name="splitTypes" />
- <public name="canDisplayOnRemoteDevices" />
- <public name="supportedTypes" />
- <public name="resetEnabledSettingsOnAppDataCleared" />
- <public name="supportsStylusHandwriting" />
- <public name="showClockAndComplications" />
- <!-- @hide @SystemApi -->
- <public name="gameSessionService" />
- <public name="supportsBatteryGameMode" />
- <public name="supportsPerformanceGameMode" />
- <public name="allowGameAngleDriver" />
- <public name="allowGameDownscaling" />
- <public name="allowGameFpsOverride" />
- <public name="localeConfig" />
- <public name="showBackdrop" />
- <public name="removed_useTargetActivityForQuickAccess"/>
- <public name="removed_inheritKeyStoreKeys" />
- <public name="preferKeepClear" />
- <public name="autoHandwritingEnabled" />
- <public name="fromExtendLeft" />
- <public name="fromExtendTop" />
- <public name="fromExtendRight" />
- <public name="fromExtendBottom" />
- <public name="toExtendLeft" />
- <public name="toExtendTop" />
- <public name="toExtendRight" />
- <public name="toExtendBottom" />
- <public name="tileService" />
- <public name="windowSplashScreenBehavior" />
- <public name="allowUntrustedActivityEmbedding" />
- <public name="knownActivityEmbeddingCerts" />
- <public name="intro" />
- <public name="enableOnBackInvokedCallback" />
- <public name="supportsInlineSuggestionsWithTouchExploration" />
- <public name="lineBreakStyle" />
- <public name="lineBreakWordStyle" />
- <!-- @hide -->
- <public name="maxDrawableWidth" />
- <!-- @hide -->
- <public name="maxDrawableHeight" />
- <public name="backdropColor" />
+ <staging-public-group type="attr" first-id="0x01ce0000">
</staging-public-group>
- <staging-public-group type="id" first-id="0x01de0000">
- <public name="removed_accessibilityActionSwipeLeft" />
- <public name="removed_accessibilityActionSwipeRight" />
- <public name="removed_accessibilityActionSwipeUp" />
- <public name="removed_accessibilityActionSwipeDown" />
- <public name="accessibilityActionShowTextSuggestions" />
- <public name="inputExtractAction" />
- <public name="inputExtractAccessories" />
+ <staging-public-group type="id" first-id="0x01cd0000">
</staging-public-group>
- <staging-public-group type="style" first-id="0x01dd0000">
- <public name="TextAppearance.DeviceDefault.Headline" />
+ <staging-public-group type="style" first-id="0x01cc0000">
</staging-public-group>
- <staging-public-group type="string" first-id="0x01dc0000">
- <!-- @hide @SystemApi -->
- <public name="config_systemSupervision" />
- <!-- @hide @SystemApi -->
- <public name="config_devicePolicyManagement" />
- <!-- @hide @SystemApi -->
- <public name="config_systemAppProtectionService" />
- <!-- @hide @SystemApi @TestApi -->
- <public name="config_systemAutomotiveCalendarSyncManager" />
- <!-- @hide @SystemApi -->
- <public name="config_defaultAutomotiveNavigation" />
- <!-- @hide @SystemApi -->
- <public name="safety_protection_display_text" />
- <!-- @hide @SystemApi -->
- <public name="config_systemSettingsIntelligence" />
- <!-- @hide -->
- <public name="config_systemBluetoothStack" />
+ <staging-public-group type="string" first-id="0x01cb0000">
</staging-public-group>
- <staging-public-group type="dimen" first-id="0x01db0000">
+ <staging-public-group type="dimen" first-id="0x01ca0000">
</staging-public-group>
- <staging-public-group type="color" first-id="0x01da0000">
+ <staging-public-group type="color" first-id="0x01c90000">
</staging-public-group>
- <staging-public-group type="array" first-id="0x01d90000">
- <!-- @hide @SystemApi -->
- <public name="config_optionalIpSecAlgorithms" />
+ <staging-public-group type="array" first-id="0x01c80000">
</staging-public-group>
- <staging-public-group type="drawable" first-id="0x01d80000">
- <!-- @hide @SystemApi -->
- <public name="ic_safety_protection" />
+ <staging-public-group type="drawable" first-id="0x01c70000">
</staging-public-group>
- <staging-public-group type="layout" first-id="0x01d70000">
+ <staging-public-group type="layout" first-id="0x01c60000">
</staging-public-group>
- <staging-public-group type="anim" first-id="0x01d60000">
+ <staging-public-group type="anim" first-id="0x01c50000">
</staging-public-group>
- <staging-public-group type="animator" first-id="0x01d50000">
+ <staging-public-group type="animator" first-id="0x01c40000">
</staging-public-group>
- <staging-public-group type="interpolator" first-id="0x01d40000">
+ <staging-public-group type="interpolator" first-id="0x01c30000">
</staging-public-group>
- <staging-public-group type="mipmap" first-id="0x01d30000">
+ <staging-public-group type="mipmap" first-id="0x01c20000">
</staging-public-group>
- <staging-public-group type="integer" first-id="0x01d20000">
+ <staging-public-group type="integer" first-id="0x01c10000">
</staging-public-group>
- <staging-public-group type="transition" first-id="0x01d10000">
+ <staging-public-group type="transition" first-id="0x01c00000">
</staging-public-group>
- <staging-public-group type="raw" first-id="0x01d00000">
+ <staging-public-group type="raw" first-id="0x01bf0000">
</staging-public-group>
- <staging-public-group type="bool" first-id="0x01cf0000">
- <!-- @hide @TestApi -->
- <public name="config_preventImeStartupUnlessTextEditor" />
- <!-- @hide @SystemApi -->
- <public name="config_enableQrCodeScannerOnLockScreen" />
+ <staging-public-group type="bool" first-id="0x01be0000">
</staging-public-group>
- <staging-public-group type="fraction" first-id="0x01ce0000">
+ <staging-public-group type="fraction" first-id="0x01bd0000">
</staging-public-group>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a9b95da..3334822 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3957,6 +3957,7 @@
<java-symbol type="bool" name="config_supportsConcurrentInternalDisplays" />
<java-symbol type="bool" name="config_unfoldTransitionEnabled" />
<java-symbol type="bool" name="config_unfoldTransitionHingeAngle" />
+ <java-symbol type="integer" name="config_unfoldTransitionHalfFoldedTimeout" />
<java-symbol type="array" name="config_perDeviceStateRotationLockDefaults" />
@@ -4764,6 +4765,7 @@
<java-symbol type="integer" name="config_bg_current_drain_media_playback_min_duration" />
<java-symbol type="integer" name="config_bg_current_drain_location_min_duration" />
<java-symbol type="bool" name="config_bg_prompt_fgs_with_noti_to_bg_restricted" />
+ <java-symbol type="bool" name="config_bg_prompt_abusive_apps_to_bg_restricted" />
<java-symbol type="integer" name="config_bg_current_drain_exempted_types" />
<java-symbol type="bool" name="config_bg_current_drain_high_threshold_by_bg_location" />
<java-symbol type="drawable" name="ic_swap_horiz" />
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index a5da442..f9f3b4c 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -17,6 +17,30 @@
package android.app;
import static android.app.Notification.Builder.ensureColorSpanContrast;
+import static android.app.Notification.CarExtender.UnreadConversation.KEY_ON_READ;
+import static android.app.Notification.CarExtender.UnreadConversation.KEY_ON_REPLY;
+import static android.app.Notification.CarExtender.UnreadConversation.KEY_REMOTE_INPUT;
+import static android.app.Notification.EXTRA_ANSWER_INTENT;
+import static android.app.Notification.EXTRA_BUILDER_APPLICATION_INFO;
+import static android.app.Notification.EXTRA_CALL_PERSON;
+import static android.app.Notification.EXTRA_CONVERSATION_ICON;
+import static android.app.Notification.EXTRA_DECLINE_INTENT;
+import static android.app.Notification.EXTRA_HANG_UP_INTENT;
+import static android.app.Notification.EXTRA_LARGE_ICON;
+import static android.app.Notification.EXTRA_LARGE_ICON_BIG;
+import static android.app.Notification.EXTRA_MEDIA_REMOTE_INTENT;
+import static android.app.Notification.EXTRA_MEDIA_SESSION;
+import static android.app.Notification.EXTRA_MESSAGING_PERSON;
+import static android.app.Notification.EXTRA_PICTURE;
+import static android.app.Notification.EXTRA_PICTURE_ICON;
+import static android.app.Notification.MessagingStyle.Message.KEY_DATA_URI;
+import static android.app.Notification.MessagingStyle.Message.KEY_SENDER_PERSON;
+import static android.app.Notification.MessagingStyle.Message.KEY_TEXT;
+import static android.app.Notification.MessagingStyle.Message.KEY_TIMESTAMP;
+import static android.app.Notification.TvExtender.EXTRA_CONTENT_INTENT;
+import static android.app.Notification.TvExtender.EXTRA_DELETE_INTENT;
+import static android.app.Notification.WearableExtender.KEY_BACKGROUND;
+import static android.app.Notification.WearableExtender.KEY_DISPLAY_INTENT;
import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
import static com.android.internal.util.ContrastColorUtilTest.assertContrastIsAtLeast;
@@ -32,6 +56,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.spy;
import android.annotation.Nullable;
import android.content.Context;
@@ -43,6 +68,7 @@
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.Icon;
+import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
@@ -170,7 +196,7 @@
assertNotSame(q.getLargeIcon(), n.getLargeIcon());
assertTrue(q.getLargeIcon().getBitmap().sameAs(n.getLargeIcon().getBitmap()));
- assertSame(q.getLargeIcon(), q.extras.getParcelable(Notification.EXTRA_LARGE_ICON));
+ assertSame(q.getLargeIcon(), q.extras.getParcelable(EXTRA_LARGE_ICON));
}
@Test
@@ -179,12 +205,12 @@
mContext.getResources(), com.android.frameworks.coretests.R.drawable.test128x96));
Notification n = new Notification.Builder(mContext).build();
- n.extras.putParcelable(Notification.EXTRA_LARGE_ICON, originalIcon);
+ n.extras.putParcelable(EXTRA_LARGE_ICON, originalIcon);
assertSame(n.getLargeIcon(), null);
Notification q = writeAndReadParcelable(n);
assertSame(q.getLargeIcon(), null);
- assertTrue(((Icon) q.extras.getParcelable(Notification.EXTRA_LARGE_ICON)).getBitmap()
+ assertTrue(((Icon) q.extras.getParcelable(EXTRA_LARGE_ICON)).getBitmap()
.sameAs(originalIcon.getBitmap()));
}
@@ -641,7 +667,7 @@
public void testIsMediaNotification_invalidSession_returnsFalse() {
// Extra was set manually to an invalid type
Bundle extras = new Bundle();
- extras.putParcelable(Notification.EXTRA_MEDIA_SESSION, new Intent());
+ extras.putParcelable(EXTRA_MEDIA_SESSION, new Intent());
Notification.MediaStyle mediaStyle = new Notification.MediaStyle();
Notification notification = new Notification.Builder(mContext, "test id")
.setStyle(mediaStyle)
@@ -650,6 +676,7 @@
assertFalse(notification.isMediaNotification());
}
+ @Test
public void validateColorizedPaletteForColor(int rawColor) {
Notification.Colors cDay = new Notification.Colors();
Notification.Colors cNight = new Notification.Colors();
@@ -681,6 +708,174 @@
}
}
+ @Test
+ public void testVisitUris_invalidExtra_noCrash() {
+ Notification n = new Notification.Builder(mContext, "test")
+ .setSmallIcon(0)
+ .build();
+ Bundle fakeTypes = new Bundle();
+ fakeTypes.putParcelable(EXTRA_LARGE_ICON_BIG, new Bundle());
+ fakeTypes.putParcelable(EXTRA_PICTURE_ICON, new Bundle());
+ fakeTypes.putParcelable(EXTRA_MESSAGING_PERSON, new Bundle());
+
+ Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
+ n.visitUris(visitor);
+
+ // no crash, good
+ }
+
+ @Test
+ public void testRecoverBuilder_invalidExtra_noCrash() {
+ Notification n = new Notification.Builder(mContext, "test")
+ .setSmallIcon(0)
+ .build();
+ Bundle fakeTypes = new Bundle();
+ fakeTypes.putParcelable(EXTRA_BUILDER_APPLICATION_INFO, new Bundle());
+
+ Notification.Builder.recoverBuilder(mContext, n);
+
+ // no crash, good
+ }
+
+ @Test
+ public void testIsMediaNotification_invalidExtra_noCrash() {
+ Notification n = new Notification.Builder(mContext, "test")
+ .setSmallIcon(0)
+ .setStyle(new Notification.MediaStyle())
+ .build();
+ Bundle fakeTypes = new Bundle();
+ fakeTypes.putParcelable(EXTRA_MEDIA_SESSION, new Bundle());
+
+ n.isMediaNotification();
+
+ // no crash, good
+ }
+
+ @Test
+ public void testRestoreFromExtras_BigText_invalidExtra_noCrash() {
+ Notification.Style style = new Notification.BigTextStyle();
+ Bundle fakeTypes = new Bundle();
+ fakeTypes.putParcelable(EXTRA_LARGE_ICON_BIG, new Bundle());
+
+ style.restoreFromExtras(fakeTypes);
+
+ // no crash, good
+ }
+
+ @Test
+ public void testRestoreFromExtras_Messaging_invalidExtra_noCrash() {
+ Notification.Style style = new Notification.MessagingStyle();
+ Bundle fakeTypes = new Bundle();
+ fakeTypes.putParcelable(EXTRA_MESSAGING_PERSON, new Bundle());
+ fakeTypes.putParcelable(EXTRA_CONVERSATION_ICON, new Bundle());
+
+ style.restoreFromExtras(fakeTypes);
+
+ // no crash, good
+ }
+
+ @Test
+ public void testRestoreFromExtras_Media_invalidExtra_noCrash() {
+ Notification.Style style = new Notification.MediaStyle();
+ Bundle fakeTypes = new Bundle();
+ fakeTypes.putParcelable(EXTRA_MEDIA_SESSION, new Bundle());
+ fakeTypes.putParcelable(EXTRA_MEDIA_REMOTE_INTENT, new Bundle());
+
+ style.restoreFromExtras(fakeTypes);
+
+ // no crash, good
+ }
+
+ @Test
+ public void testRestoreFromExtras_Call_invalidExtra_noCrash() {
+ Notification.Style style = new Notification.CallStyle();
+ Bundle fakeTypes = new Bundle();
+ fakeTypes.putParcelable(EXTRA_CALL_PERSON, new Bundle());
+ fakeTypes.putParcelable(EXTRA_ANSWER_INTENT, new Bundle());
+ fakeTypes.putParcelable(EXTRA_DECLINE_INTENT, new Bundle());
+ fakeTypes.putParcelable(EXTRA_HANG_UP_INTENT, new Bundle());
+
+ style.restoreFromExtras(fakeTypes);
+
+ // no crash, good
+ }
+
+ @Test
+ public void testGetPictureIcon_invalidExtra_noCrash() {
+ Bundle fakeTypes = new Bundle();
+ fakeTypes.putParcelable(EXTRA_PICTURE, new Bundle());
+ fakeTypes.putParcelable(EXTRA_PICTURE_ICON, new Bundle());
+
+ Notification.BigPictureStyle.getPictureIcon(fakeTypes);
+
+ // no crash, good
+ }
+
+ @Test
+ public void testWearableExtender_invalidExtra_noCrash() {
+ Notification n = new Notification.Builder(mContext, "test")
+ .setSmallIcon(0)
+ .setStyle(new Notification.MediaStyle())
+ .build();
+ Bundle fakeTypes = new Bundle();
+ fakeTypes.putParcelable(KEY_DISPLAY_INTENT, new Bundle());
+ fakeTypes.putParcelable(KEY_BACKGROUND, new Bundle());
+ Notification.WearableExtender extender = new Notification.WearableExtender(n);
+
+ // no crash, good
+ }
+
+ @Test
+ public void testCarExtender_invalidExtra_noCrash() {
+ Notification n = new Notification.Builder(mContext, "test")
+ .setSmallIcon(0)
+ .setStyle(new Notification.MediaStyle())
+ .build();
+ Bundle fakeTypes = new Bundle();
+ fakeTypes.putParcelable(EXTRA_LARGE_ICON, new Bundle());
+ Notification.CarExtender extender = new Notification.CarExtender(n);
+
+ // no crash, good
+ }
+
+ @Test
+ public void testTvExtender_invalidExtra_noCrash() {
+ Notification n = new Notification.Builder(mContext, "test")
+ .setSmallIcon(0)
+ .setStyle(new Notification.MediaStyle())
+ .build();
+ Bundle fakeTypes = new Bundle();
+ fakeTypes.putParcelable(EXTRA_CONTENT_INTENT, new Bundle());
+ fakeTypes.putParcelable(EXTRA_DELETE_INTENT, new Bundle());
+ Notification.TvExtender extender = new Notification.TvExtender(n);
+
+ // no crash, good
+ }
+
+ @Test
+ public void testGetUnreadConversationFromBundle_invalidExtra_noCrash() {
+ Bundle fakeTypes = new Bundle();
+ fakeTypes.putParcelable(KEY_ON_READ, new Bundle());
+ fakeTypes.putParcelable(KEY_ON_REPLY, new Bundle());
+ fakeTypes.putParcelable(KEY_REMOTE_INPUT, new Bundle());
+ Notification.CarExtender.UnreadConversation.getUnreadConversationFromBundle(fakeTypes);
+
+ // no crash, good
+ }
+
+ @Test
+ public void testGetMessageFromBundle_invalidExtra_noCrash() {
+ Bundle fakeTypes = new Bundle();
+ fakeTypes.putParcelable(KEY_SENDER_PERSON, new Bundle());
+ fakeTypes.putString(KEY_TEXT, "text");
+ fakeTypes.putLong(KEY_TIMESTAMP, 0);
+ fakeTypes.putParcelable(KEY_REMOTE_INPUT, new Bundle());
+ fakeTypes.putParcelable(KEY_DATA_URI, new Bundle());
+ Notification.MessagingStyle.Message.getMessageFromBundle(fakeTypes);
+
+ // no crash, good
+ }
+
private void assertValid(Notification.Colors c) {
// Assert that all colors are populated
assertThat(c.getBackgroundColor()).isNotEqualTo(Notification.COLOR_INVALID);
diff --git a/core/tests/coretests/src/android/view/InsetsStateTest.java b/core/tests/coretests/src/android/view/InsetsStateTest.java
index bf8bb76..be9da11 100644
--- a/core/tests/coretests/src/android/view/InsetsStateTest.java
+++ b/core/tests/coretests/src/android/view/InsetsStateTest.java
@@ -217,7 +217,8 @@
mState.getSource(ITYPE_CAPTION_BAR).setVisible(true);
Insets visibleInsets = mState.calculateVisibleInsets(
- new Rect(0, 0, 100, 400), SOFT_INPUT_ADJUST_NOTHING);
+ new Rect(0, 0, 100, 400), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
+ SOFT_INPUT_ADJUST_NOTHING, 0 /* windowFlags */);
assertEquals(Insets.of(0, 300, 0, 0), visibleInsets);
}
@@ -227,7 +228,8 @@
mState.getSource(ITYPE_CAPTION_BAR).setVisible(true);
Insets visibleInsets = mState.calculateVisibleInsets(
- new Rect(0, 0, 150, 400), SOFT_INPUT_ADJUST_NOTHING);
+ new Rect(0, 0, 150, 400), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
+ SOFT_INPUT_ADJUST_NOTHING, 0 /* windowFlags */);
assertEquals(Insets.of(0, 300, 0, 0), visibleInsets);
}
@@ -414,7 +416,8 @@
mState.getSource(ITYPE_BOTTOM_GESTURES).setFrame(new Rect(0, 100, 100, 300));
mState.getSource(ITYPE_BOTTOM_GESTURES).setVisible(true);
Insets visibleInsets = mState.calculateVisibleInsets(
- new Rect(0, 0, 100, 300), SOFT_INPUT_ADJUST_PAN);
+ new Rect(0, 0, 100, 300), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
+ SOFT_INPUT_ADJUST_PAN, 0 /* windowFlags */);
assertEquals(Insets.of(0, 100, 0, 100), visibleInsets);
}
@@ -429,11 +432,28 @@
mState.getSource(ITYPE_BOTTOM_GESTURES).setFrame(new Rect(0, 100, 100, 300));
mState.getSource(ITYPE_BOTTOM_GESTURES).setVisible(true);
Insets visibleInsets = mState.calculateVisibleInsets(
- new Rect(0, 0, 100, 300), SOFT_INPUT_ADJUST_NOTHING);
+ new Rect(0, 0, 100, 300), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
+ SOFT_INPUT_ADJUST_NOTHING, 0 /* windowFlags */);
assertEquals(Insets.of(0, 100, 0, 0), visibleInsets);
}
@Test
+ public void testCalculateVisibleInsets_layoutNoLimits() {
+ mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
+ mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
+ mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
+ mState.getSource(ITYPE_IME).setVisible(true);
+
+ // Make sure bottom gestures are ignored
+ mState.getSource(ITYPE_BOTTOM_GESTURES).setFrame(new Rect(0, 100, 100, 300));
+ mState.getSource(ITYPE_BOTTOM_GESTURES).setVisible(true);
+ Insets visibleInsets = mState.calculateVisibleInsets(
+ new Rect(0, 0, 100, 300), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
+ SOFT_INPUT_ADJUST_PAN, FLAG_LAYOUT_NO_LIMITS);
+ assertEquals(Insets.NONE, visibleInsets);
+ }
+
+ @Test
public void testCalculateUncontrollableInsets() {
mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 200, 100));
mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
diff --git a/core/tests/coretests/src/android/view/WindowInfoTest.java b/core/tests/coretests/src/android/view/WindowInfoTest.java
index 0a99b08..afc2c00 100644
--- a/core/tests/coretests/src/android/view/WindowInfoTest.java
+++ b/core/tests/coretests/src/android/view/WindowInfoTest.java
@@ -26,6 +26,7 @@
import static org.mockito.Mockito.mock;
import android.app.ActivityTaskManager;
+import android.graphics.Matrix;
import android.os.IBinder;
import android.os.Parcel;
import android.platform.test.annotations.Presubmit;
@@ -38,6 +39,7 @@
import org.junit.runner.RunWith;
import java.util.ArrayList;
+import java.util.Arrays;
/**
* Class for testing {@link WindowInfo}.
@@ -94,6 +96,8 @@
assertFalse(w.inPictureInPicture);
assertFalse(w.hasFlagWatchOutsideTouch);
assertTrue(w.regionInScreen.isEmpty());
+ assertEquals(w.mTransformMatrix.length, 9);
+ assertTrue(w.mMagnificationSpec.isNop());
}
@SmallTest
@@ -117,6 +121,8 @@
equality &= w1.parentToken == w2.parentToken;
equality &= w1.activityToken == w2.activityToken;
equality &= w1.regionInScreen.equals(w2.regionInScreen);
+ equality &= w1.mMagnificationSpec.equals(w2.mMagnificationSpec);
+ equality &= Arrays.equals(w1.mTransformMatrix, w2.mTransformMatrix);
return equality;
}
@@ -136,5 +142,9 @@
windowInfo.inPictureInPicture = true;
windowInfo.hasFlagWatchOutsideTouch = true;
windowInfo.regionInScreen.set(0, 0, 1080, 1080);
+ windowInfo.mMagnificationSpec.scale = 2.0f;
+ windowInfo.mMagnificationSpec.offsetX = 100f;
+ windowInfo.mMagnificationSpec.offsetY = 200f;
+ Matrix.IDENTITY_MATRIX.getValues(windowInfo.mTransformMatrix);
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 3ec8843..33a41ec 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -155,13 +155,18 @@
// Check if there are no running activities - consider the container empty if there are no
// non-finishing activities left.
if (!taskFragmentInfo.hasRunningActivity()) {
- // TODO(b/225371112): Don't finish dependent if the last activity is moved to the PIP
- // Task.
- // Do not finish the dependents if this TaskFragment was cleared due to launching
- // activity in the Task.
- final boolean shouldFinishDependent =
- !taskFragmentInfo.isTaskClearedForReuse();
- mPresenter.cleanupContainer(container, shouldFinishDependent);
+ if (taskFragmentInfo.isTaskFragmentClearedForPip()) {
+ // Do not finish the dependents if the last activity is reparented to PiP.
+ // Instead, the original split should be cleanup, and the dependent may be expanded
+ // to fullscreen.
+ cleanupForEnterPip(container);
+ mPresenter.cleanupContainer(container, false /* shouldFinishDependent */);
+ } else {
+ // Do not finish the dependents if this TaskFragment was cleared due to launching
+ // activity in the Task.
+ final boolean shouldFinishDependent = !taskFragmentInfo.isTaskClearedForReuse();
+ mPresenter.cleanupContainer(container, shouldFinishDependent);
+ }
} else if (wasInPip && isInPip) {
// No update until exit PIP.
return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index b6fb828..5ef2413 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -385,7 +385,9 @@
mMainExecutor.execute(() -> {
int expandedId = INVALID_TASK_ID;
if (mStackView != null && mStackView.getExpandedBubble() != null
- && isStackExpanded() && !mStackView.isExpansionAnimating()) {
+ && isStackExpanded()
+ && !mStackView.isExpansionAnimating()
+ && !mStackView.isSwitchAnimating()) {
expandedId = mStackView.getExpandedBubble().getTaskId();
}
if (expandedId != INVALID_TASK_ID && expandedId != taskId) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 6eb8d8a..7cfacbc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -329,6 +329,11 @@
: mBubbleSize;
}
+ /** Size of the visible (non-overlapping) part of the pointer. */
+ public int getPointerSize() {
+ return mPointerHeight - mPointerOverlap;
+ }
+
/** The maximum number of bubbles that can be displayed comfortably on screen. */
public int getMaxBubbles() {
return mMaxBubbles;
@@ -367,7 +372,7 @@
* padding is added.
*/
public int[] getExpandedViewContainerPadding(boolean onLeft, boolean isOverflow) {
- final int pointerTotalHeight = mPointerHeight - mPointerOverlap;
+ final int pointerTotalHeight = getPointerSize();
final int expandedViewLargeScreenInsetFurthestEdge =
getExpandedViewLargeScreenInsetFurthestEdge(isOverflow);
if (mIsLargeScreen) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index f60b659..b7c5eb0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -913,8 +913,10 @@
afterExpandedViewAnimation();
showManageMenu(mShowingManage);
} /* after */);
+ PointF p = mPositioner.getExpandedBubbleXY(getBubbleIndex(mExpandedBubble),
+ getState());
final float translationY = mPositioner.getExpandedViewY(mExpandedBubble,
- getBubbleIndex(mExpandedBubble));
+ mPositioner.showBubblesVertically() ? p.y : p.x);
mExpandedViewContainer.setTranslationX(0f);
mExpandedViewContainer.setTranslationY(translationY);
mExpandedViewContainer.setAlpha(1f);
@@ -1606,6 +1608,13 @@
}
/**
+ * Whether the stack of bubbles is animating a switch between bubbles.
+ */
+ public boolean isSwitchAnimating() {
+ return mIsBubbleSwitchAnimating;
+ }
+
+ /**
* The {@link Bubble} that is expanded, null if one does not exist.
*/
@VisibleForTesting
@@ -2465,6 +2474,10 @@
private void dismissBubbleIfExists(@Nullable BubbleViewProvider bubble) {
if (bubble != null && mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
+ if (mIsExpanded && mBubbleData.getBubbles().size() > 1) {
+ // If we have more than 1 bubble we will perform the switch animation
+ mIsBubbleSwitchAnimating = true;
+ }
mBubbleData.dismissBubbleWithKey(bubble.getKey(), Bubbles.DISMISS_USER_GESTURE);
}
}
@@ -2885,7 +2898,10 @@
PhysicsAnimator.getInstance(mAnimatingOutSurfaceContainer).cancel();
mAnimatingOutSurfaceContainer.setScaleX(1f);
mAnimatingOutSurfaceContainer.setScaleY(1f);
- mAnimatingOutSurfaceContainer.setTranslationX(mExpandedViewContainer.getPaddingLeft());
+ final float translationX = mPositioner.showBubblesVertically() && mStackOnLeftOrWillBe
+ ? mExpandedViewContainer.getPaddingLeft() + mPositioner.getPointerSize()
+ : mExpandedViewContainer.getPaddingLeft();
+ mAnimatingOutSurfaceContainer.setTranslationX(translationX);
mAnimatingOutSurfaceContainer.setTranslationY(0);
final int[] taskViewLocation =
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
index 6f4e22f..79d795e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
@@ -32,6 +32,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
@@ -336,6 +337,12 @@
return navigationBarPosition(res, mWidth, mHeight, mRotation);
}
+ /** @return {@link DisplayCutout} instance. */
+ @Nullable
+ public DisplayCutout getDisplayCutout() {
+ return mCutout;
+ }
+
/**
* Calculates the stable insets if we already have the non-decor insets.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java
index e28c58c..9754a03 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java
@@ -37,7 +37,6 @@
import android.graphics.Region.Op;
import android.hardware.display.DisplayManager;
import android.os.Bundle;
-import android.os.RemoteException;
import android.util.AttributeSet;
import android.util.Slog;
import android.view.Choreographer;
@@ -241,22 +240,6 @@
}
};
- private Runnable mUpdateEmbeddedMatrix = () -> {
- if (getViewRootImpl() == null) {
- return;
- }
- if (isHorizontalDivision()) {
- mTmpMatrix.setTranslate(0, mDividerPositionY - mDividerInsets);
- } else {
- mTmpMatrix.setTranslate(mDividerPositionX - mDividerInsets, 0);
- }
- mTmpMatrix.getValues(mTmpValues);
- try {
- getViewRootImpl().getAccessibilityEmbeddedConnection().setScreenMatrix(mTmpValues);
- } catch (RemoteException e) {
- }
- };
-
public DividerView(Context context) {
this(context, null);
}
@@ -1045,10 +1028,6 @@
t.setPosition(dividerCtrl, mDividerPositionX - mDividerInsets, 0);
}
}
- if (getViewRootImpl() != null) {
- getHandler().removeCallbacks(mUpdateEmbeddedMatrix);
- getHandler().post(mUpdateEmbeddedMatrix);
- }
}
void setResizeDimLayer(Transaction t, boolean primary, float alpha) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index 3379000..95bb65c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -250,7 +250,6 @@
protected T mCurrentValue;
protected T mStartValue;
private T mEndValue;
- private float mStartingAngle;
private PipAnimationCallback mPipAnimationCallback;
private PipTransactionHandler mPipTransactionHandler;
private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
@@ -260,8 +259,8 @@
protected SurfaceControl mContentOverlay;
private PipTransitionAnimator(TaskInfo taskInfo, SurfaceControl leash,
- @AnimationType int animationType, Rect destinationBounds, T baseValue, T startValue,
- T endValue, float startingAngle) {
+ @AnimationType int animationType,
+ Rect destinationBounds, T baseValue, T startValue, T endValue) {
mTaskInfo = taskInfo;
mLeash = leash;
mAnimationType = animationType;
@@ -269,7 +268,6 @@
mBaseValue = baseValue;
mStartValue = startValue;
mEndValue = endValue;
- mStartingAngle = startingAngle;
addListener(this);
addUpdateListener(this);
mSurfaceControlTransactionFactory =
@@ -480,7 +478,7 @@
static PipTransitionAnimator<Float> ofAlpha(TaskInfo taskInfo, SurfaceControl leash,
Rect destinationBounds, float startValue, float endValue) {
return new PipTransitionAnimator<Float>(taskInfo, leash, ANIM_TYPE_ALPHA,
- destinationBounds, startValue, startValue, endValue, 0) {
+ destinationBounds, startValue, startValue, endValue) {
@Override
void applySurfaceControlTransaction(SurfaceControl leash,
SurfaceControl.Transaction tx, float fraction) {
@@ -520,7 +518,7 @@
@PipAnimationController.TransitionDirection int direction, float startingAngle,
@Surface.Rotation int rotationDelta) {
final boolean isOutPipDirection = isOutPipDirection(direction);
-
+ final boolean isInPipDirection = isInPipDirection(direction);
// Just for simplicity we'll interpolate between the source rect hint insets and empty
// insets to calculate the window crop
final Rect initialSourceValue;
@@ -559,8 +557,7 @@
// construct new Rect instances in case they are recycled
return new PipTransitionAnimator<Rect>(taskInfo, leash, ANIM_TYPE_BOUNDS,
- endValue, new Rect(baseValue), new Rect(startValue), new Rect(endValue),
- startingAngle) {
+ endValue, new Rect(baseValue), new Rect(startValue), new Rect(endValue)) {
private final RectEvaluator mRectEvaluator = new RectEvaluator(new Rect());
private final RectEvaluator mInsetsEvaluator = new RectEvaluator(new Rect());
@@ -595,7 +592,8 @@
} else {
final Rect insets = computeInsets(fraction);
getSurfaceTransactionHelper().scaleAndCrop(tx, leash,
- initialSourceValue, bounds, insets);
+ sourceHintRect, initialSourceValue, bounds, insets,
+ isInPipDirection);
if (shouldApplyCornerRadius()) {
final Rect sourceBounds = new Rect(initialContainerRect);
sourceBounds.inset(insets);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
index 00f62d4..b349010 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
@@ -103,21 +103,31 @@
* @return same {@link PipSurfaceTransactionHelper} instance for method chaining
*/
public PipSurfaceTransactionHelper scaleAndCrop(SurfaceControl.Transaction tx,
- SurfaceControl leash,
- Rect sourceBounds, Rect destinationBounds, Rect insets) {
+ SurfaceControl leash, Rect sourceRectHint,
+ Rect sourceBounds, Rect destinationBounds, Rect insets,
+ boolean isInPipDirection) {
mTmpSourceRectF.set(sourceBounds);
mTmpDestinationRect.set(sourceBounds);
mTmpDestinationRect.inset(insets);
// Scale by the shortest edge and offset such that the top/left of the scaled inset source
// rect aligns with the top/left of the destination bounds
- final float scale = sourceBounds.width() <= sourceBounds.height()
- ? (float) destinationBounds.width() / sourceBounds.width()
- : (float) destinationBounds.height() / sourceBounds.height();
+ final float scale;
+ if (isInPipDirection
+ && sourceRectHint != null && sourceRectHint.width() < sourceBounds.width()) {
+ // scale by sourceRectHint if it's not edge-to-edge, for entering PiP transition only.
+ scale = sourceBounds.width() <= sourceBounds.height()
+ ? (float) destinationBounds.width() / sourceRectHint.width()
+ : (float) destinationBounds.height() / sourceRectHint.height();
+ } else {
+ scale = sourceBounds.width() <= sourceBounds.height()
+ ? (float) destinationBounds.width() / sourceBounds.width()
+ : (float) destinationBounds.height() / sourceBounds.height();
+ }
final float left = destinationBounds.left - insets.left * scale;
final float top = destinationBounds.top - insets.top * scale;
mTmpTransform.setScale(scale, scale);
tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
- .setWindowCrop(leash, mTmpDestinationRect)
+ .setCrop(leash, mTmpDestinationRect)
.setPosition(leash, left, top);
return this;
}
@@ -163,7 +173,7 @@
mTmpTransform.setScale(scale, scale);
mTmpTransform.postRotate(degrees);
mTmpTransform.postTranslate(positionX, positionY);
- tx.setMatrix(leash, mTmpTransform, mTmpFloat9).setWindowCrop(leash, crop);
+ tx.setMatrix(leash, mTmpTransform, mTmpFloat9).setCrop(leash, crop);
return this;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index 5e4c12e..f73b81e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -135,19 +135,6 @@
}
};
- private final float[] mTmpValues = new float[9];
- private final Runnable mUpdateEmbeddedMatrix = () -> {
- if (mPipMenuView == null || mPipMenuView.getViewRootImpl() == null) {
- return;
- }
- mMoveTransform.getValues(mTmpValues);
- try {
- mPipMenuView.getViewRootImpl().getAccessibilityEmbeddedConnection()
- .setScreenMatrix(mTmpValues);
- } catch (RemoteException e) {
- }
- };
-
public PhonePipMenuController(Context context, PipBoundsState pipBoundsState,
PipMediaController mediaController, SystemWindows systemWindows,
Optional<SplitScreenController> splitScreenOptional,
@@ -348,11 +335,6 @@
} else {
mApplier.scheduleApply(params);
}
-
- if (mPipMenuView.getViewRootImpl() != null) {
- mPipMenuView.getHandler().removeCallbacks(mUpdateEmbeddedMatrix);
- mPipMenuView.getHandler().post(mUpdateEmbeddedMatrix);
- }
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java
index 69ae45d..7365b95 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java
@@ -285,7 +285,7 @@
Region bounds, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags,
int interrogatingPid, long interrogatingTid, MagnificationSpec spec,
- Bundle arguments) throws RemoteException {
+ float[] matrixValues, Bundle arguments) throws RemoteException {
mMainExcutor.execute(() -> {
PipAccessibilityInteractionConnection.this
.findAccessibilityNodeInfoByAccessibilityId(accessibilityNodeId, bounds,
@@ -298,7 +298,8 @@
public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId, String viewId,
Region bounds, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags,
- int interrogatingPid, long interrogatingTid, MagnificationSpec spec)
+ int interrogatingPid, long interrogatingTid, MagnificationSpec spec,
+ float[] matrixValues)
throws RemoteException {
mMainExcutor.execute(() -> {
PipAccessibilityInteractionConnection.this.findAccessibilityNodeInfosByViewId(
@@ -311,7 +312,8 @@
public void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text,
Region bounds, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags,
- int interrogatingPid, long interrogatingTid, MagnificationSpec spec)
+ int interrogatingPid, long interrogatingTid, MagnificationSpec spec,
+ float[] matrixValues)
throws RemoteException {
mMainExcutor.execute(() -> {
PipAccessibilityInteractionConnection.this.findAccessibilityNodeInfosByText(
@@ -323,7 +325,8 @@
@Override
public void findFocus(long accessibilityNodeId, int focusType, Region bounds,
int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
- int interrogatingPid, long interrogatingTid, MagnificationSpec spec)
+ int interrogatingPid, long interrogatingTid, MagnificationSpec spec,
+ float[] matrixValues)
throws RemoteException {
mMainExcutor.execute(() -> {
PipAccessibilityInteractionConnection.this.findFocus(accessibilityNodeId, focusType,
@@ -335,7 +338,8 @@
@Override
public void focusSearch(long accessibilityNodeId, int direction, Region bounds,
int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
- int interrogatingPid, long interrogatingTid, MagnificationSpec spec)
+ int interrogatingPid, long interrogatingTid, MagnificationSpec spec,
+ float[] matrixValues)
throws RemoteException {
mMainExcutor.execute(() -> {
PipAccessibilityInteractionConnection.this.focusSearch(accessibilityNodeId,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index 147a272..ac7b9033b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -36,6 +36,7 @@
import android.graphics.Rect;
import android.provider.DeviceConfig;
import android.util.Size;
+import android.view.DisplayCutout;
import android.view.InputEvent;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
@@ -959,21 +960,38 @@
}
private boolean shouldStash(PointF vel, Rect motionBounds) {
+ final boolean flingToLeft = vel.x < -mStashVelocityThreshold;
+ final boolean flingToRight = vel.x > mStashVelocityThreshold;
+ final int offset = motionBounds.width() / 2;
+ final boolean droppingOnLeft =
+ motionBounds.left < mPipBoundsState.getDisplayBounds().left - offset;
+ final boolean droppingOnRight =
+ motionBounds.right > mPipBoundsState.getDisplayBounds().right + offset;
+
+ // Do not allow stash if the destination edge contains display cutout. We only
+ // compare the left and right edges since we do not allow stash on top / bottom.
+ final DisplayCutout displayCutout =
+ mPipBoundsState.getDisplayLayout().getDisplayCutout();
+ if (displayCutout != null) {
+ if ((flingToLeft || droppingOnLeft)
+ && !displayCutout.getBoundingRectLeft().isEmpty()) {
+ return false;
+ } else if ((flingToRight || droppingOnRight)
+ && !displayCutout.getBoundingRectRight().isEmpty()) {
+ return false;
+ }
+ }
+
// If user flings the PIP window above the minimum velocity, stash PIP.
// Only allow stashing to the edge if PIP wasn't previously stashed on the opposite
// edge.
- final boolean stashFromFlingToEdge = ((vel.x < -mStashVelocityThreshold
- && mPipBoundsState.getStashedState() != STASH_TYPE_RIGHT)
- || (vel.x > mStashVelocityThreshold
- && mPipBoundsState.getStashedState() != STASH_TYPE_LEFT));
+ final boolean stashFromFlingToEdge =
+ (flingToLeft && mPipBoundsState.getStashedState() != STASH_TYPE_RIGHT)
+ || (flingToRight && mPipBoundsState.getStashedState() != STASH_TYPE_LEFT);
// If User releases the PIP window while it's out of the display bounds, put
// PIP into stashed mode.
- final int offset = motionBounds.width() / 2;
- final boolean stashFromDroppingOnEdge =
- (motionBounds.right > mPipBoundsState.getDisplayBounds().right + offset
- || motionBounds.left
- < mPipBoundsState.getDisplayBounds().left - offset);
+ final boolean stashFromDroppingOnEdge = droppingOnLeft || droppingOnRight;
return stashFromFlingToEdge || stashFromDroppingOnEdge;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
index 7b8dcf7..2d67254 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
@@ -30,7 +30,6 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
-import android.os.RemoteException;
import android.view.LayoutInflater;
import android.view.SurfaceControl;
import android.view.SyncRtSurfaceTransactionApplier;
@@ -88,19 +87,6 @@
RectF mTmpDestinationRectF = new RectF();
Matrix mMoveTransform = new Matrix();
- private final float[] mTmpValues = new float[9];
- private final Runnable mUpdateEmbeddedMatrix = () -> {
- if (mPipMenuView == null || mPipMenuView.getViewRootImpl() == null) {
- return;
- }
- mMoveTransform.getValues(mTmpValues);
- try {
- mPipMenuView.getViewRootImpl().getAccessibilityEmbeddedConnection()
- .setScreenMatrix(mTmpValues);
- } catch (RemoteException e) {
- if (DEBUG) e.printStackTrace();
- }
- };
private final Runnable mCloseEduTextRunnable = this::closeEduText;
public TvPipMenuController(Context context, TvPipBoundsState tvPipBoundsState,
@@ -525,11 +511,6 @@
mApplier.scheduleApply(frontParams);
}
- if (mPipMenuView.getViewRootImpl() != null) {
- mPipMenuView.getHandler().removeCallbacks(mUpdateEmbeddedMatrix);
- mPipMenuView.getHandler().post(mUpdateEmbeddedMatrix);
- }
-
updateMenuBounds(pipDestBounds);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index aec51ba..10dfdc3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -190,7 +190,7 @@
mStageCoordinator = new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
mTaskOrganizer, mDisplayController, mDisplayImeController,
mDisplayInsetsController, mTransitions, mTransactionPool, mLogger,
- mIconProvider, mRecentTasksOptional, mUnfoldControllerProvider);
+ mIconProvider, mMainExecutor, mRecentTasksOptional, mUnfoldControllerProvider);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 45931de..9d6e34d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -94,6 +94,7 @@
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.common.split.SplitLayout;
@@ -157,6 +158,7 @@
private final TransactionPool mTransactionPool;
private final SplitScreenTransitions mSplitTransitions;
private final SplitscreenEventLogger mLogger;
+ private final ShellExecutor mMainExecutor;
private final Optional<RecentTasksController> mRecentTasks;
/**
@@ -196,13 +198,15 @@
DisplayImeController displayImeController,
DisplayInsetsController displayInsetsController, Transitions transitions,
TransactionPool transactionPool, SplitscreenEventLogger logger,
- IconProvider iconProvider, Optional<RecentTasksController> recentTasks,
+ IconProvider iconProvider, ShellExecutor mainExecutor,
+ Optional<RecentTasksController> recentTasks,
Provider<Optional<StageTaskUnfoldController>> unfoldControllerProvider) {
mContext = context;
mDisplayId = displayId;
mSyncQueue = syncQueue;
mTaskOrganizer = taskOrganizer;
mLogger = logger;
+ mMainExecutor = mainExecutor;
mRecentTasks = recentTasks;
mMainUnfoldController = unfoldControllerProvider.get().orElse(null);
mSideUnfoldController = unfoldControllerProvider.get().orElse(null);
@@ -247,7 +251,7 @@
DisplayController displayController, DisplayImeController displayImeController,
DisplayInsetsController displayInsetsController, SplitLayout splitLayout,
Transitions transitions, TransactionPool transactionPool,
- SplitscreenEventLogger logger,
+ SplitscreenEventLogger logger, ShellExecutor mainExecutor,
Optional<RecentTasksController> recentTasks,
Provider<Optional<StageTaskUnfoldController>> unfoldControllerProvider) {
mContext = context;
@@ -266,6 +270,7 @@
mMainUnfoldController = unfoldControllerProvider.get().orElse(null);
mSideUnfoldController = unfoldControllerProvider.get().orElse(null);
mLogger = logger;
+ mMainExecutor = mainExecutor;
mRecentTasks = recentTasks;
mDisplayController.addDisplayWindowListener(this);
mDisplayLayout = new DisplayLayout();
@@ -394,6 +399,7 @@
@Nullable PendingIntent pendingIntent, @Nullable Intent fillInIntent,
@Nullable Bundle mainOptions, @Nullable Bundle sideOptions,
@SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter) {
+ final boolean withIntent = pendingIntent != null && fillInIntent != null;
// Init divider first to make divider leash for remote animation target.
mSplitLayout.init();
// Set false to avoid record new bounds with old task still on top;
@@ -423,10 +429,7 @@
new IRemoteAnimationFinishedCallback.Stub() {
@Override
public void onAnimationFinished() throws RemoteException {
- mIsDividerRemoteAnimating = false;
- mShouldUpdateRecents = true;
- mSyncQueue.queue(evictWct);
- mSyncQueue.runInSync(t -> setDividerVisibility(true, t));
+ onRemoteAnimationFinishedOrCancelled(evictWct);
finishedCallback.onAnimationFinished();
}
};
@@ -447,10 +450,7 @@
@Override
public void onAnimationCancelled() {
- mIsDividerRemoteAnimating = false;
- mShouldUpdateRecents = true;
- mSyncQueue.queue(evictWct);
- mSyncQueue.runInSync(t -> setDividerVisibility(true, t));
+ onRemoteAnimationFinishedOrCancelled(evictWct);
try {
adapter.getRunner().onAnimationCancelled();
} catch (RemoteException e) {
@@ -486,20 +486,37 @@
addActivityOptions(sideOptions, mSideStage);
// Add task launch requests
- if (pendingIntent != null && fillInIntent != null) {
- wct.startTask(mainTaskId, mainOptions);
+ wct.startTask(mainTaskId, mainOptions);
+ if (withIntent) {
wct.sendPendingIntent(pendingIntent, fillInIntent, sideOptions);
} else {
- wct.startTask(mainTaskId, mainOptions);
wct.startTask(sideTaskId, sideOptions);
}
-
// Using legacy transitions, so we can't use blast sync since it conflicts.
mTaskOrganizer.applyTransaction(wct);
mSyncQueue.runInSync(t ->
updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */));
}
+ private void onRemoteAnimationFinishedOrCancelled(WindowContainerTransaction evictWct) {
+ mIsDividerRemoteAnimating = false;
+ mShouldUpdateRecents = true;
+ // If any stage has no child after animation finished, it means that split will display
+ // nothing, such status will happen if task and intent is same app but not support
+ // multi-instagce, we should exit split and expand that app as full screen.
+ if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) {
+ mMainExecutor.execute(() ->
+ exitSplitScreen(mMainStage.getChildCount() == 0
+ ? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
+ } else {
+ mSyncQueue.queue(evictWct);
+ mSyncQueue.runInSync(t -> {
+ setDividerVisibility(true, t);
+ updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
+ });
+ }
+ }
+
/**
* Collects all the current child tasks of a specific split and prepares transaction to evict
* them to display.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index 75a999b..d89ddd2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -56,7 +56,6 @@
import android.util.Slog;
import android.view.ContextThemeWrapper;
import android.view.SurfaceControl;
-import android.view.View;
import android.window.SplashScreenView;
import android.window.StartingWindowInfo;
import android.window.StartingWindowInfo.StartingWindowType;
@@ -543,22 +542,6 @@
mBrandingImageHeight);
}
final SplashScreenView splashScreenView = builder.build();
- if (mSuggestType != STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
- splashScreenView.addOnAttachStateChangeListener(
- new View.OnAttachStateChangeListener() {
- @Override
- public void onViewAttachedToWindow(View v) {
- SplashScreenView.applySystemBarsContrastColor(
- v.getWindowInsetsController(),
- splashScreenView.getInitBackgroundColor());
- }
-
- @Override
- public void onViewDetachedFromWindow(View v) {
- }
- });
- }
-
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
return splashScreenView;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 11f23e3..464ab1a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -50,6 +50,7 @@
import android.view.Display;
import android.view.SurfaceControlViewHost;
import android.view.View;
+import android.view.WindowInsetsController;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.widget.FrameLayout;
@@ -63,6 +64,7 @@
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.util.ContrastColorUtil;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.TransactionPool;
@@ -121,6 +123,9 @@
private StartingSurface.SysuiProxy mSysuiProxy;
private final StartingWindowRemovalInfo mTmpRemovalInfo = new StartingWindowRemovalInfo();
+ private static final int LIGHT_BARS_MASK =
+ WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
+ | WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
/**
* The minimum duration during which the splash screen is shown when the splash screen icon is
* animated.
@@ -361,9 +366,27 @@
// the window before first round relayoutWindow, which will happen after insets
// animation.
mChoreographer.postCallback(CALLBACK_INSETS_ANIMATION, setViewSynchronized, null);
- // Block until we get the background color.
final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
+ record.parseAppSystemBarColor(context);
+ // Block until we get the background color.
final SplashScreenView contentView = viewSupplier.get();
+ if (suggestType != STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
+ contentView.addOnAttachStateChangeListener(
+ new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ final int lightBarAppearance = ContrastColorUtil.isColorLight(
+ contentView.getInitBackgroundColor())
+ ? LIGHT_BARS_MASK : 0;
+ contentView.getWindowInsetsController().setSystemBarsAppearance(
+ lightBarAppearance, LIGHT_BARS_MASK);
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ }
+ });
+ }
record.mBGColor = contentView.getInitBackgroundColor();
} else {
// release the icon view host
@@ -613,6 +636,7 @@
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW,
"Removing splash screen window for task: %d", taskId);
if (record.mContentView != null) {
+ record.clearSystemBarColor();
if (immediately
|| record.mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
removeWindowInner(record.mDecorView, false);
@@ -670,6 +694,8 @@
private @StartingWindowType int mSuggestType;
private int mBGColor;
private final long mCreateTime;
+ private int mSystemBarAppearance;
+ private boolean mDrawsSystemBarBackgrounds;
StartingWindowRecord(IBinder appToken, View decorView,
TaskSnapshotWindow taskSnapshotWindow, @StartingWindowType int suggestType) {
@@ -690,5 +716,37 @@
mContentView = splashScreenView;
mSetSplashScreen = true;
}
+
+ private void parseAppSystemBarColor(Context context) {
+ final TypedArray a = context.obtainStyledAttributes(R.styleable.Window);
+ mDrawsSystemBarBackgrounds = a.getBoolean(
+ R.styleable.Window_windowDrawsSystemBarBackgrounds, false);
+ if (a.getBoolean(R.styleable.Window_windowLightStatusBar, false)) {
+ mSystemBarAppearance |= WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
+ }
+ if (a.getBoolean(R.styleable.Window_windowLightNavigationBar, false)) {
+ mSystemBarAppearance |= WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
+ }
+ a.recycle();
+ }
+
+ // Reset the system bar color which set by splash screen, make it align to the app.
+ private void clearSystemBarColor() {
+ if (mDecorView == null) {
+ return;
+ }
+ if (mDecorView.getLayoutParams() instanceof WindowManager.LayoutParams) {
+ final WindowManager.LayoutParams lp =
+ (WindowManager.LayoutParams) mDecorView.getLayoutParams();
+ if (mDrawsSystemBarBackgrounds) {
+ lp.flags |= WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ } else {
+ lp.flags &= ~WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ }
+ mDecorView.setLayoutParams(lp);
+ }
+ mDecorView.getWindowInsetsController().setSystemBarsAppearance(
+ mSystemBarAppearance, LIGHT_BARS_MASK);
+ }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
index 274d34b..0640ac5 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -26,9 +26,7 @@
import com.android.server.wm.flicker.LAUNCHER_COMPONENT
import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.rules.WMFlickerServiceRuleForTestSpec
import org.junit.FixMethodOrder
-import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -57,8 +55,6 @@
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group3
class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) {
- @get:Rule
- val flickerRule = WMFlickerServiceRuleForTestSpec(testSpec)
/**
* Defines the transition used to run the test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
index 9a8c894..8da6224 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
@@ -25,9 +25,7 @@
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.rules.WMFlickerServiceRuleForTestSpec
import org.junit.FixMethodOrder
-import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -57,8 +55,6 @@
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group3
class ExitPipViaIntentTest(testSpec: FlickerTestParameter) : ExitPipToAppTransition(testSpec) {
- @get:Rule
- val flickerRule = WMFlickerServiceRuleForTestSpec(testSpec)
/**
* Defines the transition used to run the test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt
index 9c095a2..437ad89 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt
@@ -25,9 +25,7 @@
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.rules.WMFlickerServiceRuleForTestSpec
import org.junit.FixMethodOrder
-import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -57,8 +55,6 @@
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group3
class ExitPipWithDismissButtonTest(testSpec: FlickerTestParameter) : ExitPipTransition(testSpec) {
- @get:Rule
- val flickerRule = WMFlickerServiceRuleForTestSpec(testSpec)
override val transition: FlickerBuilder.() -> Unit
get() = {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
index 49f36a4..eb9d3a1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
@@ -31,6 +31,7 @@
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController;
+import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.common.split.SplitLayout;
@@ -72,11 +73,13 @@
DisplayController displayController, DisplayImeController imeController,
DisplayInsetsController insetsController, SplitLayout splitLayout,
Transitions transitions, TransactionPool transactionPool,
- SplitscreenEventLogger logger, Optional<RecentTasksController> recentTasks,
+ SplitscreenEventLogger logger, ShellExecutor mainExecutor,
+ Optional<RecentTasksController> recentTasks,
Provider<Optional<StageTaskUnfoldController>> unfoldController) {
super(context, displayId, syncQueue, taskOrganizer, mainStage,
sideStage, displayController, imeController, insetsController, splitLayout,
- transitions, transactionPool, logger, recentTasks, unfoldController);
+ transitions, transactionPool, logger, mainExecutor, recentTasks,
+ unfoldController);
// Prepare root task for testing.
mRootTask = new TestRunningTaskInfoBuilder().build();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index f847e6e..a55f737 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -97,6 +97,7 @@
@Mock private SurfaceSession mSurfaceSession;
@Mock private SplitscreenEventLogger mLogger;
@Mock private IconProvider mIconProvider;
+ @Mock private ShellExecutor mMainExecutor;
private SplitLayout mSplitLayout;
private MainStage mMainStage;
private SideStage mSideStage;
@@ -126,7 +127,7 @@
mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
mSyncQueue, mTaskOrganizer, mMainStage, mSideStage, mDisplayController,
mDisplayImeController, mDisplayInsetsController, mSplitLayout, mTransitions,
- mTransactionPool, mLogger, Optional.empty(), Optional::empty);
+ mTransactionPool, mLogger, mMainExecutor, Optional.empty(), Optional::empty);
mSplitScreenTransitions = mStageCoordinator.getSplitTransitions();
doAnswer((Answer<IBinder>) invocation -> mock(IBinder.class))
.when(mTransitions).startTransition(anyInt(), any(), any());
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index c571d44..42d998f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -54,6 +54,7 @@
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController;
+import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.common.split.SplitLayout;
@@ -101,6 +102,8 @@
private TransactionPool mTransactionPool;
@Mock
private SplitscreenEventLogger mLogger;
+ @Mock
+ private ShellExecutor mMainExecutor;
private final Rect mBounds1 = new Rect(10, 20, 30, 40);
private final Rect mBounds2 = new Rect(5, 10, 15, 20);
@@ -116,7 +119,7 @@
mStageCoordinator = spy(new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
mTaskOrganizer, mMainStage, mSideStage, mDisplayController, mDisplayImeController,
mDisplayInsetsController, mSplitLayout, mTransitions, mTransactionPool, mLogger,
- Optional.empty(), new UnfoldControllerProvider()));
+ mMainExecutor, Optional.empty(), new UnfoldControllerProvider()));
doNothing().when(mStageCoordinator).updateActivityOptions(any(), anyInt());
when(mSplitLayout.getBounds1()).thenReturn(mBounds1);
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index ece150a..d8b077b 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -249,6 +249,7 @@
"apex/android_matrix.cpp",
"apex/android_paint.cpp",
"apex/android_region.cpp",
+ "apex/properties.cpp",
],
header_libs: ["android_graphics_apex_headers"],
diff --git a/libs/hwui/apex/include/android/graphics/properties.h b/libs/hwui/apex/include/android/graphics/properties.h
new file mode 100644
index 0000000..f24f840
--- /dev/null
+++ b/libs/hwui/apex/include/android/graphics/properties.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef ANDROID_GRAPHICS_PROPERTIES_H
+#define ANDROID_GRAPHICS_PROPERTIES_H
+
+#include <cutils/compiler.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/**
+ * Returns true if libhwui is using the vulkan backend.
+ */
+ANDROID_API bool hwui_uses_vulkan();
+
+__END_DECLS
+
+#endif // ANDROID_GRAPHICS_PROPERTIES_H
diff --git a/libs/hwui/apex/properties.cpp b/libs/hwui/apex/properties.cpp
new file mode 100644
index 0000000..abb333b
--- /dev/null
+++ b/libs/hwui/apex/properties.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "android/graphics/properties.h"
+
+#include <Properties.h>
+
+bool hwui_uses_vulkan() {
+ return android::uirenderer::Properties::peekRenderPipelineType() ==
+ android::uirenderer::RenderPipelineType::SkiaVulkan;
+}
diff --git a/libs/hwui/libhwui.map.txt b/libs/hwui/libhwui.map.txt
index 087c006..fdb2373 100644
--- a/libs/hwui/libhwui.map.txt
+++ b/libs/hwui/libhwui.map.txt
@@ -39,6 +39,7 @@
ARegionIterator_next;
ARegionIterator_getRect;
ARegionIterator_getTotalBounds;
+ hwui_uses_vulkan;
local:
*;
};
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 5283889..8be1bcd 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -187,22 +187,14 @@
*/
@SuppressWarnings("unused")
@UnsupportedAppUsage
- private long mNativeRecorderInJavaObj;
+ private long mNativeAudioRecordHandle;
/**
* Accessed by native methods: provides access to the callback data.
*/
@SuppressWarnings("unused")
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private long mNativeCallbackCookie;
-
- /**
- * Accessed by native methods: provides access to the JNIDeviceCallback instance.
- */
- @SuppressWarnings("unused")
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private long mNativeDeviceCallback;
-
+ private long mNativeJNIDataHandle;
//---------------------------------------------------------
// Member variables
@@ -492,9 +484,8 @@
* value here as no error checking is or can be done.
*/
/*package*/ AudioRecord(long nativeRecordInJavaObj) {
- mNativeRecorderInJavaObj = 0;
- mNativeCallbackCookie = 0;
- mNativeDeviceCallback = 0;
+ mNativeAudioRecordHandle = 0;
+ mNativeJNIDataHandle = 0;
// other initialization...
if (nativeRecordInJavaObj != 0) {
@@ -2131,7 +2122,7 @@
* @hide
*/
public int getPortId() {
- if (mNativeRecorderInJavaObj == 0) {
+ if (mNativeAudioRecordHandle == 0) {
return 0;
}
try {
diff --git a/media/java/android/media/tv/tuner/filter/Filter.java b/media/java/android/media/tv/tuner/filter/Filter.java
index a3e731b..d0973f4 100644
--- a/media/java/android/media/tv/tuner/filter/Filter.java
+++ b/media/java/android/media/tv/tuner/filter/Filter.java
@@ -560,6 +560,11 @@
*/
@Override
public void close() {
+ synchronized (mCallbackLock) {
+ mCallback = null;
+ mExecutor = null;
+ }
+
synchronized (mLock) {
if (mIsClosed) {
return;
@@ -568,8 +573,6 @@
if (res != Tuner.RESULT_SUCCESS) {
TunerUtils.throwExceptionForResult(res, "Failed to close filter.");
} else {
- mCallback = null;
- mExecutor = null;
mIsStarted = false;
mIsClosed = true;
}
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
index 62e53d6..a41399f 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
@@ -16,17 +16,18 @@
package com.android.dynsystem;
+import android.annotation.NonNull;
import android.content.Context;
import android.gsi.AvbPublicKey;
import android.gsi.IGsiService;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
-import android.os.MemoryFile;
-import android.os.ParcelFileDescriptor;
+import android.os.SharedMemory;
import android.os.SystemProperties;
import android.os.image.DynamicSystemManager;
import android.service.persistentdata.PersistentDataBlockManager;
+import android.system.ErrnoException;
import android.util.Log;
import android.util.Pair;
import android.util.Range;
@@ -39,6 +40,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
+import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
@@ -154,6 +156,22 @@
void onResult(int resultCode, Throwable detail);
}
+ private static class MappedMemoryBuffer implements AutoCloseable {
+ public ByteBuffer mBuffer;
+
+ MappedMemoryBuffer(@NonNull ByteBuffer buffer) {
+ mBuffer = buffer;
+ }
+
+ @Override
+ public void close() {
+ if (mBuffer != null) {
+ SharedMemory.unmap(mBuffer);
+ mBuffer = null;
+ }
+ }
+ }
+
private final int mSharedMemorySize;
private final String mUrl;
private final String mDsuSlot;
@@ -674,59 +692,66 @@
Log.d(TAG, "Start installing: " + partitionName);
- MemoryFile memoryFile = new MemoryFile("dsu_" + partitionName, mSharedMemorySize);
- ParcelFileDescriptor pfd = new ParcelFileDescriptor(memoryFile.getFileDescriptor());
-
- mInstallationSession.setAshmem(pfd, memoryFile.length());
-
- initPartitionProgress(partitionName, partitionSize, /* readonly = */ true);
- publishProgress(/* installedSize = */ 0L);
-
long prevInstalledSize = 0;
- long installedSize = 0;
- byte[] bytes = new byte[memoryFile.length()];
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<Boolean> submitPromise = null;
+ try (SharedMemory sharedMemory =
+ SharedMemory.create("dsu_buffer_" + partitionName, mSharedMemorySize);
+ MappedMemoryBuffer mappedBuffer =
+ new MappedMemoryBuffer(sharedMemory.mapReadWrite())) {
+ mInstallationSession.setAshmem(sharedMemory.getFdDup(), sharedMemory.getSize());
- while (true) {
- final int numBytesRead = sis.read(bytes, 0, bytes.length);
+ initPartitionProgress(partitionName, partitionSize, /* readonly = */ true);
+ publishProgress(/* installedSize = */ 0L);
- if (submitPromise != null) {
- // Wait until the previous submit task is complete.
- while (true) {
- try {
- if (!submitPromise.get()) {
- throw new IOException("Failed submitFromAshmem() to DynamicSystem");
+ long installedSize = 0;
+ byte[] readBuffer = new byte[sharedMemory.getSize()];
+ ByteBuffer buffer = mappedBuffer.mBuffer;
+ ExecutorService executor = Executors.newSingleThreadExecutor();
+ Future<Boolean> submitPromise = null;
+
+ while (true) {
+ final int numBytesRead = sis.read(readBuffer, 0, readBuffer.length);
+
+ if (submitPromise != null) {
+ // Wait until the previous submit task is complete.
+ while (true) {
+ try {
+ if (!submitPromise.get()) {
+ throw new IOException("Failed submitFromAshmem() to DynamicSystem");
+ }
+ break;
+ } catch (InterruptedException e) {
+ // Ignore.
}
- break;
- } catch (InterruptedException e) {
- // Ignore.
+ }
+
+ // Publish the progress of the previous submit task.
+ if (installedSize > prevInstalledSize + MIN_PROGRESS_TO_PUBLISH) {
+ publishProgress(installedSize);
+ prevInstalledSize = installedSize;
}
}
- // Publish the progress of the previous submit task.
- if (installedSize > prevInstalledSize + MIN_PROGRESS_TO_PUBLISH) {
- publishProgress(installedSize);
- prevInstalledSize = installedSize;
+ // Ensure the previous submit task (submitPromise) is complete before exiting the
+ // loop.
+ if (numBytesRead < 0) {
+ break;
}
+
+ if (isCancelled()) {
+ return;
+ }
+
+ buffer.position(0);
+ buffer.put(readBuffer, 0, numBytesRead);
+ submitPromise =
+ executor.submit(() -> mInstallationSession.submitFromAshmem(numBytesRead));
+
+ // Even though we update the bytes counter here, the actual progress is updated only
+ // after the submit task (submitPromise) is complete.
+ installedSize += numBytesRead;
}
-
- // Ensure the previous submit task (submitPromise) is complete before exiting the loop.
- if (numBytesRead < 0) {
- break;
- }
-
- if (isCancelled()) {
- return;
- }
-
- memoryFile.writeBytes(bytes, 0, 0, numBytesRead);
- submitPromise =
- executor.submit(() -> mInstallationSession.submitFromAshmem(numBytesRead));
-
- // Even though we update the bytes counter here, the actual progress is updated only
- // after the submit task (submitPromise) is complete.
- installedSize += numBytesRead;
+ } catch (ErrnoException e) {
+ e.rethrowAsIOException();
}
AvbPublicKey avbPublicKey = new AvbPublicKey();
diff --git a/packages/InputDevices/res/values-km/strings.xml b/packages/InputDevices/res/values-km/strings.xml
index 4b12321..e06ce2c8 100644
--- a/packages/InputDevices/res/values-km/strings.xml
+++ b/packages/InputDevices/res/values-km/strings.xml
@@ -32,10 +32,10 @@
<string name="keyboard_layout_hungarian" msgid="4154963661406035109">"ហុងគ្រី"</string>
<string name="keyboard_layout_icelandic" msgid="5836645650912489642">"អ៊ីស្លង់"</string>
<string name="keyboard_layout_brazilian" msgid="5117896443147781939">"ប្រេស៊ីល"</string>
- <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"ព័រទុយហ្គាល់"</string>
+ <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"ព័រទុយហ្កាល់"</string>
<string name="keyboard_layout_slovak" msgid="2469379934672837296">"ស្លូវ៉ាគី"</string>
<string name="keyboard_layout_slovenian" msgid="1735933028924982368">"ស្លូវ៉ានី"</string>
- <string name="keyboard_layout_turkish" msgid="7736163250907964898">"ទួរគី"</string>
+ <string name="keyboard_layout_turkish" msgid="7736163250907964898">"តួកគី"</string>
<string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"តួកគី F"</string>
<string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"អ៊ុយក្រែន"</string>
<string name="keyboard_layout_arabic" msgid="5671970465174968712">"អារ៉ាប់"</string>
diff --git a/packages/SettingsLib/ActivityEmbedding/Android.bp b/packages/SettingsLib/ActivityEmbedding/Android.bp
index 2569198..332bebf 100644
--- a/packages/SettingsLib/ActivityEmbedding/Android.bp
+++ b/packages/SettingsLib/ActivityEmbedding/Android.bp
@@ -15,9 +15,15 @@
static_libs: [
"androidx.annotation_annotation",
"androidx.core_core",
- "windowExtLib",
+ "androidx.window_window",
"SettingsLibUtils",
],
sdk_version: "system_current",
min_sdk_version: "21",
+ // TODO(b/228508619) Remove the optional uses after fixing upstream
+ optional_uses_libs: [
+ "org.apache.http.legacy",
+ "androidx.window.extensions",
+ "androidx.window.sidecar",
+ ],
}
diff --git a/packages/SettingsLib/ActivityEmbedding/AndroidManifest.xml b/packages/SettingsLib/ActivityEmbedding/AndroidManifest.xml
index 2e6c405..5ce08b7 100644
--- a/packages/SettingsLib/ActivityEmbedding/AndroidManifest.xml
+++ b/packages/SettingsLib/ActivityEmbedding/AndroidManifest.xml
@@ -20,4 +20,9 @@
<uses-sdk android:minSdkVersion="21" />
+ <application>
+ <uses-library android:name="androidx.window.extensions" android:required="false" />
+ <uses-library android:name="androidx.window.sidecar" android:required="false" />
+ </application>
+
</manifest>
diff --git a/packages/SettingsLib/Utils/src/com/android/settingslib/utils/BuildCompatUtils.java b/packages/SettingsLib/Utils/src/com/android/settingslib/utils/BuildCompatUtils.java
index 88e2423..ddbc907 100644
--- a/packages/SettingsLib/Utils/src/com/android/settingslib/utils/BuildCompatUtils.java
+++ b/packages/SettingsLib/Utils/src/com/android/settingslib/utils/BuildCompatUtils.java
@@ -48,37 +48,13 @@
}
/**
- * Implementation of BuildCompat.isAtLeast*() suitable for use in Settings
- *
- * <p>This still should try using BuildCompat.isAtLeastR() as source of truth, but also checking
- * for VERSION_SDK_INT and VERSION.CODENAME in case when BuildCompat implementation returned
- * false. Note that both checks should be >= and not = to make sure that when Android version
- * increases (i.e., from R to S), this does not stop working.
- *
- * <p>Supported configurations:
- *
- * <ul>
- * <li>For current Android release: when new API is not finalized yet (CODENAME = "Tiramisu",
- * SDK_INT = 32)
- * <li>For current Android release: when new API is finalized (CODENAME = "REL", SDK_INT = 33)
- * <li>For next Android release (CODENAME = "U", SDK_INT = 34+)
- * </ul>
- *
- * <p>Note that Build.VERSION_CODES.S cannot be used here until final SDK is available, because
- * it is equal to Build.VERSION_CODES.CUR_DEVELOPMENT before API finalization.
+ * Implementation of BuildCompat.isAtLeastT() suitable for use in Settings
*
* @return Whether the current OS version is higher or equal to T.
*/
+ @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.TIRAMISU)
public static boolean isAtLeastT() {
- if (!isAtLeastS()) {
- return false;
- }
-
- return (VERSION.CODENAME.equals("REL") && VERSION.SDK_INT >= 33)
- || (VERSION.CODENAME.length() >= 1
- && VERSION.CODENAME.toUpperCase().charAt(0) >= 'T'
- && VERSION.CODENAME.toUpperCase().charAt(0) <= 'Z')
- || (Build.VERSION.CODENAME.equals("Tiramisu") && Build.VERSION.SDK_INT >= 32);
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU;
}
private BuildCompatUtils() {}
diff --git a/packages/SettingsLib/res/drawable/broadcast_dialog_btn_bg.xml b/packages/SettingsLib/res/drawable/broadcast_dialog_btn_bg.xml
new file mode 100644
index 0000000..5fd7ee29
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/broadcast_dialog_btn_bg.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:shape="rectangle">
+ <solid android:color="?androidprv:attr/colorAccentPrimary" />
+ <corners android:radius="@dimen/broadcast_dialog_btn_radius" />
+</shape>
diff --git a/packages/SettingsLib/res/layout/broadcast_dialog.xml b/packages/SettingsLib/res/layout/broadcast_dialog.xml
new file mode 100644
index 0000000..ec69aa5
--- /dev/null
+++ b/packages/SettingsLib/res/layout/broadcast_dialog.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:id="@+id/dialog_bg"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/broadcast_dialog_margin"
+ android:orientation="vertical">
+
+ <ImageView
+ android:id="@+id/dialog_icon"
+ android:layout_width="@dimen/broadcast_dialog_icon_size"
+ android:layout_height="@dimen/broadcast_dialog_icon_size"
+ android:layout_marginTop="@dimen/broadcast_dialog_icon_margin_top"
+ android:layout_marginBottom="@dimen/broadcast_dialog_title_img_margin_top"
+ android:layout_gravity="center"
+ android:src="@drawable/settings_input_antenna"/>
+
+ <TextView
+ style="@style/BroadcastDialogTitleStyle"
+ android:id="@+id/dialog_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:layout_gravity="center"/>
+
+ <TextView
+ style="@style/BroadcastDialogBodyStyle"
+ android:id="@+id/dialog_subtitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:layout_gravity="center"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="@dimen/broadcast_dialog_margin"
+ android:layout_marginBottom="@dimen/broadcast_dialog_margin"
+ android:orientation="vertical">
+
+ <Button
+ android:layout_marginBottom="@dimen/broadcast_dialog_btn_margin_bottom"
+ android:id="@+id/positive_btn"
+ style="@style/BroadcastDialogButtonStyle"/>
+
+ <Button
+ android:layout_marginBottom="@dimen/broadcast_dialog_btn_margin_bottom"
+ android:id="@+id/negative_btn"
+ android:text="@string/bt_le_audio_broadcast_dialog_different_output"
+ style="@style/BroadcastDialogButtonStyle"/>
+
+ <Button
+ android:id="@+id/neutral_btn"
+ android:text="@android:string/cancel"
+ style="@style/BroadcastDialogButtonStyle"/>
+ </LinearLayout>
+
+ </LinearLayout>
+</FrameLayout>
diff --git a/packages/SettingsLib/res/layout/qrcode_scanner_fragment.xml b/packages/SettingsLib/res/layout/qrcode_scanner_fragment.xml
index e071f4c4..0a7fe09 100644
--- a/packages/SettingsLib/res/layout/qrcode_scanner_fragment.xml
+++ b/packages/SettingsLib/res/layout/qrcode_scanner_fragment.xml
@@ -92,6 +92,7 @@
android:layout_marginStart="?attr/sudMarginStart"
android:layout_marginEnd="?attr/sudMarginEnd"
android:gravity="center"
+ android:layout_gravity="center"
android:visibility="invisible"/>
</LinearLayout>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index d901b92..6bcac9d 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -280,7 +280,7 @@
<string name="wifi_display_certification" msgid="1805579519992520381">"شهادة عرض شاشة لاسلكي"</string>
<string name="wifi_verbose_logging" msgid="1785910450009679371">"تفعيل تسجيل Wi‑Fi Verbose"</string>
<string name="wifi_scan_throttling" msgid="2985624788509913617">"تقييد البحث عن شبكات Wi-Fi"</string>
- <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"التوزيع العشوائي لعناوين MAC غير الثابتة لشبكة Wi‑Fi."</string>
+ <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"التوزيع العشوائي لعناوين MAC غير الثابتة لشبكة Wi‑Fi"</string>
<string name="mobile_data_always_on" msgid="8275958101875563572">"بيانات الجوّال نشطة دائمًا"</string>
<string name="tethering_hardware_offload" msgid="4116053719006939161">"تسريع الأجهزة للتوصيل"</string>
<string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"عرض أجهزة البلوتوث بدون أسماء"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 261ee3e..b3bba95 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -55,7 +55,7 @@
<string name="wifi_disabled_network_failure" msgid="2660396183242399585">"IP কনফিগাৰেশ্বন বিফল হৈছে"</string>
<string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"নিম্নমানৰ নেটৱৰ্কৰ বাবে সংযোগ কৰা হোৱা নাই"</string>
<string name="wifi_disabled_wifi_failure" msgid="8819554899148331100">"ৱাই-ফাই সংযোগ বিফল হৈছে"</string>
- <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"সত্য়াপন কৰাত সমস্যা হৈছে"</string>
+ <string name="wifi_disabled_password_failure" msgid="6892387079613226738">"সত্যাপন কৰাত সমস্যা হৈছে"</string>
<string name="wifi_cant_connect" msgid="5718417542623056783">"সংযোগ কৰিব নোৱাৰে"</string>
<string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'ৰ সৈতে সংযোগ কৰিব পৰা নাই"</string>
<string name="wifi_check_password_try_again" msgid="8817789642851605628">"পাছৱৰ্ড পৰীক্ষা কৰি আকৌ চেষ্টা কৰক"</string>
@@ -146,12 +146,12 @@
<string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"ইনপুটৰ বাবে ব্যৱহাৰ কৰক"</string>
<string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"শ্ৰৱণ যন্ত্ৰৰ বাবে ব্যৱহাৰ কৰক"</string>
<string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"LE_AUDIOৰ বাবে ব্যৱহাৰ কৰক"</string>
- <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"যোৰা লগাওক"</string>
- <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"যোৰা লগাওক"</string>
+ <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"পেয়াৰ কৰক"</string>
+ <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"পেয়াৰ কৰক"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"বাতিল কৰক"</string>
<string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"যোৰা লগালে ইয়ে সংযোজিত কৰাৰ সময়ত আপোনাৰ সম্পৰ্কসমূহ আৰু কলৰ ইতিহাস চাবলৈ অনুমতি দিব।"</string>
- <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ সৈতে যোৰা লগাব পৰা নগ\'ল৷"</string>
- <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"এটা ভুল পিন বা পাছকীৰ কাৰণে <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ সৈতে যোৰা লগাব পৰা নাই৷"</string>
+ <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ সৈতে পেয়াৰ কৰিব পৰা নগ’ল।"</string>
+ <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"এটা ভুল পিন বা পাছকীৰ কাৰণে <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ সৈতে পেয়াৰ কৰিব পৰা নাই।"</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ সৈতে যোগাযোগ কৰিব পৰা নগ\'ল"</string>
<string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>এ যোৰা লগাব বিচৰা নাই"</string>
<string name="bluetooth_talkback_computer" msgid="3736623135703893773">"কম্পিউটাৰ"</string>
@@ -297,8 +297,8 @@
<string name="bluetooth_select_a2dp_codec_type_help_info" msgid="8647200416514412338">"ধোঁৱাবৰণীয়া হৈ থকা মানে এয়া ফ’ন অথবা হেডছেটটোৱে সমৰ্থন নকৰে"</string>
<string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="6253965294594390806">"প্ৰতি ছেম্পলত ব্লুটুথ অডিঅ\' বিটসমূহ"</string>
<string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4898693684282596143">"ব্লুটুথ অডিঅ\' ক\'ডেকৰ বাছনি\nআৰম্ভ কৰক: প্ৰতি নমুনা ইমান বিট"</string>
- <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="364277285688014427">"ব্লুটুথ অডিঅ\' চ্চেনেল ম\'ড"</string>
- <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"ব্লুটুথ অডিঅ\' ক\'ডেকৰ বাছনি\nআৰম্ভ কৰক: চ্চেনেল ম\'ড"</string>
+ <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="364277285688014427">"ব্লুটুথ অডিঅ\' চেনেল ম\'ড"</string>
+ <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"ব্লুটুথ অডিঅ\' ক\'ডেকৰ বাছনি\nআৰম্ভ কৰক: চেনেল ম\'ড"</string>
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"ব্লুটুথ অডিঅ’ LDAC ক’ডেক: পৰিৱেশনৰ মান"</string>
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"ব্লুটুথ অডিঅ\' LDAC\nক\'ডেক বাছনি আৰম্ভ কৰক: প্লেবেকৰ গুণগত মান"</string>
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"ষ্ট্ৰীম কৰি থকা হৈছে: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
@@ -401,7 +401,7 @@
<string name="show_all_anrs" msgid="9160563836616468726">"নেপথ্য এএনআৰবোৰ দেখুৱাওক"</string>
<string name="show_all_anrs_summary" msgid="8562788834431971392">"নেপথ্য এপসমূহৰ বাবে এপে সঁহাৰি দিয়া নাই ডায়ল\'গ প্ৰদৰ্শন কৰক"</string>
<string name="show_notification_channel_warnings" msgid="3448282400127597331">"জাননী চ্চেনেলৰ সকীয়নিসমূহ দেখুৱাওক"</string>
- <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"কোনো এপে বৈধ চ্চেনেল নোহোৱাকৈ কোনো জাননী প\'ষ্ট কৰিলে স্ক্ৰীনত সকীয়নি প্ৰদৰ্শন হয়"</string>
+ <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"কোনো এপে বৈধ চেনেল নোহোৱাকৈ কোনো জাননী প\'ষ্ট কৰিলে স্ক্ৰীনত সকীয়নি প্ৰদৰ্শন হয়"</string>
<string name="force_allow_on_external" msgid="9187902444231637880">"বাহ্যিক সঞ্চয়াগাৰত এপক বলেৰে অনুমতি দিয়ক"</string>
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"মেনিফেষ্টৰ মান যিয়েই নহওক, বাহ্যিক ষ্ট’ৰেজত লিখিবলৈ যিকোনো এপক উপযুক্ত কৰি তোলে"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"বলেৰে কাৰ্যকলাপসমূহৰ আকাৰ সলনি কৰিব পৰা কৰক"</string>
@@ -569,7 +569,7 @@
<string name="user_add_user_item_title" msgid="2394272381086965029">"ব্যৱহাৰকাৰী"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"সীমিত প্ৰ\'ফাইল"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"নতুন ব্যৱহাৰকাৰী যোগ কৰিবনে?"</string>
- <string name="user_add_user_message_long" msgid="1527434966294733380">"আপুনি অতিৰিক্ত ব্য়ৱহাৰকাৰীক যোগ কৰি এই ডিভাইচটো অন্য় ব্য়ক্তিৰ সৈতে শ্বেয়াৰ কৰিব পাৰে। প্ৰতিজন ব্য়ৱহাৰকাৰীৰ বাবে নিজাকৈ ঠাই আছে যাক তেওঁলোকে এপ্, ৱালপেপাৰ আৰু অন্য়ান্য় বস্তুৰ বাবে নিজৰ উপযোগিতা অনুযায়ী ব্য়ৱহাৰ কৰিব পাৰে। ব্য়ৱহাৰকাৰীসকলে সকলোকে প্ৰভাৱান্বিত কৰা ৱাই-ফাইৰ নিচিনা ডিভাইচৰ ছেটিং সাল-সলনি কৰিবও পাৰে।\n\nআপুনি যেতিয়া কোনো নতুন ব্য়ৱহাৰকাৰীক যোগ কৰে সেই ব্য়ক্তিজনে নিজেই নিজৰ বাবে ঠাই ছেট আপ কৰিব লাগিব।\n\nসকলো ব্য়ৱহাৰকাৰীয়ে অন্য় ব্য়ৱহাৰকাৰীৰ বাবে এপ্সমূহ আপডে’ট কৰিব পাৰে। সাধ্য় সুবিধাসমূহৰ ছেটিং আৰু সেৱাসমূহ নতুন ব্য়ৱহাৰকাৰীলৈ স্থানান্তৰ নহ\'বও পাৰে।"</string>
+ <string name="user_add_user_message_long" msgid="1527434966294733380">"আপুনি অতিৰিক্ত ব্যৱহাৰকাৰীক যোগ কৰি এই ডিভাইচটো অন্য় ব্য়ক্তিৰ সৈতে শ্বেয়াৰ কৰিব পাৰে। প্ৰতিজন ব্যৱহাৰকাৰীৰ বাবে নিজাকৈ ঠাই আছে যাক তেওঁলোকে এপ্, ৱালপেপাৰ আৰু অন্য়ান্য় বস্তুৰ বাবে নিজৰ উপযোগিতা অনুযায়ী ব্যৱহাৰ কৰিব পাৰে। ব্যৱহাৰকাৰীসকলে সকলোকে প্ৰভাৱান্বিত কৰা ৱাই-ফাইৰ নিচিনা ডিভাইচৰ ছেটিং সাল-সলনি কৰিবও পাৰে।\n\nআপুনি যেতিয়া কোনো নতুন ব্যৱহাৰকাৰীক যোগ কৰে সেই ব্য়ক্তিজনে নিজেই নিজৰ বাবে ঠাই ছেট আপ কৰিব লাগিব।\n\nসকলো ব্যৱহাৰকাৰীয়ে অন্য় ব্যৱহাৰকাৰীৰ বাবে এপ্সমূহ আপডে’ট কৰিব পাৰে। সাধ্য় সুবিধাসমূহৰ ছেটিং আৰু সেৱাসমূহ নতুন ব্যৱহাৰকাৰীলৈ স্থানান্তৰ নহ\'বও পাৰে।"</string>
<string name="user_add_user_message_short" msgid="3295959985795716166">"আপুনি যেতিয়া এজন নতুন ব্যৱহাৰকাৰী যোগ কৰে, তেওঁ নিজৰ ঠাই ছেট আপ কৰা প্ৰয়োজন।\n\nযিকোনো ব্যৱহাৰকাৰীয়ে সকলো ব্যৱহাৰকাৰীৰ বাবে এপ্ আপডে\'ট কৰিব পাৰে।"</string>
<string name="user_setup_dialog_title" msgid="8037342066381939995">"ব্যৱহাৰকাৰী এতিয়া ছেট আপ কৰিবনে?"</string>
<string name="user_setup_dialog_message" msgid="269931619868102841">"ডিভাইচটো লৈ নিজৰ ঠাই ছেটআপ কৰিবলৈ নতুন ব্যৱহাৰকাৰী উপলব্ধ থকাটো নিশ্চিত কৰক"</string>
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"কিউআৰ ক’ডটো স্কেন কৰক"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"শুনিবলৈ আৰম্ভ কৰিবলৈ, তলৰ মাজৰ অংশত কিউআৰ ক’ডটো ৰাখক"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"কিউআৰ ক’ডটো মান্য ফৰ্মেটৰ নহয়"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ সম্প্ৰচাৰ কৰা বন্ধ কৰিবনে?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"যদি আপুনি <xliff:g id="SWITCHAPP">%1$s</xliff:g>ৰ সম্প্ৰচাৰ কৰে অথবা আউটপুট সলনি কৰে, তেন্তে, আপোনাৰ বৰ্তমানৰ সম্প্ৰচাৰ বন্ধ হৈ যাব"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্ৰচাৰ কৰক"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"আউটপুট সলনি কৰক"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index fa8c515..ca78c68 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"QR kodu skanlayın"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"Dinləməyə başlamaq üçün aşağıda QR kodu mərkəzə yerləşdirin"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"QR kodu doğru formatda deyil"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinin yayımlanması dayandırılsın?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlasanız və ya nəticəni dəyişsəniz, cari yayımınız dayandırılacaq"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlayın"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Nəticəni dəyişdirin"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index c5ac71c..12a421d 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -225,7 +225,7 @@
<string name="choose_profile" msgid="343803890897657450">"Избор на потребителски профил"</string>
<string name="category_personal" msgid="6236798763159385225">"Лични"</string>
<string name="category_work" msgid="4014193632325996115">"Служебни"</string>
- <string name="development_settings_title" msgid="140296922921597393">"Опции на програмиста"</string>
+ <string name="development_settings_title" msgid="140296922921597393">"Опции за програмисти"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"Активиране на опциите за програмисти"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"Задаване на опции за програмиране на приложения"</string>
<string name="development_settings_not_available" msgid="355070198089140951">"Опциите за програмисти не са налице за този потребител"</string>
@@ -364,7 +364,7 @@
<string name="pointer_location_summary" msgid="957120116989798464">"Насл. на екран показва текущи данни при докосване"</string>
<string name="show_touches" msgid="8437666942161289025">"Показване на докосванията"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"Показване на визуална обр. връзка за докосванията"</string>
- <string name="show_screen_updates" msgid="2078782895825535494">"Актуал. на повърхн: Показв."</string>
+ <string name="show_screen_updates" msgid="2078782895825535494">"Актуализации на повърхн."</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"Примигв. на целите повърхности на прозорците при актуализирането им"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"Актуализации на изгледите"</string>
<string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"Примигв. на изгледите в прозорците при начертаване"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 11e9f1d..4b03267 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -273,7 +273,7 @@
<string name="oem_unlock_enable_summary" msgid="5857388174390953829">"বুট-লোডার আনলক করার অনুমতি দিন"</string>
<string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"OEM আনলক করার অনুমতি দিতে চান?"</string>
<string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"সতর্কতা: এই ডিভাইসে সেটিংটি চালু থাকা অবস্থায় ডিভাইস সুরক্ষা বৈশিষ্ট্যগুলি কাজ করবে না৷"</string>
- <string name="mock_location_app" msgid="6269380172542248304">"অনুরূপ লোকেশন অ্যাপ্লিকেশান বেছে নিন"</string>
+ <string name="mock_location_app" msgid="6269380172542248304">"অনুরূপ লোকেশন অ্যাপ বেছে নিন"</string>
<string name="mock_location_app_not_set" msgid="6972032787262831155">"কোনো অনুরূপ লোকেশন অ্যাপ্লিকেশান সেট করা নেই"</string>
<string name="mock_location_app_set" msgid="4706722469342913843">"অনুরূপ লোকেশন অ্যাপ্লিকেশান: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="debug_networking_category" msgid="6829757985772659599">"নেটওয়ার্কিং"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 7499bbc..fae2cd6 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -264,7 +264,7 @@
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Povežite se na WiFi mrežu"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, otklanjanje grešaka, programer"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"Prečica za izvještaj o greškama"</string>
- <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Prikaz dugmeta za prijavu grešaka u meniju napajanja"</string>
+ <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Vidite dugme za prijavu grešaka u meniju napajanja"</string>
<string name="keep_screen_on" msgid="1187161672348797558">"Ne zaključavaj ekran"</string>
<string name="keep_screen_on_summary" msgid="1510731514101925829">"Ekran neće prelaziti u stanje mirovanja tokom punjenja"</string>
<string name="bt_hci_snoop_log" msgid="7291287955649081448">"Omogući Bluetooth HCI snoop zapis"</string>
@@ -299,8 +299,8 @@
<string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4898693684282596143">"Aktivirajte Bluetooth Audio Codec\nOdabir: Bitovi po uzorku"</string>
<string name="bluetooth_select_a2dp_codec_channel_mode" msgid="364277285688014427">"Način Bluetooth audio kanala"</string>
<string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"Aktivirajte Bluetooth Audio Codec\nOdabir: Način rada po kanalima"</string>
- <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"Bluetooth Audio LDAC kodek: Kvalitet reprodukcije"</string>
- <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"Aktivirajte Bluetooth Audio \nOdabir kodeka: Kvalitet reprodukcije"</string>
+ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"Bluetooth Audio LDAC kodek: kvalitet reprodukcije"</string>
+ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"Aktivirajte Bluetooth Audio \nOdabir kodeka: kvalitet reprodukcije"</string>
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Prijenos: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="select_private_dns_configuration_title" msgid="7887550926056143018">"Privatni DNS"</string>
<string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Odaberite način rada privatnog DNS-a"</string>
@@ -336,7 +336,7 @@
<string name="dev_settings_warning_title" msgid="8251234890169074553">"Dopustiti postavke za razvoj?"</string>
<string name="dev_settings_warning_message" msgid="37741686486073668">"Ove postavke su namijenjene samo za svrhe razvoja. Mogu izazvati pogrešno ponašanje uređaja i aplikacija na njemu."</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Potvrdi aplikacije putem USB-a"</string>
- <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Provjerite da li se u aplikacijama instaliranim putem ADB-a/ADT-a javlja zlonamjerno ponašanje"</string>
+ <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Provjerite javlja li se zlonamjerno ponašanje u aplikacijama instaliranim putem ADB-a/ADT-a"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Prikazat će se Bluetooth uređaji bez naziva (samo MAC adrese)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Onemogućava funkciju apsolutne jačine zvuka za Bluetooth u slučaju problema s jačinom zvuka na udaljenim uređajima, kao što je neprihvatljivo glasan zvuk ili nedostatak kontrole."</string>
<string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Omogućava grupisanje funkcije Bluetooth Gabeldorsche."</string>
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"Skenirajte QR kôd"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"Da pokrenete slušanje, centrirajte QR kôd ispod"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"Format QR koda nije važeći"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Zaustaviti emitiranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, vaše će se trenutačno emitiranje zaustaviti"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Emitiranje aplikacije <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Promjena izlaza"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 5620cce..e3dca33 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -312,7 +312,7 @@
<string name="wifi_display_certification_summary" msgid="8111151348106907513">"Mostra les opcions per a la certificació de pantalla sense fil"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Augmenta el nivell de registre de la connexió Wi‑Fi i es mostra per SSID RSSI al selector de Wi‑Fi"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Exhaureix menys la bateria i millora el rendiment de la xarxa"</string>
- <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Quan aquest mode està activat, és possible que l’adreça MAC d\'aquest dispositiu canviï cada vegada que es connecti a una xarxa amb l\'aleatorització d\'adreces MAC activada."</string>
+ <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Quan aquest mode està activat, és possible que l’adreça MAC d\'aquest dispositiu canviï cada vegada que es connecti a una xarxa amb l\'aleatorització d\'adreces MAC activada"</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"D\'ús mesurat"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"D\'ús no mesurat"</string>
<string name="select_logd_size_title" msgid="1604578195914595173">"Mides de la mem. intermèdia del registrador"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 8d4aacd..58c31eb 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -173,9 +173,9 @@
<string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Odebrané aplikace"</string>
<string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Odebrané aplikace a odebraní uživatelé"</string>
<string name="data_usage_ota" msgid="7984667793701597001">"Aktualizace systému"</string>
- <string name="tether_settings_title_usb" msgid="3728686573430917722">"Připojení přes USB"</string>
+ <string name="tether_settings_title_usb" msgid="3728686573430917722">"Tethering přes USB"</string>
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"Přenosný hotspot"</string>
- <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Připojení přes Bluetooth"</string>
+ <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Tethering přes Bluetooth"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Sdílené připojení"</string>
<string name="tether_settings_title_all" msgid="8910259483383010470">"Sdílené připojení a přenosný hotspot"</string>
<string name="managed_user_title" msgid="449081789742645723">"Všechny pracovní aplikace"</string>
@@ -310,7 +310,7 @@
<string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Zadejte hostitele poskytovatele DNS"</string>
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Nelze se připojit"</string>
<string name="wifi_display_certification_summary" msgid="8111151348106907513">"Zobrazit možnosti certifikace bezdrátového displeje"</string>
- <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Zvýšit úroveň protokolování Wi‑Fi zobrazenou v SSID a RSSI při výběru sítě Wi‑Fi"</string>
+ <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Zvýšit úroveň protokolování Wi‑Fi, při výběru Wi‑Fi zobrazovat RSSI pro každý SSID"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Snižuje vyčerpávání baterie a vylepšuje výkon sítě"</string>
<string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Když je tento režim aktivován, adresa MAC tohoto zařízení se může změnit pokaždé, když se zařízení připojí k síti s aktivovanou randomizací adres MAC."</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"Měřená"</string>
@@ -336,7 +336,7 @@
<string name="dev_settings_warning_title" msgid="8251234890169074553">"Povolit nastavení pro vývojáře?"</string>
<string name="dev_settings_warning_message" msgid="37741686486073668">"Tato nastavení jsou určena pouze pro vývojáře. Mohou způsobit rozbití nebo nesprávné fungování zařízení a nainstalovaných aplikací."</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Ověřovat aplikace z USB"</string>
- <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Kontrolovat škodlivost aplikací nainstalovaných pomocí nástroje ADB/ADT"</string>
+ <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Kontrolovat škodlivost aplikací nainstalovaných pomocí nástroje ADB nebo ADT"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Zařízení Bluetooth se budou zobrazovat bez názvů (pouze adresy MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Zakáže funkci absolutní hlasitosti Bluetooth. Zabrání tak problémům s hlasitostí vzdálených zařízení (jako je příliš vysoká hlasitost nebo nemožnost ovládání)."</string>
<string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Zapne sadu funkcí Bluetooth Gabeldorche."</string>
@@ -351,7 +351,7 @@
<string name="debug_app_set" msgid="6599535090477753651">"Aplikace pro ladění: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="select_application" msgid="2543228890535466325">"Výběr aplikace"</string>
<string name="no_application" msgid="9038334538870247690">"Nic"</string>
- <string name="wait_for_debugger" msgid="7461199843335409809">"Počkat na ladicí program"</string>
+ <string name="wait_for_debugger" msgid="7461199843335409809">"Čekat na ladicí program"</string>
<string name="wait_for_debugger_summary" msgid="6846330006113363286">"Aplikace čeká na připojení ladicího programu"</string>
<string name="debug_input_category" msgid="7349460906970849771">"Vstup"</string>
<string name="debug_drawing_category" msgid="5066171112313666619">"Vykreslování"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index e9a8da9..74e2dbb 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"Scan QR code"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"To start listening, centre the QR code below"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"QR code isn\'t a valid format"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Change output"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 788968f..eacaad0 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"Scan QR code"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"To start listening, centre the QR code below"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"QR code isn\'t a valid format"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Change output"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index e9a8da9..74e2dbb 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"Scan QR code"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"To start listening, centre the QR code below"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"QR code isn\'t a valid format"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Change output"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index e9a8da9..74e2dbb 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"Scan QR code"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"To start listening, centre the QR code below"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"QR code isn\'t a valid format"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Change output"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 9ca21bb..70227dc 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"Scan QR code"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"To start listening, center the QR code below"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"QR code isn\'t a valid format"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Change output"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 6ec3f8e..9df8e7e 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -286,10 +286,10 @@
<string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Mostrar dispositivos Bluetooth sin nombre"</string>
<string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"Inhabilitar volumen absoluto"</string>
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Habilitar Gabeldorsche"</string>
- <string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Versión AVRCP de Bluetooth"</string>
- <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Selecciona la versión AVRCP de Bluetooth"</string>
- <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Versión de MAP de Bluetooth"</string>
- <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Seleccionar versión de MAP de Bluetooth"</string>
+ <string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Versión de Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Selecciona la versión de Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Versión de Bluetooth MAP"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Selecciona la versión de Bluetooth MAP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Códec de audio de Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Activar el códec de audio por Bluetooth\nSelección"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Frecuencia de muestreo de audio de Bluetooth"</string>
@@ -311,11 +311,11 @@
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"No se ha podido establecer la conexión"</string>
<string name="wifi_display_certification_summary" msgid="8111151348106907513">"Muestra opciones para la certificación de la pantalla inalámbrica"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Aumenta el nivel de registro de la conexión Wi-Fi y se muestra por SSID RSSI en el selector Wi-Fi"</string>
- <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduce el consumo de batería y mejora el rendimiento de las redes"</string>
+ <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduce el consumo de batería y mejora el rendimiento de la red"</string>
<string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Si este modo está habilitado, es posible que la dirección MAC del dispositivo cambie cada vez que se conecte a una red que tenga habilitada la aleatorización de MAC."</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"Medida"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"No medida"</string>
- <string name="select_logd_size_title" msgid="1604578195914595173">"Tamaños del búfer para registrar"</string>
+ <string name="select_logd_size_title" msgid="1604578195914595173">"Tamaños del búfer de registro"</string>
<string name="select_logd_size_dialog_title" msgid="2105401994681013578">"Elige el tamaño del Logger por búfer"</string>
<string name="dev_logpersist_clear_warning_title" msgid="8631859265777337991">"¿Borrar almacenamiento continuo del registrador?"</string>
<string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"Cuando ya no supervisamos la actividad con el registrador de forma continua, estamos obligados a borrar los datos del registrador almacenados en el dispositivo."</string>
@@ -347,7 +347,7 @@
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Establecer comprobación HDCP"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"Depuración"</string>
<string name="debug_app" msgid="8903350241392391766">"Elegir aplicación de depuración"</string>
- <string name="debug_app_not_set" msgid="1934083001283807188">"Aplicación de depuración no configurada"</string>
+ <string name="debug_app_not_set" msgid="1934083001283807188">"Aplicación de depuración no establecida"</string>
<string name="debug_app_set" msgid="6599535090477753651">"Aplicación de depuración: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="select_application" msgid="2543228890535466325">"Selecciona una aplicación"</string>
<string name="no_application" msgid="9038334538870247690">"Ninguna"</string>
@@ -366,20 +366,20 @@
<string name="show_touches_summary" msgid="3692861665994502193">"Muestra la ubicación de los toques en la pantalla"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"Mostrar cambios de superficies"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"Hace parpadear todas las superficies de la ventana cuando se actualizan"</string>
- <string name="show_hw_screen_updates" msgid="2021286231267747506">"Ver cambios de vista"</string>
+ <string name="show_hw_screen_updates" msgid="2021286231267747506">"Ver actualizaciones de vista"</string>
<string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"Hacer parpadear las vistas dentro de las ventanas cuando se dibujan"</string>
<string name="show_hw_layers_updates" msgid="5268370750002509767">"Ver actualizaciones de capas de hardware"</string>
<string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Hacer parpadear las capas de hardware en verde cuando se actualizan"</string>
<string name="debug_hw_overdraw" msgid="8944851091008756796">"Depurar sobredibujos de GPU"</string>
<string name="disable_overlays" msgid="4206590799671557143">"Inhabilitar superposiciones de hardware"</string>
- <string name="disable_overlays_summary" msgid="1954852414363338166">"Usar siempre la GPU para componer pantallas"</string>
+ <string name="disable_overlays_summary" msgid="1954852414363338166">"Usa siempre la GPU para componer pantallas"</string>
<string name="simulate_color_space" msgid="1206503300335835151">"Simular espacio de color"</string>
<string name="enable_opengl_traces_title" msgid="4638773318659125196">"Habilitar seguimiento OpenGL"</string>
<string name="usb_audio_disable_routing" msgid="3367656923544254975">"Inhabilitar enrutamiento de audio por USB"</string>
<string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"Inhabilita el enrutamiento automático a periféricos de audio USB"</string>
<string name="debug_layout" msgid="1659216803043339741">"Mostrar límites de diseño"</string>
<string name="debug_layout_summary" msgid="8825829038287321978">"Muestra límites de vídeo, márgenes, etc."</string>
- <string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forzar dirección de diseño RTL"</string>
+ <string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forzar dirección RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Fuerza la dirección RTL para todos los idiomas"</string>
<string name="window_blurs" msgid="6831008984828425106">"Difuminar ventanas"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forzar MSAA 4x"</string>
@@ -387,7 +387,7 @@
<string name="show_non_rect_clip" msgid="7499758654867881817">"Depurar operaciones de recorte no rectangulares"</string>
<string name="track_frame_time" msgid="522674651937771106">"Trazar la renderización de HWUI"</string>
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Activar capas de depuración de GPU"</string>
- <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite cargar capas de depuración de GPU para aplicaciones de depuración"</string>
+ <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite cargar capas de depuración de GPU en aplicaciones de depuración"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Habilitar registro de proveedor detallado"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluye otros registros de proveedor específicos del dispositivo en informes de errores, lo que puede añadir información privada, usar más batería u ocupar más espacio de almacenamiento."</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animación de ventana"</string>
@@ -399,7 +399,7 @@
<string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Destruye actividades cuando el usuario deja de usarlas"</string>
<string name="app_process_limit_title" msgid="8361367869453043007">"Límitar procesos en segundo plano"</string>
<string name="show_all_anrs" msgid="9160563836616468726">"Mostrar ANR en segundo plano"</string>
- <string name="show_all_anrs_summary" msgid="8562788834431971392">"Muestra el cuadro de diálogo de que la aplicación no responde para aplicaciones en segundo plano"</string>
+ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Muestra un cuadro de diálogo que informa de que la aplicación no responde en aplicaciones en segundo plano"</string>
<string name="show_notification_channel_warnings" msgid="3448282400127597331">"Ver advertencias del canal de notificaciones"</string>
<string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Muestra una advertencia en pantalla cuando una aplicación publica una notificación sin un canal válido"</string>
<string name="force_allow_on_external" msgid="9187902444231637880">"Forzar permitir aplicaciones en almacenamiento externo"</string>
@@ -552,7 +552,7 @@
<string name="help_label" msgid="3528360748637781274">"Ayuda y comentarios"</string>
<string name="storage_category" msgid="2287342585424631813">"Almacenamiento"</string>
<string name="shared_data_title" msgid="1017034836800864953">"Datos compartidos"</string>
- <string name="shared_data_summary" msgid="5516326713822885652">"Ver y modificar los datos compartidos"</string>
+ <string name="shared_data_summary" msgid="5516326713822885652">"Consulta y modifica datos compartidos"</string>
<string name="shared_data_no_blobs_text" msgid="3108114670341737434">"No hay datos compartidos de este usuario."</string>
<string name="shared_data_query_failure_text" msgid="3489828881998773687">"No se han podido generar datos compartidos. Inténtalo de nuevo."</string>
<string name="blob_id_text" msgid="8680078988996308061">"ID de datos compartidos: <xliff:g id="BLOB_ID">%d</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 996b92f..6cc5057 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -47,7 +47,7 @@
<string name="wifi_security_sae" msgid="3644520541721422843">"WPA3-Personal"</string>
<string name="wifi_security_psk_sae" msgid="8135104122179904684">"WPA2/WPA3-Personal"</string>
<string name="wifi_security_none_owe" msgid="5241745828327404101">"Puudub / Täiustatud avamine"</string>
- <string name="wifi_security_owe" msgid="3343421403561657809">"Täiustatud avamine"</string>
+ <string name="wifi_security_owe" msgid="3343421403561657809">"Enhanced Open"</string>
<string name="wifi_security_eap_suiteb" msgid="415842785991698142">"WPA3-Enterprise (192-bitine)"</string>
<string name="wifi_remembered" msgid="3266709779723179188">"Salvestatud"</string>
<string name="wifi_disconnected" msgid="7054450256284661757">"Pole ühendatud"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index d6741dc..1154f9c 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -286,7 +286,7 @@
<string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Erakutsi Bluetooth bidezko gailuak izenik gabe"</string>
<string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"Desgaitu bolumen absolutua"</string>
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gaitu Gabeldorsche"</string>
- <string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP bertsioa"</string>
+ <string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCParen bertsioa"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Hautatu Bluetooth AVRCP bertsioa"</string>
<string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAParen bertsioa"</string>
<string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Hautatu Bluetooth MAParen bertsioa"</string>
@@ -372,14 +372,14 @@
<string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Distirarazi hardware-geruzak berdez haiek eguneratzean"</string>
<string name="debug_hw_overdraw" msgid="8944851091008756796">"Araztu GPU gainidazketa"</string>
<string name="disable_overlays" msgid="4206590799671557143">"Desgaitu HW gainjartzeak"</string>
- <string name="disable_overlays_summary" msgid="1954852414363338166">"Erabili beti GPU pantaila-muntaietarako"</string>
+ <string name="disable_overlays_summary" msgid="1954852414363338166">"Erabili beti GPUa pantaila-muntaietarako"</string>
<string name="simulate_color_space" msgid="1206503300335835151">"Simulatu kolore-eremua"</string>
<string name="enable_opengl_traces_title" msgid="4638773318659125196">"Gaitu OpenGL aztarnak"</string>
<string name="usb_audio_disable_routing" msgid="3367656923544254975">"Desgaitu USB bidez audioa bideratzeko aukera"</string>
<string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"Desgaitu USB bidezko audio-gailuetara automatikoki bideratzeko aukera"</string>
<string name="debug_layout" msgid="1659216803043339741">"Erakutsi diseinu-mugak"</string>
<string name="debug_layout_summary" msgid="8825829038287321978">"Erakutsi kliparen mugak, marjinak, etab."</string>
- <string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Behartu eskuin-ezker norabidea"</string>
+ <string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Eskuinetik ezkerrerako norabidea"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Behartu pantaila-diseinuaren norabidea eskuin-ezker izatera lurraldeko ezarpen guztiekin"</string>
<string name="window_blurs" msgid="6831008984828425106">"Gaitu leiho-lausotzeak"</string>
<string name="force_msaa" msgid="4081288296137775550">"Behartu 4x MSAA"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index bbb4285..e66d28a 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -312,7 +312,7 @@
<string name="wifi_display_certification_summary" msgid="8111151348106907513">"Mostra opcións para o certificado de visualización sen fíos"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Aumenta o nivel de rexistro da wifi, móstrao por SSID RSSI no selector de wifi"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduce o consumo de batería e mellora o rendemento da rede"</string>
- <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Cando este modo está activado, o enderezo MAC pode cambiar cada vez que se este dispositivo se conecta a unha rede que teña activada a orde aleatoria de enderezos MAC."</string>
+ <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Cando este modo está activado, o enderezo MAC pode cambiar cada vez que este dispositivo se conecte a unha rede que teña activada a orde aleatoria de enderezos MAC"</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"Rede sen tarifa plana"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"Rede con tarifa plana"</string>
<string name="select_logd_size_title" msgid="1604578195914595173">"Tamaño dos búfers do rexistrador"</string>
@@ -359,37 +359,37 @@
<string name="media_category" msgid="8122076702526144053">"Multimedia"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Supervisión"</string>
<string name="strict_mode" msgid="889864762140862437">"Modo estrito activado"</string>
- <string name="strict_mode_summary" msgid="1838248687233554654">"Ilumínase se as aplicacións tardan moito no proceso principal"</string>
+ <string name="strict_mode_summary" msgid="1838248687233554654">"A pantalla ilumínase se as aplicacións tardan moito no proceso principal"</string>
<string name="pointer_location" msgid="7516929526199520173">"Localización do punteiro"</string>
<string name="pointer_location_summary" msgid="957120116989798464">"Superpón os datos dos toques na pantalla"</string>
<string name="show_touches" msgid="8437666942161289025">"Mostrar toques"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"Mostra a localización dos toques na pantalla"</string>
- <string name="show_screen_updates" msgid="2078782895825535494">"Cambios de superficie"</string>
+ <string name="show_screen_updates" msgid="2078782895825535494">"Mostrar cambios de superficie"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"Ilumina as superficies de ventás ao actualizarse"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"Mostrar actualizacións"</string>
<string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"Ilumina as vistas das ventás creadas"</string>
<string name="show_hw_layers_updates" msgid="5268370750002509767">"Ver actualizacións de capas de hardware"</string>
<string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Ilumina as capas de hardware en verde ao actualizárense"</string>
- <string name="debug_hw_overdraw" msgid="8944851091008756796">"Depurar superposición GPU"</string>
+ <string name="debug_hw_overdraw" msgid="8944851091008756796">"Depurar superposición de GPU"</string>
<string name="disable_overlays" msgid="4206590799671557143">"Desactivar superposicións de hardware"</string>
- <string name="disable_overlays_summary" msgid="1954852414363338166">"Utiliza sempre GPU para a composición da pantalla"</string>
+ <string name="disable_overlays_summary" msgid="1954852414363338166">"Utiliza sempre a GPU para a composición da pantalla"</string>
<string name="simulate_color_space" msgid="1206503300335835151">"Simular espazo de cor"</string>
<string name="enable_opengl_traces_title" msgid="4638773318659125196">"Activar rastros OpenGL"</string>
- <string name="usb_audio_disable_routing" msgid="3367656923544254975">"Desactivar encamiñamento audio USB"</string>
+ <string name="usb_audio_disable_routing" msgid="3367656923544254975">"Desactivar encamiñamento de audio por USB"</string>
<string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"Desactiva o encamiñamento automático a periféricos de audio USB"</string>
<string name="debug_layout" msgid="1659216803043339741">"Mostrar límites de deseño"</string>
<string name="debug_layout_summary" msgid="8825829038287321978">"Mostra os límites dos clips, as marxes etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forzar dirección do deseño RTL"</string>
- <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forza a dirección de pantalla a RTL (dereita a esquerda) para todas as configuración rexionais"</string>
- <string name="window_blurs" msgid="6831008984828425106">"Permitir desenfoque ventá"</string>
+ <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forza a dirección de pantalla de dereita a esquerda para todas as opcións de configuración rexionais"</string>
+ <string name="window_blurs" msgid="6831008984828425106">"Permitir desenfoque de ventás"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forzar MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Activa MSAA 4x en aplicacións OpenGL ES 2.0"</string>
- <string name="show_non_rect_clip" msgid="7499758654867881817">"Depurar accións recorte non rectangulares"</string>
- <string name="track_frame_time" msgid="522674651937771106">"Perfil procesamento HWUI"</string>
+ <string name="show_non_rect_clip" msgid="7499758654867881817">"Depurar accións de recorte non rectangulares"</string>
+ <string name="track_frame_time" msgid="522674651937771106">"Perfil de procesamento de HWUI"</string>
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Activar depuración da GPU"</string>
- <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite capas da GPU para apps de depuración"</string>
+ <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite cargar capas de depuración da GPU para aplicacións de depuración"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Activar rexistro de provedores"</string>
- <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inclúe outros rexistros de provedores específicos do dispositivo en informes de erros; pode conter información privada, consumir máis batería e ocupar máis espazo almacenamento"</string>
+ <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inclúe outros rexistros de provedores específicos do dispositivo en informes de erros; pode conter información privada, consumir máis batería e ocupar máis espazo de almacenamento"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animación da ventá"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala animación-transición"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala duración animador"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 88e22a1..436ad62 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -406,8 +406,8 @@
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"મેનિફેસ્ટ મૂલ્યોને ધ્યાનમાં લીધા સિવાય, કોઈપણ ઍપને બાહ્ય સ્ટોરેજ પર લખાવા માટે લાયક બનાવે છે"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"પ્રવૃત્તિઓને ફરીથી કદ યોગ્ય થવા માટે ફરજ પાડો"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"મૅનિફેસ્ટ મૂલ્યોને ધ્યાનમાં લીધા સિવાય, તમામ પ્રવૃત્તિઓને મલ્ટી-વિન્ડો માટે ફરીથી કદ બદલી શકે તેવી બનાવો."</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"ફ્રિફોર્મ વિંડોઝ ચાલુ કરો"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"પ્રાયોગિક ફ્રિફોર્મ વિંડોઝ માટે સમર્થનને ચાલુ કરો."</string>
+ <string name="enable_freeform_support" msgid="7599125687603914253">"ફ્રીફોર્મ વિન્ડો ચાલુ કરો"</string>
+ <string name="enable_freeform_support_summary" msgid="1822862728719276331">"પ્રાયોગિક ફ્રીફોર્મ વિન્ડો માટે સપોર્ટને ચાલુ કરો."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"ડેસ્કટૉપ બૅકઅપ પાસવર્ડ"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"ડેસ્કટૉપ સંપૂર્ણ બૅકઅપ હાલમાં સુરક્ષિત નથી"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"ડેસ્કટૉપ સંપૂર્ણ બેકઅપ્સ માટેનો પાસવર્ડ બદલવા અથવા દૂર કરવા માટે ટૅચ કરો"</string>
diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml
index 4fd8d64..7194502 100644
--- a/packages/SettingsLib/res/values-hi/arrays.xml
+++ b/packages/SettingsLib/res/values-hi/arrays.xml
@@ -55,7 +55,7 @@
</string-array>
<string-array name="hdcp_checking_summaries">
<item msgid="4045840870658484038">"कभी भी HDCP जाँच का उपयोग न करें"</item>
- <item msgid="8254225038262324761">"HDCP जांच का उपयोग सिर्फ़ डीआरएम कॉन्टेंट के लिए करें"</item>
+ <item msgid="8254225038262324761">"HDCP जांच का इस्तेमाल सिर्फ़ डीआरएम कॉन्टेंट के लिए करें"</item>
<item msgid="6421717003037072581">"हमेशा HDCP जाँच का उपयोग करें"</item>
</string-array>
<string-array name="bt_hci_snoop_log_entries">
@@ -64,7 +64,7 @@
<item msgid="2779123106632690576">"चालू है"</item>
</string-array>
<string-array name="bluetooth_avrcp_versions">
- <item msgid="6603880723315236832">"एवीआरसीपी 1.5 (डिफ़ॉल्ट)"</item>
+ <item msgid="6603880723315236832">"AVRCP 1.5 (डिफ़ॉल्ट)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
<item msgid="5896162189744596291">"एवीआरसीपी 1.4"</item>
<item msgid="7556896992111771426">"AVRCP 1.6"</item>
@@ -133,7 +133,7 @@
<item msgid="927546067692441494">"स्टीरियो"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_channel_mode_summaries">
- <item msgid="1997302811102880485">"सिस्टम चुनाव का उपयोग करें (डिफ़ॉल्ट)"</item>
+ <item msgid="1997302811102880485">"सिस्टम से चुने जाने का इस्तेमाल करें (डिफ़ॉल्ट)"</item>
<item msgid="8005696114958453588">"मोनो"</item>
<item msgid="1333279807604675720">"स्टीरियो"</item>
</string-array>
@@ -173,7 +173,7 @@
<item msgid="409235464399258501">"बंद"</item>
<item msgid="4195153527464162486">"64K प्रति लॉग बफ़र"</item>
<item msgid="7464037639415220106">"256K प्रति लॉग बफ़र"</item>
- <item msgid="8539423820514360724">"1 एमबी प्रति लॉग बफ़र"</item>
+ <item msgid="8539423820514360724">"1M प्रति लॉग बफ़र"</item>
<item msgid="1984761927103140651">"4M प्रति लॉग बफ़र"</item>
<item msgid="2983219471251787208">"8 एमबी प्रति लॉग बफ़र"</item>
</string-array>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 859c876..01e6617 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -234,7 +234,7 @@
<string name="apn_settings_not_available" msgid="1147111671403342300">"ऐक्सेस पॉइंट के नाम की सेटिंग इस उपयोगकर्ता के लिए मौजूद नहीं हैं"</string>
<string name="enable_adb" msgid="8072776357237289039">"यूएसबी डीबग करना"</string>
<string name="enable_adb_summary" msgid="3711526030096574316">"डीबग मोड जब यूएसबी कनेक्ट किया गया हो"</string>
- <string name="clear_adb_keys" msgid="3010148733140369917">"यूएसबी डीबग करने की मंज़ूरी रद्द करें"</string>
+ <string name="clear_adb_keys" msgid="3010148733140369917">"यूएसबी डीबग करने की मंज़ूरी निरस्त करें"</string>
<string name="enable_adb_wireless" msgid="6973226350963971018">"वॉयरलेस डीबगिंग"</string>
<string name="enable_adb_wireless_summary" msgid="7344391423657093011">"डिवाइस के वाई-फ़ाई से कनेक्ट हाेने पर, डीबग मोड चालू करें"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"गड़बड़ी"</string>
@@ -267,35 +267,35 @@
<string name="bugreport_in_power_summary" msgid="1885529649381831775">"गड़बड़ी की रिपोर्ट लेने के लिए पावर मेन्यू में कोई बटन दिखाएं"</string>
<string name="keep_screen_on" msgid="1187161672348797558">"स्क्रीन को चालू रखें"</string>
<string name="keep_screen_on_summary" msgid="1510731514101925829">"चार्ज करते समय स्क्रीन कभी भी कम बैटरी मोड में नहीं जाएगी"</string>
- <string name="bt_hci_snoop_log" msgid="7291287955649081448">"ब्लूटूथ एचसीआई स्नूप लॉग चालू करें"</string>
+ <string name="bt_hci_snoop_log" msgid="7291287955649081448">"ब्लूटूथ HCI स्नूप लॉग चालू करें"</string>
<string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"ब्लूटूथ पैकेट कैप्चर करें. (यह सेटिंग बदलने के बाद ब्लूटूथ टॉगल करें)"</string>
<string name="oem_unlock_enable" msgid="5334869171871566731">"OEM अनलॉक करना"</string>
<string name="oem_unlock_enable_summary" msgid="5857388174390953829">"बूटलोडर को अनलाॅक किए जाने की अनुमति दें"</string>
<string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"OEM अनलॉक करने की अनुमति दें?"</string>
<string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"चेतावनी: इस सेटिंग के चालू रहने पर डिवाइस सुरक्षा सुविधाएं इस डिवाइस पर काम नहीं करेंगी."</string>
- <string name="mock_location_app" msgid="6269380172542248304">"जगह की नकली जानकारी देने के लिए ऐप चुनें"</string>
- <string name="mock_location_app_not_set" msgid="6972032787262831155">"जगह की नकली जानकारी देने के लिए ऐप सेट नहीं है"</string>
- <string name="mock_location_app_set" msgid="4706722469342913843">"जगह की नकली जानकारी देने वाला ऐप: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="mock_location_app" msgid="6269380172542248304">"जगह की दिखावटी जानकारी देने के लिए ऐप्लिकेशन चुनें"</string>
+ <string name="mock_location_app_not_set" msgid="6972032787262831155">"जगह की दिखावटी जानकारी देने के लिए ऐप सेट नहीं है"</string>
+ <string name="mock_location_app_set" msgid="4706722469342913843">"जगह की दिखावटी जानकारी देने वाला ऐप: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="debug_networking_category" msgid="6829757985772659599">"नेटवर्किंग"</string>
<string name="wifi_display_certification" msgid="1805579519992520381">"वायरलेस डिसप्ले सर्टिफ़िकेशन"</string>
<string name="wifi_verbose_logging" msgid="1785910450009679371">"वाई-फ़ाई वर्बोस लॉगिंग चालू करें"</string>
- <string name="wifi_scan_throttling" msgid="2985624788509913617">"वाई-फ़ाई के लिए स्कैन की संख्या कम करें"</string>
+ <string name="wifi_scan_throttling" msgid="2985624788509913617">"वाई-फ़ाई के लिए स्कैन थ्रॉटलिंग करें"</string>
<string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"थोड़े समय के लिए वाई-फ़ाई नेटवर्क से जुड़ने पर MAC पता बदलने की सुविधा"</string>
<string name="mobile_data_always_on" msgid="8275958101875563572">"मोबाइल डेटा हमेशा चालू"</string>
<string name="tethering_hardware_offload" msgid="4116053719006939161">"हार्डवेयर से तेज़ी लाने के लिए टेदर करें"</string>
<string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"बिना नाम वाले ब्लूटूथ डिवाइस दिखाएं"</string>
<string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"ब्लूटूथ से आवाज़ के कंट्रोल की सुविधा रोकें"</string>
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche चालू करें"</string>
- <string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"ब्लूटूथ एवीआरसीपी वर्शन"</string>
+ <string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"ब्लूटूथ AVRCP वर्शन"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"ब्लूटूथ AVRCP वर्शन चुनें"</string>
<string name="bluetooth_select_map_version_string" msgid="526308145174175327">"ब्लूटूथ का MAP वर्शन"</string>
<string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"ब्लूटूथ का MAP वर्शन चुनें"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"ब्लूटूथ ऑडियो कोडेक"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"ब्लूटूथ ऑडियो कोडेक का\nविकल्प चालू करें"</string>
- <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"ब्लूटूथ ऑडियो नमूना दर"</string>
+ <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"ब्लूटूथ ऑडियो सैंपल रेट"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5876305103137067798">"ब्लूटूथ ऑडियो कोडेक का\nयह विकल्प चालू करें: सैंपल की दर"</string>
<string name="bluetooth_select_a2dp_codec_type_help_info" msgid="8647200416514412338">"धूसर किया गया का मतलब है कि फ़ोन या हेडसेट पर काम नहीं करता"</string>
- <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="6253965294594390806">"ब्लूटूथ ऑडियो बिट प्रति नमूना"</string>
+ <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="6253965294594390806">"हर सैंपल के लिए ब्लूटूथ ऑडियो बिट"</string>
<string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4898693684282596143">"ब्लूटूथ ऑडियो कोडेक का\nयह विकल्प चालू करें: हर सैंपल के लिए बिट की संख्या"</string>
<string name="bluetooth_select_a2dp_codec_channel_mode" msgid="364277285688014427">"ब्लूटूथ ऑडियो चैनल मोड"</string>
<string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"ब्लूटूथ ऑडियो कोडेक का\nयह विकल्प चालू करें: चैनल मोड"</string>
@@ -310,12 +310,12 @@
<string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"डीएनएस सेवा देने वाले का होस्टनाम डालें"</string>
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"कनेक्ट नहीं हो सका"</string>
<string name="wifi_display_certification_summary" msgid="8111151348106907513">"वायरलेस डिसप्ले सर्टिफ़िकेशन के विकल्प दिखाएं"</string>
- <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"वाई-फ़ाई लॉगिंग का स्तर बढ़ाएं, वाई-फ़ाई पिकर में प्रति SSID RSSI दिखाएं"</string>
+ <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"वाई-फ़ाई लॉगिंग लेवल बढ़ाएं, वाई-फ़ाई पिकर में हर SSID के लिए RSSI दिखाएं"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"बैटरी की खपत कम और नेटवर्क की परफ़ॉर्मेंस बेहतर होती है"</string>
<string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"जब यह मोड चालू होता है, तब नेटवर्क से कनेक्ट होने पर हर बार इस डिवाइस का MAC पता बदल सकता है. ऐसा तब होता है, जब डिवाइस किसी ऐसे नेटवर्क से जुड़ता है जिस पर MAC पता बदलने की सुविधा चालू होती है."</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"डेटा इस्तेमाल करने की सीमा तय की गई है"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"डेटा इस्तेमाल करने की सीमा तय नहीं की गई है"</string>
- <string name="select_logd_size_title" msgid="1604578195914595173">"लॉगर बफ़र आकार"</string>
+ <string name="select_logd_size_title" msgid="1604578195914595173">"लॉगर बफ़र साइज़"</string>
<string name="select_logd_size_dialog_title" msgid="2105401994681013578">"प्रति लॉग बफ़र लॉगर आकार चुनें"</string>
<string name="dev_logpersist_clear_warning_title" msgid="8631859265777337991">"लॉगर सतत मेमोरी साफ़ करें?"</string>
<string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"जब हम सतत लॉगर के साथ निगरानी करना बंद कर देते हैं, तो हमें आपके डिवाइस पर मौजूद लॉगर डेटा को मिटाने की आवश्यकता होती है."</string>
@@ -336,7 +336,7 @@
<string name="dev_settings_warning_title" msgid="8251234890169074553">"विकास सेटिंग की अनुमति दें?"</string>
<string name="dev_settings_warning_message" msgid="37741686486073668">"ये सेटिंग केवल विकास संबंधी उपयोग के प्रयोजन से हैं. वे आपके डिवाइस और उस पर स्थित ऐप्लिकेशन को खराब कर सकती हैं या उनके दुर्व्यवहार का कारण हो सकती हैं."</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"यूएसबी पर ऐप्लिकेशन की पुष्टि करें"</string>
- <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"नुकसानदेह व्यवहार के लिए ADB/ADT से इंस्टॉल किए गए ऐप्लिकेशन जांचें."</string>
+ <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"नुकसान पहुंचाने वाली गतिविधियों के लिए ADB/ADT से इंस्टॉल किए गए ऐप्लिकेशन जांचें."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"बिना नाम वाले ब्लूटूथ डिवाइस (सिर्फ़ MAC पते वाले) दिखाए जाएंगे"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"दूर के डिवाइस पर आवाज़ बहुत बढ़ जाने या उससे कंट्रोल हटने जैसी समस्याएं होने पर, यह ब्लूटूथ के ज़रिए आवाज़ के कंट्रोल की सुविधा रोक देता है."</string>
<string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"ब्लूटूथ सेटिंग में Gabeldorsche सुविधा को चालू करता है."</string>
@@ -358,14 +358,14 @@
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"हार्डवेयर ऐक्सेलरेटेड रेंडरिंग"</string>
<string name="media_category" msgid="8122076702526144053">"मीडिया"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"निगरानी"</string>
- <string name="strict_mode" msgid="889864762140862437">"सख्त मोड चालू किया गया"</string>
+ <string name="strict_mode" msgid="889864762140862437">"स्ट्रिक्ट मोड चालू किया गया"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"थ्रेड पर लंबा प्रोसेस होने पर स्क्रीन फ़्लैश करें"</string>
<string name="pointer_location" msgid="7516929526199520173">"पॉइंटर की जगह"</string>
<string name="pointer_location_summary" msgid="957120116989798464">"मौजूदा टच डेटा दिखाने वाला स्क्रीन ओवरले"</string>
<string name="show_touches" msgid="8437666942161289025">"टैप दिखाएं"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"टैप के लिए विज़ुअल फ़ीडबैक दिखाएं"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"सर्फ़ेस अपडेट दिखाएं"</string>
- <string name="show_screen_updates_summary" msgid="2126932969682087406">"अपडेट होने पर पूरे विंडो सर्फ़ेस को फ़्लैश करें"</string>
+ <string name="show_screen_updates_summary" msgid="2126932969682087406">"अपडेट होने पर पूरे विंडो सर्फ़ेस फ़्लैश करें"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"जीपीयू व्यू के अपडेट दिखाएं"</string>
<string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"GPU से बनाए गए व्यू, विंडो में फ़्लैश करता है"</string>
<string name="show_hw_layers_updates" msgid="5268370750002509767">"हार्डवेयर लेयर अपडेट दिखाएं"</string>
@@ -376,7 +376,7 @@
<string name="simulate_color_space" msgid="1206503300335835151">"रंग स्पेस सिम्युलेट करें"</string>
<string name="enable_opengl_traces_title" msgid="4638773318659125196">"OpenGL ट्रेस चालू करें"</string>
<string name="usb_audio_disable_routing" msgid="3367656923544254975">"यूएसबी ऑडियो रूटिंग बंद करें"</string>
- <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"यूएसबी ऑडियो पेरिफ़ेरल पर अपने-आप रूटिंग बंद करें"</string>
+ <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"यूएसबी ऑडियो पेरिफ़ेरल पर अपने-आप रूटिंग होना बंद करें"</string>
<string name="debug_layout" msgid="1659216803043339741">"लेआउट सीमाएं दिखाएं"</string>
<string name="debug_layout_summary" msgid="8825829038287321978">"क्लिप सीमाएं, मार्जिन वगैरह दिखाएं."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"लेआउट की दिशा दाएं से बाएं करें"</string>
@@ -389,7 +389,7 @@
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"जीपीयू डीबग लेयर चालू करें"</string>
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"डीबग ऐप के लिए जीपीयू डीबग लेयर लोड करने दें"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"वर्बोस वेंडर लॉगिंग चालू करें"</string>
- <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"गड़बड़ियों की रिपोर्ट में खास डिवाइस से जुड़े वेंडर लॉग शामिल करें. इन लॉग में निजी जानकारी, बैटरी का ज़्यादा इस्तेमाल, और/या डिवाइस की मेमोरी ज़्यादा इस्तेमाल करने की जानकारी हो सकती है."</string>
+ <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"गड़बड़ियों की रिपोर्ट में खास डिवाइस से जुड़े वेंडर लॉग शामिल करें. इन लॉग में निजी जानकारी, बैटरी का ज़्यादा इस्तेमाल, और/या डिवाइस का स्टोरेज ज़्यादा इस्तेमाल करने की जानकारी हो सकती है."</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"विंडो एनिमेशन स्केल"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ट्रांज़िशन एनिमेशन स्केल"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"एनिमेटर अवधि स्केल"</string>
@@ -401,11 +401,11 @@
<string name="show_all_anrs" msgid="9160563836616468726">"बैकग्राउंड के ANRs दिखाएं"</string>
<string name="show_all_anrs_summary" msgid="8562788834431971392">"बैकग्राउंड में चलने वाले ऐप्लिकेशन के लिए, \'यह ऐप्लिकेशन नहीं चल रहा\' मैसेज दिखाएं"</string>
<string name="show_notification_channel_warnings" msgid="3448282400127597331">"सूचना चैनल चेतावनी दिखाएं"</string>
- <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"ऐप्लिकेशन, मान्य चैनल के बिना सूचना पोस्ट करे तो स्क्रीन पर चेतावनी दिखाएं"</string>
- <string name="force_allow_on_external" msgid="9187902444231637880">"ऐप्लिकेशन को बाहरी मेमोरी पर ही चलाएं"</string>
- <string name="force_allow_on_external_summary" msgid="8525425782530728238">"इससे कोई भी ऐप्लिकेशन बाहरी मेमोरी में रखने लायक बन जाता है चाहे उसकी मेनिफ़ेस्ट वैल्यू कुछ भी हो"</string>
- <string name="force_resizable_activities" msgid="7143612144399959606">"विंडो के हिसाब से गतिविधियों का आकार बदल दें"</string>
- <string name="force_resizable_activities_summary" msgid="2490382056981583062">"सभी गतिविधियों को मल्टी-विंडो (एक से ज़्यादा ऐप्लिकेशन, एक साथ) के लिए आकार बदलने लायक बनाएं, चाहे उनकी मेनिफ़ेस्ट वैल्यू कुछ भी हो."</string>
+ <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"कोई ऐप, मान्य चैनल के बिना सूचना पोस्ट करे, तो स्क्रीन पर चेतावनी दिखाएं"</string>
+ <string name="force_allow_on_external" msgid="9187902444231637880">"ऐप्लिकेशन को बाहरी स्टोरेज पर ही चलाएं"</string>
+ <string name="force_allow_on_external_summary" msgid="8525425782530728238">"इससे कोई भी ऐप्लिकेशन बाहरी स्टोरेज में रखने लायक बन जाता है, चाहे उसकी मेनिफ़ेस्ट वैल्यू कुछ भी हो"</string>
+ <string name="force_resizable_activities" msgid="7143612144399959606">"विंडो के हिसाब से गतिविधियों का साइज़ बदल दें"</string>
+ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"सभी गतिविधियों को मल्टी-विंडो (एक से ज़्यादा ऐप्लिकेशन, एक साथ) के लिए साइज़ बदलने लायक बनाएं, चाहे उनकी मेनिफ़ेस्ट वैल्यू कुछ भी हो."</string>
<string name="enable_freeform_support" msgid="7599125687603914253">"फ़्रीफ़ॉर्म विंडो (एक साथ कई विंडो दिखाना) चालू करें"</string>
<string name="enable_freeform_support_summary" msgid="1822862728719276331">"जांच के लिए बनी फ़्रीफ़ॉर्म विंडो के लिए सहायता चालू करें."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"डेस्कटॉप बैक अप पासवर्ड"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 369406f..fdf14b3 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -389,7 +389,7 @@
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Omogući slojeve za otklanjanje pogrešaka GPU-a"</string>
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Omogućite učitavanje slojeva za otklanjanje pogrešaka GPU-a za aplikacije za otklanjanje pogrešaka"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Omogući opširni zapisnik"</string>
- <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Uključite dodatne zapisnike dobavljača pojedinog uređaja u izvješća o programskoj pogrešci koja mogu sadržavati privatne podatke, trošiti više baterije i/ili zauzeti više prostora za pohranu."</string>
+ <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Uključite dodatne zapisnike dobavljača pojedinog uređaja u izvješća o programskim pogreškama koja mogu sadržavati privatne podatke, trošiti više baterije i/ili zauzeti više prostora za pohranu."</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Brzina animacije prozora"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Brzina animacije prijelaza"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Razmjer duljine animatora"</string>
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"Skeniraj QR kôd"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"Da biste počeli slušati, centrirajte QR kôd u nastavku"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"QR kôd nije u važećem formatu"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Zaustaviti emitiranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, vaše će se trenutačno emitiranje zaustaviti"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Emitiranje aplikacije <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Promjena izlaza"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index 314b1bb..6349e53 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -55,7 +55,7 @@
</string-array>
<string-array name="hdcp_checking_summaries">
<item msgid="4045840870658484038">"Jangan gunakan pemeriksaan HDCP"</item>
- <item msgid="8254225038262324761">"Gunakan pemeriksaan HDCP untuk konten DRM saja"</item>
+ <item msgid="8254225038262324761">"Menggunakan pemeriksaan HDCP untuk konten DRM saja"</item>
<item msgid="6421717003037072581">"Selalu gunakan pemeriksaan HDCP"</item>
</string-array>
<string-array name="bt_hci_snoop_log_entries">
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 3bad8e8..bf95284 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -264,7 +264,7 @@
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Harap sambungkan ke jaringan Wi-Fi"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"Pintasan laporan bug"</string>
- <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Tampilkan tombol di menu daya untuk mengambil laporan bug"</string>
+ <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Menampilkan tombol di menu daya untuk mengambil laporan bug"</string>
<string name="keep_screen_on" msgid="1187161672348797558">"Tetap terjaga"</string>
<string name="keep_screen_on_summary" msgid="1510731514101925829">"Layar tidak akan redup selama mengisi daya"</string>
<string name="bt_hci_snoop_log" msgid="7291287955649081448">"Aktifkan log pengintaian HCI Bluetooth"</string>
@@ -309,8 +309,8 @@
<string name="private_dns_mode_provider" msgid="3619040641762557028">"Hostname penyedia DNS pribadi"</string>
<string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Masukkan hostname penyedia DNS"</string>
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Tidak dapat terhubung"</string>
- <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Tampilkan opsi untuk sertifikasi layar nirkabel"</string>
- <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Tingkatkan level pencatatan log Wi-Fi, tampilkan per SSID RSSI di Pemilih Wi‑Fi"</string>
+ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Menampilkan opsi untuk sertifikasi tampilan nirkabel"</string>
+ <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Meningkatkan level pencatatan log Wi-Fi, menampilkan per SSID RSSI di Pemilih Wi‑Fi"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Memperlambat kehabisan baterai & meningkatkan performa jaringan"</string>
<string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Jika mode ini diaktifkan, alamat MAC perangkat ini dapat berubah setiap kali terhubung ke jaringan yang mengaktifkan pengacakan MAC."</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"Berbayar"</string>
@@ -326,8 +326,8 @@
<string name="allow_mock_location" msgid="2102650981552527884">"Mengizinkan lokasi palsu"</string>
<string name="allow_mock_location_summary" msgid="179780881081354579">"Mengizinkan lokasi palsu"</string>
<string name="debug_view_attributes" msgid="3539609843984208216">"Aktifkan inspeksi atribut tampilan"</string>
- <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Selalu aktifkan kuota, meski Wi-Fi aktif (agar jaringan beralih dengan cepat)."</string>
- <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Gunakan akselerasi hardware tethering jika tersedia"</string>
+ <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Selalu mengaktifkan data seluler, meskipun Wi-Fi aktif (agar jaringan beralih dengan cepat)."</string>
+ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Menggunakan akselerasi hardware tethering jika tersedia"</string>
<string name="adb_warning_title" msgid="7708653449506485728">"Izinkan melakukan debug USB?"</string>
<string name="adb_warning_message" msgid="8145270656419669221">"Debugging USB dimaksudkan untuk tujuan pengembangan saja. Gunakan untuk menyalin data antara komputer dan perangkat Anda, memasang apl pada perangkat tanpa notifikasi, dan membaca data log."</string>
<string name="adbwifi_warning_title" msgid="727104571653031865">"Izinkan proses debug nirkabel?"</string>
@@ -336,7 +336,7 @@
<string name="dev_settings_warning_title" msgid="8251234890169074553">"Izinkan setelan pengembangan?"</string>
<string name="dev_settings_warning_message" msgid="37741686486073668">"Setelan ini hanya dimaksudkan untuk penggunaan pengembangan. Setelan dapat menyebabkan perangkat dan aplikasi yang menerapkannya rusak atau tidak berfungsi semestinya."</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Verifikasi aplikasi melalui USB"</string>
- <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Periksa perilaku membahayakan dalam aplikasi yang terpasang melalui ADB/ADT."</string>
+ <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Memeriksa perilaku berbahaya dalam aplikasi yang diinstal melalui ADB/ADT."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Perangkat Bluetooth tanpa nama (hanya alamat MAC) akan ditampilkan"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Menonaktifkan fitur volume absolut Bluetooth jika ada masalah volume dengan perangkat jarak jauh, misalnya volume terlalu keras atau kurangnya kontrol."</string>
<string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Mengaktifkan stack fitur Gabeldorsche Bluetooth."</string>
@@ -359,13 +359,13 @@
<string name="media_category" msgid="8122076702526144053">"Media"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Memantau"</string>
<string name="strict_mode" msgid="889864762140862437">"Mode ketat diaktifkan"</string>
- <string name="strict_mode_summary" msgid="1838248687233554654">"Kedipkan layar saat apl beroperasi lama pada utas utama"</string>
+ <string name="strict_mode_summary" msgid="1838248687233554654">"Mengedipkan layar saat apl berjalan lama di utas utama"</string>
<string name="pointer_location" msgid="7516929526199520173">"Lokasi penunjuk"</string>
- <string name="pointer_location_summary" msgid="957120116989798464">"Hamparan layar menampilkan data sentuhan saat ini"</string>
+ <string name="pointer_location_summary" msgid="957120116989798464">"Overlay layar menampilkan data sentuhan saat ini"</string>
<string name="show_touches" msgid="8437666942161289025">"Tampilkan ketukan"</string>
- <string name="show_touches_summary" msgid="3692861665994502193">"Tampilkan efek visual untuk ketukan"</string>
+ <string name="show_touches_summary" msgid="3692861665994502193">"Menampilkan efek visual untuk ketukan"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"Lihat pembaruan permukaan"</string>
- <string name="show_screen_updates_summary" msgid="2126932969682087406">"Sorot seluruh permukaan jendela saat diperbarui"</string>
+ <string name="show_screen_updates_summary" msgid="2126932969682087406">"Mengedipkan seluruh permukaan jendela saat diperbarui"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"Tampilkan update tampilan"</string>
<string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"Tampilan cepat dalam jendela saat digambar"</string>
<string name="show_hw_layers_updates" msgid="5268370750002509767">"Tunjukkan update lapisan hardware"</string>
@@ -375,39 +375,39 @@
<string name="disable_overlays_summary" msgid="1954852414363338166">"Selalu gunakan GPU untuk pengomposisian layar"</string>
<string name="simulate_color_space" msgid="1206503300335835151">"Simulasikan ruang warna"</string>
<string name="enable_opengl_traces_title" msgid="4638773318659125196">"Aktifkan jejak OpenGL"</string>
- <string name="usb_audio_disable_routing" msgid="3367656923544254975">"Pemilihan rute audio USB nonaktif"</string>
- <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"Pemilihan rute otomatis ke periferal audio USB nonaktif"</string>
+ <string name="usb_audio_disable_routing" msgid="3367656923544254975">"Nonaktifkan pemilihan rute audio USB"</string>
+ <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"Menonaktifkan pemilihan rute otomatis ke periferal audio USB"</string>
<string name="debug_layout" msgid="1659216803043339741">"Tampilkan batas tata letak"</string>
- <string name="debug_layout_summary" msgid="8825829038287321978">"Tampilkan batas klip, margin, dll."</string>
+ <string name="debug_layout_summary" msgid="8825829038287321978">"Menampilkan batas klip, margin, dll."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Paksa arah tata letak RTL"</string>
- <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Paksa arah tata letak layar RTL untuk semua lokal"</string>
+ <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Memaksa arah tata letak layar RTL untuk semua lokalitas"</string>
<string name="window_blurs" msgid="6831008984828425106">"Izinkan buram level jendela"</string>
<string name="force_msaa" msgid="4081288296137775550">"Paksa 4x MSAA"</string>
- <string name="force_msaa_summary" msgid="9070437493586769500">"Aktifkan 4x MSAA dalam aplikasi OpenGL ES 2.0"</string>
+ <string name="force_msaa_summary" msgid="9070437493586769500">"Mengaktifkan 4x MSAA dalam aplikasi OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Debug operasi klip non-kotak"</string>
<string name="track_frame_time" msgid="522674651937771106">"Rendering HWUI profil"</string>
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Aktifkan lapisan debug GPU"</string>
- <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Izinkan memuat lapisan debug GPU untuk aplikasi debug"</string>
+ <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Mengizinkan lapisan debug GPU dimuat di apl debug"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktifkan logging vendor panjang"</string>
- <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sertakan log vendor khusus perangkat tambahan dalam laporan bug, yang mungkin berisi informasi pribadi, menggunakan lebih banyak baterai, dan/atau menggunakan lebih banyak ruang penyimpanan."</string>
+ <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Menyertakan log vendor khusus perangkat tambahan dalam laporan bug, yang mungkin berisi informasi pribadi, menggunakan lebih banyak baterai, dan/atau menggunakan lebih banyak ruang penyimpanan."</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Skala animasi jendela"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animasi transisi"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala durasi animator"</string>
<string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulasikan tampilan sekunder"</string>
<string name="debug_applications_category" msgid="5394089406638954196">"Aplikasi"</string>
<string name="immediately_destroy_activities" msgid="1826287490705167403">"Jangan simpan aktivitas"</string>
- <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Hancurkan tiap aktivitas setelah ditinggal pengguna"</string>
+ <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Menghancurkan aktivitas setelah apl ditutup"</string>
<string name="app_process_limit_title" msgid="8361367869453043007">"Batas proses latar blkng"</string>
<string name="show_all_anrs" msgid="9160563836616468726">"Tampilkan ANR latar blkng"</string>
- <string name="show_all_anrs_summary" msgid="8562788834431971392">"Tampilkan dialog Aplikasi Tidak Merespons untuk aplikasi yang ada di latar belakang"</string>
+ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Menampilkan dialog Aplikasi Tidak Merespons untuk aplikasi yang ada di latar belakang"</string>
<string name="show_notification_channel_warnings" msgid="3448282400127597331">"Tampilkan peringatan saluran notifikasi"</string>
<string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Menampilkan peringatan di layar saat aplikasi memposting notifikasi tanpa channel yang valid"</string>
<string name="force_allow_on_external" msgid="9187902444231637880">"Paksa izinkan aplikasi di eksternal"</string>
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Membuat semua aplikasi dapat ditulis ke penyimpanan eksternal, terlepas dari nilai manifes"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Paksa aktivitas agar ukurannya dapat diubah"</string>
- <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Buat semua aktivitas dapat diubah ukurannya untuk banyak jendela, terlepas dari nilai manifes."</string>
+ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Membuat semua aktivitas dapat diubah ukurannya untuk banyak jendela, terlepas dari nilai manifes."</string>
<string name="enable_freeform_support" msgid="7599125687603914253">"Aktifkan jendela berformat bebas"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktifkan dukungan untuk jendela eksperimental berformat bebas."</string>
+ <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Mengaktifkan dukungan untuk jendela eksperimental berformat bebas."</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Sandi cadangan desktop"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Saat ini cadangan desktop penuh tidak dilindungi"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ketuk guna mengubah atau menghapus sandi untuk cadangan lengkap desktop"</string>
@@ -448,7 +448,7 @@
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomali (merah-hijau)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomali (biru-kuning)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Koreksi warna"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Koreksi warna dapat berguna jika Anda ingin:<br/> <ol> <li>&nbsp;Melihat warna dengan lebih akurat</li> <li>&nbsp;Menghapus warna untuk membantu Anda fokus</li> </ol>"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Koreksi warna dapat berguna jika Anda ingin:<br/> <ol> <li> Melihat warna dengan lebih akurat</li> <li> Menghapus warna agar Anda lebih fokus</li> </ol>"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Digantikan oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Sekitar <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi"</string>
@@ -653,14 +653,10 @@
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Izinkan pengaktifan layar"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Mengizinkan aplikasi mengaktifkan layar. Jika diizinkan, aplikasi dapat mengaktifkan layar kapan saja tanpa izin Anda."</string>
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"Pindai kode QR"</string>
- <string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"Untuk mulai mendengarkan, fokuskan kode QR berikut"</string>
+ <string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"Untuk mulai mendengarkan, pusatkan kode QR"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"Format kode QR tidak valid"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Hentikan siaran <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Jika Anda menyiarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g> atau mengubah output, siaran saat ini akan dihentikan"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Ubah output"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index c80e290..f908291 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -312,7 +312,7 @@
<string name="wifi_display_certification_summary" msgid="8111151348106907513">"Mostra opzioni per la certificazione display wireless"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Aumenta livello di logging Wi-Fi, mostra SSID RSSI nel selettore Wi-Fi"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Riduce il consumo della batteria e migliora le prestazioni della rete"</string>
- <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Quando questa modalità è attiva, l\'indirizzo MAC del dispositivo potrebbe cambiare ogni volta che il dispositivo si connette a una rete con randomizzazione degli indirizzi MAC attiva."</string>
+ <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Quando questa modalità è attiva, l\'indirizzo MAC del dispositivo potrebbe cambiare ogni volta che il dispositivo si connette a una rete con randomizzazione degli indirizzi MAC attiva"</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"A consumo"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"Non a consumo"</string>
<string name="select_logd_size_title" msgid="1604578195914595173">"Dimensioni buffer logger"</string>
@@ -359,17 +359,17 @@
<string name="media_category" msgid="8122076702526144053">"Contenuti multimediali"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"Monitoraggio"</string>
<string name="strict_mode" msgid="889864762140862437">"Attiva StrictMode"</string>
- <string name="strict_mode_summary" msgid="1838248687233554654">"Schermo lampeggia per operazioni lunghe su thread principale"</string>
+ <string name="strict_mode_summary" msgid="1838248687233554654">"Fai lampeggiare lo schermo per operazioni lunghe sul thread principale"</string>
<string name="pointer_location" msgid="7516929526199520173">"Posizione puntatore"</string>
<string name="pointer_location_summary" msgid="957120116989798464">"Overlay schermo che mostra i dati touch correnti"</string>
<string name="show_touches" msgid="8437666942161289025">"Mostra tocchi"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"Mostra feedback visivi per i tocchi"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"Aggiornamenti superficie"</string>
- <string name="show_screen_updates_summary" msgid="2126932969682087406">"Superfici delle finestre lampeggiano se aggiornate"</string>
+ <string name="show_screen_updates_summary" msgid="2126932969682087406">"Fai lampeggiare le superfici delle finestre quando si aggiornano"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"Aggiornam. visualizzazione"</string>
- <string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"Visualizz. lampeggiano dentro finestre se disegnate"</string>
+ <string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"Fai lampeggiare gli elementi nelle finestre se disegnati"</string>
<string name="show_hw_layers_updates" msgid="5268370750002509767">"Aggiornam. livelli hardware"</string>
- <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Livelli hardware lampeggiano in verde se aggiornati"</string>
+ <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Fai lampeggiare in verde i livelli hardware se aggiornati"</string>
<string name="debug_hw_overdraw" msgid="8944851091008756796">"Debug overdraw GPU"</string>
<string name="disable_overlays" msgid="4206590799671557143">"Disabilita overlay HW"</string>
<string name="disable_overlays_summary" msgid="1954852414363338166">"Usa sempre GPU per la composizione dello schermo"</string>
@@ -405,9 +405,9 @@
<string name="force_allow_on_external" msgid="9187902444231637880">"Forza autorizzazione app su memoria esterna"</string>
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Consente l\'installazione di qualsiasi app su memoria esterna, indipendentemente dai valori manifest"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Imponi formato modificabile alle attività"</string>
- <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Rendi il formato di tutte le attività modificabile per la modalità multi-finestra, indipendentemente dai valori manifest."</string>
+ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Rendi il formato di tutte le attività modificabile per la modalità multi-finestra, indipendentemente dai valori manifest"</string>
<string name="enable_freeform_support" msgid="7599125687603914253">"Attiva finestre a forma libera"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Attiva il supporto delle finestre a forma libera sperimentali."</string>
+ <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Attiva il supporto delle finestre a forma libera sperimentali"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Password di backup desktop"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"I backup desktop completi non sono attualmente protetti"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tocca per modificare o rimuovere la password per i backup desktop completi"</string>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index 110e72b..ad84d9e 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -191,30 +191,30 @@
</string-array>
<string-array name="window_animation_scale_entries">
<item msgid="2675263395797191850">"アニメーションオフ"</item>
- <item msgid="5790132543372767872">"アニメーションスケール.5x"</item>
- <item msgid="2529692189302148746">"アニメーションスケール1x"</item>
- <item msgid="8072785072237082286">"アニメーションスケール1.5x"</item>
- <item msgid="3531560925718232560">"アニメーションスケール2x"</item>
- <item msgid="4542853094898215187">"アニメーションスケール5x"</item>
- <item msgid="5643881346223901195">"アニメーションスケール10x"</item>
+ <item msgid="5790132543372767872">"アニメーション スケール .5x"</item>
+ <item msgid="2529692189302148746">"アニメーション スケール 1x"</item>
+ <item msgid="8072785072237082286">"アニメーション スケール 1.5x"</item>
+ <item msgid="3531560925718232560">"アニメーション スケール 2x"</item>
+ <item msgid="4542853094898215187">"アニメーション スケール 5x"</item>
+ <item msgid="5643881346223901195">"アニメーション スケール 10x"</item>
</string-array>
<string-array name="transition_animation_scale_entries">
<item msgid="3376676813923486384">"アニメーションオフ"</item>
- <item msgid="753422683600269114">"アニメーションスケール.5x"</item>
- <item msgid="3695427132155563489">"アニメーションスケール1x"</item>
- <item msgid="9032615844198098981">"アニメーションスケール1.5x"</item>
- <item msgid="8473868962499332073">"アニメーションスケール2x"</item>
- <item msgid="4403482320438668316">"アニメーションスケール5x"</item>
- <item msgid="169579387974966641">"アニメーションスケール10x"</item>
+ <item msgid="753422683600269114">"アニメーション スケール .5x"</item>
+ <item msgid="3695427132155563489">"アニメーション スケール 1x"</item>
+ <item msgid="9032615844198098981">"アニメーション スケール 1.5x"</item>
+ <item msgid="8473868962499332073">"アニメーション スケール 2x"</item>
+ <item msgid="4403482320438668316">"アニメーション スケール 5x"</item>
+ <item msgid="169579387974966641">"アニメーション スケール 10x"</item>
</string-array>
<string-array name="animator_duration_scale_entries">
<item msgid="6416998593844817378">"アニメーションオフ"</item>
- <item msgid="875345630014338616">"アニメーションスケール.5x"</item>
- <item msgid="2753729231187104962">"アニメーションスケール1x"</item>
- <item msgid="1368370459723665338">"アニメーションスケール1.5x"</item>
- <item msgid="5768005350534383389">"アニメーションスケール2x"</item>
- <item msgid="3728265127284005444">"アニメーションスケール5x"</item>
- <item msgid="2464080977843960236">"アニメーションスケール10x"</item>
+ <item msgid="875345630014338616">"アニメーション スケール .5x"</item>
+ <item msgid="2753729231187104962">"アニメーション スケール 1x"</item>
+ <item msgid="1368370459723665338">"アニメーション スケール 1.5x"</item>
+ <item msgid="5768005350534383389">"アニメーション スケール 2x"</item>
+ <item msgid="3728265127284005444">"アニメーション スケール 5x"</item>
+ <item msgid="2464080977843960236">"アニメーション スケール 10x"</item>
</string-array>
<string-array name="overlay_display_devices_entries">
<item msgid="4497393944195787240">"なし"</item>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 770f944..4e769e6 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -236,7 +236,7 @@
<string name="enable_adb_summary" msgid="3711526030096574316">"USB 接続時はデバッグモードにする"</string>
<string name="clear_adb_keys" msgid="3010148733140369917">"USB デバッグの許可の取り消し"</string>
<string name="enable_adb_wireless" msgid="6973226350963971018">"ワイヤレス デバッグ"</string>
- <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Wi-Fi 接続時にデバッグモード"</string>
+ <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Wi-Fi 接続時はデバッグモードにする"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"エラー"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"ワイヤレス デバッグ"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"利用可能なデバイスを確認して使用するには、ワイヤレス デバッグを ON にしてください"</string>
@@ -264,7 +264,7 @@
<string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Wi-Fi ネットワークに接続してください"</string>
<string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, デバッグ, dev"</string>
<string name="bugreport_in_power" msgid="8664089072534638709">"バグレポートのショートカット"</string>
- <string name="bugreport_in_power_summary" msgid="1885529649381831775">"電源ボタン メニューにバグレポートを取得するボタンを表示する"</string>
+ <string name="bugreport_in_power_summary" msgid="1885529649381831775">"電源ボタンメニューにバグレポートを取得するボタンを表示する"</string>
<string name="keep_screen_on" msgid="1187161672348797558">"スリープモードにしない"</string>
<string name="keep_screen_on_summary" msgid="1510731514101925829">"充電中に画面をスリープにしない"</string>
<string name="bt_hci_snoop_log" msgid="7291287955649081448">"Bluetooth HCI スヌープログ"</string>
@@ -336,7 +336,7 @@
<string name="dev_settings_warning_title" msgid="8251234890169074553">"開発用の設定を許可しますか?"</string>
<string name="dev_settings_warning_message" msgid="37741686486073668">"これらの設定は開発専用に設計されています。そのためデバイスやデバイス上のアプリが故障したり正常に動作しなくなったりするおそれがあります。"</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"USB 経由のアプリも検証"</string>
- <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT経由でインストールされたアプリに不正な動作がないかを確認する"</string>
+ <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT 経由でインストールされたアプリに不正な動作がないかを確認する"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth デバイスを名前なしで(MAC アドレスのみで)表示します"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"リモートデバイスで音量に関する問題(音量が大きすぎる、制御できないなど)が発生した場合に、Bluetooth の絶対音量の機能を無効にする"</string>
<string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche 機能スタックを有効にします。"</string>
@@ -364,23 +364,23 @@
<string name="pointer_location_summary" msgid="957120116989798464">"現在のタップデータをオーバーレイ表示する"</string>
<string name="show_touches" msgid="8437666942161289025">"タップを表示"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"タップを視覚表示する"</string>
- <string name="show_screen_updates" msgid="2078782895825535494">"表示面の更新を表示"</string>
+ <string name="show_screen_updates" msgid="2078782895825535494">"表示面の更新を通知"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"更新時にウィンドウの表示面全体を点滅させる"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"画面の更新を表示"</string>
<string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"描画時にウィンドウ内の表示を点滅させる"</string>
<string name="show_hw_layers_updates" msgid="5268370750002509767">"ハードウェア層の更新を表示"</string>
<string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"更新されたハードウェア層を緑で点滅させる"</string>
- <string name="debug_hw_overdraw" msgid="8944851091008756796">"GPUオーバードローをデバッグ"</string>
+ <string name="debug_hw_overdraw" msgid="8944851091008756796">"GPU オーバードローをデバッグ"</string>
<string name="disable_overlays" msgid="4206590799671557143">"HW オーバーレイを無効化"</string>
<string name="disable_overlays_summary" msgid="1954852414363338166">"画面合成に常に GPU を使用する"</string>
<string name="simulate_color_space" msgid="1206503300335835151">"色空間シミュレート"</string>
<string name="enable_opengl_traces_title" msgid="4638773318659125196">"OpenGLトレースを有効化"</string>
- <string name="usb_audio_disable_routing" msgid="3367656923544254975">"USBオーディオルーティングを無効化"</string>
- <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"USBオーディオ周辺機器への自動ルーティングを無効化"</string>
+ <string name="usb_audio_disable_routing" msgid="3367656923544254975">"USB オーディオ ルーティングを無効化"</string>
+ <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"USB オーディオ周辺機器への自動ルーティングを無効にする"</string>
<string name="debug_layout" msgid="1659216803043339741">"レイアウト境界を表示"</string>
<string name="debug_layout_summary" msgid="8825829038287321978">"クリップの境界線、マージンなどを表示"</string>
- <string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTLレイアウト方向を使用"</string>
- <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"すべての言語/地域で画面レイアウト方向をRTLに設定"</string>
+ <string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL レイアウト方向を使用"</string>
+ <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"すべての言語/地域で画面レイアウト方向を RTL に設定"</string>
<string name="window_blurs" msgid="6831008984828425106">"ウィンドウ レベルでのぼかしを許可"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA を適用"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 アプリで 4x MSAA を有効にする"</string>
@@ -390,18 +390,18 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"デバッグアプリに GPU デバッグレイヤの読み込みを許可"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ベンダーの詳細なロギングを有効にする"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"バグレポートには、その他のデバイス固有のベンダーログが含まれます。これには、非公開の情報が含まれることがあります。また、バッテリーやストレージの使用量が増えることもあります。"</string>
- <string name="window_animation_scale_title" msgid="5236381298376812508">"ウィンドウアニメスケール"</string>
- <string name="transition_animation_scale_title" msgid="1278477690695439337">"トランジションアニメスケール"</string>
- <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator再生時間スケール"</string>
- <string name="overlay_display_devices_title" msgid="5411894622334469607">"2次画面シミュレート"</string>
+ <string name="window_animation_scale_title" msgid="5236381298376812508">"ウィンドウ アニメ スケール"</string>
+ <string name="transition_animation_scale_title" msgid="1278477690695439337">"トランジション アニメ スケール"</string>
+ <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 再生時間スケール"</string>
+ <string name="overlay_display_devices_title" msgid="5411894622334469607">"2 次画面シミュレート"</string>
<string name="debug_applications_category" msgid="5394089406638954196">"アプリ"</string>
<string name="immediately_destroy_activities" msgid="1826287490705167403">"アクティビティを保持しない"</string>
- <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ユーザーが離れたアクティビティをただちに破棄します"</string>
+ <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ユーザーが離れたアクティビティを直ちに破棄する"</string>
<string name="app_process_limit_title" msgid="8361367869453043007">"バックグラウンドプロセスの上限"</string>
<string name="show_all_anrs" msgid="9160563836616468726">"バックグラウンド ANR の表示"</string>
- <string name="show_all_anrs_summary" msgid="8562788834431971392">"バックグラウンド アプリが応答しない場合にダイアログを表示"</string>
+ <string name="show_all_anrs_summary" msgid="8562788834431971392">"バックグラウンド アプリが応答しない場合にダイアログを表示する"</string>
<string name="show_notification_channel_warnings" msgid="3448282400127597331">"通知チャネルの警告を表示"</string>
- <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"アプリから有効なチャネルのない通知が投稿されたときに画面上に警告を表示します"</string>
+ <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"アプリから有効なチャネルのない通知が投稿されたときに、画面上に警告を表示する"</string>
<string name="force_allow_on_external" msgid="9187902444231637880">"外部ストレージへのアプリの書き込みを許可"</string>
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"マニフェストの値に関係なく、すべてのアプリを外部ストレージに書き込めるようになります"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"アクティビティをサイズ変更可能にする"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 66a05f1..c6a50ac 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"QR კოდის სკანირება"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"მოსმენის დასაწყებად ცენტრში მოაქციეთ ქვემოთ მოცემული QR კოდი"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"QR კოდის ფორმატი არასწორია"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"გსურთ <xliff:g id="APP_NAME">%1$s</xliff:g>-ის ტრანსლაციის შეჩერება?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-ის ტრანსლაციის შემთხვევაში ან აუდიოს გამოსასვლელის შეცვლისას, მიმდინარე ტრანსლაცია შეჩერდება"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-ის ტრანსლაცია"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"აუდიოს გამოსასვლელის შეცვლა"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index bbfa2a3..f5559d2 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -175,7 +175,7 @@
<string name="data_usage_ota" msgid="7984667793701597001">"Жүйелік жаңарту"</string>
<string name="tether_settings_title_usb" msgid="3728686573430917722">"USB тетеринг"</string>
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"Алынбалы хот-спот"</string>
- <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Bluetooth модем"</string>
+ <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Bluetooth тетеринг"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Тетеринг"</string>
<string name="tether_settings_title_all" msgid="8910259483383010470">"Тетеринг және алынбалы хотспот"</string>
<string name="managed_user_title" msgid="449081789742645723">"Барлық жұмыс қолданбалары"</string>
@@ -327,7 +327,7 @@
<string name="allow_mock_location_summary" msgid="179780881081354579">"Жасанды аймақтарды пайдалануға рұқсат беру"</string>
<string name="debug_view_attributes" msgid="3539609843984208216">"Көру төлсипатын тексеруді қосу"</string>
<string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Wi‑Fi қосулы кезде де мобильдік интернетті өшірмеу (желіні жылдам ауыстыру үшін)"</string>
- <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Тетеринг режиміндегі аппараттық жеделдетуді пайдалану (қолжетімді болса)"</string>
+ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Тетеринг режимінде аппаратпен жеделдетуді пайдалану (қолжетімді болса)"</string>
<string name="adb_warning_title" msgid="7708653449506485728">"USB арқылы түзетуге рұқсат берілсін бе?"</string>
<string name="adb_warning_message" msgid="8145270656419669221">"USB арқылы түзету дамыту мақсаттарына ғана арналған. Оны компьютер және құрылғы арасында дерек көшіру, құрылғыға ескертусіз қолданба орнату және журнал деректерін оқу үшін қолданыңыз."</string>
<string name="adbwifi_warning_title" msgid="727104571653031865">"Сымсыз түзетуге рұқсат берілсін бе?"</string>
@@ -352,7 +352,7 @@
<string name="select_application" msgid="2543228890535466325">"Қолданба таңдау"</string>
<string name="no_application" msgid="9038334538870247690">"Ешнәрсе"</string>
<string name="wait_for_debugger" msgid="7461199843335409809">"Түзеткішті күту"</string>
- <string name="wait_for_debugger_summary" msgid="6846330006113363286">"Орындау алдында түзелетін қолданба түзетушінің қосылуын күтеді"</string>
+ <string name="wait_for_debugger_summary" msgid="6846330006113363286">"Орындау алдында түзелетін қолданба түзетушінің қосылуын күтеді."</string>
<string name="debug_input_category" msgid="7349460906970849771">"Енгізу"</string>
<string name="debug_drawing_category" msgid="5066171112313666619">"Сызу"</string>
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Бейнелеуді аппаратпен жеделдету"</string>
@@ -385,7 +385,7 @@
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA қолдану"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"4x MSAA функциясын OpenGL ES 2.0 қолданбаларында іске қосу"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"Тіктөртбұрыштан басқа пішінге қиюды түзету"</string>
- <string name="track_frame_time" msgid="522674651937771106">"Профиль бойынша HWUI рендерингі"</string>
+ <string name="track_frame_time" msgid="522674651937771106">"Профильдегі HWUI рендерингі"</string>
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"GPU түзету қабаттары"</string>
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"GPU түзету қабаттарының жүктелуіне рұқсат ету"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Жеткізуші туралы толық мәліметті тіркеу"</string>
@@ -397,16 +397,16 @@
<string name="debug_applications_category" msgid="5394089406638954196">"Қолданбалар"</string>
<string name="immediately_destroy_activities" msgid="1826287490705167403">"Әрекеттерді сақтамау"</string>
<string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Әр әрекетті пайдаланушы аяқтай салысымен жою"</string>
- <string name="app_process_limit_title" msgid="8361367869453043007">"Фондық үрдіс шектеуі"</string>
+ <string name="app_process_limit_title" msgid="8361367869453043007">"Фондық процесті шектеу"</string>
<string name="show_all_anrs" msgid="9160563836616468726">"Фондық ANR-ларды көрсету"</string>
<string name="show_all_anrs_summary" msgid="8562788834431971392">"Фондық қолданбалар үшін \"Қолданба жауап бермейді\" терезесін шығару"</string>
<string name="show_notification_channel_warnings" msgid="3448282400127597331">"Хабарландыру арнасының ескертулерін көрсету"</string>
<string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Қолданба жарамсыз арна арқылы хабарландыру жариялағанда, экранға ескерту шығарады."</string>
- <string name="force_allow_on_external" msgid="9187902444231637880">"Сыртқы жадта қолданбаларға рұқсат ету"</string>
+ <string name="force_allow_on_external" msgid="9187902444231637880">"Сыртқы жадта сақтауға рұқсат ету"</string>
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"Манифест мәндеріне қарамастан, кез келген қолданбаны сыртқы жадқа жазуға рұқсат беру"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Әрекеттердің өлшемін өзгертуге рұқсат ету"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Манифест мәндеріне қарамастан, бірнеше терезе режимінде барлық әрекеттердің өлшемін өзгертуге рұқсат беру"</string>
- <string name="enable_freeform_support" msgid="7599125687603914253">"Еркін пішіндегі терезелерді қосу"</string>
+ <string name="enable_freeform_support" msgid="7599125687603914253">"Еркін пішінді терезелерге рұқсат беру"</string>
<string name="enable_freeform_support_summary" msgid="1822862728719276331">"Еркін пішінді терезелерді құру эксперименттік функиясын қосу"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"Компьютердегі сақтық көшірме құпия сөзі"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"Компьютердегі толық сақтық көшірмелер қазір қорғалмаған."</string>
@@ -429,7 +429,7 @@
<string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Белсенді емес. Ауыстырып қосу үшін түртіңіз."</string>
<string name="inactive_app_active_summary" msgid="8047630990208722344">"Белсенді. Ауыстырып қосу үшін түртіңіз."</string>
<string name="standby_bucket_summary" msgid="5128193447550429600">"Қолданбаның күту режимі: <xliff:g id="BUCKET"> %s</xliff:g>"</string>
- <string name="transcode_settings_title" msgid="2581975870429850549">"Медиамазмұнды қайта кодтау параметрлері"</string>
+ <string name="transcode_settings_title" msgid="2581975870429850549">"Медиафайлдарды қайта кодтау параметрлері"</string>
<string name="transcode_user_control" msgid="6176368544817731314">"Қайта қодтаудың әдепкі параметрлерін қайта анықтау"</string>
<string name="transcode_enable_all" msgid="2411165920039166710">"Қайта кодтауды қосу"</string>
<string name="transcode_default" msgid="3784803084573509491">"Қолданбалар қазіргі заманғы форматтарды қолдайды делік"</string>
@@ -605,7 +605,7 @@
<string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Тым көп қате әрекет жасалды. Бұл пайдаланушы жойылады."</string>
<string name="failed_attempts_now_wiping_profile" msgid="7626589520888963129">"Тым көп қате әрекет жасалды. Бұл жұмыс профилі мен оның деректері жойылады."</string>
<string name="failed_attempts_now_wiping_dialog_dismiss" msgid="2749889771223578925">"Жабу"</string>
- <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Құрылғының әдепкі параметрлері"</string>
+ <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Құрылғының әдепкі параметрі"</string>
<string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Өшірулі"</string>
<string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Қосулы"</string>
<string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Бұл өзгеріс күшіне енуі үшін, құрылғыны қайта жүктеу керек. Қазір қайта жүктеңіз не бас тартыңыз."</string>
diff --git a/packages/SettingsLib/res/values-km/arrays.xml b/packages/SettingsLib/res/values-km/arrays.xml
index 56b98dc..ef3aa52 100644
--- a/packages/SettingsLib/res/values-km/arrays.xml
+++ b/packages/SettingsLib/res/values-km/arrays.xml
@@ -249,7 +249,7 @@
<string-array name="debug_hw_overdraw_entries">
<item msgid="1968128556747588800">"បិទ"</item>
<item msgid="3033215374382962216">"បង្ហាញតំបន់ដែលលើស"</item>
- <item msgid="3474333938380896988">"បង្ហាញតំបន់សម្រាប់ Deuteranomaly"</item>
+ <item msgid="3474333938380896988">"បង្ហាញតំបន់សម្រាប់បញ្ហាខ្វាក់ពណ៌បៃតង"</item>
</string-array>
<string-array name="app_process_limit_entries">
<item msgid="794656271086646068">"ដែនកំណត់ស្តង់ដារ"</item>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 9085fb6..7a45212 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -224,7 +224,7 @@
</string-array>
<string name="choose_profile" msgid="343803890897657450">"ជ្រើសរើសកម្រងព័ត៌មាន"</string>
<string name="category_personal" msgid="6236798763159385225">"ផ្ទាល់ខ្លួន"</string>
- <string name="category_work" msgid="4014193632325996115">"កន្លែងធ្វើការ"</string>
+ <string name="category_work" msgid="4014193632325996115">"ការងារ"</string>
<string name="development_settings_title" msgid="140296922921597393">"ជម្រើសសម្រាប់អ្នកអភិវឌ្ឍន៍"</string>
<string name="development_settings_enable" msgid="4285094651288242183">"បើកដំណើរការជម្រើសអ្នកអភិវឌ្ឍន៍"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"កំណត់ជម្រើសសម្រាប់ការអភិវឌ្ឍកម្មវិធី"</string>
@@ -234,7 +234,7 @@
<string name="apn_settings_not_available" msgid="1147111671403342300">"ការកំណត់ឈ្មោះចូលដំណើរការមិនអាចប្រើបានសម្រាប់អ្នកប្រើនេះ"</string>
<string name="enable_adb" msgid="8072776357237289039">"ការជួសជុលតាម USB"</string>
<string name="enable_adb_summary" msgid="3711526030096574316">"មុខងារជួសជុល នៅពេលភ្ជាប់ USB"</string>
- <string name="clear_adb_keys" msgid="3010148733140369917">"ដកសិទ្ធិកែកំហុសតាម USB"</string>
+ <string name="clear_adb_keys" msgid="3010148733140369917">"ដកសិទ្ធិជួសជុលតាម USB"</string>
<string name="enable_adb_wireless" msgid="6973226350963971018">"ការជួសជុលដោយឥតខ្សែ"</string>
<string name="enable_adb_wireless_summary" msgid="7344391423657093011">"មុខងារជួសជុល នៅពេលភ្ជាប់ Wi‑Fi"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"បញ្ហា"</string>
@@ -399,7 +399,7 @@
<string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"បំផ្លាញគ្រប់សកម្មភាព ពេលអ្នកប្រើចាកចេញ"</string>
<string name="app_process_limit_title" msgid="8361367869453043007">"ដែនកំណត់ដំណើរការក្នុងផ្ទៃខាងក្រោយ"</string>
<string name="show_all_anrs" msgid="9160563836616468726">"បង្ហាញ ANR ផ្ទៃខាងក្រោយ"</string>
- <string name="show_all_anrs_summary" msgid="8562788834431971392">"បង្ហាញប្រអប់កម្មវិធីមិនឆ្លើយតបសម្រាប់កម្មវិធីផ្ទៃខាងក្រោយ"</string>
+ <string name="show_all_anrs_summary" msgid="8562788834431971392">"បង្ហាញប្រអប់ \"កម្មវិធីមិនឆ្លើយតប\" សម្រាប់កម្មវិធីផ្ទៃខាងក្រោយ"</string>
<string name="show_notification_channel_warnings" msgid="3448282400127597331">"បង្ហាញការព្រមានអំពីបណ្តាញជូនដំណឹង"</string>
<string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"បង្ហាញការព្រមាននៅលើអេក្រង់ នៅពេលកម្មវិធីបង្ហោះការជូនដំណឹងដោយមិនមានបណ្តាញត្រឹមត្រូវ"</string>
<string name="force_allow_on_external" msgid="9187902444231637880">"បង្ខំឲ្យអនុញ្ញាតកម្មវិធីលើឧបករណ៍ផ្ទុកខាងក្រៅ"</string>
@@ -407,7 +407,7 @@
<string name="force_resizable_activities" msgid="7143612144399959606">"បង្ខំឲ្យសកម្មភាពអាចប្តូរទំហំបាន"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"ធ្វើឲ្យសកម្មភាពទាំងអស់អាចប្តូរទំហំបានសម្រាប់ពហុវិនដូ ដោយមិនគិតពីតម្លៃមេនីហ្វេសថ៍។"</string>
<string name="enable_freeform_support" msgid="7599125687603914253">"បើកដំណើរការផ្ទាំងវិនដូទម្រង់សេរី"</string>
- <string name="enable_freeform_support_summary" msgid="1822862728719276331">"បើកដំណើរការគាំទ្រផ្ទាំងវិនដូទម្រង់សេរីសាកល្បង"</string>
+ <string name="enable_freeform_support_summary" msgid="1822862728719276331">"បើកឱ្យអាចប្រើផ្ទាំងវិនដូទម្រង់សេរីពិសោធន៍។"</string>
<string name="local_backup_password_title" msgid="4631017948933578709">"ពាក្យសម្ងាត់បម្រុងទុកលើកុំព្យូទ័រ"</string>
<string name="local_backup_password_summary_none" msgid="7646898032616361714">"បច្ចុប្បន្ន ការបម្រុងទុកពេញលេញនៅលើកុំព្យូទ័រមិនត្រូវបានការពារទេ"</string>
<string name="local_backup_password_summary_change" msgid="1707357670383995567">"ប៉ះដើម្បីប្ដូរ ឬយកពាក្យសម្ងាត់ចេញសម្រាប់ការបម្រុងទុកពេញលេញលើកុំព្យូទ័រ"</string>
@@ -444,10 +444,10 @@
<string name="picture_color_mode_desc" msgid="151780973768136200">"ប្រើ sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"បានបិទ"</string>
<string name="daltonizer_mode_monochromacy" msgid="362060873835885014">"Monochromacy"</string>
- <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"Deuteranomaly (ក្រហមពណ៌បៃតង)"</string>
- <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaly (ក្រហមពណ៌បៃតង)"</string>
- <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (ពណ៌ខៀវ-លឿង)"</string>
- <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"ការកែពណ៌"</string>
+ <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"ខ្វាក់ពណ៌បៃតង (ក្រហមបៃតង)"</string>
+ <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"ខ្វាក់ពណ៌ក្រហម (ក្រហមបៃតង)"</string>
+ <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"ខ្វាក់ពណ៌ខៀវ (ខៀវលឿង)"</string>
+ <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"ការកែតម្រូវពណ៌"</string>
<string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"ការកែតម្រូវពណ៌អាចមានប្រយោជន៍ នៅពេលអ្នកចង់៖<br/> <ol> <li>&nbsp;មើលពណ៌កាន់តែត្រឹមត្រូវ</li> <li>&nbsp;លុបពណ៌ចេញ ដើម្បីជួយឱ្យអ្នកផ្ដោតអារម្មណ៍</li> </ol>"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"បដិសេធដោយ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index fc0df56..362665b 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -236,7 +236,7 @@
<string name="enable_adb_summary" msgid="3711526030096574316">"USB компьютерге сайылганда мүчүлүштүктөрдү оңдоо режими иштейт"</string>
<string name="clear_adb_keys" msgid="3010148733140369917">"USB аркылуу мүчүлүштүктөрдү аныктоо уруксатын артка кайтаруу"</string>
<string name="enable_adb_wireless" msgid="6973226350963971018">"Мүчүлүштүктөрдү Wi-Fi аркылуу аныктоо"</string>
- <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Wi‑Fi\'га туташканда, мүчүлүштүктөрдү аныктоо режими иштейт оңдоо режими"</string>
+ <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Wi‑Fi\'га туташканда, мүчүлүштүктөрдү аныктоо режими иштейт"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"Ката"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"Мүчүлүштүктөрдү Wi-Fi аркылуу аныктоо"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Жеткиликтүү түзмөктөрдү көрүү үчүн мүчүлүштүктөрдү Wi-Fi аркылуу аныктоону күйгүзүңүз"</string>
@@ -279,8 +279,8 @@
<string name="debug_networking_category" msgid="6829757985772659599">"Тармактар"</string>
<string name="wifi_display_certification" msgid="1805579519992520381">"Зымсыз мониторлорду тастыктамалоо"</string>
<string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi‑Fi таржымалы"</string>
- <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi тармактарын издөөнү жөнгө салуу"</string>
- <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Wi‑Fi туташуусу туруксуз MAC даректерин башаламан иретте түзүү"</string>
+ <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi тармактарын издөөнү чектөө"</string>
+ <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Wi-Fi тармагындагы башаламан MAC даректери"</string>
<string name="mobile_data_always_on" msgid="8275958101875563572">"Мобилдик Интернет иштей берет"</string>
<string name="tethering_hardware_offload" msgid="4116053719006939161">"Модем режиминде аппараттын иштешин тездетүү"</string>
<string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Аталышсыз Bluetooth түзмөктөрү көрүнсүн"</string>
@@ -312,7 +312,7 @@
<string name="wifi_display_certification_summary" msgid="8111151348106907513">"Зымсыз мониторлорду тастыктамалоо параметрлери көрүнүп турат"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi-Fi тандалганда ар бир SSID үчүн RSSI көрүнүп турат"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Батареяны үнөмдөп, тармактын иштешин жакшыртат"</string>
- <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Бул режим өчүрүлгөндөн кийин, түзмөк MAC дарегин башаламан иретте түзүү функциясы иштетилген тармакка туташкан сайын анын MAC дареги өзгөрүшү мүмкүн."</string>
+ <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Бул режим иштетилсе, түзмөктүн MAC дареги башаламан MAC даректерди түзгөн тармакка туташкан сайын өзгөрүп турушу мүмкүн."</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"Трафик ченелет"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"Чектелбеген тармак"</string>
<string name="select_logd_size_title" msgid="1604578195914595173">"Журнал буферинин өлчөмү"</string>
@@ -398,7 +398,7 @@
<string name="immediately_destroy_activities" msgid="1826287490705167403">"Аракеттер сакталбасын"</string>
<string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Колдонуучу чыгып кетери менен бардык аракеттер өчүрүлөт"</string>
<string name="app_process_limit_title" msgid="8361367869453043007">"Фондогу процесстер чеги"</string>
- <string name="show_all_anrs" msgid="9160563836616468726">"Фондогу \"Колдонмо жооп бербей жатат\" деп көрсөтүү"</string>
+ <string name="show_all_anrs" msgid="9160563836616468726">"Фондук режимдеги ANR"</string>
<string name="show_all_anrs_summary" msgid="8562788834431971392">"Фондогу колдонмо жооп бербей жатат деп билдирип турат"</string>
<string name="show_notification_channel_warnings" msgid="3448282400127597331">"Билдирмелер каналынын эскертүүлөрүн көрсөтүү"</string>
<string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Тыюу салынган каналдын колдонмосунун жаңы билдирмелери тууралуу эскертүүлөр көрүнөт"</string>
@@ -552,7 +552,7 @@
<string name="help_label" msgid="3528360748637781274">"Жардам/Пикир билдирүү"</string>
<string name="storage_category" msgid="2287342585424631813">"Сактагыч"</string>
<string name="shared_data_title" msgid="1017034836800864953">"Бөлүшүлгөн маалымат"</string>
- <string name="shared_data_summary" msgid="5516326713822885652">"Бөлүшүлгөн маалыматты көрүп, өзгөртүү"</string>
+ <string name="shared_data_summary" msgid="5516326713822885652">"Бөлүшүлгөн маалыматты көрүп, өзгөртөсүз"</string>
<string name="shared_data_no_blobs_text" msgid="3108114670341737434">"Бул колдонуучу менен бөлүшүлгөн маалымат жок."</string>
<string name="shared_data_query_failure_text" msgid="3489828881998773687">"Бөлүшүлгөн маалыматты алууда ката кетти. Кайталоо."</string>
<string name="blob_id_text" msgid="8680078988996308061">"Бөлүшүлгөн маалыматты идентификатору: <xliff:g id="BLOB_ID">%d</xliff:g>"</string>
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"QR кодун скандоо"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"Угуп баштоо үчүн QR кодун борборго жайгаштырыңыз"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"QR кодунун форматы жараксыз"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда кабарлоо токтотулсунбу?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Эгер <xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарласаңыз же аудионун чыгуусун өзгөртсөңүз, учурдагы кабарлоо токтотулат"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарлоо"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Аудионун чыгуусун өзгөртүү"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-lo/arrays.xml b/packages/SettingsLib/res/values-lo/arrays.xml
index 4d9f5d9..56a9741 100644
--- a/packages/SettingsLib/res/values-lo/arrays.xml
+++ b/packages/SettingsLib/res/values-lo/arrays.xml
@@ -76,7 +76,7 @@
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
<string-array name="bluetooth_map_versions">
- <item msgid="8786402640610987099">"MAP 1.2 (Default)"</item>
+ <item msgid="8786402640610987099">"MAP 1.2 (ຄ່າເລີ່ມຕົ້ນ)"</item>
<item msgid="6817922176194686449">"MAP 1.3"</item>
<item msgid="3423518690032737851">"MAP 1.4"</item>
</string-array>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 9ad5087..b3be17a 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -393,7 +393,7 @@
<string name="window_animation_scale_title" msgid="5236381298376812508">"ຂະໜາດໜ້າຈໍຂອງອະນິເມຊັນ"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"ຂະໜາດສະຫຼັບອະນິເມຊັນ"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"ໄລຍະເວລາອະນິເມຊັນ"</string>
- <string name="overlay_display_devices_title" msgid="5411894622334469607">"ຈຳລອງຈໍສະແດງຜົນທີ່ສອງ"</string>
+ <string name="overlay_display_devices_title" msgid="5411894622334469607">"ຈຳລອງຈໍສະແດງຜົນທີສອງ"</string>
<string name="debug_applications_category" msgid="5394089406638954196">"ແອັບ"</string>
<string name="immediately_destroy_activities" msgid="1826287490705167403">"ບໍ່ຕ້ອງຮັກສາການເຄື່ອນໄຫວ"</string>
<string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ລຶບທຸກການເຄື່ອນໄຫວທັນທີທີ່ຜູ້ໃຊ້ອອກຈາກມັນ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 6f2f7042..250d24a 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"QR kodo nuskaitymas"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"Jei norite pradėti klausyti, nustatykite toliau pateiktą QR kodą per vidurį"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"QR kodas netinkamo formato"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Sustabdyti „<xliff:g id="APP_NAME">%1$s</xliff:g>“ transliaciją?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Jei transliuosite „<xliff:g id="SWITCHAPP">%1$s</xliff:g>“ arba pakeisite išvestį, dabartinė transliacija bus sustabdyta"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Transliuoti „<xliff:g id="SWITCHAPP">%1$s</xliff:g>“"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Keisti išvestį"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index bbd792e..be13fd7 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -266,7 +266,7 @@
<string name="bugreport_in_power" msgid="8664089072534638709">"Кратенка за извештај за грешка"</string>
<string name="bugreport_in_power_summary" msgid="1885529649381831775">"Прикажи копче во менито за вклучување за да се направи извештај за грешка"</string>
<string name="keep_screen_on" msgid="1187161672348797558">"Остани во активен режим"</string>
- <string name="keep_screen_on_summary" msgid="1510731514101925829">"Екранот никогаш нема да биде во режим на штедење додека се полни"</string>
+ <string name="keep_screen_on_summary" msgid="1510731514101925829">"Екранот никогаш нема да биде во режим на спиење додека се полни"</string>
<string name="bt_hci_snoop_log" msgid="7291287955649081448">"Овозможи Bluetooth HCI за евиденција на пресретнување пакети"</string>
<string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Снимај Bluetooth-пакети. (Вклучи Bluetooth по промената на поставкава)"</string>
<string name="oem_unlock_enable" msgid="5334869171871566731">"Отклучување со OEM"</string>
@@ -337,7 +337,7 @@
<string name="dev_settings_warning_message" msgid="37741686486073668">"Овие поставки се наменети само за употреба за развој. Тие може да предизвикаат уредот и апликациите во него да се расипат или да се однесуваат необично."</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Потврди апликации преку USB"</string>
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Провери апликации инсталирани преку ADB/ADT за штетно однесување."</string>
- <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Уредите со Bluetooth без имиња (само MAC-адреси) ќе се прикажуваат"</string>
+ <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Ќе се прикажуваат уредите со Bluetooth без имиња (само MAC-адреси)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Ја оневозможува функцијата за апсолутна јачина на звук преку Bluetooth во случај кога ќе настанат проблеми со далечинските уреди, како на пр., неприфатливо силен звук или недоволна контрола."</string>
<string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Ја овозможува функцијата Bluetooth Gabeldorsche."</string>
<string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Ја овозможува функцијата „Подобрена поврзливост“."</string>
@@ -352,7 +352,7 @@
<string name="select_application" msgid="2543228890535466325">"Избери апликација"</string>
<string name="no_application" msgid="9038334538870247690">"Ништо"</string>
<string name="wait_for_debugger" msgid="7461199843335409809">"Почекај ја програмата за отстранување грешки"</string>
- <string name="wait_for_debugger_summary" msgid="6846330006113363286">"Пред да се изврши, апликација за отстранување грешки чека програмата за отстранување грешки да се закачи"</string>
+ <string name="wait_for_debugger_summary" msgid="6846330006113363286">"Пред да се изврши, апликацијата во која се отстрануваат грешки чека да се закачи програмата за отстранување грешки"</string>
<string name="debug_input_category" msgid="7349460906970849771">"Внесување"</string>
<string name="debug_drawing_category" msgid="5066171112313666619">"Цртање"</string>
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"Хардверско забрзување"</string>
@@ -378,7 +378,7 @@
<string name="usb_audio_disable_routing" msgid="3367656923544254975">"Исклучи USB-пренасочување"</string>
<string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"Исклучи автоматско пренасочување до USB-аудиоуреди"</string>
<string name="debug_layout" msgid="1659216803043339741">"Прикажи граници на слој"</string>
- <string name="debug_layout_summary" msgid="8825829038287321978">"Прикажи граници на клип, маргини, итн."</string>
+ <string name="debug_layout_summary" msgid="8825829038287321978">"Прикажи граници на клип, маргини итн."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Принудно користи RTL за насока"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Принудно постави насока на распоред на екранот во RTL за сите локални стандарди"</string>
<string name="window_blurs" msgid="6831008984828425106">"Дозволи замаглување прозорец"</string>
@@ -483,7 +483,7 @@
<string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Бавно полнење"</string>
<string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Се полни безжично"</string>
<string name="battery_info_status_discharging" msgid="6962689305413556485">"Не се полни"</string>
- <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Поврзана, не се полни"</string>
+ <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Поврзано, не се полни"</string>
<string name="battery_info_status_full" msgid="1339002294876531312">"Полна"</string>
<string name="battery_info_status_full_charged" msgid="3536054261505567948">"Целосно полна"</string>
<string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Контролирано од администраторот"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index fe35772..cd41b81 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"QR код скан хийх"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"Сонсож эхлэхийн тулд доорх QR кодыг голлуулаарай"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"QR код буруу форматтай байна"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г нэвтрүүлэхээ зогсоох уу?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Хэрэв та <xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлсэн эсвэл гаралтыг өөрчилсөн бол таны одоогийн нэвтрүүлэлтийг зогсооно"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлэх"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Гаралтыг өөрчлөх"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 9e483c2..6c2dbe4 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -520,7 +520,7 @@
<string name="ims_reg_status_not_registered" msgid="2989287366045704694">"नोंदवलेले नाही"</string>
<string name="status_unavailable" msgid="5279036186589861608">"उपलब्ध नाही"</string>
<string name="wifi_status_mac_randomized" msgid="466382542497832189">"MAC रँडमाइझ केला आहे"</string>
- <string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{0 device connected}=1{एक डिव्हाइस कनेक्ट केले}other{# डिव्हाइस कनेक्ट केली}}"</string>
+ <string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{0 डिव्हाइस कनेक्ट केले}=1{एक डिव्हाइस कनेक्ट केले}other{# डिव्हाइस कनेक्ट केली}}"</string>
<string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"जास्त वेळ."</string>
<string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"कमी वेळ."</string>
<string name="cancel" msgid="5665114069455378395">"रद्द करा"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 51d5a2c..cbe99f3 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -357,7 +357,7 @@
<string name="debug_drawing_category" msgid="5066171112313666619">"रेखाचित्र"</string>
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"हार्डवेयरले बढाएको रेन्डरिङ"</string>
<string name="media_category" msgid="8122076702526144053">"मिडिया"</string>
- <string name="debug_monitoring_category" msgid="1597387133765424994">"अनुगमन गर्दै"</string>
+ <string name="debug_monitoring_category" msgid="1597387133765424994">"अनुगमन गरिँदै छ"</string>
<string name="strict_mode" msgid="889864762140862437">"स्ट्रिक्ट मोड अन गरियोस्"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"एपले मुख्य थ्रेडमा लामा गतिविधि गर्दा स्क्रिन फ्ल्यास गरियोस्"</string>
<string name="pointer_location" msgid="7516929526199520173">"पोइन्टरको स्थान"</string>
@@ -402,7 +402,7 @@
<string name="show_all_anrs_summary" msgid="8562788834431971392">"ब्याकग्राउन्डका एपको हकमा \'नचलिरहेका एप\' सन्देश देखाइयोस्"</string>
<string name="show_notification_channel_warnings" msgid="3448282400127597331">"सूचना च्यानलसम्बन्धी चेतावनी देखाइयोस्"</string>
<string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"एपले मान्य च्यानलबिना सूचना पोस्ट गर्दा स्क्रिनमा चेतावनी देखाइयोस्"</string>
- <string name="force_allow_on_external" msgid="9187902444231637880">"एपलाई बहिरी मेमोरीमा पनि चल्ने दिइयोस्"</string>
+ <string name="force_allow_on_external" msgid="9187902444231637880">"एपलाई बहिरी मेमोरीमा पनि चल्न दिइयोस्"</string>
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"तोकिएको नियमको ख्याल नगरी एपलाई बाह्य भण्डारणमा चल्ने बनाइयोस्"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"बलपूर्वक एपहरूको आकार मिलाउन मिल्ने बनाइयोस्"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"तोकिएको नियमको ख्याल नगरी एपलाई एकभन्दा बढी विन्डोमा रिसाइज गर्न सकिने बनाइयोस्।"</string>
@@ -442,7 +442,7 @@
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"यो छनोट अब मान्य छैन। फेरि प्रयास गर्नुहोस्।"</string>
<string name="picture_color_mode" msgid="1013807330552931903">"चित्र रङ्ग मोड"</string>
<string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB प्रयोग गर्नुहोस्"</string>
- <string name="daltonizer_mode_disabled" msgid="403424372812399228">"असक्षम गरिएको छ"</string>
+ <string name="daltonizer_mode_disabled" msgid="403424372812399228">"अफ गरिएको छ"</string>
<string name="daltonizer_mode_monochromacy" msgid="362060873835885014">"मोनोक्रोमेसी"</string>
<string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"ड्युटरएनोमली (रातो-हरियो)"</string>
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"प्रोटानेमली (रातो, हरियो)"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index ac95365..0da516c 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -309,9 +309,9 @@
<string name="private_dns_mode_provider" msgid="3619040641762557028">"ਨਿੱਜੀ DNS ਪ੍ਰਦਾਨਕ ਹੋਸਟਨਾਮ"</string>
<string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"DNS ਪ੍ਰਦਾਨਕ ਦਾ ਹੋਸਟਨਾਮ ਦਾਖਲ ਕਰੋ"</string>
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
- <string name="wifi_display_certification_summary" msgid="8111151348106907513">"ਵਾਇਰਲੈੱਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਚੋਣਾਂ ਪ੍ਰਦਰਸ਼ਿਤ ਕਰੋ"</string>
+ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"ਵਾਇਰਲੈੱਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਵਿਕਲਪ ਦਿਖਾਓ"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"ਵਾਈ‑ਫਾਈ ਲੌਗਿੰਗ ਪੱਧਰ ਵਧਾਓ, ਵਾਈ‑ਫਾਈ ਚੋਣਕਾਰ ਵਿੱਚ ਪ੍ਰਤੀ SSID RSSI ਦਿਖਾਓ"</string>
- <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਘਟਾ ਕੇ ਨੈੱਟਵਰਕ ਕਾਰਗੁਜ਼ਾਰੀ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਂਦਾ ਹੈ"</string>
+ <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ਤੇਜ਼ੀ ਨਾਲ ਹੋਣ ਵਾਲੇ ਬੈਟਰੀ ਖਰਚ ਨੂੰ ਘਟਾ ਕੇ ਨੈੱਟਵਰਕ ਕਾਰਗੁਜ਼ਾਰੀ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਂਦਾ ਹੈ"</string>
<string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"ਜਦੋਂ ਇਹ ਮੋਡ ਚਾਲੂ ਹੁੰਦਾ ਹੈ, ਤਾਂ ਇਸ ਡੀਵਾਈਸ ਦਾ MAC ਪਤਾ ਹਰ ਵਾਰ ਬਦਲ ਸਕਦਾ ਹੈ ਜਦੋਂ ਇਹ ਕਿਸੇ ਅਜਿਹੇ ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਹੁੰਦਾ ਹੈ ਜਿਸ ਵਿੱਚ MAC ਬੇਤਰਤੀਬਵਾਰ ਚਾਲੂ ਹੁੰਦਾ ਹੈ।"</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"ਮੀਟਰਬੱਧ ਕੀਤਾ ਗਿਆ"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"ਗੈਰ-ਮੀਟਰਬੱਧ ਕੀਤਾ ਗਿਆ"</string>
@@ -326,7 +326,7 @@
<string name="allow_mock_location" msgid="2102650981552527884">"ਨਕਲੀ ਨਿਰਧਾਰਿਤ ਸਥਾਨਾਂ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
<string name="allow_mock_location_summary" msgid="179780881081354579">"ਨਕਲੀ ਨਿਰਧਾਰਿਤ ਸਥਾਨਾਂ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
<string name="debug_view_attributes" msgid="3539609843984208216">"\'ਵਿਸ਼ੇਸ਼ਤਾ ਨਿਰੀਖਣ ਦੇਖੋ\' ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
- <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"ਵਾਈ‑ਫਾਈ ਕਿਰਿਆਸ਼ੀਲ ਹੋਣ \'ਤੇ ਵੀ ਹਮੇਸ਼ਾਂ ਮੋਬਾਈਲ ਡਾਟਾ ਨੂੰ ਕਿਰਿਆਸ਼ੀਲ ਰੱਖੋ(ਤੇਜ਼ ਨੈੱਟਵਰਕ ਸਵਿੱਚਿੰਗ ਲਈ)।"</string>
+ <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"ਵਾਈ‑ਫਾਈ ਕਿਰਿਆਸ਼ੀਲ ਹੋਣ \'ਤੇ ਵੀ ਹਮੇਸ਼ਾਂ ਮੋਬਾਈਲ ਡਾਟਾ ਨੂੰ ਕਿਰਿਆਸ਼ੀਲ ਰੱਖੋ (ਤੇਜ਼ ਨੈੱਟਵਰਕ ਸਵਿੱਚਿੰਗ ਲਈ)।"</string>
<string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"ਉਪਲਬਧ ਹੋਣ \'ਤੇ ਟੈਦਰਿੰਗ ਹਾਰਡਵੇਅਰ ਐਕਸੈੱਲਰੇਸ਼ਨ ਵਰਤੋ"</string>
<string name="adb_warning_title" msgid="7708653449506485728">"ਕੀ USB ਡੀਬਗਿੰਗ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
<string name="adb_warning_message" msgid="8145270656419669221">"USB ਡੀਬਗਿੰਗ ਸਿਰਫ਼ ਵਿਕਾਸ ਮੰਤਵਾਂ ਲਈ ਹੁੰਦੀ ਹੈ। ਇਸਨੂੰ ਆਪਣੇ ਕੰਪਿਊਟਰ ਅਤੇ ਆਪਣੇ ਡੀਵਾਈਸ ਵਿਚਕਾਰ ਡਾਟਾ ਕਾਪੀ ਕਰਨ ਲਈ ਵਰਤੋ, ਸੂਚਨਾ ਦੇ ਬਿਨਾਂ ਆਪਣੇ ਡੀਵਾਈਸ ਤੇ ਐਪਾਂ ਸਥਾਪਤ ਕਰੋ ਅਤੇ ਲੌਗ ਡਾਟਾ ਪੜ੍ਹੋ।"</string>
@@ -336,7 +336,7 @@
<string name="dev_settings_warning_title" msgid="8251234890169074553">"ਕੀ ਵਿਕਾਸ ਸੈਟਿੰਗਾਂ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
<string name="dev_settings_warning_message" msgid="37741686486073668">"ਇਹ ਸੈਟਿੰਗਾਂ ਕੇਵਲ ਵਿਕਾਸਕਾਰ ਦੀ ਵਰਤੋਂ ਲਈ ਹਨ। ਇਹ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਅਤੇ ਇਸਤੇ ਮੌਜੂਦ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਬ੍ਰੇਕ ਕਰਨ ਜਾਂ ਦੁਰਵਿਵਹਾਰ ਕਰਨ ਦਾ ਕਾਰਨ ਬਣ ਸਕਦੇ ਹਨ।"</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"USB \'ਤੇ ਐਪਾਂ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ"</string>
- <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ਹਾਨੀਕਾਰਕ ਵਿਵਹਾਰ ਲਈ ADB/ADT ਰਾਹੀਂ ਸਥਾਪਤ ਕੀਤੀਆਂ ਐਪਾਂ ਦੀ ਜਾਂਚ ਕਰੋ।"</string>
+ <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT ਰਾਹੀਂ ਸਥਾਪਤ ਕੀਤੀਆਂ ਐਪਾਂ ਦੀ ਹਾਨੀਕਾਰਕ ਵਿਵਹਾਰ ਲਈ ਜਾਂਚ ਕਰੋ।"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"ਅਨਾਮ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਦਿਖਾਈਆਂ ਜਾਣਗੀਆਂ (ਸਿਰਫ਼ MAC ਪਤੇ)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"ਰਿਮੋਟ ਡੀਵਾਈਸਾਂ ਨਾਲ ਅਵਾਜ਼ੀ ਸਮੱਸਿਆਵਾਂ ਜਿਵੇਂ ਕਿ ਨਾ ਪਸੰਦ ਕੀਤੀ ਜਾਣ ਵਾਲੀ ਉੱਚੀ ਅਵਾਜ਼ ਜਾਂ ਕੰਟਰੋਲ ਦੀ ਕਮੀ ਵਰਗੀ ਹਾਲਤ ਵਿੱਚ ਬਲੂਟੁੱਥ ਪੂਰਨ ਅਵਾਜ਼ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਬੰਦ ਕਰਦਾ ਹੈ।"</string>
<string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"ਬਲੂਟੁੱਥ Gabeldorsche ਵਿਸ਼ੇਸ਼ਤਾ ਸਟੈਕ ਨੂੰ ਚਾਲੂ ਕਰਦਾ ਹੈ।"</string>
@@ -367,9 +367,9 @@
<string name="show_screen_updates" msgid="2078782895825535494">"ਸਰਫ਼ੇਸ ਅੱਪਡੇਟ ਦਿਖਾਓ"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"ਅੱਪਡੇਟ ਹੋਣ \'ਤੇ, ਸਮੁੱਚੀਆਂ ਵਿੰਡੋ ਸਰਫ਼ੇਸਾਂ ਫਲੈਸ਼ ਕਰੋ"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"\'ਅੱਪਡੇਟ ਦੇਖੋ\' ਨੂੰ ਦਿਖਾਓ"</string>
- <string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"ਡ੍ਰਾ ਕੀਤੇ ਜਾਣ \'ਤੇ ਵਿੰਡੋਜ਼ ਦੇ ਅੰਦਰ ਦ੍ਰਿਸ਼ ਫਲੈਸ਼ ਕਰੋ"</string>
+ <string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"ਡ੍ਰਾ ਕੀਤੇ ਜਾਣ \'ਤੇ ਵਿੰਡੋ ਦੇ ਅੰਦਰ ਦ੍ਰਿਸ਼ ਫਲੈਸ਼ ਕਰੋ"</string>
<string name="show_hw_layers_updates" msgid="5268370750002509767">"ਹਾਰਡਵੇਅਰ ਤਹਿਆਂ ਦੇ ਅੱਪਡੇਟ ਦਿਖਾਓ"</string>
- <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"ਹਾਰਡਵੇਅਰ ਤਹਿਆਂ ਅੱਪਡੇਟ ਹੋਣ \'ਤੇ ਉਹਨਾਂ ਨੂੰ ਹਰਾ ਕਰੋ"</string>
+ <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"ਅੱਪਡੇਟ ਹੋਣ ਤੋਂ ਬਾਅਦ ਹਾਰਡਵੇਅਰ ਤਹਿਆਂ ਨੂੰ ਹਰਾ ਕਰੋ"</string>
<string name="debug_hw_overdraw" msgid="8944851091008756796">"GPU ਓਵਰਡ੍ਰਾ ਡੀਬੱਗ ਕਰੋ"</string>
<string name="disable_overlays" msgid="4206590799671557143">"HW ਓਵਰਲੇ ਨੂੰ ਬੰਦ ਕਰੋ"</string>
<string name="disable_overlays_summary" msgid="1954852414363338166">"ਸਕ੍ਰੀਨ ਕੰਪੋਜ਼ਿਟਿੰਗ ਲਈ ਹਮੇਸ਼ਾਂ GPU ਵਰਤੋ"</string>
@@ -382,7 +382,7 @@
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"ਸੱਜੇ ਤੋਂ ਖੱਬੇ ਵਾਲਾ ਖਾਕਾ ਲਾਗੂ ਕਰੋ"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ਸਾਰੀਆਂ ਭਾਸ਼ਾਵਾਂ ਲਈ ਸਕ੍ਰੀਨ \'ਤੇ ਸੱਜੇ ਤੋਂ ਖੱਬੇ ਵਾਲਾ ਖਾਕਾ ਲਾਗੂ ਕਰੋ"</string>
<string name="window_blurs" msgid="6831008984828425106">"ਵਿੰਡੋ-ਪੱਧਰ \'ਤੇ ਧੁੰਦਲਾ ਕਰਨ ਦਿਓ"</string>
- <string name="force_msaa" msgid="4081288296137775550">"4x MSAA ਤੇ ਜ਼ੋਰ ਪਾਓ"</string>
+ <string name="force_msaa" msgid="4081288296137775550">"4x MSAA ਜ਼ਬਰਦਸਤੀ ਲਾਗੂ ਕਰੋ"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ਐਪਾਂ ਵਿੱਚ 4x MSAA ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"ਗੈਰ-ਆਇਤਾਕਾਰ ਕਲਿੱਪ ਓਪਰੇਸ਼ਨ ਡੀਬੱਗ ਕਰੋ"</string>
<string name="track_frame_time" msgid="522674651937771106">"ਪ੍ਰੋਫਾਈਲ HWUI ਰੈਂਡਰਿੰਗ"</string>
@@ -404,7 +404,7 @@
<string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"ਐਪ ਵੱਲੋਂ ਵੈਧ ਚੈਨਲ ਤੋਂ ਬਿਨਾਂ ਸੂਚਨਾ ਪੋਸਟ ਕਰਨ \'ਤੇ ਸਕ੍ਰੀਨ \'ਤੇ ਚਿਤਾਵਨੀ ਦਿਖਾਉਂਦੀ ਹੈ"</string>
<string name="force_allow_on_external" msgid="9187902444231637880">"ਐਪਾਂ ਨੂੰ ਜ਼ਬਰਦਸਤੀ ਬਾਹਰੀ ਸਟੋਰੇਜ \'ਤੇ ਆਗਿਆ ਦਿਓ"</string>
<string name="force_allow_on_external_summary" msgid="8525425782530728238">"ਮੈਨੀਫੈਸਟ ਮੁੱਲਾਂ ਦੀ ਪਰਵਾਹ ਕੀਤੇ ਬਿਨਾਂ, ਕਿਸੇ ਵੀ ਐਪ ਨੂੰ ਬਾਹਰੀ ਸਟੋਰੇਜ \'ਤੇ ਲਿਖਣ ਦੇ ਯੋਗ ਬਣਾਉਂਦੀ ਹੈ"</string>
- <string name="force_resizable_activities" msgid="7143612144399959606">"ਆਕਾਰ ਬਦਲਣਯੋਗ ਬਣਾਉਣ ਲਈ ਸਰਗਰਮੀਆਂ \'ਤੇ ਜ਼ੋਰ ਦਿਓ"</string>
+ <string name="force_resizable_activities" msgid="7143612144399959606">"ਵਿੰਡੋ ਮੁਤਾਬਕ ਸਰਗਰਮੀਆਂ ਦਾ ਆਕਾਰ ਬਦਲ ਦਿਓ"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"ਮੈਨੀਫ਼ੈਸਟ ਮੁੱਲਾਂ ਦੀ ਪਰਵਾਹ ਕੀਤੇ ਬਿਨਾਂ, ਮਲਟੀ-ਵਿੰਡੋ ਲਈ ਸਾਰੀਆਂ ਸਰਗਰਮੀਆਂ ਨੂੰ ਆਕਾਰ ਬਦਲਣਯੋਗ ਬਣਾਓ।"</string>
<string name="enable_freeform_support" msgid="7599125687603914253">"ਫ੍ਰੀਫਾਰਮ ਵਿੰਡੋਜ਼ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
<string name="enable_freeform_support_summary" msgid="1822862728719276331">"ਪ੍ਰਯੋਗਮਈ ਫ੍ਰੀਫਾਰਮ ਵਿੰਡੋਜ਼ ਲਈ ਸਮਰਥਨ ਨੂੰ ਚਾਲੂ ਕਰੋ।"</string>
@@ -436,7 +436,7 @@
<string name="transcode_notification" msgid="5560515979793436168">"ਟ੍ਰਾਂਸਕੋਡਿੰਗ ਸੂਚਨਾਵਾਂ ਦਿਖਾਓ"</string>
<string name="transcode_disable_cache" msgid="3160069309377467045">"ਟ੍ਰਾਂਸਕੋਡਿੰਗ ਕੈਸ਼ੇ ਬੰਦ ਕਰੋ"</string>
<string name="runningservices_settings_title" msgid="6460099290493086515">"ਚੱਲ ਰਹੀਆਂ ਸੇਵਾਵਾਂ"</string>
- <string name="runningservices_settings_summary" msgid="1046080643262665743">"ਇਸ ਵੇਲੇ ਚੱਲ ਰਹੀਆਂ ਸੇਵਾਵਾਂ ਦੇਖੋ ਅਤੇ ਇਹਨਾਂ ਨੂੰ ਕੰਟਰੋਲ ਕਰੋ"</string>
+ <string name="runningservices_settings_summary" msgid="1046080643262665743">"ਇਸ ਵੇਲੇ ਚੱਲ ਰਹੀਆਂ ਸੇਵਾਵਾਂ ਦੇਖੋ ਅਤੇ ਉਨ੍ਹਾਂ ਨੂੰ ਕੰਟਰੋਲ ਕਰੋ"</string>
<string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ਅਮਲੀਕਰਨ"</string>
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView ਅਮਲੀਕਰਨ ਸੈੱਟ ਕਰੋ"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"ਇਹ ਚੋਣ ਹੁਣ ਵੈਧ ਨਹੀਂ ਹੈ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
@@ -552,7 +552,7 @@
<string name="help_label" msgid="3528360748637781274">"ਮਦਦ ਅਤੇ ਵਿਚਾਰ"</string>
<string name="storage_category" msgid="2287342585424631813">"ਸਟੋਰੇਜ"</string>
<string name="shared_data_title" msgid="1017034836800864953">"ਸਾਂਝਾ ਕੀਤਾ ਡਾਟਾ"</string>
- <string name="shared_data_summary" msgid="5516326713822885652">"ਸਾਂਝਾ ਕੀਤੇ ਡਾਟੇ ਨੂੰ ਦੇਖੋ ਅਤੇ ਸੋਧੋ"</string>
+ <string name="shared_data_summary" msgid="5516326713822885652">"ਸਾਂਝਾ ਕੀਤਾ ਡਾਟਾ ਦੇਖੋ ਅਤੇ ਉਸ ਨੂੰ ਸੋਧੋ"</string>
<string name="shared_data_no_blobs_text" msgid="3108114670341737434">"ਇਸ ਵਰਤੋਂਕਾਰ ਲਈ ਕੋਈ ਸਾਂਝਾ ਕੀਤਾ ਡਾਟਾ ਨਹੀਂ ਹੈ।"</string>
<string name="shared_data_query_failure_text" msgid="3489828881998773687">"ਸਾਂਝੇ ਕੀਤੇ ਡਾਟੇ ਨੂੰ ਪ੍ਰਾਪਤ ਕਰਨ ਵੇਲੇ ਕੋਈ ਗੜਬੜ ਹੋ ਗਈ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
<string name="blob_id_text" msgid="8680078988996308061">"ਸਾਂਝਾ ਕੀਤੇ ਡਾਟੇ ਦੀ ਆਈਡੀ: <xliff:g id="BLOB_ID">%d</xliff:g>"</string>
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"QR ਕੋਡ ਸਕੈਨ ਕਰੋ"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"ਸੁਣਨਾ ਸ਼ੁਰੂ ਕਰਨ ਲਈ, ਹੇਠਾਂ ਦਿੱਤੇ QR ਕੋਡ ਨੂੰ ਕੇਂਦਰ ਵਿੱਚ ਰੱਖੋ"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"QR ਕੋਡ ਦਾ ਫਾਰਮੈਟ ਵੈਧ ਨਹੀਂ ਹੈ"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਦੇ ਪ੍ਰਸਾਰਨ ਨੂੰ ਰੋਕਣਾ ਹੈ?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"ਜੇ ਤੁਸੀਂ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ਦਾ ਪ੍ਰਸਾਰਨ ਕਰਦੇ ਹੋ ਜਾਂ ਆਊਟਪੁੱਟ ਬਦਲਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਪ੍ਰਸਾਰਨ ਰੁਕ ਜਾਵੇਗਾ"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ਦਾ ਪ੍ਰਸਾਰਨ ਕਰੋ"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"ਆਊਟਪੁੱਟ ਬਦਲੋ"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index d523148..a72e4df 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -389,7 +389,7 @@
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Warstwy debugowania GPU"</string>
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Zezwalaj na ładowanie warstw debugowania GPU"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Włącz szczegółowe rejestrowanie dostawcy"</string>
- <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Dołączaj do raportów o błędach dodatkowe dane dostawcy dotyczące konkretnego urządzenia, które mogą zawierać dane prywatne oraz wykorzystywać więcej baterii lub pamięci."</string>
+ <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Dołączaj do raportów o błędach dodatkowe dane dostawcy dotyczące konkretnego urządzenia, które mogą zawierać dane prywatne oraz wykorzystywać więcej baterii lub pamięci"</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"Skala animacji okna"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animacji przejścia"</string>
<string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala długości animacji"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 627d7ba..cd7bbfe 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -266,7 +266,7 @@
<string name="bugreport_in_power" msgid="8664089072534638709">"Atalho para relatório de bugs"</string>
<string name="bugreport_in_power_summary" msgid="1885529649381831775">"Mostrar um botão para gerar relatórios de bugs no menu do botão liga/desliga"</string>
<string name="keep_screen_on" msgid="1187161672348797558">"Permanecer ativo"</string>
- <string name="keep_screen_on_summary" msgid="1510731514101925829">"A tela nunca entrará em suspensão enquanto estiver carregando"</string>
+ <string name="keep_screen_on_summary" msgid="1510731514101925829">"A tela nunca entra em suspensão enquanto está carregando"</string>
<string name="bt_hci_snoop_log" msgid="7291287955649081448">"Ativar registro de rastreamento Bluetooth HCI"</string>
<string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Capturar pacotes de Bluetooth. Ative o Bluetooth depois de alterar essa configuração."</string>
<string name="oem_unlock_enable" msgid="5334869171871566731">"Desbloqueio de OEM"</string>
@@ -282,7 +282,7 @@
<string name="wifi_scan_throttling" msgid="2985624788509913617">"Limitar busca por Wi-Fi"</string>
<string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Ordem aleatória de MAC não persistente no Wi-Fi"</string>
<string name="mobile_data_always_on" msgid="8275958101875563572">"Dados móveis sempre ativos"</string>
- <string name="tethering_hardware_offload" msgid="4116053719006939161">"Aceleração de hardware de tethering"</string>
+ <string name="tethering_hardware_offload" msgid="4116053719006939161">"Aceleração de hardware para tethering"</string>
<string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Mostrar dispositivos Bluetooth sem nomes"</string>
<string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"Desativar volume absoluto"</string>
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Ativar Gabeldorsche"</string>
@@ -327,7 +327,7 @@
<string name="allow_mock_location_summary" msgid="179780881081354579">"Permitir locais fictícios"</string>
<string name="debug_view_attributes" msgid="3539609843984208216">"Ativar visualização de inspeção de atributo"</string>
<string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Sempre manter dados móveis ativos, mesmo quando o Wi-Fi estiver ativado (para troca rápida de rede)"</string>
- <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Usar aceleração de hardware de tethering quando disponível"</string>
+ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Usar aceleração de hardware para tethering quando disponível"</string>
<string name="adb_warning_title" msgid="7708653449506485728">"Permitir a depuração USB?"</string>
<string name="adb_warning_message" msgid="8145270656419669221">"A depuração USB serve apenas para fins de desenvolvimento. Use-a para copiar dados entre o computador e o dispositivo, instalar apps no seu aparelho sem notificação e ler dados de registro."</string>
<string name="adbwifi_warning_title" msgid="727104571653031865">"Permitir a depuração por Wi-Fi?"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/arrays.xml b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
index 6ae02a5..3e7ee05 100644
--- a/packages/SettingsLib/res/values-pt-rPT/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
@@ -56,7 +56,7 @@
<string-array name="hdcp_checking_summaries">
<item msgid="4045840870658484038">"Nunca utilizar a verificação HDCP"</item>
<item msgid="8254225038262324761">"Utilizar a verificação HDCP para conteúdo DRM apenas"</item>
- <item msgid="6421717003037072581">"Utilizar sempre a verificação HDCP"</item>
+ <item msgid="6421717003037072581">"Usar sempre a verificação HDCP"</item>
</string-array>
<string-array name="bt_hci_snoop_log_entries">
<item msgid="695678520785580527">"Desativado"</item>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 98d65f5..d4ef103 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -335,7 +335,7 @@
<string name="adb_keys_warning_message" msgid="2968555274488101220">"Revogar acesso à depuração USB de todos os computadores anteriormente autorizados?"</string>
<string name="dev_settings_warning_title" msgid="8251234890169074553">"Permitir definições de programação?"</string>
<string name="dev_settings_warning_message" msgid="37741686486073668">"Estas definições destinam-se apenas a programação. Podem fazer com que o seu aparelho e as aplicações nele existentes falhem ou funcionem mal."</string>
- <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Verificar aplicações de USB"</string>
+ <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Verificar apps por USB"</string>
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Verificar as aplicações instaladas via ADB/ADT para detetar comportamento perigoso"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"São apresentados os dispositivos Bluetooth sem nomes (apenas endereços MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Desativa a funcionalidade de volume absoluto do Bluetooth caso existam problemas de volume com dispositivos remotos, como um volume insuportavelmente alto ou a ausência de controlo"</string>
@@ -372,7 +372,7 @@
<string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Piscar camadas de hardware em verde ao atualizar"</string>
<string name="debug_hw_overdraw" msgid="8944851091008756796">"Depurar sobreposição GPU"</string>
<string name="disable_overlays" msgid="4206590799671557143">"Desativar sobreposições HW"</string>
- <string name="disable_overlays_summary" msgid="1954852414363338166">"Utilizar sempre GPU para a composição do ecrã"</string>
+ <string name="disable_overlays_summary" msgid="1954852414363338166">"Usar sempre GPU para a composição do ecrã"</string>
<string name="simulate_color_space" msgid="1206503300335835151">"Simular espaço da cor"</string>
<string name="enable_opengl_traces_title" msgid="4638773318659125196">"Ativar vestígios OpenGL"</string>
<string name="usb_audio_disable_routing" msgid="3367656923544254975">"Desativar encaminhamento áudio USB"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 627d7ba..cd7bbfe 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -266,7 +266,7 @@
<string name="bugreport_in_power" msgid="8664089072534638709">"Atalho para relatório de bugs"</string>
<string name="bugreport_in_power_summary" msgid="1885529649381831775">"Mostrar um botão para gerar relatórios de bugs no menu do botão liga/desliga"</string>
<string name="keep_screen_on" msgid="1187161672348797558">"Permanecer ativo"</string>
- <string name="keep_screen_on_summary" msgid="1510731514101925829">"A tela nunca entrará em suspensão enquanto estiver carregando"</string>
+ <string name="keep_screen_on_summary" msgid="1510731514101925829">"A tela nunca entra em suspensão enquanto está carregando"</string>
<string name="bt_hci_snoop_log" msgid="7291287955649081448">"Ativar registro de rastreamento Bluetooth HCI"</string>
<string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Capturar pacotes de Bluetooth. Ative o Bluetooth depois de alterar essa configuração."</string>
<string name="oem_unlock_enable" msgid="5334869171871566731">"Desbloqueio de OEM"</string>
@@ -282,7 +282,7 @@
<string name="wifi_scan_throttling" msgid="2985624788509913617">"Limitar busca por Wi-Fi"</string>
<string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Ordem aleatória de MAC não persistente no Wi-Fi"</string>
<string name="mobile_data_always_on" msgid="8275958101875563572">"Dados móveis sempre ativos"</string>
- <string name="tethering_hardware_offload" msgid="4116053719006939161">"Aceleração de hardware de tethering"</string>
+ <string name="tethering_hardware_offload" msgid="4116053719006939161">"Aceleração de hardware para tethering"</string>
<string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Mostrar dispositivos Bluetooth sem nomes"</string>
<string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"Desativar volume absoluto"</string>
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Ativar Gabeldorsche"</string>
@@ -327,7 +327,7 @@
<string name="allow_mock_location_summary" msgid="179780881081354579">"Permitir locais fictícios"</string>
<string name="debug_view_attributes" msgid="3539609843984208216">"Ativar visualização de inspeção de atributo"</string>
<string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Sempre manter dados móveis ativos, mesmo quando o Wi-Fi estiver ativado (para troca rápida de rede)"</string>
- <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Usar aceleração de hardware de tethering quando disponível"</string>
+ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Usar aceleração de hardware para tethering quando disponível"</string>
<string name="adb_warning_title" msgid="7708653449506485728">"Permitir a depuração USB?"</string>
<string name="adb_warning_message" msgid="8145270656419669221">"A depuração USB serve apenas para fins de desenvolvimento. Use-a para copiar dados entre o computador e o dispositivo, instalar apps no seu aparelho sem notificação e ler dados de registro."</string>
<string name="adbwifi_warning_title" msgid="727104571653031865">"Permitir a depuração por Wi-Fi?"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index c38bd78..e6b1832 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -403,7 +403,7 @@
<string name="show_notification_channel_warnings" msgid="3448282400127597331">"Afișați avertismentele de pe canalul de notificări"</string>
<string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Afișați avertisment pe ecran când o aplicație postează o notificare fără canal valid"</string>
<string name="force_allow_on_external" msgid="9187902444231637880">"Forțați accesul aplicațiilor la stocarea externă"</string>
- <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Faceți ca orice aplicație eligibilă să fie scrisă în stocarea externă, indiferent de valorile manifestului"</string>
+ <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Permiteți scrierea oricărei aplicații eligibile în stocarea externă, indiferent de valorile manifestului"</string>
<string name="force_resizable_activities" msgid="7143612144399959606">"Forțați redimensionarea activităților"</string>
<string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permiteți redimensionarea tuturor activităților pentru modul cu ferestre multiple, indiferent de valorile manifestului."</string>
<string name="enable_freeform_support" msgid="7599125687603914253">"Activați ferestrele cu formă liberă"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 2d7ed11..6b74d5b 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -233,10 +233,10 @@
<string name="tethering_settings_not_available" msgid="266821736434699780">"Этот пользователь не может изменять настройки режима модема"</string>
<string name="apn_settings_not_available" msgid="1147111671403342300">"Этот пользователь не может изменять настройки точки доступа"</string>
<string name="enable_adb" msgid="8072776357237289039">"Отладка по USB"</string>
- <string name="enable_adb_summary" msgid="3711526030096574316">"Включить режим отладки при подключении к компьютеру по USB"</string>
- <string name="clear_adb_keys" msgid="3010148733140369917">"Отозвать доступ для USB-отладки"</string>
+ <string name="enable_adb_summary" msgid="3711526030096574316">"Режим отладки при подключении по USB"</string>
+ <string name="clear_adb_keys" msgid="3010148733140369917">"Отозвать доступ для отладки по USB"</string>
<string name="enable_adb_wireless" msgid="6973226350963971018">"Отладка по Wi-Fi"</string>
- <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Режим отладки при подключении к сети Wi‑Fi"</string>
+ <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Режим отладки при подключении по Wi‑Fi"</string>
<string name="adb_wireless_error" msgid="721958772149779856">"Ошибка"</string>
<string name="adb_wireless_settings" msgid="2295017847215680229">"Отладка по Wi-Fi"</string>
<string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Чтобы увидеть и использовать доступные устройства, включите отладку по Wi-Fi."</string>
@@ -281,7 +281,7 @@
<string name="wifi_verbose_logging" msgid="1785910450009679371">"Подробный журнал Wi‑Fi"</string>
<string name="wifi_scan_throttling" msgid="2985624788509913617">"Ограничивать поиск сетей Wi‑Fi"</string>
<string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Случайные MAC-адреса в сети Wi-Fi"</string>
- <string name="mobile_data_always_on" msgid="8275958101875563572">"Не отключать мобильный Интернет"</string>
+ <string name="mobile_data_always_on" msgid="8275958101875563572">"Не отключать мобильный интернет"</string>
<string name="tethering_hardware_offload" msgid="4116053719006939161">"Аппаратное ускорение в режиме модема"</string>
<string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Показывать Bluetooth-устройства без названий"</string>
<string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"Отключить абсолютный уровень громкости"</string>
@@ -312,7 +312,7 @@
<string name="wifi_display_certification_summary" msgid="8111151348106907513">"Показывать параметры сертификации беспроводных мониторов"</string>
<string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Вести подробный журнал, показывать RSSI для каждого SSID при выборе сети"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Уменьшает расход заряда батареи и улучшает работу сети"</string>
- <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Если этот режим активирован, MAC-адрес устройства может меняться при каждом подключении к сети, в которой возможно создание случайных MAC-адресов."</string>
+ <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Если этот режим активирован, MAC-адрес устройства может меняться при каждом подключении к сети, в которой возможно создание случайных MAC-адресов"</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"Сеть с тарификацией трафика"</string>
<string name="wifi_unmetered_label" msgid="6174142840934095093">"Сеть без тарификации трафика"</string>
<string name="select_logd_size_title" msgid="1604578195914595173">"Размер буфера журнала"</string>
@@ -380,7 +380,7 @@
<string name="debug_layout" msgid="1659216803043339741">"Показывать границы элементов"</string>
<string name="debug_layout_summary" msgid="8825829038287321978">"Показывать границы обрезки, поля и т. п."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Отразить интерфейс"</string>
- <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Принудительно расположить элементы интерфейса справа налево во всех локалях"</string>
+ <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Принудительно расположить элементы интерфейса справа налево вне зависимости от региональных настроек"</string>
<string name="window_blurs" msgid="6831008984828425106">"Размытие на уровне окон"</string>
<string name="force_msaa" msgid="4081288296137775550">"Включить 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Включить 4x MSAA в приложениях OpenGL ES 2.0"</string>
@@ -448,7 +448,7 @@
<string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Протаномалия (красный/зеленый)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Тританомалия (синий/желтый)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Коррекция цвета"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Коррекция цвета поможет вам:<br/> <ol> <li>&nbsp;Добиться нужной цветопередачи.</li> <li>&nbsp;Убрать цвета, которые мешают сосредоточиться.</li> </ol>"</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Коррекция цвета поможет вам:<br/> <ol> <li>&nbsp;Добиться нужной цветопередачи.</li> <li>&nbsp;Включить черно-белый режим, чтобы меньше отвлекаться.</li> </ol>"</string>
<string name="daltonizer_type_overridden" msgid="4509604753672535721">"Новая настройка: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
<string name="power_remaining_settings_home_page" msgid="4885165789445462557">"Уровень заряда – <xliff:g id="PERCENTAGE">%1$s</xliff:g>. <xliff:g id="TIME_STRING">%2$s</xliff:g>."</string>
<string name="power_remaining_duration_only" msgid="8264199158671531431">"Заряда хватит примерно на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -553,7 +553,7 @@
<string name="storage_category" msgid="2287342585424631813">"Хранилище"</string>
<string name="shared_data_title" msgid="1017034836800864953">"Общие данные"</string>
<string name="shared_data_summary" msgid="5516326713822885652">"Просмотр и изменение общих данных"</string>
- <string name="shared_data_no_blobs_text" msgid="3108114670341737434">"Нет общих данных для этого пользователя."</string>
+ <string name="shared_data_no_blobs_text" msgid="3108114670341737434">"Для этого пользователя нет общих данных"</string>
<string name="shared_data_query_failure_text" msgid="3489828881998773687">"При получении общих данных произошла ошибка. Повторите попытку."</string>
<string name="blob_id_text" msgid="8680078988996308061">"Идентификатор общих данных: <xliff:g id="BLOB_ID">%d</xliff:g>"</string>
<string name="blob_expires_text" msgid="7882727111491739331">"Срок действия истекает <xliff:g id="DATE">%s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index d5dd6c5..fd2406e 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -173,9 +173,9 @@
<string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Odstránené aplikácie"</string>
<string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Odstránené aplikácie a používatelia"</string>
<string name="data_usage_ota" msgid="7984667793701597001">"Aktualizácie systému"</string>
- <string name="tether_settings_title_usb" msgid="3728686573430917722">"Pripojenie cez USB"</string>
+ <string name="tether_settings_title_usb" msgid="3728686573430917722">"Tethering cez USB"</string>
<string name="tether_settings_title_wifi" msgid="4803402057533895526">"Prenosný prístupový bod"</string>
- <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Pripojenie cez Bluetooth"</string>
+ <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Tethering cez Bluetooth"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Zdieľané pripojenie"</string>
<string name="tether_settings_title_all" msgid="8910259483383010470">"Zdieľané pripojenie a prenosný hotspot"</string>
<string name="managed_user_title" msgid="449081789742645723">"Všetky pracovné aplikácie"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index a609ab8..c413bee 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"Optično branje kode QR"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"Če želite začeti poslušati, postavite spodnjo kodo QR na sredino."</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"Koda QR nima pravilne oblike zapisa."</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Želite ustaviti oddajanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Če oddajate aplikacijo <xliff:g id="SWITCHAPP">%1$s</xliff:g> ali spremenite izhod, bo trenutno oddajanje ustavljeno."</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Oddajaj aplikacijo <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Sprememba izhoda"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 9a5d1ee..e1bb766 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -233,7 +233,7 @@
<string name="tethering_settings_not_available" msgid="266821736434699780">"இவரால் இணைப்புமுறை அமைப்புகளை மாற்ற முடியாது"</string>
<string name="apn_settings_not_available" msgid="1147111671403342300">"இவரால் ஆக்சஸ் பாயிண்ட் நேம் அமைப்புகளை மாற்ற முடியாது"</string>
<string name="enable_adb" msgid="8072776357237289039">"USB பிழைதிருத்தம்"</string>
- <string name="enable_adb_summary" msgid="3711526030096574316">"USB இணைக்கப்பட்டிருக்கும்போது பிழைத்திருத்தப் பயன்முறையை அமை"</string>
+ <string name="enable_adb_summary" msgid="3711526030096574316">"USB இணைக்கப்பட்டிருக்கும்போது பிழைத்திருத்தப் பயன்முறை இயக்கப்படும்"</string>
<string name="clear_adb_keys" msgid="3010148733140369917">"USB பிழைத்திருத்த அங்கீகரிப்புகளை நிராகரி"</string>
<string name="enable_adb_wireless" msgid="6973226350963971018">"வைஃபை பிழைதிருத்தம்"</string>
<string name="enable_adb_wireless_summary" msgid="7344391423657093011">"வைஃபையை இணைக்கும்போது பிழைதிருத்தப் பயன்முறை இயக்கப்படும்"</string>
@@ -309,8 +309,8 @@
<string name="private_dns_mode_provider" msgid="3619040641762557028">"தனிப்பட்ட DNS வழங்குநரின் ஹோஸ்ட் பெயர்"</string>
<string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"DNS வழங்குநரின் ஹோஸ்ட் பெயரை உள்ளிடவும்"</string>
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"இணைக்க முடியவில்லை"</string>
- <string name="wifi_display_certification_summary" msgid="8111151348106907513">"வயர்லெஸ் காட்சி சான்றுக்கான விருப்பங்களைக் காட்டு"</string>
- <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"வைஃபை நுழைவு அளவை அதிகரித்து, வைஃபை தேர்வுக் கருவியில் ஒவ்வொன்றிற்கும் SSID RSSI ஐ காட்டுக"</string>
+ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"வயர்லெஸ் காட்சி சான்றுக்கான விருப்பங்களைக் காட்டும்"</string>
+ <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"வைஃபை நுழைவு அளவை அதிகரித்து, வைஃபை தேர்வுக் கருவியில் ஒவ்வொன்றிற்கும் SSID RSSI ஐ காட்டும்"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"பேட்டரி தீர்ந்துபோவதைக் குறைத்து நெட்வொர்க்கின் செயல்திறனை மேம்படுத்தும்"</string>
<string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"இந்தப் பயன்முறை இயக்கப்பட்டிருக்கும்போது இந்தச் சாதனத்தின் MAC முகவரி ஒவ்வொரு முறை \'MAC முகவரியை ரேண்டம் ஆக்குதல்\' இயக்கப்பட்டிருக்கும் நெட்வொர்க்குடன் இணைக்கப்படும்போதும் மாறக்கூடும்."</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"கட்டண நெட்வொர்க்"</string>
@@ -347,7 +347,7 @@
<string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP சரிபார்க்கும் செயல்பாடுகளை அமை"</string>
<string name="debug_debugging_category" msgid="535341063709248842">"பிழைதிருத்தம்"</string>
<string name="debug_app" msgid="8903350241392391766">"பிழைத்திருத்தப் பயன்பாட்டைத் தேர்ந்தெடுக்கவும்"</string>
- <string name="debug_app_not_set" msgid="1934083001283807188">"பிழைத்திருத்தப் ஆப்ஸ் அமைக்கப்படவில்லை"</string>
+ <string name="debug_app_not_set" msgid="1934083001283807188">"பிழைத்திருத்த ஆப்ஸ் அமைக்கப்படவில்லை"</string>
<string name="debug_app_set" msgid="6599535090477753651">"பிழைதிருத்தும் ஆப்ஸ்: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="select_application" msgid="2543228890535466325">"பயன்பாட்டைத் தேர்ந்தெடுக்கவும்"</string>
<string name="no_application" msgid="9038334538870247690">"ஒன்றுமில்லை"</string>
@@ -359,28 +359,28 @@
<string name="media_category" msgid="8122076702526144053">"மீடியா"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"கண்காணி"</string>
<string name="strict_mode" msgid="889864762140862437">"நிலையான பயன்முறை இயக்கப்பட்டது"</string>
- <string name="strict_mode_summary" msgid="1838248687233554654">"முக்கியத் தொடரிழையில் நீண்ட நேரம் செயல்படும்போது திரையைக் காட்சிப்படுத்து"</string>
+ <string name="strict_mode_summary" msgid="1838248687233554654">"முக்கியத் தொடரிழையில் நீண்ட நேரம் செயல்படும்போது திரையைக் காட்சிப்படுத்தும்"</string>
<string name="pointer_location" msgid="7516929526199520173">"குறிப்பான் இடம்"</string>
<string name="pointer_location_summary" msgid="957120116989798464">"திரையின் மேல் அடுக்கானது தற்போது தொடப்பட்டிருக்கும் தரவைக் காண்பிக்கிறது"</string>
<string name="show_touches" msgid="8437666942161289025">"தட்டல்களைக் காட்டு"</string>
- <string name="show_touches_summary" msgid="3692861665994502193">"தட்டல்களின் போது காட்சி அறிகுறிகளைக் காட்டு"</string>
+ <string name="show_touches_summary" msgid="3692861665994502193">"தட்டல்களின் போது காட்சி அறிகுறிகளைக் காட்டும்"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"மேலோட்ட புதுப்பிப்புகளைக் காட்டு"</string>
- <string name="show_screen_updates_summary" msgid="2126932969682087406">"சாளரத்தின் பரப்புநிலைகள் புதுப்பிக்கப்படும்போது, அவற்றை முழுவதுமாகக் காட்டு"</string>
+ <string name="show_screen_updates_summary" msgid="2126932969682087406">"சாளரத்தின் பரப்புநிலைகள் புதுப்பிக்கப்படும்போது, அவற்றை முழுவதுமாகக் காட்டும்"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"வியூ அப்டேட்ஸைக் காட்டு"</string>
- <string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"வரையும்போது, சாளரங்களில் காட்சிகளைக் காட்டு"</string>
+ <string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"வரையும்போது, சாளரங்களில் காட்சிகளைக் காட்டும்"</string>
<string name="show_hw_layers_updates" msgid="5268370750002509767">"வன்பொருள் லேயர்களின் புதுப்பிப்புகளைக் காட்டு"</string>
- <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"வன்பொருள் லேயர்களைப் புதுப்பிக்கும்போது, அவற்றைப் பச்சை நிறத்தில் காட்டு"</string>
+ <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"வன்பொருள் லேயர்களைப் புதுப்பிக்கும்போது, அவற்றைப் பச்சை நிறத்தில் காட்டும்"</string>
<string name="debug_hw_overdraw" msgid="8944851091008756796">"GPU ஓவர்டிரா பிழைதிருத்து"</string>
<string name="disable_overlays" msgid="4206590799671557143">"HW மேலடுக்குகளை முடக்கு"</string>
<string name="disable_overlays_summary" msgid="1954852414363338166">"திரைத் தொகுத்தலுக்கு எப்போதும் GPU ஐப் பயன்படுத்து"</string>
<string name="simulate_color_space" msgid="1206503300335835151">"வண்ணத்தின் இடைவெளியை உருவகப்படுத்து"</string>
<string name="enable_opengl_traces_title" msgid="4638773318659125196">"OpenGL தடயங்களை இயக்கு"</string>
<string name="usb_audio_disable_routing" msgid="3367656923544254975">"USB ஆடியோ ரூட்டிங்கை முடக்கு"</string>
- <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"USB ஆடியோ உபகரணத்திற்கு தன்னியக்க ரூட்டிங்கை முடக்கு"</string>
+ <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"USB ஆடியோ உபகரணத்திற்கு தன்னியக்க ரூட்டிங்கை முடக்கும்"</string>
<string name="debug_layout" msgid="1659216803043339741">"தளவமைப்பு எல்லைகளைக் காட்டு"</string>
<string name="debug_layout_summary" msgid="8825829038287321978">"கிளிப் எல்லைகள், ஓரங்கள், மேலும் பலவற்றைக் காட்டு"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL தளவமைப்பின் திசையை வலியுறுத்து"</string>
- <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"எல்லா மொழிகளுக்கும் திரையின் தளவமைப்பு திசையை RTL க்கு மாற்று"</string>
+ <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"எல்லா மொழிகளுக்கும் திரையின் தளவமைப்பு திசையை RTL க்கு மாற்றும்"</string>
<string name="window_blurs" msgid="6831008984828425106">"திரை-நிலை மங்கலை அனுமதி"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA ஐ வலியுறுத்து"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 பயன்பாடுகளில் 4x MSAA ஐ இயக்கு"</string>
@@ -396,7 +396,7 @@
<string name="overlay_display_devices_title" msgid="5411894622334469607">"இரண்டாம்நிலைக் காட்சிகளை உருவகப்படுத்து"</string>
<string name="debug_applications_category" msgid="5394089406638954196">"ஆப்ஸ்"</string>
<string name="immediately_destroy_activities" msgid="1826287490705167403">"செயல்பாடுகளை வைத்திருக்காதே"</string>
- <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"பயனர் வெளியேறியதும் செயல்பாடுகளை நீக்கு"</string>
+ <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"பயனர் வெளியேறியதும் செயல்பாடுகளை நீக்கும்"</string>
<string name="app_process_limit_title" msgid="8361367869453043007">"பின்புலச் செயல்முறை வரம்பு"</string>
<string name="show_all_anrs" msgid="9160563836616468726">"பின்புல ANRகளைக் காட்டு"</string>
<string name="show_all_anrs_summary" msgid="8562788834431971392">"பின்புல ஆப்ஸுக்கு, ஆப்ஸ் பதிலளிக்கவில்லை என்ற செய்தியைக் காட்டும்"</string>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index bca00c2..52554e2 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -192,7 +192,7 @@
<string-array name="window_animation_scale_entries">
<item msgid="2675263395797191850">"యానిమేషన్ ఆఫ్లో ఉంది"</item>
<item msgid="5790132543372767872">"యానిమేషన్ ప్రమాణం .5x"</item>
- <item msgid="2529692189302148746">"యానిమేషన్ ప్రమాణం 1x"</item>
+ <item msgid="2529692189302148746">"యానిమేషన్ స్కేల్ 1x"</item>
<item msgid="8072785072237082286">"యానిమేషన్ ప్రమాణం 1.5x"</item>
<item msgid="3531560925718232560">"యానిమేషన్ ప్రమాణం 2x"</item>
<item msgid="4542853094898215187">"యానిమేషన్ ప్రమాణం 5x"</item>
@@ -201,7 +201,7 @@
<string-array name="transition_animation_scale_entries">
<item msgid="3376676813923486384">"యానిమేషన్ ఆఫ్లో ఉంది"</item>
<item msgid="753422683600269114">"యానిమేషన్ ప్రమాణం .5x"</item>
- <item msgid="3695427132155563489">"యానిమేషన్ ప్రమాణం 1x"</item>
+ <item msgid="3695427132155563489">"యానిమేషన్ స్కేల్ 1x"</item>
<item msgid="9032615844198098981">"యానిమేషన్ ప్రమాణం 1.5x"</item>
<item msgid="8473868962499332073">"యానిమేషన్ ప్రమాణం 2x"</item>
<item msgid="4403482320438668316">"యానిమేషన్ ప్రమాణం 5x"</item>
@@ -210,7 +210,7 @@
<string-array name="animator_duration_scale_entries">
<item msgid="6416998593844817378">"యానిమేషన్ ఆఫ్లో ఉంది"</item>
<item msgid="875345630014338616">"యానిమేషన్ ప్రమాణం .5x"</item>
- <item msgid="2753729231187104962">"యానిమేషన్ ప్రమాణం 1x"</item>
+ <item msgid="2753729231187104962">"యానిమేషన్ స్కేల్ 1x"</item>
<item msgid="1368370459723665338">"యానిమేషన్ ప్రమాణం 1.5x"</item>
<item msgid="5768005350534383389">"యానిమేషన్ ప్రమాణం 2x"</item>
<item msgid="3728265127284005444">"యానిమేషన్ ప్రమాణం 5x"</item>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 97bd52e..41db0cc 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -282,7 +282,7 @@
<string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi స్కాన్ కుదింపు"</string>
<string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Wi‑Fi నిరంతరం కాని MAC ర్యాండమైజేషన్"</string>
<string name="mobile_data_always_on" msgid="8275958101875563572">"మొబైల్ డేటాని ఎల్లప్పుడూ యాక్టివ్గా ఉంచు"</string>
- <string name="tethering_hardware_offload" msgid="4116053719006939161">"టెథెరింగ్ హార్డ్వేర్ వేగవృద్ధి"</string>
+ <string name="tethering_hardware_offload" msgid="4116053719006939161">"టెథెరింగ్ హార్డ్వేర్ యాగ్జిలరేషన్"</string>
<string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"పేర్లు లేని బ్లూటూత్ పరికరాలు చూపించు"</string>
<string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"సంపూర్ణ వాల్యూమ్ను డిజేబుల్ చేయి"</string>
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorscheను ఎనేబుల్ చేయి"</string>
@@ -310,7 +310,7 @@
<string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"DNS ప్రొవైడర్ హోస్ట్పేరును ఎంటర్ చేయండి"</string>
<string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"కనెక్ట్ చేయడం సాధ్యపడలేదు"</string>
<string name="wifi_display_certification_summary" msgid="8111151348106907513">"వైర్లెస్ డిస్ప్లే సర్టిఫికేషన్ ఆప్షన్లను చూపు"</string>
- <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi ఎంపికలో SSID RSSI ప్రకారం చూపబడే Wi‑Fi లాగింగ్ స్థాయిని పెంచండి"</string>
+ <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi పికర్లో SSID RSSI ప్రకారం చూపబడే Wi‑Fi లాగింగ్ స్థాయిని పెంచండి"</string>
<string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"బ్యాటరీ శక్తి వినియోగాన్ని తగ్గించి & నెట్వర్క్ పనితీరును మెరుగుపరుస్తుంది"</string>
<string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"ఈ మోడ్ ఎనేబుల్ అయ్యాక, MAC ర్యాండమైజేషన్ను ఎనేబుల్ చేసిన నెట్వర్క్తో కనెక్ట్ అయ్యే ప్రతిసారీ ఈ పరికరం MAC అడ్రస్ను మారవచ్చు."</string>
<string name="wifi_metered_label" msgid="8737187690304098638">"గణించబడుతోంది"</string>
@@ -327,7 +327,7 @@
<string name="allow_mock_location_summary" msgid="179780881081354579">"డమ్మీ లొకేషన్లను అనుమతించండి"</string>
<string name="debug_view_attributes" msgid="3539609843984208216">"వీక్షణ అట్రిబ్యూట్ పర్యవేక్షణను ఎనేబుల్ చేయి"</string>
<string name="mobile_data_always_on_summary" msgid="1112156365594371019">"ఎల్లప్పుడూ మొబైల్ డేటాను యాక్టివ్గా ఉంచు, Wi‑Fi యాక్టివ్గా ఉన్నా కూడా (వేగవంతమైన నెట్వర్క్ మార్పు కోసం)."</string>
- <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"అందుబాటులో ఉంటే టెథెరింగ్ హార్డ్వేర్ వేగవృద్ధిని ఉపయోగించండి"</string>
+ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"అందుబాటులో ఉంటే గనుక టెథెరింగ్ హార్డ్వేర్ యాగ్జిలరేషన్ను ఉపయోగించండి"</string>
<string name="adb_warning_title" msgid="7708653449506485728">"USB డీబగ్గింగ్ను అనుమతించాలా?"</string>
<string name="adb_warning_message" msgid="8145270656419669221">"USB డీబగ్గింగ్ అనేది అభివృద్ధి ప్రయోజనాల కోసం మాత్రమే ఉద్దేశించబడింది. మీ కంప్యూటర్ మరియు మీ పరికరం మధ్య డేటాను కాపీ చేయడానికి, నోటిఫికేషన్ లేకుండా మీ పరికరంలో యాప్లను ఇన్స్టాల్ చేయడానికి మరియు లాగ్ డేటాను చదవడానికి దీన్ని ఉపయోగించండి."</string>
<string name="adbwifi_warning_title" msgid="727104571653031865">"వైర్లెస్ డీబగ్గింగ్ను అనుమతించాలా?"</string>
@@ -352,20 +352,20 @@
<string name="select_application" msgid="2543228890535466325">"యాప్ను ఎంచుకోండి"</string>
<string name="no_application" msgid="9038334538870247690">"ఏదీ వద్దు"</string>
<string name="wait_for_debugger" msgid="7461199843335409809">"డీబగ్గర్ కోసం వేచి ఉండండి"</string>
- <string name="wait_for_debugger_summary" msgid="6846330006113363286">"డీబగ్ చేయబడిన యాప్ అమలు కావడానికి ముందు జోడించాల్సిన డీబగ్గర్ కోసం వేచి ఉంటుంది"</string>
+ <string name="wait_for_debugger_summary" msgid="6846330006113363286">"డీబగ్ చేయబడిన యాప్, ఎగ్జిక్యూట్ కావడానికి ముందు జోడించాల్సిన డీబగ్గర్ కోసం వేచి ఉంటుంది"</string>
<string name="debug_input_category" msgid="7349460906970849771">"ఇన్పుట్"</string>
<string name="debug_drawing_category" msgid="5066171112313666619">"డ్రాయింగ్"</string>
- <string name="debug_hw_drawing_category" msgid="5830815169336975162">"హార్డ్వేర్తో వేగవంతమైన రెండరింగ్"</string>
+ <string name="debug_hw_drawing_category" msgid="5830815169336975162">"హార్డ్వేర్ యాగ్జిలరేషన్ ఆధారిత రెండరింగ్"</string>
<string name="media_category" msgid="8122076702526144053">"మీడియా"</string>
<string name="debug_monitoring_category" msgid="1597387133765424994">"పర్యవేక్షణ"</string>
<string name="strict_mode" msgid="889864762140862437">"ఖచ్చితమైన మోడ్ ప్రారంభించబడింది"</string>
<string name="strict_mode_summary" msgid="1838248687233554654">"యాప్లు ప్రధాన థ్రెడ్లో సుదీర్ఘ చర్యలు చేసేటప్పుడు స్క్రీన్ను ఫ్లాష్ చేయండి"</string>
<string name="pointer_location" msgid="7516929526199520173">"పాయింటర్ లొకేషన్"</string>
- <string name="pointer_location_summary" msgid="957120116989798464">"ప్రస్తుత స్పర్శ డేటాను చూపుతోన్న స్క్రీన్"</string>
+ <string name="pointer_location_summary" msgid="957120116989798464">"ప్రస్తుత టచ్ డేటాను చూపుతోన్న స్క్రీన్"</string>
<string name="show_touches" msgid="8437666942161289025">"నొక్కినవి చూపు"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"నొక్కినప్పుడు దృశ్యపరమైన ప్రతిస్పందన చూపు"</string>
- <string name="show_screen_updates" msgid="2078782895825535494">"సర్ఫేస్ అప్డేట్లను చూపండి"</string>
- <string name="show_screen_updates_summary" msgid="2126932969682087406">"పూర్తి విండో ఉపరితలాలు అప్డేట్ చేయబడినప్పుడు వాటిని ఫ్లాష్ చేయండి"</string>
+ <string name="show_screen_updates" msgid="2078782895825535494">"సర్ఫేస్ అప్డేట్లను చూపు"</string>
+ <string name="show_screen_updates_summary" msgid="2126932969682087406">"విండో సర్ఫేస్లన్నీ అప్డేట్ అయితే ఫ్లాష్ చేయి"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"వీక్షణ అప్డేట్లను చూపు"</string>
<string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"గీసినప్పుడు విండోల లోపల వీక్షణలను ఫ్లాష్ చేయి"</string>
<string name="show_hw_layers_updates" msgid="5268370750002509767">"హార్డ్వేర్ లేయర్ల అప్డేట్లను చూపు"</string>
@@ -373,16 +373,16 @@
<string name="debug_hw_overdraw" msgid="8944851091008756796">"GPU ఓవర్డ్రాను డీబగ్ చేయండి"</string>
<string name="disable_overlays" msgid="4206590799671557143">"డిజేబుల్- HW ఓవర్లేలు"</string>
<string name="disable_overlays_summary" msgid="1954852414363338166">"స్క్రీన్ కంపాజిటింగ్కు ఎల్లప్పుడూ GPUని ఉపయోగించు"</string>
- <string name="simulate_color_space" msgid="1206503300335835151">"వివిధ రంగులను అనుకరించు"</string>
+ <string name="simulate_color_space" msgid="1206503300335835151">"రంగులను సిమ్యులేట్ చేయి"</string>
<string name="enable_opengl_traces_title" msgid="4638773318659125196">"OpenGL ట్రేస్లను ప్రారంభించండి"</string>
<string name="usb_audio_disable_routing" msgid="3367656923544254975">"USB ఆడియో రూటింగ్ నిలిపివేయి"</string>
<string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"USB ఆడియో పరికరాలకు ఆటోమేటిక్ రూటింగ్ను నిలిపివేయండి"</string>
- <string name="debug_layout" msgid="1659216803043339741">"లేఅవుట్ బౌండ్లు చూపు"</string>
+ <string name="debug_layout" msgid="1659216803043339741">"లేఅవుట్ హద్దులను చూపు"</string>
<string name="debug_layout_summary" msgid="8825829038287321978">"క్లిప్ సరిహద్దులు, అంచులు మొ. చూపు"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL లేఅవుట్ దిశను నిర్బంధం చేయండి"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"అన్ని లొకేల్ల కోసం RTLకి స్క్రీన్ లేఅవుట్ దిశను నిర్భందించు"</string>
<string name="window_blurs" msgid="6831008984828425106">"విండో-స్థాయి బ్లర్ అనుమతించు"</string>
- <string name="force_msaa" msgid="4081288296137775550">"నిర్భందం 4x MSAA"</string>
+ <string name="force_msaa" msgid="4081288296137775550">"4x MSAA అమలు తప్పనిసరి"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 యాప్లలో 4x MSAAను ప్రారంభించండి"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"దీర్ఘ చతురస్రం కాని క్లిప్ చర్యలను డీబగ్ చేయండి"</string>
<string name="track_frame_time" msgid="522674651937771106">"ప్రొఫైల్ HWUI రెండరింగ్"</string>
@@ -390,13 +390,13 @@
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"డీబగ్ యాప్ల కోసం GPU డీబగ్ లేయర్లను లోడ్ చేయడాన్ని అనుమతించండి"</string>
<string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"వివరణాత్మక వెండార్ లాగింగ్ను ఎనేబుల్ చేయండి"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"బగ్ రిపోర్ట్లలో అదనపు పరికర-నిర్దిష్ట వెండార్ లాగ్లను చేర్చండి, అవి ప్రైవేట్ సమాచారాన్ని కలిగి ఉండవచ్చు, మరింత బ్యాటరీని, మరియు/లేదా మరింత స్టోరేజ్ను ఉపయోగించవచ్చు."</string>
- <string name="window_animation_scale_title" msgid="5236381298376812508">"విండో యానిమేషన్ ప్రమాణం"</string>
- <string name="transition_animation_scale_title" msgid="1278477690695439337">"పరివర్తన యానిమేషన్ ప్రమాణం"</string>
- <string name="animator_duration_scale_title" msgid="7082913931326085176">"యానిమేటర్ వ్యవధి ప్రమాణం"</string>
- <string name="overlay_display_devices_title" msgid="5411894622334469607">"ప్రత్యామ్నాయ ప్రదర్శనలను అనుకరించండి"</string>
+ <string name="window_animation_scale_title" msgid="5236381298376812508">"విండో యానిమేషన్ స్కేల్"</string>
+ <string name="transition_animation_scale_title" msgid="1278477690695439337">"ట్రాన్సిషన్ యానిమేషన్ స్కేల్"</string>
+ <string name="animator_duration_scale_title" msgid="7082913931326085176">"యానిమేటర్ వ్యవధి స్కేల్"</string>
+ <string name="overlay_display_devices_title" msgid="5411894622334469607">"ఇతర డిస్ప్లేలను సిమ్యులేట్ చేయండి"</string>
<string name="debug_applications_category" msgid="5394089406638954196">"యాప్లు"</string>
<string name="immediately_destroy_activities" msgid="1826287490705167403">"యాక్టివిటీస్ను ఉంచవద్దు"</string>
- <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"యూజర్ నిష్క్రమించాక పూర్తి యాక్టివిటీ తొలగింపు"</string>
+ <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"యూజర్ నిష్క్రమించాక పూర్తి యాక్టివిటీని తొలగించు"</string>
<string name="app_process_limit_title" msgid="8361367869453043007">"బ్యాక్గ్రౌండ్ ప్రాసెస్ పరిమితి"</string>
<string name="show_all_anrs" msgid="9160563836616468726">"బ్యాక్గ్రౌండ్ ANRలను చూపు"</string>
<string name="show_all_anrs_summary" msgid="8562788834431971392">"బ్యాక్గ్రౌండ్ యాప్ల కోసం యాప్ ప్రతిస్పందించడం లేదు అనే డైలాగ్ను చూపు"</string>
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"QR కోడ్ను స్కాన్ చేయండి"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"వినడం ప్రారంభించడానికి, కింద ఉన్న QR కోడ్ను మధ్యలో ఉంచండి"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"QR కోడ్ చెల్లుబాటు అయ్యే ఫార్మాట్లో లేదు"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g> ప్రసారం చేయడాన్ని ఆపివేయాలా?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"మీరు <xliff:g id="SWITCHAPP">%1$s</xliff:g> ప్రసారం చేస్తే లేదా అవుట్పుట్ను మార్చినట్లయితే, మీ ప్రస్తుత ప్రసారం ఆగిపోతుంది"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ప్రసారం చేయండి"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"అవుట్పుట్ను మార్చండి"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 96b40d5..41ef1e4 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -226,9 +226,9 @@
<string name="category_personal" msgid="6236798763159385225">"ส่วนตัว"</string>
<string name="category_work" msgid="4014193632325996115">"ที่ทำงาน"</string>
<string name="development_settings_title" msgid="140296922921597393">"ตัวเลือกสำหรับนักพัฒนาแอป"</string>
- <string name="development_settings_enable" msgid="4285094651288242183">"เปิดใช้ตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์"</string>
+ <string name="development_settings_enable" msgid="4285094651288242183">"เปิดใช้ตัวเลือกสำหรับนักพัฒนาแอป"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"ตั้งค่าตัวเลือกสำหรับการพัฒนาแอปพลิเคชัน"</string>
- <string name="development_settings_not_available" msgid="355070198089140951">"ตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ไม่สามารถใช้ได้สำหรับผู้ใช้นี้"</string>
+ <string name="development_settings_not_available" msgid="355070198089140951">"ตัวเลือกสำหรับนักพัฒนาแอปไม่สามารถใช้ได้สำหรับผู้ใช้นี้"</string>
<string name="vpn_settings_not_available" msgid="2894137119965668920">"การตั้งค่า VPN ไม่สามารถใช้ได้สำหรับผู้ใช้รายนี้"</string>
<string name="tethering_settings_not_available" msgid="266821736434699780">"การตั้งค่าการปล่อยสัญญาณไม่สามารถใช้ได้สำหรับผู้ใช้รายนี้"</string>
<string name="apn_settings_not_available" msgid="1147111671403342300">"การตั้งค่าจุดเข้าใช้งานไม่สามารถใช้ได้สำหรับผู้ใช้รายนี้"</string>
@@ -352,7 +352,7 @@
<string name="select_application" msgid="2543228890535466325">"เลือกแอปพลิเคชัน"</string>
<string name="no_application" msgid="9038334538870247690">"ไม่มี"</string>
<string name="wait_for_debugger" msgid="7461199843335409809">"รอโปรแกรมแก้ไขข้อบกพร่อง"</string>
- <string name="wait_for_debugger_summary" msgid="6846330006113363286">"แอปพลิเคชันที่มีการแก้ปัญหาจะรอให้โปรแกรมแก้ไขข้อบกพร่องแนบข้อมูลก่อนปฏิบัติการ"</string>
+ <string name="wait_for_debugger_summary" msgid="6846330006113363286">"แอปพลิเคชันที่มีการแก้ไขข้อบกพร่องจะรอให้โปรแกรมแก้ไขข้อบกพร่องแนบข้อมูลก่อนปฏิบัติการ"</string>
<string name="debug_input_category" msgid="7349460906970849771">"อินพุต"</string>
<string name="debug_drawing_category" msgid="5066171112313666619">"การวาดภาพ"</string>
<string name="debug_hw_drawing_category" msgid="5830815169336975162">"การแสดงผลที่มีการเร่งด้วยฮาร์ดแวร์"</string>
@@ -379,8 +379,8 @@
<string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"ปิดการกำหนดเส้นทางโดยอัตโนมัติไปยังอุปกรณ์ต่อพ่วงเสียงทาง USB"</string>
<string name="debug_layout" msgid="1659216803043339741">"แสดงขอบของการจัดวาง"</string>
<string name="debug_layout_summary" msgid="8825829038287321978">"แสดงหน้าปกคลิป ขอบ ฯลฯ"</string>
- <string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"บังคับทิศทางการจัดวาง RTL"</string>
- <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"บังคับทิศทางการจัดวางหน้าจอเป็น RTL สำหรับทุกภาษา"</string>
+ <string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"บังคับทิศทางการจัดวางขวาไปซ้าย"</string>
+ <string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"บังคับทิศทางการจัดวางหน้าจอเป็นขวาไปซ้ายสำหรับทุกภาษา"</string>
<string name="window_blurs" msgid="6831008984828425106">"อนุญาตการเบลอระดับหน้าต่าง"</string>
<string name="force_msaa" msgid="4081288296137775550">"บังคับใช้ 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"เปิดใช้งาน 4x MSAA ในแอปพลิเคชัน OpenGL ES 2.0"</string>
@@ -398,7 +398,7 @@
<string name="immediately_destroy_activities" msgid="1826287490705167403">"ไม่เก็บกิจกรรม"</string>
<string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ล้างทุกกิจกรรมทันทีที่ผู้ใช้ออกไป"</string>
<string name="app_process_limit_title" msgid="8361367869453043007">"ขีดจำกัดกระบวนการเบื้องหลัง"</string>
- <string name="show_all_anrs" msgid="9160563836616468726">"แสดง ANR พื้นหลัง"</string>
+ <string name="show_all_anrs" msgid="9160563836616468726">"แสดง ANR เบื้องหลัง"</string>
<string name="show_all_anrs_summary" msgid="8562788834431971392">"แสดงกล่องโต้ตอบ \"แอปไม่ตอบสนอง\" สำหรับแอปเบื้องหลัง"</string>
<string name="show_notification_channel_warnings" msgid="3448282400127597331">"แสดงคำเตือนจากช่องทางการแจ้งเตือน"</string>
<string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"แสดงคำเตือนบนหน้าจอเมื่อแอปโพสต์การแจ้งเตือนโดยไม่มีช่องทางที่ถูกต้อง"</string>
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"สแกนคิวอาร์โค้ด"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"ถือให้คิวอาร์โค้ดอยู่กลางช่องด้านล่างเพื่อเริ่มฟัง"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"คิวอาร์โค้ดมีรูปแบบไม่ถูกต้อง"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"หยุดการออกอากาศ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"หากคุณออกอากาศ <xliff:g id="SWITCHAPP">%1$s</xliff:g> หรือเปลี่ยนแปลงเอาต์พุต การออกอากาศในปัจจุบันจะหยุดลง"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"ออกอากาศ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"เปลี่ยนเอาต์พุต"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml
index 4e06a6d..bdd8706 100644
--- a/packages/SettingsLib/res/values-tl/arrays.xml
+++ b/packages/SettingsLib/res/values-tl/arrays.xml
@@ -55,7 +55,7 @@
</string-array>
<string-array name="hdcp_checking_summaries">
<item msgid="4045840870658484038">"Huwag kailanman gumamit ng pagsusuring HDCP"</item>
- <item msgid="8254225038262324761">"Gamitin lang ang pagsusuring HDCP para sa nilalamang DRM"</item>
+ <item msgid="8254225038262324761">"Gamitin ang pagsusuring HDCP para sa content na DRM lang"</item>
<item msgid="6421717003037072581">"Palaging gumamit ng pagsusuring HDCP"</item>
</string-array>
<string-array name="bt_hci_snoop_log_entries">
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 73d3dd5..7d4a4b4 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -266,7 +266,7 @@
<string name="bugreport_in_power" msgid="8664089072534638709">"Shortcut ng ulat sa bug"</string>
<string name="bugreport_in_power_summary" msgid="1885529649381831775">"Magpakita ng button sa power menu sa pagkuha ng ulat sa bug"</string>
<string name="keep_screen_on" msgid="1187161672348797558">"Manatiling gumagana"</string>
- <string name="keep_screen_on_summary" msgid="1510731514101925829">"Hindi kailanman hihinto ang screen kapag kinakargahan"</string>
+ <string name="keep_screen_on_summary" msgid="1510731514101925829">"Hindi kailanman hihinto ang screen kapag nagcha-charge"</string>
<string name="bt_hci_snoop_log" msgid="7291287955649081448">"I-enable ang Bluetooth HCI snoop log"</string>
<string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"I-capture ang mga Bluetooth packet. (I-toggle ang Bluetooth pagkatapos baguhin ang setting na ito)"</string>
<string name="oem_unlock_enable" msgid="5334869171871566731">"Pag-a-unlock ng OEM"</string>
@@ -367,7 +367,7 @@
<string name="show_screen_updates" msgid="2078782895825535494">"Ipakita update sa surface"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"I-flash ang buong window surface kapag nag-update"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"Ipakita update ng view"</string>
- <string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"I-flash mga view sa loob ng window kapag na-draw"</string>
+ <string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"I-flash ang views sa loob ng window kapag na-draw"</string>
<string name="show_hw_layers_updates" msgid="5268370750002509767">"Ipakita ang mga update ng hardware layers"</string>
<string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"I-flash nang berde ang hardware layer pag nag-update ito"</string>
<string name="debug_hw_overdraw" msgid="8944851091008756796">"I-debug ang GPU overdraw"</string>
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"I-scan ang QR code"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"Para simulang makinig, igitna ang QR code sa ibaba"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"Hindi valid na format ang QR code"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Ihinto ang pag-broadcast ng <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Kung magbo-broadcast ka ng <xliff:g id="SWITCHAPP">%1$s</xliff:g> o babaguhin mo ang output, hihinto ang iyong kasalukuyang broadcast"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"I-broadcast ang <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Baguhin ang output"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index cca694b..8ef368c 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -280,7 +280,7 @@
<string name="wifi_display_certification" msgid="1805579519992520381">"Kablosuz ekran sertifikası"</string>
<string name="wifi_verbose_logging" msgid="1785910450009679371">"Kablosuz Ayrıntılı Günlük Kaydını etkinleştir"</string>
<string name="wifi_scan_throttling" msgid="2985624788509913617">"Kablosuz ağ taramasını kısma"</string>
- <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Kablosuz kalıcı olmayan MAC rastgele hale getirme süreci"</string>
+ <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Kablosuz kalıcı olmayan MAC rastgele hale getirme modu"</string>
<string name="mobile_data_always_on" msgid="8275958101875563572">"Mobil veri her zaman etkin"</string>
<string name="tethering_hardware_offload" msgid="4116053719006939161">"Tethering donanım hızlandırıcısı"</string>
<string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Adsız Bluetooth cihazlarını göster"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index ebbd45e..5c53509 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -279,7 +279,7 @@
<string name="debug_networking_category" msgid="6829757985772659599">"نیٹ ورکنگ"</string>
<string name="wifi_display_certification" msgid="1805579519992520381">"وائرلیس ڈسپلے سرٹیفیکیشن"</string>
<string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi‑Fi وربوس لاگنگ فعال کریں"</string>
- <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi اسکین کو زبردستی روکا جا رہا ہے"</string>
+ <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi اسکین کو زبردستی روکنا"</string>
<string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"Wi-Fi غیر مستقل MAC کی رینڈمائزیشن"</string>
<string name="mobile_data_always_on" msgid="8275958101875563572">"موبائل ڈیٹا ہمیشہ فعال رکھیں"</string>
<string name="tethering_hardware_offload" msgid="4116053719006939161">"ٹیدرنگ ہارڈویئر سرعت کاری"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 7837779..52cc9cb 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -327,7 +327,7 @@
<string name="allow_mock_location_summary" msgid="179780881081354579">"Joylashuv emulyatsiyasiga ruxsat berish"</string>
<string name="debug_view_attributes" msgid="3539609843984208216">"Alomatlar tekshiruvini yoqish"</string>
<string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Mobil internet har doim yoniq tursin, hatto Wi-Fi yoniq bo‘lsa ham (bir tarmoqdan ikkinchisiga tezroq o‘tish uchun)."</string>
- <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Modem rejimida apparatli tezlashtirishdan foydalanish (agar mavjud bo‘lsa)"</string>
+ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Modem rejimida apparatli tezlatishdan foydalanish (mavjud bo‘lsa)."</string>
<string name="adb_warning_title" msgid="7708653449506485728">"USB orqali nosozliklarni tuzatishga ruxsat berilsinmi?"</string>
<string name="adb_warning_message" msgid="8145270656419669221">"USB orqali nosozliklarni aniqlash faqat dasturlash maqsadlarida yoqiladi. Undan maʼlumotlarni qurilmangiz va kompyuter o‘rtasida ko‘chirish, ilovalarni xabarnomasiz o‘rnatish va jurnal maʼlumotlarini o‘qish uchun foydalaniladi."</string>
<string name="adbwifi_warning_title" msgid="727104571653031865">"Wi-Fi orqali debagging uchun ruxsat berilsinmi?"</string>
@@ -375,14 +375,14 @@
<string name="disable_overlays_summary" msgid="1954852414363338166">"Ekranda tasvirlarni biriktirish uchun doim GPU ishlatilsin"</string>
<string name="simulate_color_space" msgid="1206503300335835151">"Rang maydonini simulyatsiyalash"</string>
<string name="enable_opengl_traces_title" msgid="4638773318659125196">"OpenGL trassasini yoqish"</string>
- <string name="usb_audio_disable_routing" msgid="3367656923544254975">"Audio uzatishni o‘ch. qo‘yish (USB)"</string>
- <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"Tashqi USB qurilmaga avto-yo‘naltirishni o‘ch. qo‘yish"</string>
+ <string name="usb_audio_disable_routing" msgid="3367656923544254975">"Audio uzatishni faolsizlantirish (USB)"</string>
+ <string name="usb_audio_disable_routing_summary" msgid="8768242894849534699">"Tashqi USB qurilmaga avto-yo‘naltirishni faolsizlantirish"</string>
<string name="debug_layout" msgid="1659216803043339741">"Elementlar hoshiyasi"</string>
<string name="debug_layout_summary" msgid="8825829038287321978">"Klip, maydon va h.k. chegaralarini ko‘rsatish"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"O‘ngdan chapga qarab yozish"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Barcha tillarda o‘ngdan chapga qarab yozish"</string>
<string name="window_blurs" msgid="6831008984828425106">"Oyna xiralashga ruxsat"</string>
- <string name="force_msaa" msgid="4081288296137775550">"4x MSAAni yoqish"</string>
+ <string name="force_msaa" msgid="4081288296137775550">"4x MSAA sozlamasini yoqish"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ilovasidan 4x MSAAni yoqish"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"To‘g‘ri burchakli bo‘lmagan kesishma amallarini tuzatish"</string>
<string name="track_frame_time" msgid="522674651937771106">"HWUI ishlash vaqtining hisobi"</string>
@@ -655,12 +655,8 @@
<string name="bt_le_audio_scan_qr_code" msgid="3521809854780392679">"QR kodni skanerlash"</string>
<string name="bt_le_audio_scan_qr_code_scanner" msgid="4679500020630341107">"Tinglashni boshlash uchun quyidagi QR kodni markazga joylang"</string>
<string name="bt_le_audio_qr_code_is_not_valid_format" msgid="6092191081849434734">"QR xato formatda"</string>
- <!-- no translation found for bt_le_audio_broadcast_dialog_title (5392738488989777074) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_sub_title (268234802198852753) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_switch_app (5749813313369517812) -->
- <skip />
- <!-- no translation found for bt_le_audio_broadcast_dialog_different_output (2638402023060391333) -->
- <skip />
+ <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga translatsiya toʻxtatilsinmi?"</string>
+ <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Agar <xliff:g id="SWITCHAPP">%1$s</xliff:g> ilovasiga translatsiya qilsangiz yoki ovoz chiqishini oʻzgartirsangiz, joriy translatsiya toʻxtab qoladi"</string>
+ <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ilovasiga translatsiya"</string>
+ <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Ovoz chiqishini oʻzgartirish"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index b669708..5280f10 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -369,7 +369,7 @@
<string name="show_hw_screen_updates" msgid="2021286231267747506">"显示视图更新"</string>
<string name="show_hw_screen_updates_summary" msgid="3539770072741435691">"绘图时闪烁显示窗口中的视图"</string>
<string name="show_hw_layers_updates" msgid="5268370750002509767">"显示硬件层更新"</string>
- <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Flash 硬件层在进行更新时会显示为绿色"</string>
+ <string name="show_hw_layers_updates_summary" msgid="5850955890493054618">"Flash 硬件层在更新时会显示为绿色"</string>
<string name="debug_hw_overdraw" msgid="8944851091008756796">"调试 GPU 过度绘制"</string>
<string name="disable_overlays" msgid="4206590799671557143">"停用 HW 叠加层"</string>
<string name="disable_overlays_summary" msgid="1954852414363338166">"始终使用 GPU 进行屏幕合成"</string>
diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml
index 8315e8b..cbc79d2 100644
--- a/packages/SettingsLib/res/values/dimens.xml
+++ b/packages/SettingsLib/res/values/dimens.xml
@@ -120,4 +120,18 @@
<dimen name="qrcode_preview_margin">40dp</dimen>
<dimen name="qrcode_preview_radius">30dp</dimen>
<dimen name="qrcode_icon_size">27dp</dimen>
+
+ <!-- Broadcast dialog -->
+ <dimen name="broadcast_dialog_title_img_margin_top">18dp</dimen>
+ <dimen name="broadcast_dialog_title_text_size">24sp</dimen>
+ <dimen name="broadcast_dialog_title_text_margin">16dp</dimen>
+ <dimen name="broadcast_dialog_title_text_margin_top">18dp</dimen>
+ <dimen name="broadcast_dialog_subtitle_text_size">14sp</dimen>
+ <dimen name="broadcast_dialog_icon_size">24dp</dimen>
+ <dimen name="broadcast_dialog_icon_margin_top">25dp</dimen>
+ <dimen name="broadcast_dialog_btn_radius">100dp</dimen>
+ <dimen name="broadcast_dialog_btn_margin_bottom">4dp</dimen>
+ <dimen name="broadcast_dialog_btn_text_size">16sp</dimen>
+ <dimen name="broadcast_dialog_btn_minHeight">44dp</dimen>
+ <dimen name="broadcast_dialog_margin">16dp</dimen>
</resources>
diff --git a/packages/SettingsLib/res/values/styles.xml b/packages/SettingsLib/res/values/styles.xml
index 28cd27b..3234515 100644
--- a/packages/SettingsLib/res/values/styles.xml
+++ b/packages/SettingsLib/res/values/styles.xml
@@ -39,4 +39,49 @@
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textDirection">locale</item>
</style>
+
+ <style name="BroadcastDialogTitleStyle">
+ <item name="android:textAppearance">@style/TextAppearanceBroadcastDialogTitle</item>
+ <item name="android:layout_marginStart">@dimen/broadcast_dialog_title_text_margin</item>
+ <item name="android:layout_marginEnd">@dimen/broadcast_dialog_title_text_margin</item>
+ <item name="android:layout_marginTop">@dimen/broadcast_dialog_title_text_margin_top</item>
+ <item name="android:layout_marginBottom">18dp</item>
+ </style>
+
+ <style name="TextAppearanceBroadcastDialogTitle" parent="@android:TextAppearance.DeviceDefault.Headline">
+ <item name="android:textSize">@dimen/broadcast_dialog_title_text_size</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:textDirection">locale</item>
+ <item name="android:ellipsize">end</item>
+ </style>
+
+ <style name="BroadcastDialogBodyStyle">
+ <item name="android:textAppearance">@style/TextAppearanceBroadcastDialogSubTitle</item>
+ <item name="android:layout_margin">@dimen/broadcast_dialog_title_text_margin</item>
+ </style>
+
+ <style name="TextAppearanceBroadcastDialogSubTitle" parent="@android:TextAppearance.DeviceDefault.Headline">
+ <item name="android:textSize">@dimen/broadcast_dialog_subtitle_text_size</item>
+ <item name="android:textColor">?android:attr/textColorSecondary</item>
+ <item name="android:textDirection">locale</item>
+ <item name="android:ellipsize">end</item>
+ </style>
+
+ <style name="BroadcastDialogButtonStyle">
+ <item name="android:textAppearance">@style/TextAppearanceBroadcastDialogButton</item>
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:layout_gravity">center</item>
+ <item name="android:gravity">center</item>
+ <item name="android:stateListAnimator">@null</item>
+ <item name="android:elevation">0dp</item>
+ <item name="android:minHeight">@dimen/broadcast_dialog_btn_minHeight</item>
+ <item name="android:background">@drawable/broadcast_dialog_btn_bg</item>
+ </style>
+
+ <style name="TextAppearanceBroadcastDialogButton" parent="@android:TextAppearance.DeviceDefault.Headline">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:textSize">@dimen/broadcast_dialog_btn_text_size</item>
+ </style>
+
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
index 0f34023..f627bcb 100644
--- a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
@@ -36,7 +36,8 @@
import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting;
-import androidx.core.os.BuildCompat;
+
+import com.android.settingslib.utils.BuildCompatUtils;
import java.io.BufferedReader;
import java.io.FileReader;
@@ -220,7 +221,7 @@
}
private static String getRawPhoneNumber(Context context, int subscriptionId) {
- if (BuildCompat.isAtLeastT()) {
+ if (BuildCompatUtils.isAtLeastT()) {
return getRawPhoneNumberFromT(context, subscriptionId);
} else {
final TelephonyManager telephonyManager = context.getSystemService(
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 3a4a8d2..284da73 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -31,10 +31,11 @@
import android.widget.TextView;
import androidx.annotation.RequiresApi;
-import androidx.core.os.BuildCompat;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
+import com.android.settingslib.utils.BuildCompatUtils;
+
/**
* Helper class for managing settings preferences that can be disabled
* by device admins via user restrictions.
@@ -105,7 +106,7 @@
if (mDisabledSummary) {
final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
if (summaryView != null) {
- final CharSequence disabledText = BuildCompat.isAtLeastT()
+ final CharSequence disabledText = BuildCompatUtils.isAtLeastT()
? getDisabledByAdminUpdatableString()
: mContext.getString(R.string.disabled_by_admin_summary_text);
if (mDisabledByAdmin) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index aaa0114..feb4212 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -45,7 +45,6 @@
import androidx.annotation.RequiresApi;
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
-import androidx.core.os.BuildCompat;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.UserIcons;
@@ -53,6 +52,7 @@
import com.android.launcher3.icons.IconFactory;
import com.android.settingslib.drawable.UserIconDrawable;
import com.android.settingslib.fuelgauge.BatteryStatus;
+import com.android.settingslib.utils.BuildCompatUtils;
import java.text.NumberFormat;
@@ -130,7 +130,7 @@
String name = info != null ? info.name : null;
if (info.isManagedProfile()) {
// We use predefined values for managed profiles
- return BuildCompat.isAtLeastT()
+ return BuildCompatUtils.isAtLeastT()
? getUpdatableManagedUserTitle(context)
: context.getString(R.string.managed_user_title);
} else if (info.isGuest()) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BroadcastDialog.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BroadcastDialog.java
new file mode 100644
index 0000000..cb4eba4
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BroadcastDialog.java
@@ -0,0 +1,66 @@
+/**
+ * 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.settingslib.bluetooth;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.android.settingslib.R;
+
+public class BroadcastDialog extends AlertDialog {
+
+ private static final String TAG = "BroadcastDialog";
+
+ private String mCurrentApp;
+ private String mSwitchApp;
+ private Context mContext;
+
+ public BroadcastDialog(Context context) {
+ super(context);
+ mContext = context;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+
+ View layout = View.inflate(mContext, R.layout.broadcast_dialog, null);
+ final Window window = getWindow();
+ window.setContentView(layout);
+ window.setWindowAnimations(R.style.Theme_AlertDialog_SettingsLib);
+
+ TextView title = layout.findViewById(R.id.dialog_title);
+ TextView subTitle = layout.findViewById(R.id.dialog_subtitle);
+ title.setText(mContext.getString(R.string.bt_le_audio_broadcast_dialog_title, mCurrentApp));
+ subTitle.setText(
+ mContext.getString(R.string.bt_le_audio_broadcast_dialog_sub_title, mSwitchApp));
+ Button positiveBtn = layout.findViewById(R.id.positive_btn);
+ Button negativeBtn = layout.findViewById(R.id.negative_btn);
+ Button neutralBtn = layout.findViewById(R.id.neutral_btn);
+ positiveBtn.setText(mContext.getString(
+ R.string.bt_le_audio_broadcast_dialog_switch_app, mSwitchApp), null);
+ neutralBtn.setOnClickListener((view) -> {
+ Log.d(TAG, "BroadcastDialog dismiss.");
+ dismiss();
+ });
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java b/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
index 91d7388..11fae24 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
@@ -47,7 +47,8 @@
import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting;
-import androidx.core.os.BuildCompat;
+
+import com.android.settingslib.utils.BuildCompatUtils;
/**
* Converts the user avatar icon to a circularly clipped one with an optional badge and frame
@@ -87,7 +88,7 @@
* @return drawable containing just the badge
*/
public static Drawable getManagedUserDrawable(Context context) {
- if (BuildCompat.isAtLeastT()) {
+ if (BuildCompatUtils.isAtLeastT()) {
return getUpdatableManagedUserDrawable(context);
} else {
return getDrawableForDisplayDensity(
@@ -226,7 +227,7 @@
}
private static Drawable getManagementBadge(Context context) {
- if (BuildCompat.isAtLeastT()) {
+ if (BuildCompatUtils.isAtLeastT()) {
return getUpdatableManagementBadge(context);
} else {
return getDrawableForDisplayDensity(
diff --git a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeActivity.java b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeActivity.java
index 9021fcb..15a910e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeActivity.java
@@ -26,8 +26,8 @@
import androidx.fragment.app.FragmentTransaction;
-import com.android.settingslib.bluetooth.BluetoothBroadcastUtils;
import com.android.settingslib.R;
+import com.android.settingslib.bluetooth.BluetoothBroadcastUtils;
import com.android.settingslib.bluetooth.BluetoothUtils;
public class QrCodeScanModeActivity extends QrCodeScanModeBaseActivity {
diff --git a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeBaseActivity.java b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeBaseActivity.java
index 9aaec41..361fd5b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeBaseActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeBaseActivity.java
@@ -1,4 +1,4 @@
-/*
+/**
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,8 +21,8 @@
import androidx.fragment.app.FragmentManager;
-import com.android.settingslib.core.lifecycle.ObservableActivity;
import com.android.settingslib.R;
+import com.android.settingslib.core.lifecycle.ObservableActivity;
public abstract class QrCodeScanModeBaseActivity extends ObservableActivity {
diff --git a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeController.java b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeController.java
index d7640bb..153d2d2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeController.java
@@ -1,4 +1,4 @@
-/*
+/**
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeFragment.java b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeFragment.java
index 81165aa..069b950 100644
--- a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeFragment.java
+++ b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCodeScanModeFragment.java
@@ -1,4 +1,4 @@
-/*
+/**
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -35,9 +35,9 @@
import android.view.accessibility.AccessibilityEvent;
import android.widget.TextView;
+import com.android.settingslib.R;
import com.android.settingslib.bluetooth.BluetoothBroadcastUtils;
import com.android.settingslib.bluetooth.BluetoothUtils;
-import com.android.settingslib.R;
import com.android.settingslib.core.lifecycle.ObservableFragment;
import androidx.annotation.NonNull;
diff --git a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrDecorateView.java b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrDecorateView.java
index 7005d36..51cf59c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrDecorateView.java
+++ b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrDecorateView.java
@@ -1,4 +1,4 @@
-/*
+/**
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrYuvLuminanceSource.java b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrYuvLuminanceSource.java
index 421cf5c..33f0cdd 100644
--- a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrYuvLuminanceSource.java
+++ b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrYuvLuminanceSource.java
@@ -1,4 +1,4 @@
-/*
+/**
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index a28c4cf..3b862ff 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -686,6 +686,9 @@
<!-- Permission required for CTS test - CtsKeystoreTestCases -->
<uses-permission android:name="android.permission.REQUEST_UNIQUE_ID_ATTESTATION" />
+ <!-- Permission required for CTS test - CtsDevicePolicyManagerTestCases -->
+ <uses-permission android:name="android.permission.READ_NEARBY_STREAMING_POLICY" />
+
<application android:label="@string/app_label"
android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/Shell/res/values-as/strings.xml b/packages/Shell/res/values-as/strings.xml
index 6e80931..9b9db6e 100644
--- a/packages/Shell/res/values-as/strings.xml
+++ b/packages/Shell/res/values-as/strings.xml
@@ -28,7 +28,7 @@
<string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"ষ্ক্ৰীণশ্বট নোলোৱাকৈ বাগ সম্পৰ্কীয় অভিযোগ শ্বেয়াৰ কৰিবলৈ বাছনি কৰক বা ষ্ক্ৰীণশ্বট লোৱা কাৰ্য সম্পূৰ্ণ হোৱালৈ অপেক্ষা কৰক"</string>
<string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"স্ক্ৰীণশ্বট নোলোৱাকৈ বাগ সম্পর্কীয় অভিযোগ শ্বেয়াৰ কৰিবলৈ ইয়াত টিপক বা স্ক্ৰীণশ্বট সম্পূৰ্ণ হোৱালৈ অপেক্ষা কৰক"</string>
<string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"স্ক্ৰীণশ্বট নোলোৱাকৈ বাগ সম্পর্কীয় অভিযোগ শ্বেয়াৰ কৰিবলৈ ইয়াত টিপক বা স্ক্ৰীণশ্বট সম্পূৰ্ণ হোৱালৈ অপেক্ষা কৰক"</string>
- <string name="bugreport_confirm" msgid="5917407234515812495">"বাগ সম্পর্কীয় অভিযোগত ছিষ্টেমৰ বিভিন্ন লগ ফাইল থাকে, ইয়াৰ ভিতৰত আপুনি স্পর্শকাতৰ বুলি গণ্য কৰা ডেটা (যেনে এপৰ ব্য়ৱহাৰ আৰু অৱস্থান সম্পৰ্কীয় তথ্য়) অন্তর্ভুক্ত হ\'ব পাৰে। কেৱল আপোনাৰ বিশ্বাসী লোক বা এপৰ সৈতেহে বাগ সম্পর্কীয় অভিযোগ শ্বেয়াৰ কৰিব।"</string>
+ <string name="bugreport_confirm" msgid="5917407234515812495">"বাগ সম্পর্কীয় অভিযোগত ছিষ্টেমৰ বিভিন্ন লগ ফাইল থাকে, ইয়াৰ ভিতৰত আপুনি স্পর্শকাতৰ বুলি গণ্য কৰা ডেটা (যেনে এপৰ ব্যৱহাৰ আৰু অৱস্থান সম্পৰ্কীয় তথ্য) অন্তর্ভুক্ত হ\'ব পাৰে। কেৱল আপোনাৰ বিশ্বাসী লোক বা এপৰ সৈতেহে বাগ সম্পর্কীয় অভিযোগ শ্বেয়াৰ কৰিব।"</string>
<string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"পুনৰাই নেদেখুৱাব"</string>
<string name="bugreport_storage_title" msgid="5332488144740527109">"বাগ সম্পর্কীয় প্ৰতিবেদনসমূহ"</string>
<string name="bugreport_unreadable_text" msgid="586517851044535486">"বাগ সম্পর্কীয় অভিযোগৰ ফাইলটো পঢ়িব পৰা নগ\'ল"</string>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 6d7172e..6887d03 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -523,7 +523,8 @@
android:launchMode="singleTop"
android:permission="android.permission.MANAGE_SENSOR_PRIVACY"
android:theme="@style/Theme.SystemUI.Dialog.Alert"
- android:finishOnCloseSystemDialogs="true">
+ android:finishOnCloseSystemDialogs="true"
+ android:showForAllUsers="true">
</activity>
<!-- started from SensoryPrivacyService -->
@@ -532,7 +533,8 @@
android:launchMode="singleTop"
android:permission="android.permission.MANAGE_SENSOR_PRIVACY"
android:theme="@style/BottomSheet"
- android:finishOnCloseSystemDialogs="true">
+ android:finishOnCloseSystemDialogs="true"
+ android:showForAllUsers="true">
</activity>
diff --git a/packages/SystemUI/docs/usb_audio.md b/packages/SystemUI/docs/usb_audio.md
new file mode 100644
index 0000000..66e2df9
--- /dev/null
+++ b/packages/SystemUI/docs/usb_audio.md
@@ -0,0 +1,30 @@
+# USB audio Permission and Confirmation warning dialog resource string id matrix table
+### go/support-usb-access-aoc-offload-feature
+
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | # | Permission |isUsbAudioDevice| hasAudioPlayback | hasAudioCapture | string resource ID |
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 1 | TRUE | TRUE | TRUE | FALSE | usb_audio_device_
+ permission_prompt |
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 2 | TRUE | TRUE | FALSE | TRUE | usb_audio_device_
+ permission_prompt |
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 3 | TRUE | TRUE | TRUE | TRUE | usb_audio_device_
+ permission_prompt |
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 4 | TRUE | FALSE | N/A | N/A | usb_device_
+ permission_prompt |
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 5 | FALSE | TRUE | TRUE | FALSE | usb_audio_device_
+ permission_prompt |
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 6 | FALSE | TRUE | FALSE | TRUE | usb_audio_device_
+ permission_prompt_warn
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 7 | FALSE | TRUE | TRUE | TRUE | usb_audio_device_
+ permission_prompt_warn
+ |---|------------|----------------|------------------|-----------------|--------------------|
+ | 8 | FALSE | FALSE | N/A | N/A | usb_device_
+ permission_prompt |
+ |---|------------|----------------|------------------|-----------------|--------------------|
diff --git a/packages/SystemUI/res/anim/media_metadata_enter.xml b/packages/SystemUI/res/anim/media_metadata_enter.xml
new file mode 100644
index 0000000..fccb766
--- /dev/null
+++ b/packages/SystemUI/res/anim/media_metadata_enter.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:ordering="together">
+ <objectAnimator
+ android:propertyName="translationX"
+ android:valueFrom="32dp"
+ android:valueTo="0dp"
+ android:duration="600"
+ android:valueType="floatType" />
+ <objectAnimator
+ android:propertyName="transitionAlpha"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:duration="167"
+ android:valueType="floatType" />
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/media_metadata_exit.xml b/packages/SystemUI/res/anim/media_metadata_exit.xml
new file mode 100644
index 0000000..0ee1171
--- /dev/null
+++ b/packages/SystemUI/res/anim/media_metadata_exit.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:ordering="together">
+ <objectAnimator
+ android:propertyName="translationX"
+ android:valueFrom="0dp"
+ android:valueTo="-32dp"
+ android:duration="167"
+ android:valueType="floatType" />
+ <objectAnimator
+ android:propertyName="transitionAlpha"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:duration="83"
+ android:startOffset="83"
+ android:valueType="floatType" />
+</set>
diff --git a/packages/SystemUI/res/layout/media_output_list_item.xml b/packages/SystemUI/res/layout/media_output_list_item.xml
index d39b0d5..b85ea59 100644
--- a/packages/SystemUI/res/layout/media_output_list_item.xml
+++ b/packages/SystemUI/res/layout/media_output_list_item.xml
@@ -33,7 +33,7 @@
android:layout_height="match_parent"
android:background="@drawable/media_output_item_background"
android:layout_gravity="center_vertical|start">
- <com.android.systemui.media.dialog.MediaOutputSeekbar
+ <SeekBar
android:id="@+id/volume_seekbar"
android:splitTrack="false"
android:visibility="gone"
@@ -119,15 +119,24 @@
android:importantForAccessibility="no"
android:visibility="gone"/>
+ <LinearLayout
+ android:id="@+id/end_action_area"
+ android:visibility="gone"
+ android:orientation="vertical"
+ android:layout_width="48dp"
+ android:layout_height="64dp"
+ android:layout_gravity="right|center"
+ android:gravity="center_vertical">
<CheckBox
android:id="@+id/check_box"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="16dp"
- android:layout_gravity="right|center"
+ android:layout_gravity="right"
android:button="@drawable/ic_circle_check_box"
android:visibility="gone"
- android:clickable="false"
/>
+
+ </LinearLayout>
</FrameLayout>
</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/media_smartspace_recommendations.xml b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
index c3fc669..6611c59 100644
--- a/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
+++ b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
@@ -22,163 +22,145 @@
android:id="@+id/media_recommendations"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingStart="@dimen/qs_media_padding"
- android:paddingEnd="@dimen/qs_media_padding"
android:clipChildren="false"
android:clipToPadding="false"
android:forceHasOverlappingRendering="false"
android:background="@drawable/qs_media_background"
android:theme="@style/MediaPlayer">
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/media_vertical_start_guideline"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- app:layout_constraintGuide_percent="0.25" />
-
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/media_horizontal_center_guideline"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- app:layout_constraintGuide_percent="0.5" />
+ <!-- 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" />
<com.android.internal.widget.CachingIconView
android:id="@+id/recommendation_card_icon"
- android:layout_width="@dimen/qs_media_icon_size"
- android:layout_height="@dimen/qs_media_icon_size"
- android:layout_marginTop="@dimen/qs_media_padding"
- android:src="@drawable/ic_headset"
- style="@style/MediaPlayer.AppIcon"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/media_vertical_start_guideline"
- app:layout_constraintHorizontal_bias="0"/>
-
- <TextView
- android:id="@+id/recommendation_card_text"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:maxLines="1"
- android:text="@string/controls_media_smartspace_rec_title"
- android:fontFamily="google-sans-medium"
- android:textDirection="locale"
- android:textSize="@dimen/qq_aa_media_rec_header_text_size"
- android:hyphenationFrequency="none"
- app:layout_constraintTop_toBottomOf="@id/recommendation_card_icon"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/media_vertical_start_guideline"
- app:layout_constraintHorizontal_bias="0"/>
-
- <View
- android:id="@+id/recommendation_gradient_view"
- android:layout_width="@dimen/qs_aa_media_gradient_bg_width"
- android:layout_height="0dp"
- android:clipToPadding="false"
- android:clipChildren="false"
- android:background="@drawable/qs_media_recommendation_bg_gradient"
- app:layout_constraintTop_toTopOf="@id/recommendation_card_text"
- app:layout_constraintBottom_toBottomOf="@id/recommendation_card_text"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/media_vertical_start_guideline"
- app:layout_constraintHorizontal_bias="1"/>
+ style="@style/MediaPlayer.Recommendation.AppIcon" />
<FrameLayout
android:id="@+id/media_cover1_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
- android:background="@drawable/qs_media_light_source">
+ style="@style/MediaPlayer.Recommendation.AlbumContainer"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@+id/media_title1"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/media_cover2_container"
+ android:layout_marginEnd="@dimen/qs_media_rec_album_side_margin"
+ app:layout_constraintHorizontal_chainStyle="packed"
+ app:layout_constraintHorizontal_bias="1.0"
+ app:layout_constraintVertical_bias="0.5"
+ >
<ImageView
android:id="@+id/media_cover1"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
android:adjustViewBounds="true"
android:background="@drawable/bg_smartspace_media_item"
- style="@style/MediaPlayer.Album"
+ style="@style/MediaPlayer.Recommendation.Album"
android:clipToOutline="true"
android:scaleType="centerCrop"/>
</FrameLayout>
+ <TextView
+ android:id="@+id/media_title1"
+ style="@style/MediaPlayer.Recommendation.Text.Title"
+ app:layout_constraintStart_toStartOf="@+id/media_cover1_container"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover1_container"
+ app:layout_constraintTop_toBottomOf="@+id/media_cover1_container"
+ app:layout_constraintBottom_toTopOf="@+id/media_subtitle1"
+ />
+
+ <TextView
+ android:id="@+id/media_subtitle1"
+ style="@style/MediaPlayer.Recommendation.Text.Subtitle"
+ app:layout_constraintStart_toStartOf="@+id/media_cover1_container"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover1_container"
+ app:layout_constraintTop_toBottomOf="@+id/media_title1"
+ app:layout_constraintBottom_toBottomOf="parent"
+ android:layout_marginBottom="@dimen/qs_media_padding"
+ />
+
<FrameLayout
android:id="@+id/media_cover2_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
- android:background="@drawable/qs_media_light_source">
+ style="@style/MediaPlayer.Recommendation.AlbumContainer"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/media_title2"
+ app:layout_constraintStart_toEndOf="@id/media_cover1_container"
+ app:layout_constraintEnd_toStartOf="@id/media_cover3_container"
+ android:layout_marginEnd="@dimen/qs_media_rec_album_side_margin"
+ app:layout_constraintVertical_bias="0.5"
+ >
<ImageView
android:id="@+id/media_cover2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:background="@drawable/bg_smartspace_media_item"
- style="@style/MediaPlayer.Album"
+ style="@style/MediaPlayer.Recommendation.Album"
android:clipToOutline="true"
android:scaleType="centerCrop"/>
</FrameLayout>
+ <TextView
+ android:id="@+id/media_title2"
+ style="@style/MediaPlayer.Recommendation.Text.Title"
+ app:layout_constraintStart_toStartOf="@+id/media_cover2_container"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover2_container"
+ app:layout_constraintTop_toBottomOf="@+id/media_cover2_container"
+ app:layout_constraintBottom_toTopOf="@+id/media_subtitle2"
+ />
+
+ <TextView
+ android:id="@+id/media_subtitle2"
+ style="@style/MediaPlayer.Recommendation.Text.Subtitle"
+ app:layout_constraintStart_toStartOf="@+id/media_cover2_container"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover2_container"
+ app:layout_constraintTop_toBottomOf="@+id/media_title2"
+ app:layout_constraintBottom_toBottomOf="parent"
+ android:layout_marginBottom="@dimen/qs_media_padding"
+ />
+
<FrameLayout
android:id="@+id/media_cover3_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
- android:background="@drawable/qs_media_light_source">
+ style="@style/MediaPlayer.Recommendation.AlbumContainer"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/media_title3"
+ app:layout_constraintStart_toEndOf="@id/media_cover2_container"
+ app:layout_constraintEnd_toEndOf="parent"
+ android:layout_marginEnd="@dimen/qs_media_padding"
+ app:layout_constraintVertical_bias="0.5"
+ >
<ImageView
android:id="@+id/media_cover3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:background="@drawable/bg_smartspace_media_item"
- style="@style/MediaPlayer.Album"
+ style="@style/MediaPlayer.Recommendation.Album"
android:clipToOutline="true"
android:scaleType="centerCrop"/>
</FrameLayout>
- <FrameLayout
- android:id="@+id/media_cover4_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
- android:background="@drawable/qs_media_light_source">
- <ImageView
- android:id="@+id/media_cover4"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:adjustViewBounds="true"
- android:background="@drawable/bg_smartspace_media_item"
- style="@style/MediaPlayer.Album"
- android:clipToOutline="true"
- android:scaleType="centerCrop"/>
- </FrameLayout>
+ <TextView
+ android:id="@+id/media_title3"
+ style="@style/MediaPlayer.Recommendation.Text.Title"
+ app:layout_constraintStart_toStartOf="@+id/media_cover3_container"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover3_container"
+ app:layout_constraintTop_toBottomOf="@+id/media_cover3_container"
+ app:layout_constraintBottom_toTopOf="@+id/media_subtitle3"
+ />
- <FrameLayout
- android:id="@+id/media_cover5_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
- android:background="@drawable/qs_media_light_source">
- <ImageView
- android:id="@+id/media_cover5"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:adjustViewBounds="true"
- android:background="@drawable/bg_smartspace_media_item"
- style="@style/MediaPlayer.Album"
- android:clipToOutline="true"
- android:scaleType="centerCrop"/>
- </FrameLayout>
-
- <FrameLayout
- android:id="@+id/media_cover6_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
- android:background="@drawable/qs_media_light_source">
- <ImageView
- android:id="@+id/media_cover6"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:adjustViewBounds="true"
- android:background="@drawable/bg_smartspace_media_item"
- style="@style/MediaPlayer.Album"
- android:clipToOutline="true"
- android:scaleType="centerCrop"/>
- </FrameLayout>
+ <TextView
+ android:id="@+id/media_subtitle3"
+ style="@style/MediaPlayer.Recommendation.Text.Subtitle"
+ app:layout_constraintStart_toStartOf="@+id/media_cover3_container"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover3_container"
+ app:layout_constraintTop_toBottomOf="@+id/media_title3"
+ app:layout_constraintBottom_toBottomOf="parent"
+ android:layout_marginBottom="@dimen/qs_media_padding"
+ />
<!-- Long press menu -->
<TextView
@@ -273,4 +255,4 @@
android:text="@string/controls_media_dismiss_button"
/>
</FrameLayout>
-</com.android.systemui.util.animation.TransitionLayout>
\ No newline at end of file
+</com.android.systemui.util.animation.TransitionLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index ecc52d3ad..e56a810 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"Onderbreek"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Vorige snit"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"Volgende snit"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Koppel tans"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Speel"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Maak <xliff:g id="APP_LABEL">%1$s</xliff:g> oop"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Speel <xliff:g id="SONG_NAME">%1$s</xliff:g> deur <xliff:g id="ARTIST_NAME">%2$s</xliff:g> vanaf <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 6b7e301..e9b2a1c 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"ላፍታ አቁም"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"ቀዳሚ ትራክ"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"ቀጣይ ትራክ"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"በመገናኘት ላይ"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"አጫውት"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ክፈት"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> በ<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ከ<xliff:g id="APP_LABEL">%3$s</xliff:g> ያጫውቱ"</string>
diff --git a/packages/SystemUI/res/values-as-ldrtl/strings.xml b/packages/SystemUI/res/values-as-ldrtl/strings.xml
index adee93a..f017d0c 100644
--- a/packages/SystemUI/res/values-as-ldrtl/strings.xml
+++ b/packages/SystemUI/res/values-as-ldrtl/strings.xml
@@ -19,5 +19,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"তাত্ক্ষণিকভাৱে আনটো এপ্ ব্য়ৱহাৰ কৰিবলৈ বাওঁফালে টানক"</string>
+ <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"তাত্ক্ষণিকভাৱে আনটো এপ্ ব্যৱহাৰ কৰিবলৈ বাওঁফালে টানক"</string>
</resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index acc4acf..ce58c7c 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"পজ কৰক"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"পূৰ্বৱৰ্তী ট্ৰেক"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"পৰৱৰ্তী ট্ৰেক"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"সংযোগ কৰি থকা হৈছে"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"প্লে’ কৰক"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> খোলক"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ত <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ৰ <xliff:g id="SONG_NAME">%1$s</xliff:g> গীতটো প্লে’ কৰক"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 5ad9207..5a62066 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"Durdurun"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Əvvəlki trek"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"Növbəti trek"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Qoşulur"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Oxudun"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> tətbiqini açın"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> tərəfindən <xliff:g id="SONG_NAME">%1$s</xliff:g> mahnısını <xliff:g id="APP_LABEL">%3$s</xliff:g> tətbiqindən oxudun"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index b539c47..a5ad4f7 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -811,8 +811,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pauziraj"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Prethodna pesma"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"Sledeća pesma"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Povezuje se"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Pusti"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otvorite <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Pustite <xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 6fabe3f..67e838b 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -27,7 +27,7 @@
<string name="invalid_charger_title" msgid="938685362320735167">"Зареждането през USB не е възможно"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Използвайте оригиналното зарядно устройство"</string>
<string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Да се включи ли режимът за запазване на батерията?"</string>
- <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"Всичко за режима за запазване на батерията"</string>
+ <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"За режима за запазване на батерията"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Включване"</string>
<string name="battery_saver_start_action" msgid="8353766979886287140">"Включване"</string>
<string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Не, благодаря"</string>
@@ -732,8 +732,8 @@
<string name="privacy_type_microphone" msgid="9136763906797732428">"микрофона"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Няма заглавие"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим на готовност"</string>
- <string name="magnification_window_title" msgid="4863914360847258333">"Прозорец за ниво на мащаба"</string>
- <string name="magnification_controls_title" msgid="8421106606708891519">"Контроли за прозореца за ниво на мащаба"</string>
+ <string name="magnification_window_title" msgid="4863914360847258333">"Прозорец за увеличение"</string>
+ <string name="magnification_controls_title" msgid="8421106606708891519">"Контроли за прозореца за увеличение"</string>
<string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Увеличаване на мащаба"</string>
<string name="accessibility_control_zoom_out" msgid="69578832020304084">"Намаляване на мащаба"</string>
<string name="accessibility_control_move_up" msgid="6622825494014720136">"Преместване нагоре"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index b3f20da..d763748 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -570,7 +570,7 @@
<string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"বিজ্ঞপ্তি"</string>
<string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"কীবোর্ড শর্টকাট"</string>
<string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"কীবোর্ড লে-আউট পাল্টান"</string>
- <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"অ্যাপ্লিকেশানগুলি"</string>
+ <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"অ্যাপ্লিকেশন"</string>
<string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"সহযোগিতা"</string>
<string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"ব্রাউজার"</string>
<string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"পরিচিতি"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index fad3ec8..11b9f42 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -27,7 +27,7 @@
<string name="invalid_charger_title" msgid="938685362320735167">"Punjenje putem USB-a nije moguće"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Koristite punjač koji ste dobili uz uređaj"</string>
<string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Uključiti Uštedu baterije?"</string>
- <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"Informacije o Uštedi baterije"</string>
+ <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"O Uštedi baterije"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Uključi"</string>
<string name="battery_saver_start_action" msgid="8353766979886287140">"Uključi"</string>
<string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ne, hvala"</string>
@@ -453,7 +453,7 @@
<string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"Pozivi i obavještenja će zvoniti jačinom (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string>
<string name="system_ui_tuner" msgid="1471348823289954729">"Podešavač za korisnički interfejs sistema"</string>
<string name="status_bar" msgid="4357390266055077437">"Statusna traka"</string>
- <string name="demo_mode" msgid="263484519766901593">"Način rada za demonstraciju Sistemskog UI-a"</string>
+ <string name="demo_mode" msgid="263484519766901593">"Demo način rada Sistemskog UI-ja"</string>
<string name="enable_demo_mode" msgid="3180345364745966431">"Omogući način rada za demonstraciju"</string>
<string name="show_demo_mode" msgid="3677956462273059726">"Prikaži način rada za demonstraciju"</string>
<string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
@@ -811,8 +811,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pauziranje"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Prethodna numera"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"Sljedeća numera"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Povezivanje"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Pokrenite"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otvorite aplikaciju <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Reproducirajte pjesmu <xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> pomoću aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index b51ae5f..8118f54 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pausar"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Pista anterior"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"Siguiente pista"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Conectando"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Reproducir"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Abrir <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Poner <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -905,7 +904,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Por ahora no se conectará automáticamente a redes Wi-Fi"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Ver todo"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Para cambiar de red, desconecta el cable Ethernet"</string>
- <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Para mejorar la experiencia con el dispositivo, las aplicaciones y los servicios podrán buscar redes Wi-Fi en cualquier momento, aunque la conexión Wi-Fi esté desactivada. Puedes cambiarlo en los ajustes de búsqueda de redes Wi-Fi. "<annotation id="link">"Cambiar"</annotation></string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Para mejorar la experiencia con el dispositivo, las aplicaciones y los servicios podrán buscar redes Wi-Fi en cualquier momento, aunque la conexión Wi-Fi esté desactivada. Puedes cambiar esto en los ajustes de búsqueda de redes Wi-Fi. "<annotation id="link">"Cambiar"</annotation></string>
<string name="turn_off_airplane_mode" msgid="8425587763226548579">"Desactivar modo avión"</string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> quiere añadir el siguiente recuadro a ajustes rápidos"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Añadir recuadro"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 6d7bf05..dd4c43f 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"توقف موقت"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"آهنگ قبلی"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"آهنگ بعدی"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"درحال اتصال"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"پخش"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"باز کردن <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> از <xliff:g id="ARTIST_NAME">%2$s</xliff:g> را ازطریق <xliff:g id="APP_LABEL">%3$s</xliff:g> پخش کنید"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 2822eb2..bac2f5a 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -383,7 +383,7 @@
<string name="monitoring_title_device_owned" msgid="7029691083837606324">"डिवाइस मैनेजमेंट"</string>
<string name="monitoring_subtitle_vpn" msgid="800485258004629079">"वीपीएन"</string>
<string name="monitoring_subtitle_network_logging" msgid="2444199331891219596">"नेटवर्क लॉगिंग"</string>
- <string name="monitoring_subtitle_ca_certificate" msgid="8588092029755175800">"CA प्रमाणपत्र"</string>
+ <string name="monitoring_subtitle_ca_certificate" msgid="8588092029755175800">"CA सर्टिफ़िकेट"</string>
<string name="monitoring_button_view_policies" msgid="3869724835853502410">"नीतियां देखें"</string>
<string name="monitoring_button_view_controls" msgid="8316440345340701117">"कंट्रोल देखें"</string>
<string name="monitoring_description_named_management" msgid="505833016545056036">"इस डिवाइस का मालिकाना हक <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> के पास है.\n\nआपके संगठन का आईटी एडमिन कुछ चीज़ों की निगरानी और उन्हें प्रबंधित कर सकता है, जैसे कि सेटिंग, कॉर्पोरेट ऐक्सेस, ऐप्लिकेशन, आपके डिवाइस से जुड़ा डेटा, और आपके डिवाइस की जगह की जानकारी.\n\nज़्यादा जानकारी के लिए, अपने आईटी एडमिन से संपर्क करें."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index ef31620..2d03d51 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -27,7 +27,7 @@
<string name="invalid_charger_title" msgid="938685362320735167">"Punjenje putem USB-a nije moguće"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Koristite punjač koji ste dobili s uređajem"</string>
<string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Uključiti štednju baterije?"</string>
- <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"O Štednji baterije"</string>
+ <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"O štednji baterije"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Uključi"</string>
<string name="battery_saver_start_action" msgid="8353766979886287140">"Uključi"</string>
<string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ne, hvala"</string>
@@ -811,8 +811,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pauziraj"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Prethodni zapis"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"Sljedeći zapis"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Povezivanje"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Reprodukcija"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otvori <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Pustite <xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g> putem aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 8c7569c..2e87901 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -568,7 +568,7 @@
<string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"Terbaru"</string>
<string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"Kembali"</string>
<string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Notifikasi"</string>
- <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Pintasan Keyboard"</string>
+ <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"Pintasan keyboard"</string>
<string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"Ganti tata letak keyboard"</string>
<string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Aplikasi"</string>
<string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"Bantuan"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 9b2178a..d2e0f0a 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -27,7 +27,7 @@
<string name="invalid_charger_title" msgid="938685362320735167">"Impossibile ricaricare tramite USB"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"Utilizza il caricabatterie fornito in dotazione con il dispositivo"</string>
<string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Attivare il risparmio energetico?"</string>
- <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"Informazioni su Risparmio energetico"</string>
+ <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"Informazioni sul risparmio energetico"</string>
<string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Attiva"</string>
<string name="battery_saver_start_action" msgid="8353766979886287140">"Attiva"</string>
<string name="battery_saver_dismiss_action" msgid="7199342621040014738">"No, grazie"</string>
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"Metti in pausa"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Traccia precedente"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"Traccia successiva"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Connessione in corso…"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Riproduci"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Apri <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Riproduci <xliff:g id="SONG_NAME">%1$s</xliff:g> di <xliff:g id="ARTIST_NAME">%2$s</xliff:g> da <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
@@ -905,7 +904,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Connessione automatica rete Wi-Fi non attiva al momento"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Mostra tutte"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Per cambiare rete, scollega il cavo Ethernet"</string>
- <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Per migliorare l\'esperienza con il dispositivo, le app e i servizi possono continuare a cercare reti Wi-Fi in qualsiasi momento, anche quando la connessione Wi-Fi non è attiva. Puoi modificare questa preferenza nelle impostazioni relative alla ricerca di reti Wi-Fi. "<annotation id="link">"Cambia"</annotation></string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Per migliorare l\'esperienza con il dispositivo, le app e i servizi possono continuare a cercare reti Wi-Fi in qualsiasi momento, anche quando la connessione Wi-Fi non è attiva. Puoi modificare questa preferenza nelle impostazioni relative alla ricerca di reti Wi-Fi. "<annotation id="link">"Modifica"</annotation></string>
<string name="turn_off_airplane_mode" msgid="8425587763226548579">"Disattiva la modalità aereo"</string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> vuole aggiungere il seguente riquadro alle Impostazioni rapide"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Aggiungi riquadro"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 69f4ba1..d675b7c 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"პაუზა"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"წინა ჩანაწერი"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"შემდეგი ჩანაწერი"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"მიმდინარეობს დაკავშირება"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"დაკვრა"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"გახსენით <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"დაუკარით <xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, <xliff:g id="APP_LABEL">%3$s</xliff:g>-დან"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index a5d8fd9..50b3215 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"ຢຸດຊົ່ວຄາວ"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"ເພງກ່ອນໜ້າ"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"ເພງຕໍ່ໄປ"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"ກຳລັງເຊື່ອມຕໍ່"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"ຫຼິ້ນ"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"ເປີດ <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"ຫຼິ້ນ <xliff:g id="SONG_NAME">%1$s</xliff:g> ໂດຍ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ຈາກ <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index b58338c..3609663 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -564,7 +564,7 @@
<string name="keyboard_key_numpad_template" msgid="7316338238459991821">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="notif_inline_reply_remove_attachment_description" msgid="7954075334095405429">"Отстрани го прилогот"</string>
<string name="keyboard_shortcut_group_system" msgid="1583416273777875970">"Систем"</string>
- <string name="keyboard_shortcut_group_system_home" msgid="7465138628692109907">"Почетна страница"</string>
+ <string name="keyboard_shortcut_group_system_home" msgid="7465138628692109907">"Почетен екран"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"Неодамнешни"</string>
<string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"Назад"</string>
<string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"Известувања"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index be345ac..31d33d7 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -564,7 +564,7 @@
<string name="keyboard_key_numpad_template" msgid="7316338238459991821">"നംപാഡ് <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="notif_inline_reply_remove_attachment_description" msgid="7954075334095405429">"അറ്റാച്ച്മെന്റ് നീക്കം ചെയ്യുക"</string>
<string name="keyboard_shortcut_group_system" msgid="1583416273777875970">"സിസ്റ്റം"</string>
- <string name="keyboard_shortcut_group_system_home" msgid="7465138628692109907">"വീട്"</string>
+ <string name="keyboard_shortcut_group_system_home" msgid="7465138628692109907">"ഹോം"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"പുതിയവ"</string>
<string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"മടങ്ങുക"</string>
<string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"അറിയിപ്പുകൾ"</string>
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"താൽക്കാലികമായി നിർത്തുക"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"മുമ്പത്തെ ട്രാക്ക്"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"അടുത്ത ട്രാക്ക്"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"കണക്റ്റ് ചെയ്യുന്നു"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"പ്ലേ ചെയ്യുക"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> തുറക്കുക"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> എന്ന ആർട്ടിസ്റ്റിന്റെ <xliff:g id="SONG_NAME">%1$s</xliff:g> എന്ന ഗാനം <xliff:g id="APP_LABEL">%3$s</xliff:g> ആപ്പിൽ പ്ലേ ചെയ്യുക"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 45211c4..2f3a089 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"Түр зогсоох"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Өмнөх бичлэг"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"Дараагийн бичлэг"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Холбогдож байна"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Тоглуулах"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g>-г нээх"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>-н <xliff:g id="SONG_NAME">%1$s</xliff:g>-г <xliff:g id="APP_LABEL">%3$s</xliff:g> дээр тоглуулах"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index d431a2b..9e2b73e 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -563,7 +563,7 @@
<string name="keyboard_key_num_lock" msgid="7209960042043090548">"Num Lock"</string>
<string name="keyboard_key_numpad_template" msgid="7316338238459991821">"Numpad <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="notif_inline_reply_remove_attachment_description" msgid="7954075334095405429">"अटॅचमेंट काढा"</string>
- <string name="keyboard_shortcut_group_system" msgid="1583416273777875970">"सिस्टम"</string>
+ <string name="keyboard_shortcut_group_system" msgid="1583416273777875970">"सिस्टीम"</string>
<string name="keyboard_shortcut_group_system_home" msgid="7465138628692109907">"होम"</string>
<string name="keyboard_shortcut_group_system_recents" msgid="8628108256824616927">"अलीकडील"</string>
<string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"परत"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 9bab5cb..046025e 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"Jeda"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Lagu sebelumnya"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"Lagu seterusnya"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Menyambung"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Main"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Buka <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Mainkan <xliff:g id="SONG_NAME">%1$s</xliff:g> oleh <xliff:g id="ARTIST_NAME">%2$s</xliff:g> daripada <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 6492303..d06fd26 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"ਰੋਕੋ"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"ਪਿਛਲਾ ਟਰੈਕ"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"ਅਗਲਾ ਟਰੈਕ"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"ਕਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"ਚਲਾਓ"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ਖੋਲ੍ਹੋ"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ਤੋਂ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ਦਾ <xliff:g id="SONG_NAME">%1$s</xliff:g> ਚਲਾਓ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 7196471..c9e8a29 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -817,8 +817,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"Wstrzymaj"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Poprzedni utwór"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"Następny utwór"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Łączę"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Odtwórz"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otwórz aplikację <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Odtwórz utwór <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) w aplikacji <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
index aae48c8..f5d8f1f 100644
--- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
@@ -87,9 +87,9 @@
<item msgid="2075645297847971154">"Włączony"</item>
</string-array>
<string-array name="tile_states_color_correction">
- <item msgid="2840507878437297682">"Brak dostępu"</item>
- <item msgid="1909756493418256167">"Wyłączono"</item>
- <item msgid="4531508423703413340">"Włączono"</item>
+ <item msgid="2840507878437297682">"Niedostępna"</item>
+ <item msgid="1909756493418256167">"Wyłączona"</item>
+ <item msgid="4531508423703413340">"Włączona"</item>
</string-array>
<string-array name="tile_states_inversion">
<item msgid="3638187931191394628">"Niedostępne"</item>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 5ad4272..d8519df 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -52,7 +52,7 @@
<string name="usb_debugging_always" msgid="4003121804294739548">"Permitir sempre a partir deste computador"</string>
<string name="usb_debugging_allow" msgid="1722643858015321328">"Permitir"</string>
<string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Depuração USB não permitida"</string>
- <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"O utilizador com sessão iniciada atualmente neste dispositivo não pode ativar a depuração USB. Para utilizar esta funcionalidade, mude para o utilizador principal."</string>
+ <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"O utilizador com sessão iniciada atualmente neste dispositivo não pode ativar a depuração USB. Para usar esta funcionalidade, mude para o utilizador principal."</string>
<string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Quer alterar o idioma do sistema para <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
<string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Alteração do idioma do sistema solicitada por outro dispositivo"</string>
<string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Alterar idioma"</string>
@@ -62,7 +62,7 @@
<string name="wifi_debugging_always" msgid="2968383799517975155">"Permitir sempre nesta rede"</string>
<string name="wifi_debugging_allow" msgid="4573224609684957886">"Permitir"</string>
<string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Depuração sem fios não permitida"</string>
- <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"O utilizador com sessão iniciada atualmente neste dispositivo não pode ativar a depuração sem fios. Para utilizar esta funcionalidade, mude para o utilizador principal."</string>
+ <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"O utilizador com sessão iniciada atualmente neste dispositivo não pode ativar a depuração sem fios. Para usar esta funcionalidade, mude para o utilizador principal."</string>
<string name="usb_contaminant_title" msgid="894052515034594113">"Porta USB desativada"</string>
<string name="usb_contaminant_message" msgid="7730476585174719805">"Para proteger o dispositivo contra líquidos ou resíduos, a porta USB está desativada e não irá detetar quaisquer acessórios.\n\nSerá notificado quando for seguro utilizar a porta USB novamente."</string>
<string name="usb_port_enabled" msgid="531823867664717018">"Porta USB ativada para detetar carregadores e acessórios"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 6af0388..d7d6622 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -811,8 +811,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"Întrerupeți"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Melodia anterioară"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"Melodia următoare"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Se conectează"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Redați"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Deschideți <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Redați <xliff:g id="SONG_NAME">%1$s</xliff:g> de la <xliff:g id="ARTIST_NAME">%2$s</xliff:g> în <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 1e2949e..22f0a04 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -817,8 +817,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pozastaviť"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Predchádzajúca skladba"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"Ďalšia skladba"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Pripája sa"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Prehrať"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otvoriť <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Prehrať skladbu <xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> z aplikácie <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 8ff71a4..5b06c83 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -817,8 +817,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"Začasno zaustavi"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Prejšnja skladba"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"Naslednja skladba"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Vzpostavljanje povezave"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Predvajaj"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Odpri aplikacijo <xliff:g id="APP_LABEL">%1$s</xliff:g>."</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Predvajaj skladbo <xliff:g id="SONG_NAME">%1$s</xliff:g> izvajalca <xliff:g id="ARTIST_NAME">%2$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index e1cd04f..4f4ffab 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -811,8 +811,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"Паузирај"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Претходна песма"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"Следећа песма"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Повезује се"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Пусти"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Отворите <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Пустите <xliff:g id="SONG_NAME">%1$s</xliff:g> извођача <xliff:g id="ARTIST_NAME">%2$s</xliff:g> из апликације <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 111da21..cbdc9e0 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"இடைநிறுத்து"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"முந்தைய டிராக்"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"அடுத்த டிராக்"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"இணைக்கிறது"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"இயக்குதல்"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ஆப்ஸைத் திறங்கள்"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> இன் <xliff:g id="SONG_NAME">%1$s</xliff:g> பாடலை <xliff:g id="APP_LABEL">%3$s</xliff:g> ஆப்ஸில் பிளேசெய்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index e76253a..08e9c2f 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"పాజ్ చేయండి"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"మునుపటి ట్రాక్"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"తర్వాతి ట్రాక్"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"కనెక్ట్ అవుతోంది"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"ప్లే చేయండి"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g>ను తెరవండి"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> నుండి <xliff:g id="ARTIST_NAME">%2$s</xliff:g> పాడిన <xliff:g id="SONG_NAME">%1$s</xliff:g>ను ప్లే చేయండి"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index df36f46..5db1ee3 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -907,7 +907,7 @@
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"ตัดการเชื่อมต่ออีเทอร์เน็ตเพื่อสลับเครือข่าย"</string>
<string name="wifi_scan_notify_message" msgid="3753839537448621794">"เพื่อปรับปรุงประสบการณ์การใช้อุปกรณ์ แอปและบริการต่างๆ จะยังคงสแกนหาเครือข่าย Wi‑Fi ได้ทุกเมื่อแม้ว่า Wi‑Fi จะปิดอยู่ คุณเปลี่ยนตัวเลือกนี้ได้ในการตั้งค่าการสแกนหา Wi-Fi "<annotation id="link">"เปลี่ยนการตั้งค่า"</annotation></string>
<string name="turn_off_airplane_mode" msgid="8425587763226548579">"ปิดโหมดบนเครื่องบิน"</string>
- <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> ต้องการเพิ่มชิ้นส่วนต่อไปนี้ในการตั้งค่าด่วน"</string>
+ <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> ต้องการเพิ่มองค์ประกอบต่อไปนี้ในการตั้งค่าด่วน"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"เพิ่มชิ้นส่วน"</string>
<string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ไม่ต้องเพิ่มชิ้นส่วน"</string>
<string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"เลือกผู้ใช้"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 4c4e49b..9424162 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -905,7 +905,7 @@
<string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Şu anda kablosuz ağa otomatik olarak bağlanılamıyor"</string>
<string name="see_all_networks" msgid="3773666844913168122">"Tümünü göster"</string>
<string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Ağ değiştirmek için ethernet bağlantısını kesin"</string>
- <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Uygulamalar ve hizmetler, cihaz deneyimini iyileştirmek için Kablosuz özelliği kapalı bile olsa kablosuz ağlar herhangi bir zamanda tarayabilir. Bunu kablosuz ağ taraması ayarlarından değiştirebilirsiniz. "<annotation id="link">"Değiştir"</annotation></string>
+ <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Uygulamalar ve hizmetler, cihaz deneyimini iyileştirmek için Kablosuz özelliği kapalı bile olsa kablosuz ağları herhangi bir zamanda tarayabilir. Bunu kablosuz ağ taraması ayarlarından değiştirebilirsiniz. "<annotation id="link">"Değiştir"</annotation></string>
<string name="turn_off_airplane_mode" msgid="8425587763226548579">"Uçak modunu kapat"</string>
<string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> aşağıdaki kartı Hızlı Ayarlar\'a eklemek istiyor"</string>
<string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Kart ekle"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index c0f12bd..a2ce6be 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -805,8 +805,7 @@
<string name="controls_media_button_pause" msgid="8614887780950376258">"Pauza"</string>
<string name="controls_media_button_prev" msgid="8126822360056482970">"Avvalgi trek"</string>
<string name="controls_media_button_next" msgid="6662636627525947610">"Keyingi trek"</string>
- <!-- no translation found for controls_media_button_connecting (3138354625847598095) -->
- <skip />
+ <string name="controls_media_button_connecting" msgid="3138354625847598095">"Ulanmoqda"</string>
<string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Ijro"</string>
<string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ilovasini ochish"</string>
<string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ilovasida ijro etish: <xliff:g id="SONG_NAME">%1$s</xliff:g> – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 15a32fe..b77e008 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -21,8 +21,8 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4811759950673118541">"系统界面"</string>
<string name="battery_low_title" msgid="5319680173344341779">"要开启省电模式吗?"</string>
- <string name="battery_low_description" msgid="3282977755476423966">"您的电池还剩 <xliff:g id="PERCENTAGE">%s</xliff:g> 的电量。省电模式会开启深色主题,限制后台活动并将通知延迟。"</string>
- <string name="battery_low_intro" msgid="5148725009653088790">"省电模式会开启深色主题,限制后台活动并将通知延迟。"</string>
+ <string name="battery_low_description" msgid="3282977755476423966">"您的电池还剩 <xliff:g id="PERCENTAGE">%s</xliff:g> 的电量。省电模式会开启深色主题、限制后台活动,并将通知延迟。"</string>
+ <string name="battery_low_intro" msgid="5148725009653088790">"省电模式会开启深色主题、限制后台活动,并将通知延迟。"</string>
<string name="battery_low_percent_format" msgid="4276661262843170964">"剩余<xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="invalid_charger_title" msgid="938685362320735167">"无法通过 USB 充电"</string>
<string name="invalid_charger_text" msgid="2339310107232691577">"使用设备随附的充电器"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index d148403..80582ef 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -959,7 +959,6 @@
<dimen name="qs_media_album_radius">14dp</dimen>
<dimen name="qs_media_info_margin">12dp</dimen>
<dimen name="qs_media_info_spacing">8dp</dimen>
- <dimen name="qs_media_icon_size">20dp</dimen>
<dimen name="qs_media_icon_offset">4dp</dimen>
<dimen name="qs_center_guideline_padding">10dp</dimen>
<dimen name="qs_media_action_spacing">4dp</dimen>
@@ -980,12 +979,10 @@
<dimen name="qs_media_session_collapsed_guideline">144dp</dimen>
<!-- Size of Smartspace media recommendations cards in the QSPanel carousel -->
- <dimen name="qs_aa_media_rec_album_size_collapsed">72dp</dimen>
- <dimen name="qs_aa_media_rec_album_size_expanded">76dp</dimen>
- <dimen name="qs_aa_media_gradient_bg_width">32dp</dimen>
- <dimen name="qs_aa_media_rec_album_margin">8dp</dimen>
- <dimen name="qs_aa_media_rec_album_margin_vert">4dp</dimen>
- <dimen name="qq_aa_media_rec_header_text_size">16sp</dimen>
+ <dimen name="qs_media_rec_album_size">88dp</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_icon_size">24dp</dimen>
<!-- Media tap-to-transfer chip for sender device -->
<dimen name="media_ttt_chip_outer_padding">16dp</dimen>
@@ -1368,7 +1365,7 @@
<dimen name="keyguard_unfold_translation_x">16dp</dimen>
- <dimen name="fgs_manager_min_width_minor">100%</dimen>
+ <dimen name="fgs_manager_list_top_spacing">12dp</dimen>
<!-- Dream overlay related dimensions -->
<dimen name="dream_overlay_status_bar_height">60dp</dimen>
@@ -1380,8 +1377,8 @@
<dimen name="dream_overlay_notification_indicator_size">6dp</dimen>
<!-- Dream overlay complications related dimensions -->
- <dimen name="dream_overlay_complication_clock_time_text_size">72sp</dimen>
- <dimen name="dream_overlay_complication_clock_subtitle_text_size">18sp</dimen>
+ <dimen name="dream_overlay_complication_clock_time_text_size">100sp</dimen>
+ <dimen name="dream_overlay_complication_clock_subtitle_text_size">24sp</dimen>
<dimen name="dream_overlay_complication_preview_text_size">36sp</dimen>
<dimen name="dream_overlay_complication_preview_icon_padding">28dp</dimen>
<dimen name="dream_overlay_complication_shadow_padding">2dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 0f5115b..f7acda7e 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2440,14 +2440,16 @@
<!-- Label for the entry point to open the dialog which shows currently running applications [CHAR LIMIT=NONE]-->
<plurals name="fgs_manager_footer_label">
- <item quantity="one"><xliff:g id="count" example="1">%s</xliff:g> active app</item>
- <item quantity="other"><xliff:g id="count" example="2">%s</xliff:g> active apps</item>
+ <item quantity="one"><xliff:g id="count" example="1">%s</xliff:g> app is active</item>
+ <item quantity="other"><xliff:g id="count" example="2">%s</xliff:g> apps are active</item>
</plurals>
<!-- Content description for a dot indicator in the running application indicating that there
is new information [CHAR LIMIT=NONE] -->
<string name="fgs_dot_content_description">New information</string>
<!-- Title for dialog listing applications currently running [CHAR LIMIT=NONE]-->
<string name="fgs_manager_dialog_title">Active apps</string>
+ <!-- Detailed message for dialog listing applications currently running [CHAR LIMIT=NONE]-->
+ <string name="fgs_manager_dialog_message">Even if you\u2019re not using these apps, they\u2019re still active and might affect battery life</string>
<!-- Label of the button to stop an app from running [CHAR LIMIT=12]-->
<string name="fgs_manager_app_item_stop_button_label">Stop</string>
<!-- Label of the button to stop an app from running but the app is already stopped and the button is disabled [CHAR LIMIT=12]-->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index d7799a7..827631b 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -653,16 +653,50 @@
<item name="android:textColor">?android:attr/textColorPrimary</item>
</style>
- <style name="MediaPlayer.AppIcon">
+ <style name="MediaPlayer.Recommendation"/>
+
+ <style name="MediaPlayer.Recommendation.AppIcon">
<item name="android:background">@drawable/qs_media_icon_background</item>
<item name="android:backgroundTint">@color/media_player_solid_button_bg</item>
- <item name="android:padding">4dp</item>
+ <item name="android:layout_width">@dimen/qs_media_rec_icon_size</item>
+ <item name="android:layout_height">@dimen/qs_media_rec_icon_size</item>
+ <item name="layout_constraintTop_toTopOf">parent</item>
+ <item name="layout_constraintStart_toStartOf">parent</item>
+ <item name="android:layout_marginTop">@dimen/qs_media_padding</item>
+ <item name="android:layout_marginStart">@dimen/qs_media_padding</item>
+ <item name="android:src">@drawable/ic_headset</item>
</style>
- <style name="MediaPlayer.Album">
+ <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>
+ <item name="android:background">@drawable/qs_media_light_source</item>
+ <item name="android:layout_marginTop">@dimen/qs_media_padding</item>
+ <item name="android:layout_marginBottom">@dimen/qs_media_rec_album_bottom_margin</item>
+ </style>
+
+ <style name="MediaPlayer.Recommendation.Album">
<item name="android:backgroundTint">@color/media_player_album_bg</item>
</style>
+ <style name="MediaPlayer.Recommendation.Text">
+ <item name="android:layout_width">@dimen/qs_media_rec_album_size</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:maxLines">1</item>
+ <item name="android:ellipsize">end</item>
+ <item name="android:textSize">14sp</item>
+ <item name="android:gravity">start</item>
+ </style>
+
+ <style name="MediaPlayer.Recommendation.Text.Title">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ </style>
+
+ <style name="MediaPlayer.Recommendation.Text.Subtitle">
+ <item name="android:textColor">?android:attr/textColorSecondary</item>
+ </style>
+
+
<!-- Used to style charging animation AVD animation -->
<style name="ChargingAnim" />
@@ -1085,6 +1119,7 @@
<style name="FgsManagerAppLabel" parent="TextAppearance.Dialog.Body">
<item name="android:textDirection">locale</item>
+ <item name="android:textStyle">bold</item>
</style>
<style name="FgsManagerAppDuration">
diff --git a/packages/SystemUI/res/xml/media_recommendation_collapsed.xml b/packages/SystemUI/res/xml/media_recommendation_collapsed.xml
index b6258d1..a6113473 100644
--- a/packages/SystemUI/res/xml/media_recommendation_collapsed.xml
+++ b/packages/SystemUI/res/xml/media_recommendation_collapsed.xml
@@ -16,91 +16,84 @@
-->
<ConstraintSet
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto">
+ 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"
+ />
+
+ <!-- Only the constraintBottom and marginBottom are different. The rest of the constraints are
+ the same as the constraints in media_smartspace_recommendations. But due to how
+ ConstraintSets work, all the constraints need to be in the same place.
+ Ditto for the other cover containers. -->
+ <Constraint
android:id="@+id/media_cover1_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
- app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_collapsed"
- app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
- android:layout_marginTop="@dimen/qs_media_padding"
android:layout_marginBottom="@dimen/qs_media_padding"
- android:layout_marginEnd="@dimen/qs_aa_media_rec_album_margin"
- app:layout_constraintStart_toEndOf="@id/media_vertical_start_guideline"
+ style="@style/MediaPlayer.Recommendation.AlbumContainer"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/media_cover2_container"
+ android:layout_marginEnd="@dimen/qs_media_rec_album_side_margin"
app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintHorizontal_bias="1"
- android:visibility="gone" />
+ app:layout_constraintHorizontal_bias="1.0"
+ app:layout_constraintVertical_bias="0.5"
+ />
+
+ <Constraint
+ android:id="@+id/media_title1"
+ android:visibility="gone"
+ />
+
+ <Constraint
+ android:id="@+id/media_subtitle1"
+ android:visibility="gone"
+ />
<Constraint
android:id="@+id/media_cover2_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
- app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_collapsed"
- android:layout_marginTop="@dimen/qs_media_padding"
- android:layout_marginBottom="@dimen/qs_media_padding"
- android:layout_marginEnd="@dimen/qs_aa_media_rec_album_margin"
- app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
+ android:layout_marginBottom="@dimen/qs_media_padding"
+ style="@style/MediaPlayer.Recommendation.AlbumContainer"
+ app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/media_cover1_container"
app:layout_constraintEnd_toStartOf="@id/media_cover3_container"
- app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintHorizontal_bias="1"
- android:visibility="gone" />
+ android:layout_marginEnd="@dimen/qs_media_rec_album_side_margin"
+ app:layout_constraintVertical_bias="0.5"
+ />
+
+ <Constraint
+ android:id="@+id/media_title2"
+ android:visibility="gone"
+ />
+
+ <Constraint
+ android:id="@+id/media_subtitle2"
+ android:visibility="gone"
+ />
<Constraint
android:id="@+id/media_cover3_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_aa_media_rec_album_size_collapsed"
- app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_collapsed"
- android:layout_marginTop="@dimen/qs_media_padding"
- android:layout_marginBottom="@dimen/qs_media_padding"
- app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
+ android:layout_marginBottom="@dimen/qs_media_padding"
+ style="@style/MediaPlayer.Recommendation.AlbumContainer"
+ app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/media_cover2_container"
app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintHorizontal_bias="1"
- android:visibility="gone" />
+ android:layout_marginEnd="@dimen/qs_media_padding"
+ app:layout_constraintVertical_bias="0.5"
+ />
<Constraint
- android:id="@+id/media_cover4_container"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginEnd="@dimen/qs_aa_media_rec_album_margin"
- app:layout_constraintTop_toBottomOf="@+id/media_cover1_container"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/media_vertical_start_guideline"
- app:layout_constraintEnd_toStartOf="@id/media_cover5_container"
- app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintHorizontal_bias="1"
- android:visibility="gone" />
+ android:id="@+id/media_title3"
+ android:visibility="gone"
+ />
<Constraint
- android:id="@+id/media_cover5_container"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginEnd="@dimen/qs_aa_media_rec_album_margin"
- app:layout_constraintTop_toBottomOf="@+id/media_cover2_container"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@+id/media_cover4_container"
- app:layout_constraintEnd_toStartOf="@+id/media_cover6_container"
- app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintHorizontal_bias="1"
- android:visibility="gone" />
-
- <Constraint
- android:id="@+id/media_cover6_container"
- android:layout_width="0dp"
- android:layout_height="0dp"
- app:layout_constraintTop_toBottomOf="@id/media_cover3_container"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/media_cover5_container"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintHorizontal_bias="1"
- android:visibility="gone" />
+ android:id="@+id/media_subtitle3"
+ android:visibility="gone"
+ />
</ConstraintSet>
diff --git a/packages/SystemUI/res/xml/media_recommendation_expanded.xml b/packages/SystemUI/res/xml/media_recommendation_expanded.xml
index 2fb3341..09ffebb 100644
--- a/packages/SystemUI/res/xml/media_recommendation_expanded.xml
+++ b/packages/SystemUI/res/xml/media_recommendation_expanded.xml
@@ -15,113 +15,12 @@
~ limitations under the License
-->
<ConstraintSet
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto">
+ xmlns:android="http://schemas.android.com/apk/res/android" >
<Constraint
- android:id="@+id/media_cover1_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_aa_media_rec_album_size_expanded"
- app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_expanded"
- android:layout_marginTop="@dimen/qs_media_padding"
- android:layout_marginBottom="@dimen/qs_aa_media_rec_album_margin_vert"
- android:layout_marginEnd="@dimen/qs_aa_media_rec_album_margin"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@+id/media_horizontal_center_guideline"
- app:layout_constraintStart_toEndOf="@id/media_vertical_start_guideline"
- app:layout_constraintEnd_toStartOf="@id/media_cover2_container"
- app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintHorizontal_bias="1"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintVertical_bias="0"
- android:visibility="gone" />
-
- <Constraint
- android:id="@+id/media_cover2_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_aa_media_rec_album_size_expanded"
- app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_expanded"
- android:layout_marginTop="@dimen/qs_media_padding"
- android:layout_marginBottom="@dimen/qs_aa_media_rec_album_margin_vert"
- android:layout_marginEnd="@dimen/qs_aa_media_rec_album_margin"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@+id/media_horizontal_center_guideline"
- app:layout_constraintStart_toEndOf="@id/media_cover1_container"
- app:layout_constraintEnd_toStartOf="@id/media_cover3_container"
- app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintHorizontal_bias="1"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintVertical_bias="0"
- android:visibility="gone" />
-
- <Constraint
- android:id="@+id/media_cover3_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_aa_media_rec_album_size_expanded"
- app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_expanded"
- android:layout_marginTop="@dimen/qs_media_padding"
- android:layout_marginBottom="@dimen/qs_aa_media_rec_album_margin_vert"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@+id/media_horizontal_center_guideline"
- app:layout_constraintStart_toEndOf="@id/media_cover2_container"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintHorizontal_bias="1"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintVertical_bias="0"
- android:visibility="gone" />
-
- <Constraint
- android:id="@+id/media_cover4_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_aa_media_rec_album_size_expanded"
- app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_expanded"
- android:layout_marginTop="@dimen/qs_aa_media_rec_album_margin_vert"
- android:layout_marginBottom="@dimen/qs_media_padding"
- android:layout_marginEnd="@dimen/qs_aa_media_rec_album_margin"
- app:layout_constraintTop_toBottomOf="@+id/media_horizontal_center_guideline"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/media_vertical_start_guideline"
- app:layout_constraintEnd_toStartOf="@id/media_cover5_container"
- app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintHorizontal_bias="1"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintVertical_bias="1"
- android:visibility="gone" />
-
- <Constraint
- android:id="@+id/media_cover5_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_aa_media_rec_album_size_expanded"
- app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_expanded"
- android:layout_marginTop="@dimen/qs_aa_media_rec_album_margin_vert"
- android:layout_marginBottom="@dimen/qs_media_padding"
- android:layout_marginEnd="@dimen/qs_aa_media_rec_album_margin"
- app:layout_constraintTop_toBottomOf="@+id/media_horizontal_center_guideline"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@+id/media_cover4_container"
- app:layout_constraintEnd_toStartOf="@+id/media_cover6_container"
- app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintHorizontal_bias="1"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintVertical_bias="1"
- android:visibility="gone" />
-
- <Constraint
- android:id="@+id/media_cover6_container"
- android:layout_width="0dp"
- android:layout_height="@dimen/qs_aa_media_rec_album_size_expanded"
- app:layout_constraintWidth_max="@dimen/qs_aa_media_rec_album_size_expanded"
- android:layout_marginTop="@dimen/qs_aa_media_rec_album_margin_vert"
- android:layout_marginBottom="@dimen/qs_media_padding"
- app:layout_constraintTop_toBottomOf="@id/media_horizontal_center_guideline"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/media_cover5_container"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintHorizontal_bias="1"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintVertical_bias="1"
- android:visibility="gone" />
+ android:id="@+id/sizing_view"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/qs_media_session_height_expanded"
+ />
</ConstraintSet>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
index 238690c..938b1ca 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
@@ -80,21 +80,29 @@
public PictureInPictureSurfaceTransaction scaleAndCrop(
SurfaceControl.Transaction tx, SurfaceControl leash,
- Rect sourceBounds, Rect destinationBounds, Rect insets) {
+ Rect sourceRectHint, Rect sourceBounds, Rect destinationBounds, Rect insets) {
mTmpSourceRectF.set(sourceBounds);
mTmpDestinationRect.set(sourceBounds);
mTmpDestinationRect.inset(insets);
// Scale by the shortest edge and offset such that the top/left of the scaled inset
// source rect aligns with the top/left of the destination bounds
- final float scale = sourceBounds.width() <= sourceBounds.height()
- ? (float) destinationBounds.width() / sourceBounds.width()
- : (float) destinationBounds.height() / sourceBounds.height();
+ final float scale;
+ if (sourceRectHint.isEmpty() || sourceRectHint.width() == sourceBounds.width()) {
+ scale = sourceBounds.width() <= sourceBounds.height()
+ ? (float) destinationBounds.width() / sourceBounds.width()
+ : (float) destinationBounds.height() / sourceBounds.height();
+ } else {
+ // scale by sourceRectHint if it's not edge-to-edge
+ scale = sourceRectHint.width() <= sourceRectHint.height()
+ ? (float) destinationBounds.width() / sourceRectHint.width()
+ : (float) destinationBounds.height() / sourceRectHint.height();
+ }
final float left = destinationBounds.left - (insets.left + sourceBounds.left) * scale;
final float top = destinationBounds.top - (insets.top + sourceBounds.top) * scale;
mTmpTransform.setScale(scale, scale);
final float cornerRadius = getScaledCornerRadius(mTmpDestinationRect, destinationBounds);
tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
- .setWindowCrop(leash, mTmpDestinationRect)
+ .setCrop(leash, mTmpDestinationRect)
.setPosition(leash, left, top)
.setCornerRadius(leash, cornerRadius)
.setShadowRadius(leash, mShadowRadius);
@@ -127,7 +135,7 @@
adjustedPositionY = positionY - insets.left * scale;
}
tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
- .setWindowCrop(leash, mTmpDestinationRect)
+ .setCrop(leash, mTmpDestinationRect)
.setPosition(leash, adjustedPositionX, adjustedPositionY)
.setCornerRadius(leash, cornerRadius)
.setShadowRadius(leash, mShadowRadius);
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
index bb7a0a71..01f417f 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
@@ -568,7 +568,7 @@
}
}
- private class TaskStackListenerImpl extends TaskStackChangeListener {
+ private class TaskStackListenerImpl implements TaskStackChangeListener {
// Invalidate any rotation suggestion on task change or activity orientation change
// Note: all callbacks happen on main thread
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
index c5d5439..f65d82a 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
@@ -26,30 +26,30 @@
* An interface to track task stack changes. Classes should implement this instead of
* {@link android.app.ITaskStackListener} to reduce IPC calls from system services.
*/
-public abstract class TaskStackChangeListener {
+public interface TaskStackChangeListener {
// Binder thread callbacks
- public void onTaskStackChangedBackground() { }
+ default void onTaskStackChangedBackground() { }
// Main thread callbacks
- public void onTaskStackChanged() { }
- public void onTaskSnapshotChanged(int taskId, ThumbnailData snapshot) { }
- public void onActivityPinned(String packageName, int userId, int taskId, int stackId) { }
- public void onActivityUnpinned() { }
- public void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible,
+ default void onTaskStackChanged() { }
+ default void onTaskSnapshotChanged(int taskId, ThumbnailData snapshot) { }
+ default void onActivityPinned(String packageName, int userId, int taskId, int stackId) { }
+ default void onActivityUnpinned() { }
+ default void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible,
boolean clearedTask, boolean wasVisible) { }
- public void onActivityForcedResizable(String packageName, int taskId, int reason) { }
- public void onActivityDismissingDockedStack() { }
- public void onActivityLaunchOnSecondaryDisplayFailed() { }
+ default void onActivityForcedResizable(String packageName, int taskId, int reason) { }
+ default void onActivityDismissingDockedStack() { }
+ default void onActivityLaunchOnSecondaryDisplayFailed() { }
- public void onActivityLaunchOnSecondaryDisplayFailed(RunningTaskInfo taskInfo) {
+ default void onActivityLaunchOnSecondaryDisplayFailed(RunningTaskInfo taskInfo) {
onActivityLaunchOnSecondaryDisplayFailed();
}
/**
* @see #onActivityLaunchOnSecondaryDisplayRerouted(RunningTaskInfo taskInfo)
*/
- public void onActivityLaunchOnSecondaryDisplayRerouted() { }
+ default void onActivityLaunchOnSecondaryDisplayRerouted() { }
/**
* Called when an activity was requested to be launched on a secondary display but was rerouted
@@ -57,16 +57,16 @@
*
* @param taskInfo info about the Activity's task
*/
- public void onActivityLaunchOnSecondaryDisplayRerouted(RunningTaskInfo taskInfo) {
+ default void onActivityLaunchOnSecondaryDisplayRerouted(RunningTaskInfo taskInfo) {
onActivityLaunchOnSecondaryDisplayRerouted();
}
- public void onTaskProfileLocked(int taskId, int userId) { }
- public void onTaskCreated(int taskId, ComponentName componentName) { }
- public void onTaskRemoved(int taskId) { }
- public void onTaskMovedToFront(int taskId) { }
+ default void onTaskProfileLocked(int taskId, int userId) { }
+ default void onTaskCreated(int taskId, ComponentName componentName) { }
+ default void onTaskRemoved(int taskId) { }
+ default void onTaskMovedToFront(int taskId) { }
- public void onTaskMovedToFront(RunningTaskInfo taskInfo) {
+ default void onTaskMovedToFront(RunningTaskInfo taskInfo) {
onTaskMovedToFront(taskInfo.taskId);
}
@@ -74,13 +74,14 @@
* Called when a task’s description is changed due to an activity calling
* ActivityManagerService.setTaskDescription
*
- * @param taskInfo info about the task which changed, with {@link TaskInfo#taskDescription}
+ * @param taskInfo info about the task which changed, with
+ * {@link RunningTaskInfo#taskDescription}
*/
- public void onTaskDescriptionChanged(RunningTaskInfo taskInfo) { }
+ default void onTaskDescriptionChanged(RunningTaskInfo taskInfo) { }
- public void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation) { }
+ default void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation) { }
- public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) { }
+ default void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) { }
/**
* Called when a task is reparented to a stack on a different display.
@@ -88,22 +89,22 @@
* @param taskId id of the task which was moved to a different display.
* @param newDisplayId id of the new display.
*/
- public void onTaskDisplayChanged(int taskId, int newDisplayId) { }
+ default void onTaskDisplayChanged(int taskId, int newDisplayId) { }
/**
* Called when any additions or deletions to the recent tasks list have been made.
*/
- public void onRecentTaskListUpdated() { }
+ default void onRecentTaskListUpdated() { }
/** @see ITaskStackListener#onRecentTaskListFrozenChanged(boolean) */
- public void onRecentTaskListFrozenChanged(boolean frozen) { }
+ default void onRecentTaskListFrozenChanged(boolean frozen) { }
/** @see ITaskStackListener#onActivityRotation(int)*/
- public void onActivityRotation(int displayId) { }
+ default void onActivityRotation(int displayId) { }
/**
* Called when the lock task mode changes. See ActivityManager#LOCK_TASK_MODE_* and
* LockTaskController.
*/
- public void onLockTaskModeChanged(int mode) { }
+ default void onLockTaskModeChanged(int mode) { }
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
index ed973d6..83b72e8 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
@@ -57,6 +57,15 @@
private val foldStateListener = FoldStateListener(context)
private val timeoutRunnable = TimeoutRunnable()
+ /**
+ * Time after which [FOLD_UPDATE_FINISH_HALF_OPEN] is emitted following a
+ * [FOLD_UPDATE_START_CLOSING] or [FOLD_UPDATE_START_OPENING] event, if an end state is not
+ * reached.
+ */
+ private val halfOpenedTimeoutMillis: Int =
+ context.resources.getInteger(
+ com.android.internal.R.integer.config_unfoldTransitionHalfFoldedTimeout)
+
private var isFolded = false
private var isUnfoldHandled = true
@@ -171,7 +180,7 @@
if (isTransitionInProgess) {
cancelTimeout()
}
- handler.postDelayed(timeoutRunnable, HALF_OPENED_TIMEOUT_MILLIS)
+ handler.postDelayed(timeoutRunnable, halfOpenedTimeoutMillis.toLong())
}
private fun cancelTimeout() {
@@ -222,12 +231,6 @@
private const val TAG = "DeviceFoldProvider"
private const val DEBUG = false
-/**
- * Time after which [FOLD_UPDATE_FINISH_HALF_OPEN] is emitted following a
- * [FOLD_UPDATE_START_CLOSING] or [FOLD_UPDATE_START_OPENING] event, if an end state is not reached.
- */
-@VisibleForTesting const val HALF_OPENED_TIMEOUT_MILLIS = 600L
-
/** Threshold after which we consider the device fully unfolded. */
@VisibleForTesting const val FULLY_OPEN_THRESHOLD_DEGREES = 15f
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
index 5953611..db2b4ac 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
@@ -63,7 +63,8 @@
val primaryUser: Boolean,
val scanningAllowedByStrongAuth: Boolean,
val secureCameraLaunched: Boolean,
- val switchingUser: Boolean
+ val switchingUser: Boolean,
+ val udfpsBouncerShowing: Boolean
) : KeyguardListenModel()
/**
* Verbose debug information associated with [KeyguardUpdateMonitor.shouldTriggerActiveUnlock].
@@ -73,6 +74,7 @@
override val userId: Int,
override val listening: Boolean,
// keep sorted
+ val awakeKeyguard: Boolean,
val authInterruptActive: Boolean,
val encryptedOrTimedOut: Boolean,
val fpLockout: Boolean,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 3103219..53d7b8c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -700,6 +700,7 @@
}
public void reset() {
+ mViewMode.reset();
mDisappearAnimRunning = false;
}
@@ -798,9 +799,6 @@
mUserSwitcherViewGroup = mView.findViewById(R.id.keyguard_bouncer_user_switcher);
}
- Drawable userIcon = findUserIcon(KeyguardUpdateMonitor.getCurrentUser());
- ((ImageView) mView.findViewById(R.id.user_icon)).setImageDrawable(userIcon);
-
updateSecurityViewLocation();
mUserSwitcher = mView.findViewById(R.id.user_switcher_header);
@@ -813,6 +811,7 @@
mPopup.dismiss();
mPopup = null;
}
+ setupUserSwitcher();
}
private Drawable findUserIcon(int userId) {
@@ -858,6 +857,12 @@
private void setupUserSwitcher() {
final UserRecord currentUser = mUserSwitcherController.getCurrentUserRecord();
+ if (currentUser == null) {
+ Log.wtf(TAG, "Current user in user switcher is null.");
+ return;
+ }
+ Drawable userIcon = findUserIcon(currentUser.info.id);
+ ((ImageView) mView.findViewById(R.id.user_icon)).setImageDrawable(userIcon);
mUserSwitcher.setText(mUserSwitcherController.getCurrentUserName());
ViewGroup anchor = mView.findViewById(R.id.user_switcher_anchor);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 1a325d3..ce4aad8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -219,6 +219,11 @@
mKeyguardSecurityCallback.userActivity();
showMessage(null, null);
}
+ if (mUpdateMonitor.isFaceEnrolled()
+ && mUpdateMonitor.mRequestActiveUnlockOnUnlockIntent) {
+ mUpdateMonitor.requestActiveUnlock("unlock-intent, reason=swipeUpOnBouncer",
+ true);
+ }
}
};
private ConfigurationController.ConfigurationListener mConfigurationListener =
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index f1bec81..a6feedb5 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -56,6 +56,7 @@
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.hardware.SensorPrivacyManager;
+import android.hardware.biometrics.BiometricFaceConstants;
import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricSourceType;
@@ -88,6 +89,7 @@
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -246,6 +248,12 @@
}
}
+ public final boolean mRequestActiveUnlockOnAssistant;
+ public final boolean mRequestActiveUnlockOnWakeup;
+ public final boolean mInitiateActiveUnlockOnWakeup;
+ public final boolean mRequestActiveUnlockOnUnlockIntent;
+ public final boolean mRequestActiveUnlockOnBioFail;
+
private final Context mContext;
private final boolean mIsPrimaryUser;
private final boolean mIsAutomotive;
@@ -281,6 +289,7 @@
private boolean mGoingToSleep;
private boolean mBouncerFullyShown;
private boolean mBouncerIsOrWillBeShowing;
+ private boolean mUdfpsBouncerShowing;
private boolean mAuthInterruptActive;
private boolean mNeedsSlowUnlockTransition;
private boolean mAssistantVisible;
@@ -451,10 +460,16 @@
}
}
- if (KeyguardUpdateMonitor.getCurrentUser() == userId && getUserHasTrust(userId)) {
+ if (KeyguardUpdateMonitor.getCurrentUser() == userId) {
CharSequence message = null;
- if (trustGrantedMessages != null && trustGrantedMessages.size() > 0) {
- message = trustGrantedMessages.get(0); // for now only shows the first in the list
+ final boolean userHasTrust = getUserHasTrust(userId);
+ if (userHasTrust && trustGrantedMessages != null) {
+ for (String msg : trustGrantedMessages) {
+ if (!TextUtils.isEmpty(msg)) {
+ message = msg;
+ break;
+ }
+ }
}
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -463,6 +478,7 @@
}
}
}
+
}
@Override
@@ -1354,8 +1370,8 @@
void setAssistantVisible(boolean assistantVisible) {
mAssistantVisible = assistantVisible;
updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
- if (mAssistantVisible) {
- requestActiveUnlock();
+ if (mAssistantVisible && mRequestActiveUnlockOnAssistant) {
+ requestActiveUnlock("assistant", false);
}
}
@@ -1502,11 +1518,11 @@
@Override
public void onAuthenticationFailed() {
+ if (mRequestActiveUnlockOnBioFail) {
+ requestActiveUnlock("biometric-failure, extra=fingerprintFailure",
+ true);
+ }
handleFingerprintAuthFailed();
-
- // TODO(b/225231929): Refactor as needed, add tests, etc.
- mTrustManager.reportUserRequestedUnlock(
- KeyguardUpdateMonitor.getCurrentUser(), true);
}
@Override
@@ -1564,6 +1580,15 @@
@Override
public void onAuthenticationFailed() {
+ if (shouldRequestActiveUnlockOnFaceError()) {
+ String reason =
+ mKeyguardBypassController.canBypass() ? "bypass"
+ : mUdfpsBouncerShowing ? "udfpsBouncer" :
+ mBouncerFullyShown ? "bouncer" : "udfpsFpDown";
+ requestActiveUnlock("biometric-failure"
+ + ", extra=faceFailure-" + reason, true);
+ }
+
handleFaceAuthFailed();
if (mKeyguardBypassController != null) {
mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
@@ -1592,12 +1617,23 @@
if (mKeyguardBypassController != null) {
mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
}
+ if (errMsgId == BiometricFaceConstants.FACE_ERROR_TIMEOUT
+ && shouldRequestActiveUnlockOnFaceError()) {
+ requestActiveUnlock("biometric-failure"
+ + ", extra=faceError-" + errMsgId, true);
+ }
}
@Override
public void onAuthenticationAcquired(int acquireInfo) {
handleFaceAcquired(acquireInfo);
}
+
+ private boolean shouldRequestActiveUnlockOnFaceError() {
+ return mRequestActiveUnlockOnBioFail
+ && (mKeyguardBypassController.canBypass() || mBouncerFullyShown
+ || mUdfpsBouncerShowing || mAuthController.isUdfpsFingerDown());
+ }
};
@VisibleForTesting
@@ -1713,7 +1749,11 @@
Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
Assert.isMainThread();
updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
- requestActiveUnlock();
+ if (mRequestActiveUnlockOnWakeup) {
+ requestActiveUnlock("wake-unlock");
+ } else if (mInitiateActiveUnlockOnWakeup) {
+ initiateActiveUnlock("wake-initiate");
+ }
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -1860,6 +1900,18 @@
dumpManager.registerDumpable(getClass().getName(), this);
mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
+ // TODO, b/222459888: add official configurable names to Settings.java
+ mRequestActiveUnlockOnWakeup = Settings.Global.getInt(
+ mContext.getContentResolver(), "wake-unlock", 0) == 1;
+ mInitiateActiveUnlockOnWakeup = Settings.Global.getInt(
+ mContext.getContentResolver(), "wake-initiate", 1) == 1;
+ mRequestActiveUnlockOnUnlockIntent = Settings.Global.getInt(
+ mContext.getContentResolver(), "unlock-intent", 0) == 1;
+ mRequestActiveUnlockOnBioFail = Settings.Global.getInt(
+ mContext.getContentResolver(), "bio-fail", 0) == 1;
+ mRequestActiveUnlockOnAssistant = Settings.Global.getInt(
+ mContext.getContentResolver(), "assistant", 0) == 1;
+
mHandler = new Handler(mainLooper) {
@Override
public void handleMessage(Message msg) {
@@ -2194,7 +2246,7 @@
}
// don't start running fingerprint until they're registered
- if (!mAuthController.areAllAuthenticatorsRegistered()) {
+ if (!mAuthController.areAllFingerprintAuthenticatorsRegistered()) {
return;
}
final boolean shouldListenForFingerprint = shouldListenForFingerprint(isUdfpsSupported());
@@ -2240,7 +2292,11 @@
}
mAuthInterruptActive = active;
updateFaceListeningState(BIOMETRIC_ACTION_UPDATE);
- requestActiveUnlock();
+ if (mRequestActiveUnlockOnWakeup) {
+ requestActiveUnlock("wake-unlock, extra=onReach");
+ } else if (mInitiateActiveUnlockOnWakeup) {
+ initiateActiveUnlock("wake-initiate, extra=onReach");
+ }
}
/**
@@ -2290,25 +2346,69 @@
}
/**
- * Attempts to trigger active unlock.
+ * Initiates active unlock to get the unlock token ready.
*/
- public void requestActiveUnlock() {
+ public void initiateActiveUnlock(String reason) {
// If this message exists, FP has already authenticated, so wait until that is handled
if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
return;
}
if (shouldTriggerActiveUnlock()) {
- // TODO(b/225231929): Refactor surrounding code to reflect calling of new method
+ if (DEBUG) {
+ Log.d("ActiveUnlock", "initiate active unlock triggerReason=" + reason);
+ }
mTrustManager.reportUserMayRequestUnlock(KeyguardUpdateMonitor.getCurrentUser());
}
}
+ /**
+ * Attempts to trigger active unlock from trust agent.
+ */
+ public void requestActiveUnlock(String reason, boolean dismissKeyguard) {
+ // If this message exists, FP has already authenticated, so wait until that is handled
+ if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
+ return;
+ }
+
+ if (shouldTriggerActiveUnlock()) {
+ if (DEBUG) {
+ Log.d("ActiveUnlock", "reportUserRequestedUnlock triggerReason=" + reason
+ + " dismissKeyguard=" + dismissKeyguard);
+ }
+ mTrustManager.reportUserRequestedUnlock(KeyguardUpdateMonitor.getCurrentUser(),
+ dismissKeyguard);
+ }
+ }
+
+ /**
+ * Attempts to trigger active unlock from trust agent.
+ * Only dismisses the keyguard if only face is enrolled (no FP) and bypass is enabled.
+ */
+ public void requestActiveUnlock(String reason) {
+ requestActiveUnlock(reason, isFaceEnrolled() && !isUdfpsEnrolled()
+ && mKeyguardBypassController.getBypassEnabled());
+ }
+
+ /**
+ * Whether the UDFPS bouncer is showing.
+ */
+ public void setUdfpsBouncerShowing(boolean showing) {
+ mUdfpsBouncerShowing = showing;
+ if (mUdfpsBouncerShowing) {
+ updateFaceListeningState(BIOMETRIC_ACTION_START);
+ if (mRequestActiveUnlockOnUnlockIntent) {
+ requestActiveUnlock("unlock-intent, extra=udfpsBouncer", true);
+ }
+ }
+ }
+
private boolean shouldTriggerActiveUnlock() {
// Triggers:
final boolean triggerActiveUnlockForAssistant = shouldTriggerActiveUnlockForAssistant();
- final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep
- && mStatusBarState != StatusBarState.SHADE_LOCKED;
+ final boolean awakeKeyguard = mBouncerFullyShown || mUdfpsBouncerShowing
+ || (mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep
+ && mStatusBarState != StatusBarState.SHADE_LOCKED);
// Gates:
final int user = getCurrentUser();
@@ -2341,20 +2441,19 @@
&& !mSecureCameraLaunched;
// Aggregate relevant fields for debug logging.
- if (DEBUG_ACTIVE_UNLOCK || DEBUG_SPEW) {
- maybeLogListenerModelData(
- new KeyguardActiveUnlockModel(
- System.currentTimeMillis(),
- user,
- shouldTriggerActiveUnlock,
- mAuthInterruptActive,
- isEncryptedOrTimedOut,
- fpLockedout,
- isLockDown,
- mSwitchingUser,
- triggerActiveUnlockForAssistant,
- userCanDismissLockScreen));
- }
+ maybeLogListenerModelData(
+ new KeyguardActiveUnlockModel(
+ System.currentTimeMillis(),
+ user,
+ shouldTriggerActiveUnlock,
+ awakeKeyguard,
+ mAuthInterruptActive,
+ isEncryptedOrTimedOut,
+ fpLockedout,
+ isLockDown,
+ mSwitchingUser,
+ triggerActiveUnlockForAssistant,
+ userCanDismissLockScreen));
return shouldTriggerActiveUnlock;
}
@@ -2507,7 +2606,8 @@
|| mOccludingAppRequestingFace
|| awakeKeyguard
|| shouldListenForFaceAssistant
- || mAuthController.isUdfpsFingerDown())
+ || mAuthController.isUdfpsFingerDown()
+ || mUdfpsBouncerShowing)
&& !mSwitchingUser && !faceDisabledForUser && becauseCannotSkipBouncer
&& !mKeyguardGoingAway && biometricEnabledForUser && !mLockIconPressed
&& strongAuthAllowsScanning && mIsPrimaryUser
@@ -2537,7 +2637,8 @@
mIsPrimaryUser,
strongAuthAllowsScanning,
mSecureCameraLaunched,
- mSwitchingUser));
+ mSwitchingUser,
+ mUdfpsBouncerShowing));
}
return shouldListen;
@@ -2550,8 +2651,7 @@
}
if (DEBUG_ACTIVE_UNLOCK
- && model instanceof KeyguardActiveUnlockModel
- && model.getListening()) {
+ && model instanceof KeyguardActiveUnlockModel) {
mListenModels.add(model);
return;
}
@@ -3133,6 +3233,9 @@
}
if (wasBouncerFullyShown != mBouncerFullyShown) {
+ if (mBouncerFullyShown && mRequestActiveUnlockOnUnlockIntent) {
+ requestActiveUnlock("unlock-intent, reason=bouncerFullyShown", true);
+ }
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -3619,8 +3722,8 @@
final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
BiometricAuthenticated fingerprint = mUserFingerprintAuthenticated.get(userId);
pw.println(" Fingerprint state (user=" + userId + ")");
- pw.println(" areAllAuthenticatorsRegistered="
- + mAuthController.areAllAuthenticatorsRegistered());
+ pw.println(" areAllFpAuthenticatorsRegistered="
+ + mAuthController.areAllFingerprintAuthenticatorsRegistered());
pw.println(" allowed="
+ (fingerprint != null
&& isUnlockingWithBiometricAllowed(fingerprint.mIsStrongBiometric)));
@@ -3641,6 +3744,7 @@
pw.println(" shouldListenForUdfps=" + shouldListenForFingerprint(true));
pw.println(" mBouncerIsOrWillBeShowing=" + mBouncerIsOrWillBeShowing);
pw.println(" mStatusBarState=" + StatusBarState.toString(mStatusBarState));
+ pw.println(" mUdfpsBouncerShowing=" + mUdfpsBouncerShowing);
}
}
if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
@@ -3667,6 +3771,13 @@
}
mListenModels.print(pw);
+ pw.println("Enabled active unlock triggers:");
+ pw.println(" mRequestActiveUnlockOnWakeup=" + mRequestActiveUnlockOnWakeup);
+ pw.println(" mInitiateActiveUnlockOnWakeup=" + mInitiateActiveUnlockOnWakeup);
+ pw.println(" mRequestActiveUnlockOnUnlockIntent=" + mRequestActiveUnlockOnUnlockIntent);
+ pw.println(" mRequestActiveUnlockOnBiometricFail=" + mRequestActiveUnlockOnBioFail);
+ pw.println(" mRequestActiveUnlockOnAssistant=" + mRequestActiveUnlockOnAssistant);
+
if (mIsAutomotive) {
pw.println(" Running on Automotive build");
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java
index 295d77d..ca8728a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java
@@ -55,6 +55,11 @@
void reset(boolean hideBouncerWhenShowing);
/**
+ * Stop showing any alternate auth methods.
+ */
+ void resetAlternateAuth(boolean forceUpdateScrim);
+
+ /**
* Called when the device started going to sleep.
*/
default void onStartedGoingToSleep() {};
diff --git a/packages/SystemUI/src/com/android/systemui/LatencyTester.java b/packages/SystemUI/src/com/android/systemui/LatencyTester.java
index 7afd43d..9cdce64 100644
--- a/packages/SystemUI/src/com/android/systemui/LatencyTester.java
+++ b/packages/SystemUI/src/com/android/systemui/LatencyTester.java
@@ -23,21 +23,31 @@
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricSourceType;
import android.os.Build;
+import android.provider.DeviceConfig;
+import androidx.annotation.NonNull;
+
+import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
+import com.android.systemui.util.DeviceConfigProxy;
+import com.android.systemui.util.concurrency.DelayableExecutor;
+
+import java.io.PrintWriter;
import javax.inject.Inject;
/**
- * Class that only runs on debuggable builds that listens to broadcasts that simulate actions in the
+ * Class that only runs on debuggable builds with the LatencyTracker setting enabled
+ * that listens to broadcasts that simulate actions in the
* system that are used for testing the latency.
*/
@SysUISingleton
public class LatencyTester extends CoreStartable {
-
+ private static final boolean DEFAULT_ENABLED = Build.IS_ENG;
private static final String
ACTION_FINGERPRINT_WAKE =
"com.android.systemui.latency.ACTION_FINGERPRINT_WAKE";
@@ -46,42 +56,78 @@
"com.android.systemui.latency.ACTION_FACE_WAKE";
private final BiometricUnlockController mBiometricUnlockController;
private final BroadcastDispatcher mBroadcastDispatcher;
+ private final DeviceConfigProxy mDeviceConfigProxy;
+
+ private boolean mEnabled;
@Inject
- public LatencyTester(Context context, BiometricUnlockController biometricUnlockController,
- BroadcastDispatcher broadcastDispatcher) {
+ public LatencyTester(
+ Context context,
+ BiometricUnlockController biometricUnlockController,
+ BroadcastDispatcher broadcastDispatcher,
+ DeviceConfigProxy deviceConfigProxy,
+ @Main DelayableExecutor mainExecutor
+ ) {
super(context);
-
mBiometricUnlockController = biometricUnlockController;
mBroadcastDispatcher = broadcastDispatcher;
+ mDeviceConfigProxy = deviceConfigProxy;
+
+ updateEnabled();
+ mDeviceConfigProxy.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
+ mainExecutor, properties -> updateEnabled());
}
@Override
public void start() {
- if (!Build.IS_DEBUGGABLE) {
- return;
- }
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(ACTION_FINGERPRINT_WAKE);
- filter.addAction(ACTION_FACE_WAKE);
- mBroadcastDispatcher.registerReceiver(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (ACTION_FINGERPRINT_WAKE.equals(action)) {
- fakeWakeAndUnlock(BiometricSourceType.FINGERPRINT);
- } else if (ACTION_FACE_WAKE.equals(action)) {
- fakeWakeAndUnlock(BiometricSourceType.FACE);
- }
- }
- }, filter);
+ registerForBroadcasts(mEnabled);
}
private void fakeWakeAndUnlock(BiometricSourceType type) {
+ if (!mEnabled) {
+ return;
+ }
mBiometricUnlockController.onBiometricAcquired(type,
BiometricConstants.BIOMETRIC_ACQUIRED_GOOD);
mBiometricUnlockController.onBiometricAuthenticated(
KeyguardUpdateMonitor.getCurrentUser(), type, true /* isStrongBiometric */);
}
+
+ private void registerForBroadcasts(boolean register) {
+ if (register) {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_FINGERPRINT_WAKE);
+ filter.addAction(ACTION_FACE_WAKE);
+ mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter);
+ } else {
+ mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
+ }
+ }
+
+ private void updateEnabled() {
+ boolean wasEnabled = mEnabled;
+ mEnabled = Build.IS_DEBUGGABLE
+ && mDeviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
+ LatencyTracker.SETTINGS_ENABLED_KEY, DEFAULT_ENABLED);
+ if (mEnabled != wasEnabled) {
+ registerForBroadcasts(mEnabled);
+ }
+ }
+
+ @Override
+ public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
+ pw.println("mEnabled=" + mEnabled);
+ }
+
+ private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (ACTION_FINGERPRINT_WAKE.equals(action)) {
+ fakeWakeAndUnlock(BiometricSourceType.FINGERPRINT);
+ } else if (ACTION_FACE_WAKE.equals(action)) {
+ fakeWakeAndUnlock(BiometricSourceType.FACE);
+ }
+ }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index b05bc24..15d0648 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -37,6 +37,7 @@
import android.hardware.biometrics.BiometricManager.Authenticators;
import android.hardware.biometrics.BiometricManager.BiometricMultiSensorMode;
import android.hardware.biometrics.BiometricPrompt;
+import android.hardware.biometrics.BiometricStateListener;
import android.hardware.biometrics.IBiometricContextListener;
import android.hardware.biometrics.IBiometricSysuiReceiver;
import android.hardware.biometrics.PromptInfo;
@@ -45,7 +46,6 @@
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.hardware.fingerprint.FingerprintStateListener;
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
import android.hardware.fingerprint.IUdfpsHbmListener;
import android.os.Bundle;
@@ -138,7 +138,7 @@
@NonNull private final SparseBooleanArray mUdfpsEnrolledForUser;
@NonNull private final SensorPrivacyManager mSensorPrivacyManager;
private final WakefulnessLifecycle mWakefulnessLifecycle;
- private boolean mAllAuthenticatorsRegistered;
+ private boolean mAllFingerprintAuthenticatorsRegistered;
@NonNull private final UserManager mUserManager;
@NonNull private final LockPatternUtils mLockPatternUtils;
private final @Background DelayableExecutor mBackgroundExecutor;
@@ -157,12 +157,12 @@
@Override
public void onAllAuthenticatorsRegistered(
List<FingerprintSensorPropertiesInternal> sensors) {
- mHandler.post(() -> handleAllAuthenticatorsRegistered(sensors));
+ mHandler.post(() -> handleAllFingerprintAuthenticatorsRegistered(sensors));
}
};
- private final FingerprintStateListener mFingerprintStateListener =
- new FingerprintStateListener() {
+ private final BiometricStateListener mBiometricStateListener =
+ new BiometricStateListener() {
@Override
public void onEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) {
mHandler.post(
@@ -234,20 +234,20 @@
}
/**
- * Whether all authentictors have been registered.
+ * Whether all fingerprint authentictors have been registered.
*/
- public boolean areAllAuthenticatorsRegistered() {
- return mAllAuthenticatorsRegistered;
+ public boolean areAllFingerprintAuthenticatorsRegistered() {
+ return mAllFingerprintAuthenticatorsRegistered;
}
- private void handleAllAuthenticatorsRegistered(
+ private void handleAllFingerprintAuthenticatorsRegistered(
List<FingerprintSensorPropertiesInternal> sensors) {
mExecution.assertIsMainThread();
if (DEBUG) {
Log.d(TAG, "handleAllAuthenticatorsRegistered | sensors: " + Arrays.toString(
sensors.toArray()));
}
- mAllAuthenticatorsRegistered = true;
+ mAllFingerprintAuthenticatorsRegistered = true;
mFpProps = sensors;
List<FingerprintSensorPropertiesInternal> udfpsProps = new ArrayList<>();
List<FingerprintSensorPropertiesInternal> sidefpsProps = new ArrayList<>();
@@ -281,7 +281,7 @@
for (Callback cb : mCallbacks) {
cb.onAllAuthenticatorsRegistered();
}
- mFingerprintManager.registerFingerprintStateListener(mFingerprintStateListener);
+ mFingerprintManager.registerBiometricStateListener(mBiometricStateListener);
}
private void handleEnrollmentsChanged(int userId, int sensorId, boolean hasEnrollments) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 2ac2408..eba87e4 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -799,6 +799,11 @@
if (!mKeyguardUpdateMonitor.isFaceDetectionRunning()) {
mKeyguardUpdateMonitor.requestFaceAuth(/* userInitiatedRequest */ false);
}
+
+ if (mKeyguardUpdateMonitor.mRequestActiveUnlockOnUnlockIntent) {
+ mKeyguardUpdateMonitor.requestActiveUnlock("unlock-intent extra=udfpsFingerDown",
+ true);
+ }
}
mOnFingerDown = true;
mFingerprintManager.onPointerDown(requestId, mSensorProps.sensorId, x, y, minor, major);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
index f5f07c8..1a726ce 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -475,7 +475,7 @@
public void onPanelExpansionChanged(
float fraction, boolean expanded, boolean tracking) {
mPanelExpansionFraction =
- mKeyguardViewManager.bouncerIsInTransit() ? BouncerPanelExpansionCalculator
+ mKeyguardViewManager.isBouncerInTransit() ? BouncerPanelExpansionCalculator
.aboutToShowBouncerProgress(fraction) : fraction;
updateAlpha();
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
index 1653e0a..fb01691 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
@@ -29,8 +29,10 @@
import com.android.systemui.settings.brightness.BrightnessDialog;
import com.android.systemui.statusbar.tv.notifications.TvNotificationPanelActivity;
import com.android.systemui.tuner.TunerActivity;
+import com.android.systemui.usb.UsbConfirmActivity;
import com.android.systemui.usb.UsbDebuggingActivity;
import com.android.systemui.usb.UsbDebuggingSecondaryUserActivity;
+import com.android.systemui.usb.UsbPermissionActivity;
import com.android.systemui.user.CreateUserActivity;
import dagger.Binds;
@@ -80,6 +82,18 @@
public abstract Activity bindUsbDebuggingSecondaryUserActivity(
UsbDebuggingSecondaryUserActivity activity);
+ /** Inject into UsbPermissionActivity. */
+ @Binds
+ @IntoMap
+ @ClassKey(UsbPermissionActivity.class)
+ public abstract Activity bindUsbPermissionActivity(UsbPermissionActivity activity);
+
+ /** Inject into UsbConfirmActivity. */
+ @Binds
+ @IntoMap
+ @ClassKey(UsbConfirmActivity.class)
+ public abstract Activity bindUsbConfirmActivity(UsbConfirmActivity activity);
+
/** Inject into CreateUserActivity. */
@Binds
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
index b172e92..535b548 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
@@ -490,5 +490,4 @@
static SafetyCenterManager provideSafetyCenterManager(Context context) {
return context.getSystemService(SafetyCenterManager.class);
}
-
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
index aaa4d9e..c4531b5 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
@@ -42,10 +42,14 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.statusbar.commandline.Command;
+import com.android.systemui.statusbar.commandline.CommandRegistry;
import com.android.systemui.util.settings.SecureSettings;
import java.io.PrintWriter;
+import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
@@ -59,6 +63,10 @@
*
* Flags can be set (or unset) via the following adb command:
*
+ * adb shell cmd statusbar flag <id> <on|off|toggle|erase>
+ *
+ * Alternatively, you can change flags via a broadcast intent:
+ *
* adb shell am broadcast -a com.android.systemui.action.SET_FLAG --ei id <id> [--ez value <0|1>]
*
* To restore a flag back to its default, leave the `--ez value <0|1>` off of the command.
@@ -67,6 +75,7 @@
public class FeatureFlagsDebug implements FeatureFlags, Dumpable {
private static final String TAG = "SysUIFlags";
static final String ALL_FLAGS = "all_flags";
+ private static final String FLAG_COMMAND = "flag";
private final FlagManager mFlagManager;
private final SecureSettings mSecureSettings;
@@ -86,12 +95,15 @@
@Main Resources resources,
DumpManager dumpManager,
@Named(ALL_FLAGS) Map<Integer, Flag<?>> allFlags,
+ CommandRegistry commandRegistry,
IStatusBarService barService) {
mFlagManager = flagManager;
mSecureSettings = secureSettings;
mResources = resources;
mSystemProperties = systemProperties;
mAllFlags = allFlags;
+ mBarService = barService;
+
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_SET_FLAG);
filter.addAction(ACTION_GET_FLAGS);
@@ -100,7 +112,7 @@
context.registerReceiver(mReceiver, filter, null, null,
Context.RECEIVER_EXPORTED_UNAUDITED);
dumpManager.registerDumpable(TAG, this);
- mBarService = barService;
+ commandRegistry.registerCommand(FLAG_COMMAND, FlagCommand::new);
}
@Override
@@ -276,6 +288,31 @@
}
}
+ private void setBooleanFlagInternal(Flag<?> flag, boolean value) {
+ if (flag instanceof BooleanFlag) {
+ setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE);
+ } else if (flag instanceof ResourceBooleanFlag) {
+ setFlagValue(flag.getId(), 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(),
+ FeatureFlagsDebug.this::restartAndroid);
+ } else {
+ throw new IllegalArgumentException("Unknown flag type");
+ }
+ }
+
+ private void setStringFlagInternal(Flag<?> flag, String value) {
+ if (flag instanceof StringFlag) {
+ setFlagValue(flag.getId(), value, StringFlagSerializer.INSTANCE);
+ } else if (flag instanceof ResourceStringFlag) {
+ setFlagValue(flag.getId(), value, StringFlagSerializer.INSTANCE);
+ } else {
+ throw new IllegalArgumentException("Unknown flag type");
+ }
+ }
+
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -327,24 +364,19 @@
}
Object value = extras.get(EXTRA_VALUE);
- if (flag instanceof BooleanFlag && value instanceof Boolean) {
- setFlagValue(id, (Boolean) value, BooleanFlagSerializer.INSTANCE);
- } else if (flag instanceof ResourceBooleanFlag && value instanceof Boolean) {
- setFlagValue(id, (Boolean) value, BooleanFlagSerializer.INSTANCE);
- } else if (flag instanceof SysPropBooleanFlag && value instanceof Boolean) {
- // Store SysProp flags in SystemProperties where they can read by outside parties.
- mSystemProperties.setBoolean(
- ((SysPropBooleanFlag) flag).getName(), (Boolean) value);
- dispatchListenersAndMaybeRestart(flag.getId(),
- FeatureFlagsDebug.this::restartAndroid);
- } else if (flag instanceof StringFlag && value instanceof String) {
- setFlagValue(id, (String) value, StringFlagSerializer.INSTANCE);
- } else if (flag instanceof ResourceStringFlag && value instanceof String) {
- setFlagValue(id, (String) value, StringFlagSerializer.INSTANCE);
- } else {
+
+ try {
+ if (value instanceof Boolean) {
+ setBooleanFlagInternal(flag, (Boolean) value);
+ } else if (value instanceof String) {
+ setStringFlagInternal(flag, (String) value);
+ } else {
+ throw new IllegalArgumentException("Unknown value type");
+ }
+ } catch (IllegalArgumentException e) {
Log.w(TAG,
- "Unable to set " + id + " of type " + flag.getClass() + " to value of type "
- + (value == null ? null : value.getClass()));
+ "Unable to set " + flag.getId() + " of type " + flag.getClass()
+ + " to value of type " + (value == null ? null : value.getClass()));
}
}
@@ -388,4 +420,153 @@
mStringFlagCache.forEach((key, value) -> pw.println(" sysui_flag_" + key
+ ": [length=" + value.length() + "] \"" + value + "\""));
}
+
+ class FlagCommand implements Command {
+ private final List<String> mOnCommands = List.of("true", "on", "1", "enabled");
+ private final List<String> mOffCommands = List.of("false", "off", "0", "disable");
+
+ @Override
+ public void execute(@NonNull PrintWriter pw, @NonNull List<String> args) {
+ if (args.size() == 0) {
+ pw.println("Error: no flag id supplied");
+ help(pw);
+ pw.println();
+ printKnownFlags(pw);
+ return;
+ }
+
+ if (args.size() > 2) {
+ pw.println("Invalid number of arguments.");
+ help(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;
+ }
+ }
+ Flag<?> flag = mAllFlags.get(id);
+
+ String cmd = "";
+ if (args.size() == 2) {
+ cmd = args.get(1).toLowerCase();
+ }
+
+ if ("erase".equals(cmd) || "reset".equals(cmd)) {
+ eraseFlag(flag);
+ return;
+ }
+
+ boolean newValue = true;
+ if (args.size() == 1 || "toggle".equals(cmd)) {
+ boolean enabled = isBooleanFlagEnabled(flag);
+
+ if (args.size() == 1) {
+ pw.println("Flag " + id + " is " + enabled);
+ return;
+ }
+
+ newValue = !enabled;
+ } else {
+ newValue = mOnCommands.contains(cmd);
+ if (!newValue && !mOffCommands.contains(cmd)) {
+ pw.println("Invalid on/off argument supplied");
+ help(pw);
+ return;
+ }
+ }
+
+ pw.flush(); // Next command will restart sysui, so flush before we do so.
+ setBooleanFlagInternal(flag, newValue);
+ }
+
+ @Override
+ public void help(PrintWriter pw) {
+ pw.println(
+ "Usage: adb shell cmd statusbar flag <id> "
+ + "[true|false|1|0|on|off|enable|disable|toggle|erase|reset]");
+ pw.println("The id can either be a numeric integer or the corresponding field name");
+ pw.println(
+ "If no argument is supplied after the id, the flags runtime value is output");
+ }
+
+ private boolean isBooleanFlagEnabled(Flag<?> flag) {
+ if (flag instanceof BooleanFlag) {
+ return isEnabled((BooleanFlag) flag);
+ } else if (flag instanceof ResourceBooleanFlag) {
+ return isEnabled((ResourceBooleanFlag) flag);
+ } else if (flag instanceof SysPropFlag) {
+ return isEnabled((SysPropBooleanFlag) flag);
+ }
+
+ return false;
+ }
+
+ private int flagNameToId(String flagName) {
+ List<Field> fields = Flags.getFlagFields();
+ for (Field field : fields) {
+ if (flagName.equals(field.getName())) {
+ return fieldToId(field);
+ }
+ }
+
+ return 0;
+ }
+
+ private int fieldToId(Field field) {
+ try {
+ Flag<?> flag = (Flag<?>) field.get(null);
+ return flag.getId();
+ } catch (IllegalAccessException e) {
+ // no-op
+ }
+
+ return 0;
+ }
+
+ private void printKnownFlags(PrintWriter pw) {
+ List<Field> fields = Flags.getFlagFields();
+
+ int longestFieldName = 0;
+ for (Field field : fields) {
+ longestFieldName = Math.max(longestFieldName, field.getName().length());
+ }
+
+ pw.println("Known Flags:");
+ pw.print("Flag Name");
+ for (int i = 0; i < longestFieldName - "Flag Name".length() + 1; i++) {
+ pw.print(" ");
+ }
+ pw.println("ID Enabled?");
+ for (int i = 0; i < longestFieldName; i++) {
+ pw.print("=");
+ }
+ pw.println(" ==== ========");
+ for (Field field : fields) {
+ int id = fieldToId(field);
+ if (id == 0 || !mAllFlags.containsKey(id)) {
+ continue;
+ }
+ pw.print(field.getName());
+ int fieldWidth = field.getName().length();
+ for (int i = 0; i < longestFieldName - fieldWidth + 1; i++) {
+ pw.print(" ");
+ }
+ pw.printf("%-4d ", id);
+ pw.println(isBooleanFlagEnabled(mAllFlags.get(id)));
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index 44580aa..afa7d5e 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -20,7 +20,9 @@
import com.android.systemui.R;
import java.lang.reflect.Field;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -182,19 +184,16 @@
if (sFlagMap != null) {
return sFlagMap;
}
+
Map<Integer, Flag<?>> flags = new HashMap<>();
+ List<Field> flagFields = getFlagFields();
- Field[] fields = Flags.class.getFields();
-
- for (Field field : fields) {
- Class<?> t = field.getType();
- if (Flag.class.isAssignableFrom(t)) {
- try {
- Flag<?> flag = (Flag<?>) field.get(null);
- flags.put(flag.getId(), flag);
- } catch (IllegalAccessException e) {
- // no-op
- }
+ for (Field field : flagFields) {
+ try {
+ Flag<?> flag = (Flag<?>) field.get(null);
+ flags.put(flag.getId(), flag);
+ } catch (IllegalAccessException e) {
+ // no-op
}
}
@@ -202,6 +201,20 @@
return sFlagMap;
}
+
+ static List<Field> getFlagFields() {
+ Field[] fields = Flags.class.getFields();
+ List<Field> result = new ArrayList<>();
+
+ for (Field field : fields) {
+ Class<?> t = field.getType();
+ if (Flag.class.isAssignableFrom(t)) {
+ result.add(field);
+ }
+ }
+
+ return result;
+ }
// | . . . . . . . . . . . . . . . . . . . |
// | |
// \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
diff --git a/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt b/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
index 6d589aa..e16da89 100644
--- a/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
@@ -23,6 +23,9 @@
import java.text.SimpleDateFormat
import java.util.ArrayDeque
import java.util.Locale
+import java.util.concurrent.ArrayBlockingQueue
+import java.util.concurrent.BlockingQueue
+import kotlin.concurrent.thread
/**
* A simple ring buffer of recyclable log messages
@@ -81,6 +84,22 @@
}
private val buffer: ArrayDeque<LogMessageImpl> = ArrayDeque()
+ private val echoMessageQueue: BlockingQueue<LogMessageImpl>? =
+ if (logcatEchoTracker.logInBackgroundThread) ArrayBlockingQueue(poolSize) else null
+
+ init {
+ if (logcatEchoTracker.logInBackgroundThread && echoMessageQueue != null) {
+ thread(start = true, priority = Thread.NORM_PRIORITY) {
+ try {
+ while (true) {
+ echoToDesiredEndpoints(echoMessageQueue.take())
+ }
+ } catch (e: InterruptedException) {
+ Thread.currentThread().interrupt()
+ }
+ }
+ }
+ }
var frozen = false
private set
@@ -176,6 +195,22 @@
buffer.removeFirst()
}
buffer.add(message as LogMessageImpl)
+ // Log in the background thread only if echoMessageQueue exists and has capacity (checking
+ // capacity avoids the possibility of blocking this thread)
+ if (echoMessageQueue != null && echoMessageQueue.remainingCapacity() > 0) {
+ try {
+ echoMessageQueue.put(message)
+ } catch (e: InterruptedException) {
+ // the background thread has been shut down, so just log on this one
+ echoToDesiredEndpoints(message)
+ }
+ } else {
+ echoToDesiredEndpoints(message)
+ }
+ }
+
+ /** Sends message to echo after determining whether to use Logcat and/or systrace. */
+ private fun echoToDesiredEndpoints(message: LogMessageImpl) {
val includeInLogcat = logcatEchoTracker.isBufferLoggable(name, message.level) ||
logcatEchoTracker.isTagLoggable(message.tag, message.level)
echo(message, toLogcat = includeInLogcat, toSystrace = systrace)
diff --git a/packages/SystemUI/src/com/android/systemui/log/LogcatEchoTracker.kt b/packages/SystemUI/src/com/android/systemui/log/LogcatEchoTracker.kt
index 3022f4b..8cda423 100644
--- a/packages/SystemUI/src/com/android/systemui/log/LogcatEchoTracker.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/LogcatEchoTracker.kt
@@ -29,4 +29,9 @@
* Whether [tagName] should echo messages of [level] or higher to logcat.
*/
fun isTagLoggable(tagName: String, level: LogLevel): Boolean
+
+ /**
+ * Whether to log messages in a background thread.
+ */
+ val logInBackgroundThread: Boolean
}
diff --git a/packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerDebug.kt b/packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerDebug.kt
index 23942e1..91734cc 100644
--- a/packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerDebug.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerDebug.kt
@@ -41,6 +41,7 @@
) : LogcatEchoTracker {
private val cachedBufferLevels: MutableMap<String, LogLevel> = mutableMapOf()
private val cachedTagLevels: MutableMap<String, LogLevel> = mutableMapOf()
+ override val logInBackgroundThread = true
companion object Factory {
@JvmStatic
diff --git a/packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerProd.kt b/packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerProd.kt
index 394f624..1a4ad19 100644
--- a/packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerProd.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerProd.kt
@@ -20,6 +20,8 @@
* Production version of [LogcatEchoTracker] that isn't configurable.
*/
class LogcatEchoTrackerProd : LogcatEchoTracker {
+ override val logInBackgroundThread = false
+
override fun isBufferLoggable(bufferName: String, level: LogLevel): Boolean {
return level >= LogLevel.WARNING
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/AnimationBindHandler.kt b/packages/SystemUI/src/com/android/systemui/media/AnimationBindHandler.kt
new file mode 100644
index 0000000..013683e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/AnimationBindHandler.kt
@@ -0,0 +1,81 @@
+/*
+ * 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.media
+
+import android.graphics.drawable.Animatable2
+import android.graphics.drawable.Drawable
+
+/**
+ * AnimationBindHandler is responsible for tracking the bound animation state and preventing
+ * jank and conflicts due to media notifications arriving at any time during an animation. It
+ * does this in two parts.
+ * - Exit animations fired as a result of user input are tracked. When these are running, any
+ * bind actions are delayed until the animation completes (and then fired in sequence).
+ * - Continuous animations are tracked using their rebind id. Later calls using the same
+ * rebind id will be totally ignored to prevent the continuous animation from restarting.
+ */
+internal class AnimationBindHandler : Animatable2.AnimationCallback() {
+ private val onAnimationsComplete = mutableListOf<() -> Unit>()
+ private val registrations = mutableListOf<Animatable2>()
+ private var rebindId: Int? = null
+
+ val isAnimationRunning: Boolean
+ get() = registrations.any { it.isRunning }
+
+ /**
+ * This check prevents rebinding to the action button if the identifier has not changed. A
+ * null value is always considered to be changed. This is used to prevent the connecting
+ * animation from rebinding (and restarting) if multiple buffer PlaybackStates are pushed by
+ * an application in a row.
+ */
+ fun updateRebindId(newRebindId: Int?): Boolean {
+ if (rebindId == null || newRebindId == null || rebindId != newRebindId) {
+ rebindId = newRebindId
+ return true
+ }
+ return false
+ }
+
+ fun tryRegister(drawable: Drawable?) {
+ if (drawable is Animatable2) {
+ val anim = drawable as Animatable2
+ anim.registerAnimationCallback(this)
+ registrations.add(anim)
+ }
+ }
+
+ fun unregisterAll() {
+ registrations.forEach { it.unregisterAnimationCallback(this) }
+ registrations.clear()
+ }
+
+ fun tryExecute(action: () -> Unit) {
+ if (isAnimationRunning) {
+ onAnimationsComplete.add(action)
+ } else {
+ action()
+ }
+ }
+
+ override fun onAnimationEnd(drawable: Drawable) {
+ super.onAnimationEnd(drawable)
+ if (!isAnimationRunning) {
+ onAnimationsComplete.forEach { it() }
+ onAnimationsComplete.clear()
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt b/packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt
new file mode 100644
index 0000000..2ae1806
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt
@@ -0,0 +1,170 @@
+/*
+ * 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.media
+
+import android.animation.ArgbEvaluator
+import android.animation.ValueAnimator.AnimatorUpdateListener
+import android.animation.ValueAnimator
+import android.content.Context
+import android.content.res.ColorStateList
+import com.android.internal.R
+import com.android.internal.annotations.VisibleForTesting
+import com.android.settingslib.Utils
+import com.android.systemui.monet.ColorScheme
+
+/**
+ * ColorTransition is responsible for managing the animation between two specific colors.
+ * It uses a ValueAnimator to execute the animation and interpolate between the source color and
+ * the target color.
+ *
+ * Selection of the target color from the scheme, and application of the interpolated color
+ * are delegated to callbacks.
+ */
+open class ColorTransition(
+ private val defaultColor: Int,
+ private val extractColor: (ColorScheme) -> Int,
+ private val applyColor: (Int) -> Unit
+) : AnimatorUpdateListener {
+
+ private val argbEvaluator = ArgbEvaluator()
+ private val valueAnimator = buildAnimator()
+ var sourceColor: Int = defaultColor
+ var currentColor: Int = defaultColor
+ var targetColor: Int = defaultColor
+
+ override fun onAnimationUpdate(animation: ValueAnimator) {
+ currentColor = argbEvaluator.evaluate(
+ animation.animatedFraction, sourceColor, targetColor
+ ) as Int
+ applyColor(currentColor)
+ }
+
+ fun updateColorScheme(scheme: ColorScheme?) {
+ val newTargetColor = if (scheme == null) defaultColor else extractColor(scheme)
+ if (newTargetColor != targetColor) {
+ sourceColor = currentColor
+ targetColor = newTargetColor
+ valueAnimator.cancel()
+ valueAnimator.start()
+ }
+ }
+
+ init {
+ applyColor(defaultColor)
+ }
+
+ @VisibleForTesting
+ open fun buildAnimator(): ValueAnimator {
+ val animator = ValueAnimator.ofFloat(0f, 1f)
+ animator.duration = 333
+ animator.addUpdateListener(this)
+ return animator
+ }
+}
+
+typealias ColorTransitionFactory = (Int, (ColorScheme) -> Int, (Int) -> Unit) -> ColorTransition
+
+/**
+ * ColorSchemeTransition constructs a ColorTransition for each color in the scheme
+ * that needs to be transitioned when changed. It also sets up the assignment functions for sending
+ * the sending the interpolated colors to the appropriate views.
+ */
+class ColorSchemeTransition internal constructor(
+ private val context: Context,
+ mediaViewHolder: MediaViewHolder,
+ colorTransitionFactory: ColorTransitionFactory
+) {
+ constructor(context: Context, mediaViewHolder: MediaViewHolder) :
+ this(context, mediaViewHolder, ::ColorTransition)
+
+ val bgColor = context.getColor(com.android.systemui.R.color.material_dynamic_secondary95)
+
+ val surfaceColor = colorTransitionFactory(
+ bgColor,
+ { colorScheme -> colorScheme.accent2[9] }, // A2-800
+ { surfaceColor ->
+ val colorList = ColorStateList.valueOf(surfaceColor)
+ mediaViewHolder.player.backgroundTintList = colorList
+ mediaViewHolder.albumView.foregroundTintList = colorList
+ mediaViewHolder.albumView.backgroundTintList = colorList
+ mediaViewHolder.seamlessIcon.imageTintList = colorList
+ mediaViewHolder.seamlessText.setTextColor(surfaceColor)
+ mediaViewHolder.dismissText.setTextColor(surfaceColor)
+ })
+
+ val accentPrimary = colorTransitionFactory(
+ loadDefaultColor(R.attr.textColorPrimary),
+ { colorScheme -> colorScheme.accent1[2] }, // A1-100
+ { accentPrimary ->
+ val accentColorList = ColorStateList.valueOf(accentPrimary)
+ mediaViewHolder.actionPlayPause.backgroundTintList = accentColorList
+ mediaViewHolder.seamlessButton.backgroundTintList = accentColorList
+ mediaViewHolder.settings.imageTintList = accentColorList
+ mediaViewHolder.cancelText.backgroundTintList = accentColorList
+ mediaViewHolder.dismissText.backgroundTintList = accentColorList
+ })
+
+ val textPrimary = colorTransitionFactory(
+ loadDefaultColor(R.attr.textColorPrimary),
+ { colorScheme -> colorScheme.neutral1[1] }, // N1-50
+ { textPrimary ->
+ mediaViewHolder.titleText.setTextColor(textPrimary)
+ val textColorList = ColorStateList.valueOf(textPrimary)
+ mediaViewHolder.seekBar.thumb.setTintList(textColorList)
+ mediaViewHolder.seekBar.progressTintList = textColorList
+ mediaViewHolder.longPressText.setTextColor(textColorList)
+ mediaViewHolder.cancelText.setTextColor(textColorList)
+ mediaViewHolder.scrubbingElapsedTimeView.setTextColor(textColorList)
+ mediaViewHolder.scrubbingTotalTimeView.setTextColor(textColorList)
+ for (button in mediaViewHolder.getTransparentActionButtons()) {
+ button.imageTintList = textColorList
+ }
+ })
+
+ val textPrimaryInverse = colorTransitionFactory(
+ loadDefaultColor(R.attr.textColorPrimaryInverse),
+ { colorScheme -> colorScheme.neutral1[10] }, // N1-900
+ { textPrimaryInverse ->
+ mediaViewHolder.actionPlayPause.imageTintList =
+ ColorStateList.valueOf(textPrimaryInverse)
+ })
+
+ val textSecondary = colorTransitionFactory(
+ loadDefaultColor(R.attr.textColorSecondary),
+ { colorScheme -> colorScheme.neutral2[3] }, // N2-200
+ { textSecondary -> mediaViewHolder.artistText.setTextColor(textSecondary) })
+
+ val textTertiary = colorTransitionFactory(
+ loadDefaultColor(R.attr.textColorTertiary),
+ { colorScheme -> colorScheme.neutral2[5] }, // N2-400
+ { textTertiary ->
+ mediaViewHolder.seekBar.progressBackgroundTintList =
+ ColorStateList.valueOf(textTertiary)
+ })
+
+ val colorTransitions = arrayOf(
+ surfaceColor, accentPrimary, textPrimary,
+ textPrimaryInverse, textSecondary, textTertiary)
+
+ private fun loadDefaultColor(id: Int): Int {
+ return Utils.getColorAttr(context, id).defaultColor
+ }
+
+ fun updateColorScheme(colorScheme: ColorScheme?) {
+ colorTransitions.forEach { it.updateColorScheme(colorScheme) }
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index 8e81831..49966a6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -904,7 +904,6 @@
private val EMPTY = MediaData(
userId = -1,
initialized = false,
- backgroundColor = 0,
app = null,
appIcon = null,
artist = null,
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index c956783..766e7b0 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -18,6 +18,9 @@
import static android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS;
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorSet;
import android.app.PendingIntent;
import android.app.WallpaperColors;
import android.app.smartspace.SmartspaceAction;
@@ -31,20 +34,22 @@
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.Animatable;
-import android.graphics.drawable.Animatable2;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
+import android.graphics.drawable.TransitionDrawable;
import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
import android.os.Process;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.animation.Interpolator;
import android.widget.ImageButton;
import android.widget.ImageView;
-import android.widget.SeekBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
@@ -52,12 +57,15 @@
import androidx.annotation.UiThread;
import androidx.constraintlayout.widget.ConstraintSet;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.InstanceId;
import com.android.settingslib.widget.AdaptiveIcon;
+import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.R;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.animation.GhostedViewLaunchAnimatorController;
+import com.android.systemui.animation.Interpolators;
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
@@ -66,6 +74,8 @@
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.shared.system.SysUiStatsLog;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.animation.TransitionLayout;
import com.android.systemui.util.time.SystemClock;
@@ -90,8 +100,7 @@
+ ".android.apps.gsa.staticplugins.opa.smartspace.ExportedSmartspaceTrampolineActivity";
private static final String EXTRAS_SMARTSPACE_INTENT =
"com.google.android.apps.gsa.smartspace.extra.SMARTSPACE_INTENT";
- private static final int MEDIA_RECOMMENDATION_ITEMS_PER_ROW = 3;
- private static final int MEDIA_RECOMMENDATION_MAX_NUM = 6;
+ private static final int MEDIA_RECOMMENDATION_MAX_NUM = 3;
private static final String KEY_SMARTSPACE_ARTIST_NAME = "artist_name";
private static final String KEY_SMARTSPACE_OPEN_IN_FOREGROUND = "KEY_OPEN_IN_FOREGROUND";
private static final String KEY_SMARTSPACE_APP_NAME = "KEY_SMARTSPACE_APP_NAME";
@@ -141,13 +150,21 @@
private MediaSession.Token mToken;
private MediaController mController;
private Lazy<MediaDataManager> mMediaDataManagerLazy;
- private int mBackgroundColor;
// Uid for the media app.
protected int mUid = Process.INVALID_UID;
private int mSmartspaceMediaItemsCount;
private MediaCarouselController mMediaCarouselController;
private final MediaOutputDialogFactory mMediaOutputDialogFactory;
private final FalsingManager mFalsingManager;
+ private MetadataAnimationHandler mMetadataAnimationHandler;
+ private ColorSchemeTransition mColorSchemeTransition;
+ private Drawable mPrevArtwork = null;
+ private int mArtworkBoundId = 0;
+ private int mArtworkNextBindRequestId = 0;
+
+ private final KeyguardStateController mKeyguardStateController;
+ private final ActivityIntentHelper mActivityIntentHelper;
+ private final NotificationLockscreenUserManager mLockscreenUserManager;
// Used for logging.
protected boolean mIsImpressed = false;
@@ -171,15 +188,23 @@
* @param activityStarter activity starter
*/
@Inject
- public MediaControlPanel(Context context,
+ public MediaControlPanel(
+ Context context,
@Background Executor backgroundExecutor,
@Main Executor mainExecutor,
- ActivityStarter activityStarter, BroadcastSender broadcastSender,
- MediaViewController mediaViewController, SeekBarViewModel seekBarViewModel,
+ ActivityStarter activityStarter,
+ BroadcastSender broadcastSender,
+ MediaViewController mediaViewController,
+ SeekBarViewModel seekBarViewModel,
Lazy<MediaDataManager> lazyMediaDataManager,
MediaOutputDialogFactory mediaOutputDialogFactory,
MediaCarouselController mediaCarouselController,
- FalsingManager falsingManager, SystemClock systemClock, MediaUiEventLogger logger) {
+ FalsingManager falsingManager,
+ SystemClock systemClock,
+ MediaUiEventLogger logger,
+ KeyguardStateController keyguardStateController,
+ ActivityIntentHelper activityIntentHelper,
+ NotificationLockscreenUserManager lockscreenUserManager) {
mContext = context;
mBackgroundExecutor = backgroundExecutor;
mMainExecutor = mainExecutor;
@@ -193,6 +218,9 @@
mFalsingManager = falsingManager;
mSystemClock = systemClock;
mLogger = logger;
+ mKeyguardStateController = keyguardStateController;
+ mActivityIntentHelper = activityIntentHelper;
+ mLockscreenUserManager = lockscreenUserManager;
mSeekBarViewModel.setLogSeek(() -> {
if (mPackageName != null && mInstanceId != null) {
@@ -306,6 +334,32 @@
mActivityStarter.startActivity(SETTINGS_INTENT, true /* dismissShade */);
}
});
+
+ TextView titleText = mMediaViewHolder.getTitleText();
+ TextView artistText = mMediaViewHolder.getArtistText();
+ AnimatorSet enter = loadAnimator(R.anim.media_metadata_enter,
+ Interpolators.EMPHASIZED_DECELERATE, titleText, artistText);
+ AnimatorSet exit = loadAnimator(R.anim.media_metadata_exit,
+ Interpolators.EMPHASIZED_ACCELERATE, titleText, artistText);
+
+ mColorSchemeTransition = new ColorSchemeTransition(mContext, mMediaViewHolder);
+ mMetadataAnimationHandler = new MetadataAnimationHandler(exit, enter);
+ }
+
+ @VisibleForTesting
+ protected AnimatorSet loadAnimator(int animId, Interpolator motionInterpolator,
+ View... targets) {
+ ArrayList<Animator> animators = new ArrayList<>();
+ for (View target : targets) {
+ AnimatorSet animator = (AnimatorSet) AnimatorInflater.loadAnimator(mContext, animId);
+ animator.getChildAnimations().get(0).setInterpolator(motionInterpolator);
+ animator.setTarget(target);
+ animators.add(animator);
+ }
+
+ AnimatorSet result = new AnimatorSet();
+ result.playTogether(animators);
+ return result;
}
/** Attaches the recommendations to the recommendation view holder. */
@@ -353,7 +407,6 @@
}
mInstanceId = data.getInstanceId();
- mBackgroundColor = data.getBackgroundColor();
if (mToken == null || !mToken.equals(token)) {
mToken = token;
}
@@ -372,25 +425,24 @@
if (mMediaViewController.isGutsVisible()) return;
mLogger.logTapContentView(mUid, mPackageName, mInstanceId);
logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT);
- mActivityStarter.postStartActivityDismissingKeyguard(clickIntent,
- buildLaunchAnimatorController(mMediaViewHolder.getPlayer()));
+
+ // See StatusBarNotificationActivityStarter#onNotificationClicked
+ boolean showOverLockscreen = mKeyguardStateController.isShowing()
+ && mActivityIntentHelper.wouldShowOverLockscreen(clickIntent.getIntent(),
+ mLockscreenUserManager.getCurrentUserId());
+
+ if (showOverLockscreen) {
+ mActivityStarter.startActivity(clickIntent.getIntent(),
+ /* dismissShade */ true,
+ /* animationController */ null,
+ /* showOverLockscreenWhenLocked */ true);
+ } else {
+ mActivityStarter.postStartActivityDismissingKeyguard(clickIntent,
+ buildLaunchAnimatorController(mMediaViewHolder.getPlayer()));
+ }
});
}
- // Accessibility label
- mMediaViewHolder.getPlayer().setContentDescription(
- mContext.getString(
- R.string.controls_media_playing_item_description,
- data.getSong(), data.getArtist(), data.getApp()));
-
- // Song name
- TextView titleText = mMediaViewHolder.getTitleText();
- titleText.setText(data.getSong());
-
- // Artist name
- TextView artistText = mMediaViewHolder.getArtistText();
- artistText.setText(data.getArtist());
-
// Seek Bar
final MediaController controller = getController();
mBackgroundExecutor.execute(() -> mSeekBarViewModel.updateController(controller));
@@ -399,11 +451,16 @@
bindLongPressMenu(data);
bindActionButtons(data);
bindScrubbingTime(data);
- bindArtworkAndColors(data);
+
+ boolean isSongUpdated = bindSongMetadata(data);
+ bindArtworkAndColors(data, isSongUpdated);
// TODO: We don't need to refresh this state constantly, only if the state actually changed
// to something which might impact the measurement
- mMediaViewController.refreshState();
+ // State refresh interferes with the translation animation, only run it if it's not running.
+ if (!mMetadataAnimationHandler.isRunning()) {
+ mMediaViewController.refreshState();
+ }
}
private void bindOutputSwitcherChip(MediaData data) {
@@ -425,7 +482,7 @@
Drawable icon = device.getIcon();
if (icon instanceof AdaptiveIcon) {
AdaptiveIcon aIcon = (AdaptiveIcon) icon;
- aIcon.setBackgroundColor(mBackgroundColor);
+ aIcon.setBackgroundColor(mColorSchemeTransition.getBgColor());
iconView.setImageDrawable(aIcon);
} else {
iconView.setImageDrawable(icon);
@@ -494,120 +551,135 @@
});
}
- private void bindArtworkAndColors(MediaData data) {
- // Default colors
- int surfaceColor = mBackgroundColor;
- int accentPrimary = com.android.settingslib.Utils.getColorAttr(mContext,
- com.android.internal.R.attr.textColorPrimary).getDefaultColor();
- int textPrimary = com.android.settingslib.Utils.getColorAttr(mContext,
- com.android.internal.R.attr.textColorPrimary).getDefaultColor();
- int textPrimaryInverse = com.android.settingslib.Utils.getColorAttr(mContext,
- com.android.internal.R.attr.textColorPrimaryInverse).getDefaultColor();
- int textSecondary = com.android.settingslib.Utils.getColorAttr(mContext,
- com.android.internal.R.attr.textColorSecondary).getDefaultColor();
- int textTertiary = com.android.settingslib.Utils.getColorAttr(mContext,
- com.android.internal.R.attr.textColorTertiary).getDefaultColor();
+ private boolean bindSongMetadata(MediaData data) {
+ // Accessibility label
+ mMediaViewHolder.getPlayer().setContentDescription(
+ mContext.getString(
+ R.string.controls_media_playing_item_description,
+ data.getSong(), data.getArtist(), data.getApp()));
- // Album art
- ColorScheme colorScheme = null;
- ImageView albumView = mMediaViewHolder.getAlbumView();
- boolean hasArtwork = data.getArtwork() != null;
- if (hasArtwork) {
- colorScheme = new ColorScheme(WallpaperColors.fromBitmap(data.getArtwork().getBitmap()),
- true);
+ TextView titleText = mMediaViewHolder.getTitleText();
+ TextView artistText = mMediaViewHolder.getArtistText();
+ return mMetadataAnimationHandler.setNext(
+ Pair.create(data.getSong(), data.getArtist()),
+ () -> {
+ titleText.setText(data.getSong());
+ artistText.setText(data.getArtist());
- // Scale artwork to fit background
- int width = mMediaViewHolder.getPlayer().getWidth();
- int height = mMediaViewHolder.getPlayer().getHeight();
- Drawable artwork = getScaledBackground(data.getArtwork(), width, height);
- albumView.setPadding(0, 0, 0, 0);
- albumView.setImageDrawable(artwork);
- albumView.setClipToOutline(true);
- } else {
- // If there's no artwork, use colors from the app icon
- try {
- Drawable icon = mContext.getPackageManager().getApplicationIcon(
- data.getPackageName());
- colorScheme = new ColorScheme(WallpaperColors.fromDrawable(icon), true);
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Cannot find icon for package " + data.getPackageName(), e);
+ // refreshState is required here to resize the text views (and prevent ellipsis)
+ mMediaViewController.refreshState();
+
+ // Use OnPreDrawListeners to enforce zero alpha on these views for a frame.
+ // TransitionLayout insists on resetting the alpha of these views to 1 when onLayout
+ // is called which causes the animation to look bad. These suppress that behavior.
+ titleText.getViewTreeObserver().addOnPreDrawListener(
+ new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ titleText.setAlpha(0);
+ titleText.getViewTreeObserver().removeOnPreDrawListener(this);
+ return true;
+ }
+ });
+
+ artistText.getViewTreeObserver().addOnPreDrawListener(
+ new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ artistText.setAlpha(0);
+ artistText.getViewTreeObserver().removeOnPreDrawListener(this);
+ return true;
+ }
+ });
+
+ return Unit.INSTANCE;
+ },
+ () -> {
+ // After finishing the enter animation, we refresh state. This could pop if
+ // something is incorrectly bound, but needs to be run if other elements were
+ // updated while the enter animation was running
+ mMediaViewController.refreshState();
+ return Unit.INSTANCE;
+ });
+ }
+
+ private void bindArtworkAndColors(MediaData data, boolean updateBackground) {
+ final int reqId = mArtworkNextBindRequestId++;
+
+ // Capture width & height from views in foreground for artwork scaling in background
+ int width = mMediaViewHolder.getPlayer().getWidth();
+ int height = mMediaViewHolder.getPlayer().getHeight();
+
+ // 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;
+ Icon artworkIcon = data.getArtwork();
+ if (artworkIcon != null) {
+ WallpaperColors wallpaperColors = WallpaperColors
+ .fromBitmap(artworkIcon.getBitmap());
+ mutableColorScheme = new ColorScheme(wallpaperColors, true);
+ artwork = getScaledBackground(artworkIcon, width, height);
+ } else {
+ // If there's no artwork, use colors from the app icon
+ artwork = null;
+ try {
+ Drawable icon = mContext.getPackageManager()
+ .getApplicationIcon(data.getPackageName());
+ mutableColorScheme = new ColorScheme(WallpaperColors.fromDrawable(icon), true);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Cannot find icon for package " + data.getPackageName(), e);
+ }
}
- }
- // Get colors for player
- if (colorScheme != null) {
- surfaceColor = colorScheme.getAccent2().get(9); // A2-800
- accentPrimary = colorScheme.getAccent1().get(2); // A1-100
- textPrimary = colorScheme.getNeutral1().get(1); // N1-50
- textPrimaryInverse = colorScheme.getNeutral1().get(10); // N1-900
- textSecondary = colorScheme.getNeutral2().get(3); // N2-200
- textTertiary = colorScheme.getNeutral2().get(5); // N2-400
- }
+ final ColorScheme colorScheme = mutableColorScheme;
+ mMainExecutor.execute(() -> {
+ // Cancel the request if a later one arrived first
+ if (reqId < mArtworkBoundId) return;
+ mArtworkBoundId = reqId;
- ColorStateList bgColorList = ColorStateList.valueOf(surfaceColor);
- ColorStateList accentColorList = ColorStateList.valueOf(accentPrimary);
- ColorStateList textColorList = ColorStateList.valueOf(textPrimary);
+ // Bind the album view to the artwork or a transition drawable
+ ImageView albumView = mMediaViewHolder.getAlbumView();
+ albumView.setPadding(0, 0, 0, 0);
+ albumView.setClipToOutline(true);
+ if (updateBackground) {
+ if (mPrevArtwork == null || artwork == null) {
+ albumView.setImageDrawable(artwork);
+ } else {
+ TransitionDrawable transitionDrawable = new TransitionDrawable(
+ new Drawable[] { mPrevArtwork, artwork });
+ albumView.setImageDrawable(transitionDrawable);
+ transitionDrawable.startTransition(333);
+ }
+ mPrevArtwork = artwork;
+ }
- // Gradient and background (visible when there is no art)
- albumView.setForegroundTintList(ColorStateList.valueOf(surfaceColor));
- albumView.setBackgroundTintList(
- ColorStateList.valueOf(surfaceColor));
- mMediaViewHolder.getPlayer().setBackgroundTintList(bgColorList);
+ // Transition Colors to current color scheme
+ mColorSchemeTransition.updateColorScheme(colorScheme);
- // App icon - use notification icon
- ImageView appIconView = mMediaViewHolder.getAppIcon();
- appIconView.clearColorFilter();
- if (data.getAppIcon() != null && !data.getResumption()) {
- appIconView.setImageIcon(data.getAppIcon());
- appIconView.setColorFilter(accentPrimary);
- } else {
- // Resume players use launcher icon
- appIconView.setColorFilter(getGrayscaleFilter());
- try {
- Drawable icon = mContext.getPackageManager().getApplicationIcon(
- data.getPackageName());
- appIconView.setImageDrawable(icon);
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Cannot find icon for package " + data.getPackageName(), e);
- appIconView.setImageResource(R.drawable.ic_music_note);
- }
- }
-
- // Metadata text
- mMediaViewHolder.getTitleText().setTextColor(textPrimary);
- mMediaViewHolder.getArtistText().setTextColor(textSecondary);
-
- // Seekbar
- SeekBar seekbar = mMediaViewHolder.getSeekBar();
- seekbar.getThumb().setTintList(textColorList);
- seekbar.setProgressTintList(textColorList);
- seekbar.setProgressBackgroundTintList(ColorStateList.valueOf(textTertiary));
- mMediaViewHolder.getScrubbingElapsedTimeView().setTextColor(textColorList);
- mMediaViewHolder.getScrubbingTotalTimeView().setTextColor(textColorList);
-
- // Action buttons
- mMediaViewHolder.getActionPlayPause().setBackgroundTintList(accentColorList);
- mMediaViewHolder.getActionPlayPause().setImageTintList(
- ColorStateList.valueOf(textPrimaryInverse));
- for (ImageButton button : mMediaViewHolder.getTransparentActionButtons()) {
- button.setImageTintList(textColorList);
- }
-
- // Output switcher
- View seamlessView = mMediaViewHolder.getSeamlessButton();
- seamlessView.setBackgroundTintList(accentColorList);
- ImageView seamlessIconView = mMediaViewHolder.getSeamlessIcon();
- seamlessIconView.setImageTintList(bgColorList);
- TextView seamlessText = mMediaViewHolder.getSeamlessText();
- seamlessText.setTextColor(surfaceColor);
-
- // Long press buttons
- mMediaViewHolder.getLongPressText().setTextColor(textColorList);
- mMediaViewHolder.getSettings().setImageTintList(accentColorList);
- mMediaViewHolder.getCancelText().setTextColor(textColorList);
- mMediaViewHolder.getCancelText().setBackgroundTintList(accentColorList);
- mMediaViewHolder.getDismissText().setTextColor(surfaceColor);
- mMediaViewHolder.getDismissText().setBackgroundTintList(accentColorList);
+ // App icon - use notification icon
+ ImageView appIconView = mMediaViewHolder.getAppIcon();
+ appIconView.clearColorFilter();
+ if (data.getAppIcon() != null && !data.getResumption()) {
+ appIconView.setImageIcon(data.getAppIcon());
+ appIconView.setColorFilter(
+ mColorSchemeTransition.getAccentPrimary().getTargetColor());
+ } else {
+ // Resume players use launcher icon
+ appIconView.setColorFilter(getGrayscaleFilter());
+ try {
+ Drawable icon = mContext.getPackageManager()
+ .getApplicationIcon(data.getPackageName());
+ appIconView.setImageDrawable(icon);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Cannot find icon for package " + data.getPackageName(), e);
+ appIconView.setImageResource(R.drawable.ic_music_note);
+ }
+ }
+ });
+ });
}
private void bindActionButtons(MediaData data) {
@@ -714,6 +786,7 @@
animHandler.tryExecute(() -> {
bindButtonWithAnimations(button, mediaAction, animHandler);
setSemanticButtonVisibleAndAlpha(button.getId(), mediaAction, semanticActions);
+ return Unit.INSTANCE;
});
}
@@ -786,7 +859,14 @@
scrubbingTimeViewsEnabled(semanticActions) && hideWhenScrubbing && mIsScrubbing;
boolean visible = mediaAction != null && !shouldBeHiddenDueToScrubbing;
- setVisibleAndAlpha(expandedSet, buttonId, visible);
+ int notVisibleValue;
+ if ((buttonId == R.id.actionPrev && semanticActions.getReservePrev())
+ || (buttonId == R.id.actionNext && semanticActions.getReserveNext())) {
+ notVisibleValue = ConstraintSet.INVISIBLE;
+ } else {
+ notVisibleValue = ConstraintSet.GONE;
+ }
+ setVisibleAndAlpha(expandedSet, buttonId, visible, notVisibleValue);
setVisibleAndAlpha(collapsedSet, buttonId, visible && showInCompact);
}
@@ -795,11 +875,12 @@
private void updateDisplayForScrubbingChange(@NonNull MediaButton semanticActions) {
// Update visibilities of the scrubbing time views and the scrubbing-dependent buttons.
bindScrubbingTime(mMediaData);
- SEMANTIC_ACTIONS_HIDE_WHEN_SCRUBBING.forEach((id) ->
- setSemanticButtonVisibleAndAlpha(
- id, semanticActions.getActionById(id), semanticActions));
- // Trigger a state refresh so that we immediately update visibilities.
- mMediaViewController.refreshState();
+ SEMANTIC_ACTIONS_HIDE_WHEN_SCRUBBING.forEach((id) -> setSemanticButtonVisibleAndAlpha(
+ id, semanticActions.getActionById(id), semanticActions));
+ if (!mMetadataAnimationHandler.isRunning()) {
+ // Trigger a state refresh so that we immediately update visibilities.
+ mMediaViewController.refreshState();
+ }
}
private void bindScrubbingTime(MediaData data) {
@@ -824,74 +905,6 @@
);
}
- // AnimationBindHandler is responsible for tracking the bound animation state and preventing
- // jank and conflicts due to media notifications arriving at any time during an animation. It
- // does this in two parts.
- // - Exit animations fired as a result of user input are tracked. When these are running, any
- // bind actions are delayed until the animation completes (and then fired in sequence).
- // - Continuous animations are tracked using their rebind id. Later calls using the same
- // rebind id will be totally ignored to prevent the continuous animation from restarting.
- private static class AnimationBindHandler extends Animatable2.AnimationCallback {
- private ArrayList<Runnable> mOnAnimationsComplete = new ArrayList<>();
- private ArrayList<Animatable2> mRegistrations = new ArrayList<>();
- private Integer mRebindId = null;
-
- // This check prevents rebinding to the action button if the identifier has not changed. A
- // null value is always considered to be changed. This is used to prevent the connecting
- // animation from rebinding (and restarting) if multiple buffer PlaybackStates are pushed by
- // an application in a row.
- public boolean updateRebindId(Integer rebindId) {
- if (mRebindId == null || rebindId == null || !mRebindId.equals(rebindId)) {
- mRebindId = rebindId;
- return true;
- }
- return false;
- }
-
- public void tryRegister(Drawable drawable) {
- if (drawable instanceof Animatable2) {
- Animatable2 anim = (Animatable2) drawable;
- anim.registerAnimationCallback(this);
- mRegistrations.add(anim);
- }
- }
-
- public void unregisterAll() {
- for (Animatable2 anim : mRegistrations) {
- anim.unregisterAnimationCallback(this);
- }
- mRegistrations.clear();
- }
-
- public boolean isAnimationRunning() {
- for (Animatable2 anim : mRegistrations) {
- if (anim.isRunning()) {
- return true;
- }
- }
- return false;
- }
-
- public void tryExecute(Runnable action) {
- if (isAnimationRunning()) {
- mOnAnimationsComplete.add(action);
- } else {
- action.run();
- }
- }
-
- @Override
- public void onAnimationEnd(Drawable drawable) {
- super.onAnimationEnd(drawable);
- if (!isAnimationRunning()) {
- for (Runnable action : mOnAnimationsComplete) {
- action.run();
- }
- mOnAnimationsComplete.clear();
- }
- }
- }
-
@Nullable
private ActivityLaunchAnimator.Controller buildLaunchAnimatorController(
TransitionLayout player) {
@@ -940,11 +953,11 @@
}
mSmartspaceId = SmallHash.hash(data.getTargetId());
- mBackgroundColor = data.getBackgroundColor();
+ int backgroundColor = data.getBackgroundColor();
mPackageName = data.getPackageName();
mInstanceId = data.getInstanceId();
TransitionLayout recommendationCard = mRecommendationViewHolder.getRecommendations();
- recommendationCard.setBackgroundTintList(ColorStateList.valueOf(mBackgroundColor));
+ recommendationCard.setBackgroundTintList(ColorStateList.valueOf(backgroundColor));
List<SmartspaceAction> mediaRecommendationList = data.getRecommendations();
if (mediaRecommendationList == null || mediaRecommendationList.isEmpty()) {
@@ -984,11 +997,6 @@
appName = packageManager.getApplicationLabel(applicationInfo);
}
}
- // Set the app name as card's title.
- if (!TextUtils.isEmpty(appName)) {
- TextView headerTitleText = mRecommendationViewHolder.getCardText();
- headerTitleText.setText(appName);
- }
// Set up media rec card's tap action if applicable.
setSmartspaceRecItemOnClickListener(recommendationCard, data.getCardAction(),
@@ -999,11 +1007,6 @@
List<ImageView> mediaCoverItems = mRecommendationViewHolder.getMediaCoverItems();
List<ViewGroup> mediaCoverContainers = mRecommendationViewHolder.getMediaCoverContainers();
- List<Integer> mediaCoverItemsResIds = mRecommendationViewHolder.getMediaCoverItemsResIds();
- List<Integer> mediaCoverContainersResIds =
- mRecommendationViewHolder.getMediaCoverContainersResIds();
- ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
- ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
int mediaRecommendationNum = Math.min(mediaRecommendationList.size(),
MEDIA_RECOMMENDATION_MAX_NUM);
int uiComponentIndex = 0;
@@ -1048,21 +1051,24 @@
recommendation.getTitle(), artistName, appName));
}
- if (uiComponentIndex < MEDIA_RECOMMENDATION_ITEMS_PER_ROW) {
- setVisibleAndAlpha(collapsedSet,
- mediaCoverItemsResIds.get(uiComponentIndex), true);
- setVisibleAndAlpha(collapsedSet,
- mediaCoverContainersResIds.get(uiComponentIndex), true);
- } else {
- setVisibleAndAlpha(collapsedSet,
- mediaCoverItemsResIds.get(uiComponentIndex), false);
- setVisibleAndAlpha(collapsedSet,
- mediaCoverContainersResIds.get(uiComponentIndex), false);
- }
- setVisibleAndAlpha(expandedSet,
- mediaCoverItemsResIds.get(uiComponentIndex), true);
- setVisibleAndAlpha(expandedSet,
- mediaCoverContainersResIds.get(uiComponentIndex), true);
+
+ // Set up title
+ CharSequence title = recommendation.getTitle();
+ TextView titleView =
+ mRecommendationViewHolder.getMediaTitles().get(uiComponentIndex);
+ titleView.setText(title);
+ // TODO(b/223603970): If none of them have titles, should we then hide the views?
+
+ // Set up subtitle
+ CharSequence subtitle = recommendation.getSubtitle();
+ TextView subtitleView =
+ mRecommendationViewHolder.getMediaSubtitles().get(uiComponentIndex);
+ // It would look awkward to show a subtitle if we don't have a title.
+ boolean shouldShowSubtitleText = !TextUtils.isEmpty(title);
+ CharSequence subtitleText = shouldShowSubtitleText ? subtitle : "";
+ subtitleView.setText(subtitleText);
+ // TODO(b/223603970): If none of them have subtitles, should we then hide the views?
+
uiComponentIndex++;
}
@@ -1097,7 +1103,9 @@
});
mController = null;
- mMediaViewController.refreshState();
+ if (mMetadataAnimationHandler == null || !mMetadataAnimationHandler.isRunning()) {
+ mMediaViewController.refreshState();
+ }
}
/**
@@ -1191,7 +1199,12 @@
}
private void setVisibleAndAlpha(ConstraintSet set, int actionId, boolean visible) {
- set.setVisibility(actionId, visible ? ConstraintSet.VISIBLE : ConstraintSet.GONE);
+ setVisibleAndAlpha(set, actionId, visible, ConstraintSet.GONE);
+ }
+
+ private void setVisibleAndAlpha(ConstraintSet set, int actionId, boolean visible,
+ int notVisibleValue) {
+ set.setVisibility(actionId, visible ? ConstraintSet.VISIBLE : notVisibleValue);
set.setAlpha(actionId, visible ? 1.0f : 0.0f);
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
index bc8cca5..d04ec40 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
@@ -27,7 +27,6 @@
data class MediaData(
val userId: Int,
val initialized: Boolean = false,
- val backgroundColor: Int,
/**
* App name that will be displayed on the player.
*/
@@ -149,23 +148,31 @@
/**
* Play/pause button
*/
- var playOrPause: MediaAction? = null,
+ val playOrPause: MediaAction? = null,
/**
* Next button, or custom action
*/
- var nextOrCustom: MediaAction? = null,
+ val nextOrCustom: MediaAction? = null,
/**
* Previous button, or custom action
*/
- var prevOrCustom: MediaAction? = null,
+ val prevOrCustom: MediaAction? = null,
/**
* First custom action space
*/
- var custom0: MediaAction? = null,
+ val custom0: MediaAction? = null,
/**
* Second custom action space
*/
- var custom1: MediaAction? = null
+ val custom1: MediaAction? = null,
+ /**
+ * Whether to reserve the empty space when the nextOrCustom is null
+ */
+ val reserveNext: Boolean = false,
+ /**
+ * Whether to reserve the empty space when the prevOrCustom is null
+ */
+ val reservePrev: Boolean = false
) {
fun getActionById(id: Int): MediaAction? {
return when (id) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 0ad15fa..fd44993 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -85,7 +85,6 @@
private val LOADING = MediaData(
userId = -1,
initialized = false,
- backgroundColor = 0,
app = null,
appIcon = null,
artist = null,
@@ -173,15 +172,10 @@
// Maximum number of actions allowed in expanded view
@JvmField
val MAX_NOTIFICATION_ACTIONS = MediaViewHolder.genericButtonIds.size
-
- /** Maximum number of [PlaybackState.CustomAction] buttons supported */
- @JvmField
- val MAX_CUSTOM_ACTIONS = 4
}
private val themeText = com.android.settingslib.Utils.getColorAttr(context,
com.android.internal.R.attr.textColorPrimary).defaultColor
- private val bgColor = context.getColor(R.color.material_dynamic_secondary95)
// Internal listeners are part of the internal pipeline. External listeners (those registered
// with [MediaDeviceManager.addListener]) receive events after they have propagated through
@@ -595,7 +589,7 @@
val mediaAction = getResumeMediaAction(resumeAction)
val lastActive = systemClock.elapsedRealtime()
foregroundExecutor.execute {
- onMediaDataLoaded(packageName, null, MediaData(userId, true, bgColor, appName,
+ onMediaDataLoaded(packageName, null, MediaData(userId, true, appName,
null, desc.subtitle, desc.title, artworkIcon, listOf(mediaAction), listOf(0),
MediaButton(playOrPause = mediaAction), packageName, token, appIntent,
device = null, active = false,
@@ -605,14 +599,17 @@
}
}
- private fun loadMediaDataInBg(
+ fun loadMediaDataInBg(
key: String,
sbn: StatusBarNotification,
oldKey: String?,
logEvent: Boolean = false
) {
- val token = sbn.notification.extras.getParcelable(Notification.EXTRA_MEDIA_SESSION)
- as MediaSession.Token?
+ val token = sbn.notification.extras.getParcelable(
+ Notification.EXTRA_MEDIA_SESSION, MediaSession.Token::class.java)
+ if (token == null) {
+ return
+ }
val mediaController = mediaControllerFactory.create(token)
val metadata = mediaController.metadata
@@ -659,8 +656,8 @@
val extras = sbn.notification.extras
val deviceName = extras.getCharSequence(Notification.EXTRA_MEDIA_REMOTE_DEVICE, null)
val deviceIcon = extras.getInt(Notification.EXTRA_MEDIA_REMOTE_ICON, -1)
- val deviceIntent = extras.getParcelable(Notification.EXTRA_MEDIA_REMOTE_INTENT)
- as PendingIntent?
+ val deviceIntent = extras.getParcelable(
+ Notification.EXTRA_MEDIA_REMOTE_INTENT, PendingIntent::class.java)
Log.d(TAG, "$key is RCN for $deviceName")
if (deviceName != null && deviceIcon > -1) {
@@ -714,7 +711,7 @@
val resumeAction: Runnable? = mediaEntries[key]?.resumeAction
val hasCheckedForResume = mediaEntries[key]?.hasCheckedForResume == true
val active = mediaEntries[key]?.active ?: true
- onMediaDataLoaded(key, oldKey, MediaData(sbn.normalizedUserId, true, bgColor, app,
+ onMediaDataLoaded(key, oldKey, MediaData(sbn.normalizedUserId, true, app,
smallIcon, artist, song, artWorkIcon, actionIcons, actionsToShowCollapsed,
semanticActions, sbn.packageName, token, notif.contentIntent, device,
active, resumeAction = resumeAction, playbackLocation = playbackLocation,
@@ -795,71 +792,74 @@
*/
private fun createActionsFromState(packageName: String, controller: MediaController):
MediaButton? {
- val actions = MediaButton()
- controller.playbackState?.let { state ->
- // First, check for standard actions
- actions.playOrPause = if (isConnectingState(state.state)) {
- // Spinner needs to be animating to render anything. Start it here.
- val drawable = context.getDrawable(
- com.android.internal.R.drawable.progress_small_material)
- (drawable as Animatable).start()
- MediaAction(
- drawable,
- null, // no action to perform when clicked
- context.getString(R.string.controls_media_button_connecting),
- context.getDrawable(R.drawable.ic_media_connecting_container),
- // Specify a rebind id to prevent the spinner from restarting on later binds.
- com.android.internal.R.drawable.progress_small_material
- )
- } else if (isPlayingState(state.state)) {
- getStandardAction(controller, state.actions, PlaybackState.ACTION_PAUSE)
- } else {
- getStandardAction(controller, state.actions, PlaybackState.ACTION_PLAY)
- }
- val prevButton = getStandardAction(controller, state.actions,
- PlaybackState.ACTION_SKIP_TO_PREVIOUS)
- val nextButton = getStandardAction(controller, state.actions,
- PlaybackState.ACTION_SKIP_TO_NEXT)
-
- // Then, check for custom actions
- val customActions = MutableList<MediaAction?>(MAX_CUSTOM_ACTIONS) { null }
- var customCount = 0
- for (i in 0..(MAX_CUSTOM_ACTIONS - 1)) {
- getCustomAction(state, packageName, controller, customCount)?.let {
- customActions[customCount++] = it
- }
- }
-
- // Finally, assign the remaining button slots: play/pause A B C D
- // A = previous, else custom action (if not reserved)
- // B = next, else custom action (if not reserved)
- // C and D are always custom actions
- val reservePrev = controller.extras?.getBoolean(
- MediaConstants.SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV) == true
- val reserveNext = controller.extras?.getBoolean(
- MediaConstants.SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT) == true
- var customIdx = 0
-
- actions.prevOrCustom = if (prevButton != null) {
- prevButton
- } else if (!reservePrev) {
- customActions[customIdx++]
- } else {
- null
- }
-
- actions.nextOrCustom = if (nextButton != null) {
- nextButton
- } else if (!reserveNext) {
- customActions[customIdx++]
- } else {
- null
- }
-
- actions.custom0 = customActions[customIdx++]
- actions.custom1 = customActions[customIdx++]
+ val state = controller.playbackState
+ if (state == null) {
+ return MediaButton()
}
- return actions
+ // First, check for} standard actions
+ val playOrPause = if (isConnectingState(state.state)) {
+ // Spinner needs to be animating to render anything. Start it here.
+ val drawable = context.getDrawable(
+ com.android.internal.R.drawable.progress_small_material)
+ (drawable as Animatable).start()
+ MediaAction(
+ drawable,
+ null, // no action to perform when clicked
+ context.getString(R.string.controls_media_button_connecting),
+ context.getDrawable(R.drawable.ic_media_connecting_container),
+ // Specify a rebind id to prevent the spinner from restarting on later binds.
+ com.android.internal.R.drawable.progress_small_material
+ )
+ } else if (isPlayingState(state.state)) {
+ getStandardAction(controller, state.actions, PlaybackState.ACTION_PAUSE)
+ } else {
+ getStandardAction(controller, state.actions, PlaybackState.ACTION_PLAY)
+ }
+ val prevButton = getStandardAction(controller, state.actions,
+ PlaybackState.ACTION_SKIP_TO_PREVIOUS)
+ val nextButton = getStandardAction(controller, state.actions,
+ PlaybackState.ACTION_SKIP_TO_NEXT)
+
+ // Then, create a way to build any custom actions that will be needed
+ val customActions = state.customActions.asSequence().filterNotNull().map {
+ getCustomAction(state, packageName, controller, it)
+ }.iterator()
+ fun nextCustomAction() = if (customActions.hasNext()) customActions.next() else null
+
+ // Finally, assign the remaining button slots: play/pause A B C D
+ // A = previous, else custom action (if not reserved)
+ // B = next, else custom action (if not reserved)
+ // C and D are always custom actions
+ val reservePrev = controller.extras?.getBoolean(
+ MediaConstants.SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV) == true
+ val reserveNext = controller.extras?.getBoolean(
+ MediaConstants.SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT) == true
+
+ val prevOrCustom = if (prevButton != null) {
+ prevButton
+ } else if (!reservePrev) {
+ nextCustomAction()
+ } else {
+ null
+ }
+
+ val nextOrCustom = if (nextButton != null) {
+ nextButton
+ } else if (!reserveNext) {
+ nextCustomAction()
+ } else {
+ null
+ }
+
+ return MediaButton(
+ playOrPause,
+ nextOrCustom,
+ prevOrCustom,
+ nextCustomAction(),
+ nextCustomAction(),
+ reserveNext,
+ reservePrev
+ )
}
/**
@@ -938,18 +938,12 @@
state: PlaybackState,
packageName: String,
controller: MediaController,
- index: Int
- ): MediaAction? {
- if (state.customActions.size <= index || state.customActions[index] == null) {
- if (DEBUG) { Log.d(TAG, "not enough actions or action was null at $index") }
- return null
- }
-
- val it = state.customActions[index]
+ customAction: PlaybackState.CustomAction
+ ): MediaAction {
return MediaAction(
- Icon.createWithResource(packageName, it.icon).loadDrawable(context),
- { controller.transportControls.sendCustomAction(it, it.extras) },
- it.name,
+ Icon.createWithResource(packageName, customAction.icon).loadDrawable(context),
+ { controller.transportControls.sendCustomAction(customAction, customAction.extras) },
+ customAction.name,
null
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MetadataAnimationHandler.kt b/packages/SystemUI/src/com/android/systemui/media/MetadataAnimationHandler.kt
new file mode 100644
index 0000000..9a1a6d3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/MetadataAnimationHandler.kt
@@ -0,0 +1,86 @@
+/*
+ * 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.media
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.AnimatorSet
+import com.android.internal.annotations.VisibleForTesting
+
+/**
+ * MetadataAnimationHandler controls the current state of the MediaControlPanel's transition motion.
+ *
+ * It checks for a changed data object (artist & title from MediaControlPanel) and runs the
+ * animation if necessary. When the motion has fully transitioned the elements out, it runs the
+ * update callback to modify the view data, before the enter animation runs.
+ */
+internal open class MetadataAnimationHandler(
+ private val exitAnimator: Animator,
+ private val enterAnimator: Animator
+) : AnimatorListenerAdapter() {
+
+ private val animator: AnimatorSet
+ private var postExitUpdate: (() -> Unit)? = null
+ private var postEnterUpdate: (() -> Unit)? = null
+ private var targetData: Any? = null
+
+ val isRunning: Boolean
+ get() = animator.isRunning
+
+ fun setNext(targetData: Any, postExit: () -> Unit, postEnter: () -> Unit): Boolean {
+ if (targetData != this.targetData) {
+ this.targetData = targetData
+ postExitUpdate = postExit
+ postEnterUpdate = postEnter
+ if (!animator.isRunning) {
+ animator.start()
+ }
+ return true
+ }
+ return false
+ }
+
+ override fun onAnimationEnd(animator: Animator) {
+ if (animator === exitAnimator) {
+ postExitUpdate?.let { it() }
+ postExitUpdate = null
+ }
+
+ if (animator === enterAnimator) {
+ // Another new update appeared while entering
+ if (postExitUpdate != null) {
+ this.animator.start()
+ } else {
+ postEnterUpdate?.let { it() }
+ postEnterUpdate = null
+ }
+ }
+ }
+
+ init {
+ exitAnimator.addListener(this)
+ enterAnimator.addListener(this)
+ animator = buildAnimatorSet(exitAnimator, enterAnimator)
+ }
+
+ @VisibleForTesting
+ protected open fun buildAnimatorSet(exit: Animator, enter: Animator): AnimatorSet {
+ val result = AnimatorSet()
+ result.playSequentially(exitAnimator, enterAnimator)
+ return result
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt
index c0f79d5..a839840 100644
--- a/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt
@@ -31,35 +31,26 @@
// Recommendation screen
val cardIcon = itemView.requireViewById<ImageView>(R.id.recommendation_card_icon)
- val cardText = itemView.requireViewById<TextView>(R.id.recommendation_card_text)
val mediaCoverItems = listOf<ImageView>(
itemView.requireViewById(R.id.media_cover1),
itemView.requireViewById(R.id.media_cover2),
- itemView.requireViewById(R.id.media_cover3),
- itemView.requireViewById(R.id.media_cover4),
- itemView.requireViewById(R.id.media_cover5),
- itemView.requireViewById(R.id.media_cover6))
+ itemView.requireViewById(R.id.media_cover3)
+ )
val mediaCoverContainers = listOf<ViewGroup>(
itemView.requireViewById(R.id.media_cover1_container),
itemView.requireViewById(R.id.media_cover2_container),
- itemView.requireViewById(R.id.media_cover3_container),
- itemView.requireViewById(R.id.media_cover4_container),
- itemView.requireViewById(R.id.media_cover5_container),
- itemView.requireViewById(R.id.media_cover6_container))
- val mediaCoverItemsResIds = listOf<Int>(
- R.id.media_cover1,
- R.id.media_cover2,
- R.id.media_cover3,
- R.id.media_cover4,
- R.id.media_cover5,
- R.id.media_cover6)
- val mediaCoverContainersResIds = listOf<Int>(
- R.id.media_cover1_container,
- R.id.media_cover2_container,
- R.id.media_cover3_container,
- R.id.media_cover4_container,
- R.id.media_cover5_container,
- R.id.media_cover6_container)
+ 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)
+ )
+ val mediaSubtitles: List<TextView> = listOf(
+ itemView.requireViewById(R.id.media_subtitle1),
+ itemView.requireViewById(R.id.media_subtitle2),
+ itemView.requireViewById(R.id.media_subtitle3)
+ )
// Settings/Guts screen
val longPressText = itemView.requireViewById<TextView>(R.id.remove_text)
@@ -107,19 +98,12 @@
// Res Ids for the control components on the recommendation view.
val controlsIds = setOf(
R.id.recommendation_card_icon,
- R.id.recommendation_card_text,
R.id.media_cover1,
R.id.media_cover2,
R.id.media_cover3,
- R.id.media_cover4,
- R.id.media_cover5,
- R.id.media_cover6,
R.id.media_cover1_container,
R.id.media_cover2_container,
R.id.media_cover3_container,
- R.id.media_cover4_container,
- R.id.media_cover5_container,
- R.id.media_cover6_container
)
// Res Ids for the components on the guts panel.
diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
index 612a7f9..c9d300b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
@@ -16,20 +16,29 @@
package com.android.systemui.media
+import android.animation.Animator
+import android.animation.ObjectAnimator
import android.text.format.DateUtils
import androidx.annotation.UiThread
import androidx.lifecycle.Observer
+import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.R
+import com.android.systemui.animation.Interpolators
/**
* Observer for changes from SeekBarViewModel.
*
* <p>Updates the seek bar views in response to changes to the model.
*/
-class SeekBarObserver(
+open class SeekBarObserver(
private val holder: MediaViewHolder
) : Observer<SeekBarViewModel.Progress> {
+ companion object {
+ @JvmStatic val RESET_ANIMATION_DURATION_MS: Int = 750
+ @JvmStatic val RESET_ANIMATION_THRESHOLD_MS: Int = 250
+ }
+
val seekBarEnabledMaxHeight = holder.seekBar.context.resources
.getDimensionPixelSize(R.dimen.qs_media_enabled_seekbar_height)
val seekBarDisabledHeight = holder.seekBar.context.resources
@@ -38,6 +47,7 @@
.getDimensionPixelSize(R.dimen.qs_media_session_enabled_seekbar_vertical_padding)
val seekBarDisabledVerticalPadding = holder.seekBar.context.resources
.getDimensionPixelSize(R.dimen.qs_media_session_disabled_seekbar_vertical_padding)
+ var seekBarResetAnimator: Animator? = null
init {
val seekBarProgressWavelength = holder.seekBar.context.resources
@@ -91,7 +101,17 @@
holder.scrubbingTotalTimeView.text = totalTimeString
data.elapsedTime?.let {
- holder.seekBar.setProgress(it)
+ if (!data.scrubbing && !(seekBarResetAnimator?.isRunning ?: false)) {
+ if (it <= RESET_ANIMATION_THRESHOLD_MS &&
+ holder.seekBar.progress > RESET_ANIMATION_THRESHOLD_MS) {
+ // This animation resets for every additional update to zero.
+ val animator = buildResetAnimator(it)
+ animator.start()
+ seekBarResetAnimator = animator
+ } else {
+ holder.seekBar.progress = it
+ }
+ }
val elapsedTimeString = DateUtils.formatElapsedTime(
it / DateUtils.SECOND_IN_MILLIS)
holder.scrubbingElapsedTimeView.text = elapsedTimeString
@@ -104,6 +124,16 @@
}
}
+ @VisibleForTesting
+ open fun buildResetAnimator(targetTime: Int): Animator {
+ val animator = ObjectAnimator.ofInt(holder.seekBar, "progress",
+ holder.seekBar.progress, targetTime + RESET_ANIMATION_DURATION_MS)
+ animator.setAutoCancel(true)
+ animator.duration = RESET_ANIMATION_DURATION_MS.toLong()
+ animator.interpolator = Interpolators.EMPHASIZED
+ return animator
+ }
+
@UiThread
fun setVerticalPadding(padding: Int) {
val leftPadding = holder.seekBar.paddingLeft
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index 0edadcc..73ab66e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -117,6 +117,7 @@
}
mCheckBox.setVisibility(View.GONE);
mStatusIcon.setVisibility(View.GONE);
+ mEndTouchArea.setVisibility(View.GONE);
mContainerLayout.setOnClickListener(null);
mTitleText.setTextColor(mController.getColorItemContent());
mSubTitleText.setTextColor(mController.getColorItemContent());
@@ -168,12 +169,16 @@
setSingleLineLayout(getItemTitle(device), true /* bFocused */,
true /* showSeekBar */,
false /* showProgressBar */, false /* showStatus */);
+ mCheckBox.setOnCheckedChangeListener(null);
mCheckBox.setVisibility(View.VISIBLE);
mCheckBox.setChecked(true);
- mSeekBar.setOnClickListener(null);
- mSeekBar.setOnClickListener(v -> onGroupActionTriggered(false, device));
+ mCheckBox.setOnCheckedChangeListener(
+ (buttonView, isChecked) -> onGroupActionTriggered(false, device));
setCheckBoxColor(mCheckBox, mController.getColorItemContent());
initSeekbar(device);
+ mEndTouchArea.setVisibility(View.VISIBLE);
+ mEndTouchArea.setOnClickListener(null);
+ mEndTouchArea.setOnClickListener((v) -> mCheckBox.performClick());
} else if (!mController.hasAdjustVolumeUserRestriction() && currentlyConnected) {
mStatusIcon.setImageDrawable(
mContext.getDrawable(R.drawable.media_output_status_check));
@@ -185,8 +190,12 @@
initSeekbar(device);
mCurrentActivePosition = position;
} else if (isDeviceIncluded(mController.getSelectableMediaDevice(), device)) {
+ mCheckBox.setOnCheckedChangeListener(null);
mCheckBox.setVisibility(View.VISIBLE);
mCheckBox.setChecked(false);
+ mCheckBox.setOnCheckedChangeListener(
+ (buttonView, isChecked) -> onGroupActionTriggered(true, device));
+ mEndTouchArea.setVisibility(View.VISIBLE);
mContainerLayout.setOnClickListener(v -> onGroupActionTriggered(true, device));
setCheckBoxColor(mCheckBox, mController.getColorItemContent());
setSingleLineLayout(getItemTitle(device), false /* bFocused */,
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 5c536d4..9dc29bd 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -144,6 +144,7 @@
final LinearLayout mTwoLineLayout;
final ImageView mStatusIcon;
final CheckBox mCheckBox;
+ final LinearLayout mEndTouchArea;
private String mDeviceId;
MediaDeviceBaseViewHolder(View view) {
@@ -159,6 +160,7 @@
mSeekBar = view.requireViewById(R.id.volume_seekbar);
mStatusIcon = view.requireViewById(R.id.media_output_item_status);
mCheckBox = view.requireViewById(R.id.check_box);
+ mEndTouchArea = view.requireViewById(R.id.end_action_area);
}
void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin, int position) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSeekbar.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSeekbar.java
deleted file mode 100644
index 72f308e..0000000
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSeekbar.java
+++ /dev/null
@@ -1,57 +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.systemui.media.dialog;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.widget.SeekBar;
-
-/**
- * Customized seekbar used by MediaOutputDialog, which only changes progress when dragging,
- * otherwise performs click.
- */
-public class MediaOutputSeekbar extends SeekBar {
- private int mLastDownPosition = -1;
-
- public MediaOutputSeekbar(Context context) {
- super(context);
- }
-
- public MediaOutputSeekbar(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- mLastDownPosition = Math.round(event.getX());
- } else if (event.getAction() == MotionEvent.ACTION_UP) {
- if (mLastDownPosition == event.getX()) {
- performClick();
- return true;
- }
- mLastDownPosition = -1;
- }
- return super.onTouchEvent(event);
- }
-
- @Override
- public boolean performClick() {
- return super.performClick();
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 72488f3..740ecff 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -197,6 +197,7 @@
private final Optional<Pip> mPipOptional;
private final Optional<Recents> mRecentsOptional;
private final DeviceConfigProxy mDeviceConfigProxy;
+ private final NavigationBarTransitions mNavigationBarTransitions;
private final Optional<BackAnimation> mBackAnimation;
private final Handler mHandler;
private final NavigationBarOverlayController mNavbarOverlayController;
@@ -513,6 +514,7 @@
InputMethodManager inputMethodManager,
DeadZone deadZone,
DeviceConfigProxy deviceConfigProxy,
+ NavigationBarTransitions navigationBarTransitions,
Optional<BackAnimation> backAnimation) {
super(navigationBarView);
mFrame = navigationBarFrame;
@@ -537,6 +539,7 @@
mRecentsOptional = recentsOptional;
mDeadZone = deadZone;
mDeviceConfigProxy = deviceConfigProxy;
+ mNavigationBarTransitions = navigationBarTransitions;
mBackAnimation = backAnimation;
mHandler = mainHandler;
mNavbarOverlayController = navbarOverlayController;
@@ -561,6 +564,7 @@
public void onInit() {
// TODO: A great deal of this code should probably live in onViewAttached.
// It should also has corresponding cleanup in onViewDetached.
+ mView.setBarTransitions(mNavigationBarTransitions);
mView.setTouchHandler(mTouchHandler);
mView.setNavBarMode(mNavBarMode);
mView.updateRotationButton();
@@ -632,7 +636,7 @@
mView.setOnVerticalChangedListener(this::onVerticalChanged);
mView.setOnTouchListener(this::onNavigationTouch);
if (mSavedState != null) {
- mView.getLightTransitionsController().restoreState(mSavedState);
+ getBarTransitions().getLightTransitionsController().restoreState(mSavedState);
}
setNavigationIconHints(mNavigationIconHints);
mView.setWindowVisible(isNavBarWindowVisible());
@@ -705,8 +709,7 @@
mView.getRotationButtonController();
rotationButtonController.setRotationCallback(null);
mView.setUpdateActiveTouchRegionsCallback(null);
- mView.getBarTransitions().destroy();
- mView.getLightTransitionsController().destroy(mContext);
+ getBarTransitions().destroy();
mOverviewProxyService.removeCallback(mOverviewProxyListener);
mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
if (mOrientationHandle != null) {
@@ -732,7 +735,7 @@
outState.putInt(EXTRA_APPEARANCE, mAppearance);
outState.putInt(EXTRA_BEHAVIOR, mBehavior);
outState.putBoolean(EXTRA_TRANSIENT_STATE, mTransientShown);
- mView.getLightTransitionsController().saveState(outState);
+ getBarTransitions().getLightTransitionsController().saveState(outState);
}
/**
@@ -893,7 +896,7 @@
pw.println(" mTransientShown=" + mTransientShown);
pw.println(" mTransientShownFromGestureOnSystemBar="
+ mTransientShownFromGestureOnSystemBar);
- dumpBarTransitions(pw, "mNavigationBarView", mView.getBarTransitions());
+ dumpBarTransitions(pw, "mNavigationBarView", getBarTransitions());
mView.dump(pw);
}
@@ -1430,7 +1433,7 @@
mLightBarController = lightBarController;
if (mLightBarController != null) {
mLightBarController.setNavigationBar(
- mView.getLightTransitionsController());
+ getBarTransitions().getLightTransitionsController());
}
}
@@ -1472,7 +1475,7 @@
mCentralSurfacesOptionalLazy.get().map(CentralSurfaces::isDeviceInteractive)
.orElse(false)
&& mNavigationBarWindowState != WINDOW_STATE_HIDDEN;
- mView.getBarTransitions().transitionTo(mTransitionMode, anim);
+ getBarTransitions().transitionTo(mTransitionMode, anim);
}
public void disableAnimationsDuringHide(long delay) {
@@ -1492,11 +1495,11 @@
}
public NavigationBarTransitions getBarTransitions() {
- return mView.getBarTransitions();
+ return mNavigationBarTransitions;
}
public void finishBarAnimations() {
- mView.getBarTransitions().finishAnimations();
+ getBarTransitions().finishAnimations();
}
private WindowManager.LayoutParams getBarLayoutParams(int rotation) {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
index 58e07db..e625501 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
@@ -31,17 +31,19 @@
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.BarTransitions;
import com.android.systemui.statusbar.phone.LightBarTransitionsController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
+import javax.inject.Inject;
+
+/** */
+@NavigationBarScope
public final class NavigationBarTransitions extends BarTransitions implements
LightBarTransitionsController.DarkIntensityApplier {
@@ -81,15 +83,13 @@
}
};
- public NavigationBarTransitions(NavigationBarView view, CommandQueue commandQueue) {
+ @Inject
+ public NavigationBarTransitions(
+ NavigationBarView view,
+ LightBarTransitionsController.Factory lightBarTransitionsControllerFactory) {
super(view, R.drawable.nav_background);
mView = view;
- mLightTransitionsController = new LightBarTransitionsController(
- view.getContext(),
- this,
- commandQueue,
- Dependency.get(KeyguardStateController.class),
- Dependency.get(StatusBarStateController.class));
+ mLightTransitionsController = lightBarTransitionsControllerFactory.create(this);
mAllowAutoDimWallpaperNotVisible = view.getContext().getResources()
.getBoolean(R.bool.config_navigation_bar_enable_auto_dim_no_visible_wallpaper);
mDarkIntensityListeners = new ArrayList();
@@ -127,6 +127,7 @@
Display.DEFAULT_DISPLAY);
} catch (RemoteException e) {
}
+ mLightTransitionsController.destroy();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index abff914..8878c2d 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -85,7 +85,6 @@
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.LightBarTransitionsController;
@@ -140,7 +139,7 @@
private EdgeBackGestureHandler mEdgeBackGestureHandler;
private final DeadZone mDeadZone;
private boolean mDeadZoneConsuming = false;
- private final NavigationBarTransitions mBarTransitions;
+ private NavigationBarTransitions mBarTransitions;
@Nullable
private AutoHideController mAutoHideController;
@@ -370,7 +369,6 @@
mConfiguration.updateFrom(context.getResources().getConfiguration());
mScreenPinningNotify = new ScreenPinningNotify(mContext);
- mBarTransitions = new NavigationBarTransitions(this, Dependency.get(CommandQueue.class));
mButtonDispatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
mButtonDispatchers.put(R.id.home, new ButtonDispatcher(R.id.home));
@@ -418,12 +416,12 @@
}
}
- public void setAutoHideController(AutoHideController autoHideController) {
- mAutoHideController = autoHideController;
+ void setBarTransitions(NavigationBarTransitions navigationBarTransitions) {
+ mBarTransitions = navigationBarTransitions;
}
- public NavigationBarTransitions getBarTransitions() {
- return mBarTransitions;
+ public void setAutoHideController(AutoHideController autoHideController) {
+ mAutoHideController = autoHideController;
}
public LightBarTransitionsController getLightTransitionsController() {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index cdc6b3b..363baaa 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -264,7 +264,7 @@
mWindowContext = null;
}
mAutoHideController.setNavigationBar(null);
- mLightBarTransitionsController.destroy(mContext);
+ mLightBarTransitionsController.destroy();
mLightBarController.setNavigationBar(null);
mPipOptional.ifPresent(this::removePipExclusionBoundsChangeListener);
mInitialized = false;
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
index 097cf35..00aa138 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
@@ -706,7 +706,7 @@
Drawable drawable = resolveImage(imageUri, mContext);
Bitmap bitmap = convertDrawableToBitmap(drawable);
views.setImageViewBitmap(R.id.image, bitmap);
- } catch (IOException e) {
+ } catch (IOException | SecurityException e) {
Log.e(TAG, "Could not decode image: " + e);
// If we couldn't load the image, show text that we have a new image.
views.setTextViewText(R.id.text_content, newImageDescription);
@@ -754,7 +754,7 @@
return views;
}
- private Drawable resolveImage(Uri uri, Context context) throws IOException {
+ Drawable resolveImage(Uri uri, Context context) throws IOException {
final ImageDecoder.Source source =
ImageDecoder.createSource(context.getContentResolver(), uri);
final Drawable drawable =
diff --git a/packages/SystemUI/src/com/android/systemui/power/BatteryWarningEvents.java b/packages/SystemUI/src/com/android/systemui/power/BatteryWarningEvents.java
new file mode 100644
index 0000000..1f8a303
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/power/BatteryWarningEvents.java
@@ -0,0 +1,64 @@
+/*
+ * 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.power;
+
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+
+/**
+ * Events related to the battery warning.
+ */
+public class BatteryWarningEvents {
+
+ /** Enums for logging low battery warning notification and dialog */
+ public enum LowBatteryWarningEvent implements UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "Low battery warning notification displayed")
+ LOW_BATTERY_NOTIFICATION(1048),
+
+ @UiEvent(doc = "Low battery warning notification positive button clicked")
+ LOW_BATTERY_NOTIFICATION_TURN_ON(1049),
+
+ @UiEvent(doc = "Low battery warning notification negative button clicked")
+ LOW_BATTERY_NOTIFICATION_CANCEL(1050),
+
+ @UiEvent(doc = "Low battery warning notification content clicked")
+ LOW_BATTERY_NOTIFICATION_SETTINGS(1051),
+
+ @UiEvent(doc = "Battery saver confirm dialog displayed")
+ SAVER_CONFIRM_DIALOG(1052),
+
+ @UiEvent(doc = "Battery saver confirm dialog positive button clicked")
+ SAVER_CONFIRM_OK(1053),
+
+ @UiEvent(doc = "Battery saver confirm dialog negative button clicked")
+ SAVER_CONFIRM_CANCEL(1054),
+
+ @UiEvent(doc = "Battery saver confirm dialog dismissed")
+ SAVER_CONFIRM_DISMISS(1055);
+
+ private final int mId;
+
+ LowBatteryWarningEvent(int id) {
+ mId = id;
+ }
+
+ @Override
+ public int getId() {
+ return mId;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 3e00a5f..429f2df 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -55,6 +55,7 @@
import androidx.annotation.VisibleForTesting;
+import com.android.internal.logging.UiEventLogger;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.settingslib.Utils;
import com.android.settingslib.fuelgauge.BatterySaverUtils;
@@ -169,6 +170,7 @@
private BatteryStateSnapshot mCurrentBatterySnapshot;
private ActivityStarter mActivityStarter;
private final BroadcastSender mBroadcastSender;
+ private final UiEventLogger mUiEventLogger;
private final Lazy<BatteryController> mBatteryControllerLazy;
private final DialogLaunchAnimator mDialogLaunchAnimator;
@@ -178,7 +180,7 @@
@Inject
public PowerNotificationWarnings(Context context, ActivityStarter activityStarter,
BroadcastSender broadcastSender, Lazy<BatteryController> batteryControllerLazy,
- DialogLaunchAnimator dialogLaunchAnimator) {
+ DialogLaunchAnimator dialogLaunchAnimator, UiEventLogger uiEventLogger) {
mContext = context;
mNoMan = mContext.getSystemService(NotificationManager.class);
mPowerMan = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
@@ -189,6 +191,7 @@
mBatteryControllerLazy = batteryControllerLazy;
mDialogLaunchAnimator = dialogLaunchAnimator;
mUseSevereDialog = mContext.getResources().getBoolean(R.bool.config_severe_battery_dialog);
+ mUiEventLogger = uiEventLogger;
}
@Override
@@ -333,6 +336,7 @@
final Notification n = nb.build();
mNoMan.cancelAsUser(TAG_BATTERY, SystemMessage.NOTE_BAD_CHARGER, UserHandle.ALL);
mNoMan.notifyAsUser(TAG_BATTERY, SystemMessage.NOTE_POWER_LOW, n, UserHandle.ALL);
+ logEvent(BatteryWarningEvents.LowBatteryWarningEvent.LOW_BATTERY_NOTIFICATION);
}
private boolean showSevereLowBatteryDialog() {
@@ -692,17 +696,25 @@
} else {
d.setTitle(R.string.battery_saver_confirmation_title);
d.setPositiveButton(R.string.battery_saver_confirmation_ok,
- (dialog, which) -> setSaverMode(true, false));
- d.setNegativeButton(android.R.string.cancel, null);
+ (dialog, which) -> {
+ setSaverMode(true, false);
+ logEvent(BatteryWarningEvents.LowBatteryWarningEvent.SAVER_CONFIRM_OK);
+ });
+ d.setNegativeButton(android.R.string.cancel, (dialog, which) ->
+ logEvent(BatteryWarningEvents.LowBatteryWarningEvent.SAVER_CONFIRM_CANCEL));
}
d.setShowForAllUsers(true);
- d.setOnDismissListener((dialog) -> mSaverConfirmation = null);
+ d.setOnDismissListener((dialog) -> {
+ mSaverConfirmation = null;
+ logEvent(BatteryWarningEvents.LowBatteryWarningEvent.SAVER_CONFIRM_DISMISS);
+ });
WeakReference<View> ref = mBatteryControllerLazy.get().getLastPowerSaverStartView();
if (ref != null && ref.get() != null && ref.get().isAggregatedVisible()) {
mDialogLaunchAnimator.showFromView(d, ref.get());
} else {
d.show();
}
+ logEvent(BatteryWarningEvents.LowBatteryWarningEvent.SAVER_CONFIRM_DIALOG);
mSaverConfirmation = d;
mBatteryControllerLazy.get().clearLastPowerSaverStartView();
}
@@ -794,6 +806,12 @@
mActivityStarter.startActivity(intent, true /* dismissShade */);
}
+ private void logEvent(BatteryWarningEvents.LowBatteryWarningEvent event) {
+ if (mUiEventLogger != null) {
+ mUiEventLogger.log(event);
+ }
+ }
+
private final class Receiver extends BroadcastReceiver {
public void init() {
@@ -819,15 +837,21 @@
final String action = intent.getAction();
Slog.i(TAG, "Received " + action);
if (action.equals(ACTION_SHOW_BATTERY_SAVER_SETTINGS)) {
+ logEvent(BatteryWarningEvents
+ .LowBatteryWarningEvent.LOW_BATTERY_NOTIFICATION_SETTINGS);
dismissLowBatteryNotification();
mContext.startActivityAsUser(mOpenBatterySaverSettings, UserHandle.CURRENT);
} else if (action.equals(ACTION_START_SAVER)) {
+ logEvent(BatteryWarningEvents
+ .LowBatteryWarningEvent.LOW_BATTERY_NOTIFICATION_TURN_ON);
setSaverMode(true, true);
dismissLowBatteryNotification();
} else if (action.equals(ACTION_SHOW_START_SAVER_CONFIRMATION)) {
dismissLowBatteryNotification();
showStartSaverConfirmation(intent.getExtras());
} else if (action.equals(ACTION_DISMISSED_WARNING)) {
+ logEvent(BatteryWarningEvents
+ .LowBatteryWarningEvent.LOW_BATTERY_NOTIFICATION_CANCEL);
dismissLowBatteryWarning();
} else if (ACTION_CLICKED_TEMP_WARNING.equals(action)) {
dismissHighTemperatureWarningInternal();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
index cc37ef4..13340b7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
@@ -234,6 +234,7 @@
val dialog = SystemUIDialog(context)
dialog.setTitle(R.string.fgs_manager_dialog_title)
+ dialog.setMessage(R.string.fgs_manager_dialog_message)
val dialogContext = dialog.context
@@ -241,7 +242,9 @@
recyclerView.layoutManager = LinearLayoutManager(dialogContext)
recyclerView.adapter = appListAdapter
- dialog.setView(recyclerView)
+ val topSpacing = dialogContext.resources
+ .getDimensionPixelSize(R.dimen.fgs_manager_list_top_spacing)
+ dialog.setView(recyclerView, 0, topSpacing, 0, 0)
this.dialog = dialog
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index a64b670..f87cb29 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -519,7 +519,10 @@
@Override
public void setOverScrollAmount(int overScrollAmount) {
mOverScrolling = overScrollAmount != 0;
- getView().setTranslationY(overScrollAmount);
+ View view = getView();
+ if (view != null) {
+ view.setTranslationY(overScrollAmount);
+ }
}
@Override
@@ -609,7 +612,7 @@
} else if (progress > 0 && view.getVisibility() != View.VISIBLE) {
view.setVisibility((View.VISIBLE));
}
- float alpha = mQSPanelController.bouncerInTransit()
+ float alpha = mQSPanelController.isBouncerInTransit()
? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(progress)
: ShadeInterpolation.getContentAlpha(progress);
view.setAlpha(alpha);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index 5670836..851307a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -254,8 +254,8 @@
*
* @return if bouncer is in transit
*/
- public boolean bouncerInTransit() {
- return mStatusBarKeyguardViewManager.bouncerIsInTransit();
+ public boolean isBouncerInTransit() {
+ return mStatusBarKeyguardViewManager.isBouncerInTransit();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
index 5d4b3da..628964a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
@@ -35,6 +35,7 @@
import com.android.systemui.statusbar.policy.DataSaverController;
import com.android.systemui.statusbar.policy.DeviceControlsController;
import com.android.systemui.statusbar.policy.HotspotController;
+import com.android.systemui.statusbar.policy.SafetyController;
import com.android.systemui.statusbar.policy.WalletController;
import com.android.systemui.util.settings.SecureSettings;
@@ -66,6 +67,7 @@
ReduceBrightColorsController reduceBrightColorsController,
DeviceControlsController deviceControlsController,
WalletController walletController,
+ SafetyController safetyController,
@Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) {
AutoTileManager manager = new AutoTileManager(
context,
@@ -81,6 +83,7 @@
reduceBrightColorsController,
deviceControlsController,
walletController,
+ safetyController,
isReduceBrightColorsAvailable
);
manager.init();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 83138f0..551e8b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -502,8 +502,8 @@
private void updateLockScreenTrustMsg(int userId, CharSequence trustGrantedIndication,
CharSequence trustManagedIndication) {
- if (!TextUtils.isEmpty(trustGrantedIndication)
- && mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
+ final boolean userHasTrust = mKeyguardUpdateMonitor.getUserHasTrust(userId);
+ if (!TextUtils.isEmpty(trustGrantedIndication) && userHasTrust) {
mRotateTextViewController.updateIndication(
INDICATION_TYPE_TRUST,
new KeyguardIndication.Builder()
@@ -513,7 +513,7 @@
false);
} else if (!TextUtils.isEmpty(trustManagedIndication)
&& mKeyguardUpdateMonitor.getUserTrustIsManaged(userId)
- && !mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
+ && !userHasTrust) {
mRotateTextViewController.updateIndication(
INDICATION_TYPE_TRUST,
new KeyguardIndication.Builder()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 241a745..76f9db4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -454,7 +454,7 @@
* update this manager's internal state.
* @return whether the current MediaMetadata changed (and needs to be announced to listeners).
*/
- private boolean findPlayingMediaNotification(
+ boolean findPlayingMediaNotification(
@NonNull Collection<NotificationEntry> allNotifications) {
boolean metaDataChanged = false;
// Promote the media notification with a controller in 'playing' state, if any.
@@ -465,7 +465,7 @@
if (notif.isMediaNotification()) {
final MediaSession.Token token =
entry.getSbn().getNotification().extras.getParcelable(
- Notification.EXTRA_MEDIA_SESSION);
+ Notification.EXTRA_MEDIA_SESSION, MediaSession.Token.class);
if (token != null) {
MediaController aController = new MediaController(mContext, token);
if (PlaybackState.STATE_PLAYING
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 0fb6ea6..039a362 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -573,11 +573,10 @@
} catch (RuntimeException e) {
Log.e(TAG, "Unable to recover builder", e);
// Trying to get the app name from the app info instead.
- Parcelable appInfo = n.extras.getParcelable(
- Notification.EXTRA_BUILDER_APPLICATION_INFO);
- if (appInfo instanceof ApplicationInfo) {
- appName = String.valueOf(((ApplicationInfo) appInfo).loadLabel(
- c.getPackageManager()));
+ ApplicationInfo appInfo = n.extras.getParcelable(
+ Notification.EXTRA_BUILDER_APPLICATION_INFO, ApplicationInfo.class);
+ if (appInfo != null) {
+ appName = String.valueOf(appInfo.loadLabel(c.getPackageManager()));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index 0fd9272..4fc347a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -542,7 +542,8 @@
if (senderPerson == null) {
return true;
}
- Person user = extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON);
+ Person user = extras.getParcelable(
+ Notification.EXTRA_MESSAGING_PERSON, Person.class);
return Objects.equals(user, senderPerson);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java
index 79f99b8..8732696 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java
@@ -44,9 +44,8 @@
private void updateImageTag(StatusBarNotification sbn) {
final Bundle extras = sbn.getNotification().extras;
- boolean bigLargeIconSet = extras.containsKey(Notification.EXTRA_LARGE_ICON_BIG);
- if (bigLargeIconSet) {
- Icon bigLargeIcon = extras.getParcelable(Notification.EXTRA_LARGE_ICON_BIG);
+ Icon bigLargeIcon = extras.getParcelable(Notification.EXTRA_LARGE_ICON_BIG, Icon.class);
+ if (bigLargeIcon != null) {
mRightIcon.setTag(ImageTransformState.ICON_TAG, bigLargeIcon);
mLeftIcon.setTag(ImageTransformState.ICON_TAG, bigLargeIcon);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 2f1022a..25999a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -31,6 +31,7 @@
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.BypassController;
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import javax.inject.Inject;
@@ -45,6 +46,10 @@
private final SectionProvider mSectionProvider;
private final BypassController mBypassController;
+ /**
+ * Used to read bouncer states.
+ */
+ private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private int mScrollY;
private boolean mDimmed;
private ActivatableNotificationView mActivatedChild;
@@ -204,9 +209,11 @@
public AmbientState(
Context context,
@NonNull SectionProvider sectionProvider,
- @NonNull BypassController bypassController) {
+ @NonNull BypassController bypassController,
+ @Nullable StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
mSectionProvider = sectionProvider;
mBypassController = bypassController;
+ mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
reload(context);
}
@@ -661,4 +668,14 @@
public int getStackTopMargin() {
return mStackTopMargin;
}
+
+ /**
+ * Check to see if we are about to show bouncer.
+ *
+ * @return if bouncer expansion is between 0 and 1.
+ */
+ public boolean isBouncerInTransit() {
+ return mStatusBarKeyguardViewManager != null
+ && mStatusBarKeyguardViewManager.isBouncerInTransit();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 15a93c8..b52fd61 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -417,7 +417,6 @@
private NotificationShelf mShelf;
private int mMaxDisplayedNotifications = -1;
private float mKeyguardBottomPadding = -1;
- private float mKeyguardNotificationAvailableSpace = -1;
@VisibleForTesting int mStatusBarHeight;
private int mMinInteractionHeight;
private final Rect mClipRect = new Rect();
@@ -775,9 +774,11 @@
y = (int) mMaxLayoutHeight;
drawDebugInfo(canvas, y, Color.MAGENTA, /* label= */ "mMaxLayoutHeight = " + y);
+ // The space between mTopPadding and mKeyguardBottomPadding determines the available space
+ // for notifications on keyguard.
if (mKeyguardBottomPadding >= 0) {
y = getHeight() - (int) mKeyguardBottomPadding;
- drawDebugInfo(canvas, y, Color.GRAY,
+ drawDebugInfo(canvas, y, Color.RED,
/* label= */ "getHeight() - mKeyguardBottomPadding = " + y);
}
@@ -789,7 +790,7 @@
drawDebugInfo(canvas, y, Color.CYAN, /* label= */ "mAmbientState.getStackY() = " + y);
y = (int) (mAmbientState.getStackY() + mAmbientState.getStackHeight());
- drawDebugInfo(canvas, y, Color.BLUE,
+ drawDebugInfo(canvas, y, Color.LTGRAY,
/* label= */ "mAmbientState.getStackY() + mAmbientState.getStackHeight() = " + y);
y = (int) mAmbientState.getStackY() + mContentHeight;
@@ -800,10 +801,6 @@
drawDebugInfo(canvas, y, Color.YELLOW,
/* label= */ "mAmbientState.getStackY() + mIntrinsicContentHeight = " + y);
- y = (int) (mAmbientState.getStackY() + mKeyguardNotificationAvailableSpace);
- drawDebugInfo(canvas, y, Color.RED, /* label= */
- "mAmbientState.getStackY() + mKeyguardNotificationAvailableSpace = " + y);
-
drawDebugInfo(canvas, mRoundedRectClippingBottom, Color.DKGRAY,
/* label= */ "mRoundedRectClippingBottom) = " + y);
}
@@ -2267,10 +2264,11 @@
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
private void updateContentHeight() {
final float scrimTopPadding = mAmbientState.isOnKeyguard() ? 0 : mMinimumPaddings;
+ final int shelfIntrinsicHeight = mShelf != null ? mShelf.getIntrinsicHeight() : 0;
final int height =
(int) scrimTopPadding + (int) mNotificationStackSizeCalculator.computeHeight(
/* notificationStackScrollLayout= */ this, mMaxDisplayedNotifications,
- mShelf != null ? mShelf.getIntrinsicHeight() : 0);
+ shelfIntrinsicHeight);
mIntrinsicContentHeight = height;
// The topPadding can be bigger than the regular padding when qs is expanded, in that
@@ -4914,15 +4912,6 @@
mKeyguardBottomPadding = keyguardBottomPadding;
}
- /**
- * For debugging only. Enables to draw a line related to the available size for notifications in
- * keyguard.
- */
- public void setKeyguardAvailableSpaceForDebug(float keyguardNotificationAvailableSpace) {
- mKeyguardNotificationAvailableSpace = keyguardNotificationAvailableSpace;
- }
-
-
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void setShouldShowShelfOnly(boolean shouldShowShelfOnly) {
mShouldShowShelfOnly = shouldShowShelfOnly;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 440bea6..ea6987a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -1305,12 +1305,6 @@
mView.setKeyguardBottomPadding(keyguardBottomPadding);
}
- /** For debugging only. */
- public void mKeyguardNotificationAvailableSpaceForDebug(
- float keyguardNotificationAvailableSpace) {
- mView.setKeyguardAvailableSpaceForDebug(keyguardNotificationAvailableSpace);
- }
-
public RemoteInputController.Delegate createDelegate() {
return new RemoteInputController.Delegate() {
public void setRemoteInputActive(NotificationEntry entry,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
index 7fb115d..9417aac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
@@ -29,6 +29,7 @@
import com.android.systemui.util.children
import javax.inject.Inject
import kotlin.math.max
+import kotlin.math.min
import kotlin.properties.Delegates.notNull
private const val TAG = "NotificationStackSizeCalculator"
@@ -51,9 +52,7 @@
*/
private var maxKeyguardNotifications by notNull<Int>()
- /**
- * Minimum space between two notifications, see [calculateGapAndDividerHeight].
- */
+ /** Minimum space between two notifications, see [calculateGapAndDividerHeight]. */
private var dividerHeight by notNull<Int>()
init {
@@ -61,55 +60,34 @@
}
/**
- * Given the [availableSpace] constraint, calculates how many notification to show.
+ * Given the [totalAvailableSpace] constraint, calculates how many notification to show.
*
* This number is only valid in keyguard.
*
- * @param availableSpace space for notifications. This doesn't include the space for the shelf.
+ * @param totalAvailableSpace space for notifications. This includes the space for the shelf.
*/
fun computeMaxKeyguardNotifications(
stack: NotificationStackScrollLayout,
- availableSpace: Float,
- shelfHeight: Float
+ totalAvailableSpace: Float,
+ shelfIntrinsicHeight: Float
): Int {
+ val stackHeightSequence = computeHeightPerNotificationLimit(stack, shelfIntrinsicHeight)
+
+ var maxNotifications =
+ stackHeightSequence.lastIndexWhile { stackHeight -> stackHeight <= totalAvailableSpace }
+
+ if (onLockscreen()) {
+ maxNotifications = min(maxKeyguardNotifications, maxNotifications)
+ }
+
+ // Could be < 0 if the space available is less than the shelf size. Returns 0 in this case.
+ maxNotifications = max(0, maxNotifications)
log {
"computeMaxKeyguardNotifications(" +
- "availableSpace=$availableSpace shelfHeight=$shelfHeight)"
+ "availableSpace=$totalAvailableSpace" +
+ " shelfHeight=$shelfIntrinsicHeight) -> $maxNotifications"
}
-
- val children: Sequence<ExpandableView> = stack.childrenSequence
- var remainingSpace: Float = availableSpace
- var count = 0
- var previous: ExpandableView? = null
- val onLockscreen = true
- val showableRows = children.filter { it.isShowable(onLockscreen) }
- val showableRowsCount = showableRows.count()
- log { "\tshowableRowsCount=$showableRowsCount "}
-
- showableRows.forEachIndexed { i, current ->
- val spaceNeeded = current.spaceNeeded(count, previous, stack, onLockscreen)
- val spaceAfter = remainingSpace - spaceNeeded
- previous = current
- log { "\ti=$i spaceNeeded=$spaceNeeded remainingSpace=$remainingSpace " +
- "spaceAfter=$spaceAfter" }
-
- if (remainingSpace - spaceNeeded >= 0 && count < maxKeyguardNotifications) {
- count += 1
- remainingSpace -= spaceNeeded
- } else if (remainingSpace - spaceNeeded > -shelfHeight && i == showableRowsCount - 1) {
- log { "Show all notifications. Shelf not needed." }
- // If this is the last one, and it fits using the space shelf would use, then we can
- // display it, as the shelf will not be needed (as all notifications are shown).
- return count + 1
- } else {
- log {
- "No more fit. Returning $count. Space used: ${availableSpace - remainingSpace}"
- }
- return count
- }
- }
- log { "All fit. Returning $count" }
- return count
+ return maxNotifications
}
/**
@@ -119,47 +97,60 @@
* @param stack stack containing notifications as children.
* @param maxNotifications Maximum number of notifications. When reached, the others will go
* into the shelf.
- * @param shelfHeight height of the shelf. It might be zero.
+ * @param shelfIntrinsicHeight height of the shelf, without any padding. It might be zero.
*
* @return height of the stack, including shelf height, if needed.
*/
fun computeHeight(
stack: NotificationStackScrollLayout,
maxNotifications: Int,
- shelfHeight: Float
+ shelfIntrinsicHeight: Float
): Float {
- val children: Sequence<ExpandableView> = stack.childrenSequence
- val maxNotificationsArg = infiniteIfNegative(maxNotifications)
+ val heightPerMaxNotifications =
+ computeHeightPerNotificationLimit(stack, shelfIntrinsicHeight)
+ val height =
+ heightPerMaxNotifications.elementAtOrElse(maxNotifications) {
+ heightPerMaxNotifications.last() // Height with all notifications visible.
+ }
+ log { "computeHeight(maxNotifications=$maxNotifications) -> $height" }
+ return height
+ }
+
+ /** The ith result in the sequence is the height with ith max notifications. */
+ private fun computeHeightPerNotificationLimit(
+ stack: NotificationStackScrollLayout,
+ shelfIntrinsicHeight: Float
+ ): Sequence<Float> = sequence {
+ val children = stack.showableChildren().toList()
var height = 0f
var previous: ExpandableView? = null
- var count = 0
val onLockscreen = onLockscreen()
- log { "computeHeight(maxNotification=$maxNotifications, shelf=$shelfHeight" }
- children.filter { it.isShowable(onLockscreen) }.forEach { current ->
- if (count < maxNotificationsArg) {
- val spaceNeeded = current.spaceNeeded(count, previous, stack, onLockscreen)
- log { "\ti=$count spaceNeeded=$spaceNeeded" }
- height += spaceNeeded
- count += 1
- } else {
- height += current.calculateGapAndDividerHeight(stack, previous, count)
- height += shelfHeight
- log { "returning height with shelf -> $height" }
- return height
- }
- previous = current
+ yield(dividerHeight + shelfIntrinsicHeight) // Only shelf.
+
+ children.forEachIndexed { i, currentNotification ->
+ height += currentNotification.spaceNeeded(i, previous, stack, onLockscreen)
+ previous = currentNotification
+
+ val shelfHeight =
+ if (i == children.lastIndex) {
+ 0f // No shelf needed.
+ } else {
+ val spaceBeforeShelf =
+ calculateGapAndDividerHeight(
+ stack, previous = currentNotification, current = children[i + 1], i)
+ spaceBeforeShelf + shelfIntrinsicHeight
+ }
+
+ yield(height + shelfHeight)
}
- log { "Returning height without shelf -> $height" }
- return height
}
fun updateResources() {
maxKeyguardNotifications =
infiniteIfNegative(resources.getInteger(R.integer.keyguard_max_notification_count))
- dividerHeight =
- max(1, resources.getDimensionPixelSize(R.dimen.notification_divider_height))
+ dividerHeight = max(1, resources.getDimensionPixelSize(R.dimen.notification_divider_height))
}
private val NotificationStackScrollLayout.childrenSequence: Sequence<ExpandableView>
@@ -180,7 +171,7 @@
} else {
intrinsicHeight.toFloat()
}
- size += calculateGapAndDividerHeight(stack, previousView, visibleIndex)
+ size += calculateGapAndDividerHeight(stack, previousView, current = this, visibleIndex)
return size
}
@@ -200,18 +191,22 @@
return true
}
- private fun ExpandableView.calculateGapAndDividerHeight(
+ private fun calculateGapAndDividerHeight(
stack: NotificationStackScrollLayout,
previous: ExpandableView?,
+ current: ExpandableView?,
visibleIndex: Int
- ) : Float {
- var height = stack.calculateGapHeight(previous, /* current= */ this, visibleIndex)
+ ): Float {
+ var height = stack.calculateGapHeight(previous, current, visibleIndex)
if (visibleIndex != 0) {
height += dividerHeight
}
return height
}
+ private fun NotificationStackScrollLayout.showableChildren() =
+ this.childrenSequence.filter { it.isShowable(onLockscreen()) }
+
/**
* Can a view be shown on the lockscreen when calculating the number of allowed notifications to
* show?
@@ -240,4 +235,8 @@
} else {
v
}
+
+ /** Returns the last index where [predicate] returns true, or -1 if it was always false. */
+ private fun <T> Sequence<T>.lastIndexWhile(predicate: (T) -> Boolean): Int =
+ takeWhile(predicate).count() - 1
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index c097133..9204c45e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -27,6 +27,7 @@
import androidx.annotation.VisibleForTesting;
import com.android.internal.policy.SystemBarUtils;
+import com.android.keyguard.BouncerPanelExpansionCalculator;
import com.android.systemui.R;
import com.android.systemui.animation.ShadeInterpolation;
import com.android.systemui.statusbar.EmptyShadeView;
@@ -431,7 +432,9 @@
} else if (ambientState.isExpansionChanging()) {
// Adjust alpha for shade open & close.
float expansion = ambientState.getExpansionFraction();
- viewState.alpha = ShadeInterpolation.getContentAlpha(expansion);
+ viewState.alpha = ambientState.isBouncerInTransit()
+ ? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion)
+ : ShadeInterpolation.getContentAlpha(expansion);
}
if (ambientState.isShadeExpanded() && view.mustStayOnScreen()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index ccb37ae..61780cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -40,6 +40,7 @@
import com.android.systemui.statusbar.policy.DeviceControlsController;
import com.android.systemui.statusbar.policy.HotspotController;
import com.android.systemui.statusbar.policy.HotspotController.Callback;
+import com.android.systemui.statusbar.policy.SafetyController;
import com.android.systemui.statusbar.policy.WalletController;
import com.android.systemui.util.UserAwareController;
import com.android.systemui.util.settings.SecureSettings;
@@ -83,6 +84,7 @@
private final DeviceControlsController mDeviceControlsController;
private final WalletController mWalletController;
private final ReduceBrightColorsController mReduceBrightColorsController;
+ private final SafetyController mSafetyController;
private final boolean mIsReduceBrightColorsAvailable;
private final ArrayList<AutoAddSetting> mAutoAddSettingList = new ArrayList<>();
@@ -98,6 +100,7 @@
ReduceBrightColorsController reduceBrightColorsController,
DeviceControlsController deviceControlsController,
WalletController walletController,
+ SafetyController safetyController,
@Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) {
mContext = context;
mHost = host;
@@ -114,6 +117,7 @@
mIsReduceBrightColorsAvailable = isReduceBrightColorsAvailable;
mDeviceControlsController = deviceControlsController;
mWalletController = walletController;
+ mSafetyController = safetyController;
String safetySpecRes;
try {
safetySpecRes = context.getResources().getString(R.string.safety_quick_settings_tile);
@@ -163,8 +167,11 @@
if (!mAutoTracker.isAdded(WALLET)) {
initWalletController();
}
- if (mSafetySpec != null && !mAutoTracker.isAdded(mSafetySpec)) {
- initSafetyTile();
+ if (mSafetySpec != null) {
+ if (!mAutoTracker.isAdded(mSafetySpec)) {
+ initSafetyTile();
+ }
+ mSafetyController.addCallback(mSafetyCallback);
}
int settingsN = mAutoAddSettingList.size();
@@ -187,6 +194,9 @@
}
mCastController.removeCallback(mCastCallback);
mDeviceControlsController.removeCallback();
+ if (mSafetySpec != null) {
+ mSafetyController.removeCallback(mSafetyCallback);
+ }
int settingsN = mAutoAddSettingList.size();
for (int i = 0; i < settingsN; i++) {
mAutoAddSettingList.get(i).setListening(false);
@@ -327,10 +337,9 @@
}
private void initSafetyTile() {
- if (mSafetySpec == null) {
+ if (mSafetySpec == null || mAutoTracker.isAdded(mSafetySpec)) {
return;
}
- if (mAutoTracker.isAdded(mSafetySpec)) return;
mHost.addTile(CustomTile.getComponentFromSpec(mSafetySpec), true);
mAutoTracker.setTileAdded(mSafetySpec);
}
@@ -403,6 +412,23 @@
};
@VisibleForTesting
+ final SafetyController.Listener mSafetyCallback = new SafetyController.Listener() {
+ @Override
+ public void onSafetyCenterEnableChanged(boolean isSafetyCenterEnabled) {
+ if (mSafetySpec == null) {
+ return;
+ }
+
+ if (isSafetyCenterEnabled && !mAutoTracker.isAdded(mSafetySpec)) {
+ initSafetyTile();
+ } else if (!isSafetyCenterEnabled && mAutoTracker.isAdded(mSafetySpec)) {
+ mHost.removeTile(CustomTile.getComponentFromSpec(mSafetySpec));
+ mHost.unmarkTileAsAutoAdded(mSafetySpec);
+ }
+ }
+ };
+
+ @VisibleForTesting
protected SettingObserver getSecureSettingForKey(String key) {
for (SettingObserver s : mAutoAddSettingList) {
if (Objects.equals(key, s.getKey())) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index a19d5f1..54d39fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -31,8 +31,6 @@
import android.util.Log;
import android.util.MathUtils;
-import android.util.Log;
-
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
@@ -293,11 +291,6 @@
}
public void updateControlScreenOff() {
- Log.i("TEST", "Display needs blanking?" + getDisplayNeedsBlanking());
- Log.i("TEST", "Should control screen off?" + shouldControlUnlockedScreenOff());
- Log.i("TEST", "alwaysOn?" + getAlwaysOn());
- Log.i("TEST", "keyguard showing?" + mKeyguardShowing);
- Log.i("TEST", "Flag enabled? " + mFeatureFlags.isEnabled(Flags.LOCKSCREEN_ANIMATIONS));
if (!getDisplayNeedsBlanking()) {
final boolean controlScreenOff =
getAlwaysOn() && (mKeyguardShowing || shouldControlUnlockedScreenOff());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
index 7db677a..3e32b64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
@@ -71,7 +71,13 @@
isListening = false
updateListeningState()
keyguardUpdateMonitor.requestFaceAuth(true)
- keyguardUpdateMonitor.requestActiveUnlock()
+ if (keyguardUpdateMonitor.mRequestActiveUnlockOnWakeup) {
+ keyguardUpdateMonitor.requestActiveUnlock("wake-unlock," +
+ " extra=KeyguardLiftController")
+ } else if (keyguardUpdateMonitor.mInitiateActiveUnlockOnWakeup) {
+ keyguardUpdateMonitor.initiateActiveUnlock("wake-initiate," +
+ " extra=KeyguardLiftController")
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
index b6ad9f7..16fddb42 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
@@ -93,7 +93,8 @@
mDisplayId = mContext.getDisplayId();
}
- public void destroy(Context context) {
+ /** Call to cleanup the LightBarTransitionsController when done with it. */
+ public void destroy() {
mCommandQueue.removeCallback(this);
mStatusBarStateController.removeCallback(this);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index a6b5c4d..af62f18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -317,8 +317,6 @@
private boolean mShouldUseSplitNotificationShade;
// The bottom padding reserved for elements of the keyguard measuring notifications
private float mKeyguardNotificationBottomPadding;
- // Space available for notifications.
- private float mKeyguardNotificationAvailableSpace;
// Current max allowed keyguard notifications determined by measuring the panel
private int mMaxAllowedKeyguardNotifications;
@@ -1245,8 +1243,6 @@
mMaxAllowedKeyguardNotifications);
mNotificationStackScrollLayoutController.setKeyguardBottomPaddingForDebug(
mKeyguardNotificationBottomPadding);
- mNotificationStackScrollLayoutController.mKeyguardNotificationAvailableSpaceForDebug(
- mKeyguardNotificationAvailableSpace);
} else {
// no max when not on the keyguard
mNotificationStackScrollLayoutController.setMaxDisplayedNotifications(-1);
@@ -1468,13 +1464,11 @@
* @return the maximum keyguard notifications that can fit on the screen
*/
private int computeMaxKeyguardNotifications() {
- int notificationPadding = Math.max(
- 1, mResources.getDimensionPixelSize(R.dimen.notification_divider_height));
float topPadding = mNotificationStackScrollLayoutController.getTopPadding();
- float shelfHeight =
+ float shelfIntrinsicHeight =
mNotificationShelfController.getVisibility() == View.GONE
? 0
- : mNotificationShelfController.getIntrinsicHeight() + notificationPadding;
+ : mNotificationShelfController.getIntrinsicHeight();
// Padding to add to the bottom of the stack to keep a minimum distance from the top of
// the lock icon.
@@ -1493,13 +1487,11 @@
float availableSpace =
mNotificationStackScrollLayoutController.getHeight()
- topPadding
- - shelfHeight
- bottomPadding;
- mKeyguardNotificationAvailableSpace = availableSpace;
return mNotificationStackSizeCalculator.computeMaxKeyguardNotifications(
mNotificationStackScrollLayoutController.getView(), availableSpace,
- shelfHeight);
+ shelfIntrinsicHeight);
}
private void updateClock() {
@@ -3173,7 +3165,10 @@
mFalsingCollector.onTrackingStarted(!mKeyguardStateController.canDismissLockScreen());
super.onTrackingStarted();
mScrimController.onTrackingStarted();
- if (mShouldUseSplitNotificationShade) {
+ // normally we want to set mQsExpandImmediate for every split shade case (at least when
+ // expanding), but keyguard tracking logic is different - this callback is called when
+ // unlocking with swipe up but not when swiping down to reveal shade
+ if (mShouldUseSplitNotificationShade && !mKeyguardShowing) {
mQsExpandImmediate = true;
}
if (mQsFullyExpanded) {
@@ -3215,7 +3210,7 @@
@Override
protected void startUnlockHintAnimation() {
- if (mPowerManager.isPowerSaveMode()) {
+ if (mPowerManager.isPowerSaveMode() || mAmbientState.getDozeAmount() > 0f) {
onUnlockHintStarted();
onUnlockHintFinished();
return;
@@ -3341,6 +3336,12 @@
.log(LockscreenUiEvent.LOCKSCREEN_LOCK_SHOW_HINT);
startUnlockHintAnimation();
}
+ if (mUpdateMonitor.isFaceEnrolled()
+ && mUpdateMonitor.mRequestActiveUnlockOnUnlockIntent
+ && mKeyguardBypassController.canBypass()) {
+ mUpdateMonitor.requestActiveUnlock("unlock-intent,"
+ + " extra=lockScreenEmptySpaceTap", true);
+ }
}
return true;
case StatusBarState.SHADE_LOCKED:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index 56c74bf..24660b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -288,7 +288,7 @@
final boolean keyguardOrAod = state.mKeyguardShowing
|| (state.mDozing && mDozeParameters.getAlwaysOn());
if ((keyguardOrAod && !state.mBackdropShowing && !state.mLightRevealScrimOpaque)
- || mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehindOrWillBe()) {
+ || mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind()) {
// Show the wallpaper if we're on keyguard/AOD and the wallpaper is not occluded by a
// solid backdrop. Also, show it if we are currently animating between the
// keyguard and the surface behind the keyguard - we want to use the wallpaper as a
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index d492c57..4ba8441 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -48,7 +48,6 @@
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.LatencyTracker;
-import com.android.keyguard.BouncerPanelExpansionCalculator;
import com.android.systemui.DejankUtils;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
@@ -796,9 +795,7 @@
}
mExpandedFraction = Math.min(1f,
maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight);
- mAmbientState.setExpansionFraction(mStatusBarKeyguardViewManager.bouncerIsInTransit()
- ? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(mExpandedFraction)
- : mExpandedFraction);
+ mAmbientState.setExpansionFraction(mExpandedFraction);
onHeightUpdated(mExpandedHeight);
updatePanelExpansionAndVisibility();
});
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index cc2ff3f..8c1ed19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -1074,7 +1074,7 @@
}
private float getInterpolatedFraction() {
- if (mStatusBarKeyguardViewManager.bouncerIsInTransit()) {
+ if (mStatusBarKeyguardViewManager.isBouncerInTransit()) {
return BouncerPanelExpansionCalculator
.aboutToShowBouncerProgress(mPanelExpansionFraction);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index ce1289e..8016ea5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -580,9 +580,7 @@
}
}
- /**
- * Stop showing any alternate auth methods
- */
+ @Override
public void resetAlternateAuth(boolean forceUpdateScrim) {
final boolean updateScrim = (mAlternateAuthInterceptor != null
&& mAlternateAuthInterceptor.hideAlternateAuthBouncer())
@@ -591,10 +589,12 @@
}
private void updateAlternateAuthShowing(boolean updateScrim) {
+ final boolean isShowingAltAuth = isShowingAlternateAuth();
if (mKeyguardMessageAreaController != null) {
- mKeyguardMessageAreaController.setAltBouncerShowing(isShowingAlternateAuth());
+ mKeyguardMessageAreaController.setAltBouncerShowing(isShowingAltAuth);
}
- mBypassController.setAltBouncerShowing(isShowingAlternateAuth());
+ mBypassController.setAltBouncerShowing(isShowingAltAuth);
+ mKeyguardUpdateManager.setUdfpsBouncerShowing(isShowingAltAuth);
if (updateScrim) {
mCentralSurfaces.updateScrimController();
@@ -1378,7 +1378,7 @@
/**
* Returns if bouncer expansion is between 0 and 1 non-inclusive.
*/
- public boolean bouncerIsInTransit() {
+ public boolean isBouncerInTransit() {
if (mBouncer == null) return false;
return mBouncer.inTransit();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialogManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialogManager.java
index 36e705a..e7d9221 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialogManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialogManager.java
@@ -18,6 +18,7 @@
import androidx.annotation.NonNull;
+import com.android.keyguard.KeyguardViewController;
import com.android.systemui.Dumpable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
@@ -37,7 +38,7 @@
*/
@SysUISingleton
public class SystemUIDialogManager implements Dumpable {
- private final StatusBarKeyguardViewManager mKeyguardViewManager;
+ private final KeyguardViewController mKeyguardViewController;
private final Set<SystemUIDialog> mDialogsShowing = new HashSet<>();
private final Set<Listener> mListeners = new HashSet<>();
@@ -45,9 +46,9 @@
@Inject
public SystemUIDialogManager(
DumpManager dumpManager,
- StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
+ KeyguardViewController keyguardViewController) {
dumpManager.registerDumpable(this);
- mKeyguardViewManager = statusBarKeyguardViewManager;
+ mKeyguardViewController = keyguardViewController;
}
/**
@@ -86,7 +87,7 @@
private void updateDialogListeners() {
if (shouldHideAffordance()) {
- mKeyguardViewManager.resetAlternateAuth(true);
+ mKeyguardViewController.resetAlternateAuth(true);
}
for (Listener listener : mListeners) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SafetyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SafetyController.java
new file mode 100644
index 0000000..f3d183c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SafetyController.java
@@ -0,0 +1,146 @@
+/*
+ * 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.statusbar.policy;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.Handler;
+import android.safetycenter.SafetyCenterManager;
+
+import androidx.annotation.NonNull;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.dagger.qualifiers.Background;
+
+import java.util.ArrayList;
+import java.util.Objects;
+
+import javax.inject.Inject;
+
+/**
+ * Controller which calls listeners when a PACKAGE_CHANGED broadcast is sent for the
+ * PermissionController. These broadcasts may be because the PermissionController enabled or
+ * disabled its TileService, and the tile should be added if the component was enabled, or removed
+ * if disabled.
+ */
+public class SafetyController implements
+ CallbackController<SafetyController.Listener> {
+ private boolean mSafetyCenterEnabled;
+ private final Handler mBgHandler;
+ private final ArrayList<Listener> mListeners = new ArrayList<>();
+ private static final IntentFilter PKG_CHANGE_INTENT_FILTER;
+ private final Context mContext;
+ private final SafetyCenterManager mSafetyCenterManager;
+ private final PackageManager mPackageManager;
+
+ static {
+ PKG_CHANGE_INTENT_FILTER = new IntentFilter(Intent.ACTION_PACKAGE_CHANGED);
+ PKG_CHANGE_INTENT_FILTER.addDataScheme("package");
+ }
+
+ @Inject
+ public SafetyController(Context context, PackageManager pm, SafetyCenterManager scm,
+ @Background Handler bgHandler) {
+ mContext = context;
+ mSafetyCenterManager = scm;
+ mPackageManager = pm;
+ mBgHandler = bgHandler;
+ mSafetyCenterEnabled = mSafetyCenterManager.isSafetyCenterEnabled();
+ }
+
+ public boolean isSafetyCenterEnabled() {
+ return mSafetyCenterEnabled;
+ }
+
+ /**
+ * Adds a listener, registering the broadcast receiver if need be. Immediately calls the
+ * provided listener on the calling thread.
+ */
+ @Override
+ public void addCallback(@NonNull Listener listener) {
+ synchronized (mListeners) {
+ mListeners.add(listener);
+ if (mListeners.size() == 1) {
+ mContext.registerReceiver(mPermControllerChangeReceiver, PKG_CHANGE_INTENT_FILTER);
+ mBgHandler.post(() -> {
+ mSafetyCenterEnabled = mSafetyCenterManager.isSafetyCenterEnabled();
+ listener.onSafetyCenterEnableChanged(isSafetyCenterEnabled());
+ });
+ } else {
+ listener.onSafetyCenterEnableChanged(isSafetyCenterEnabled());
+ }
+ }
+ }
+
+ @Override
+ public void removeCallback(@NonNull Listener listener) {
+ synchronized (mListeners) {
+ mListeners.remove(listener);
+ if (mListeners.isEmpty()) {
+ mContext.unregisterReceiver(mPermControllerChangeReceiver);
+ }
+ }
+ }
+
+ private void handleSafetyCenterEnableChange() {
+ synchronized (mListeners) {
+ for (int i = 0; i < mListeners.size(); i++) {
+ mListeners.get(i).onSafetyCenterEnableChanged(mSafetyCenterEnabled);
+ }
+ }
+ }
+
+ /**
+ * Upon receiving a package changed broadcast for the PermissionController, checks if the
+ * safety center is enabled or disabled, and sends an update on the main thread if the state
+ * changed.
+ */
+ @VisibleForTesting
+ final BroadcastReceiver mPermControllerChangeReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String packageName = intent.getData() != null ? intent.getData().getSchemeSpecificPart()
+ : null;
+ if (!Objects.equals(packageName,
+ mPackageManager.getPermissionControllerPackageName())) {
+ return;
+ }
+
+ boolean wasSafetyCenterEnabled = mSafetyCenterEnabled;
+ mSafetyCenterEnabled = mSafetyCenterManager.isSafetyCenterEnabled();
+ if (wasSafetyCenterEnabled == mSafetyCenterEnabled) {
+ return;
+ }
+
+ mBgHandler.post(() -> handleSafetyCenterEnableChange());
+ }
+ };
+
+ /**
+ * Listener for safety center enabled changes
+ */
+ public interface Listener {
+ /**
+ * Callback to be notified when the safety center is enabled or disabled
+ * @param isSafetyCenterEnabled If the safety center is enabled
+ */
+ void onSafetyCenterEnableChanged(boolean isSafetyCenterEnabled);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java b/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java
new file mode 100644
index 0000000..e06353b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbAudioWarningDialogMessage.java
@@ -0,0 +1,124 @@
+/*
+ * 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.usb;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
+import android.content.res.Resources;
+import android.util.Log;
+
+import com.android.systemui.R;
+
+import java.lang.annotation.Retention;
+
+import javax.inject.Inject;
+
+/**
+ * USB Audio devices warning dialog messages help class.
+ */
+public class UsbAudioWarningDialogMessage {
+ private static final String TAG = "UsbAudioWarningDialogMessage";
+
+ @Retention(SOURCE)
+ @IntDef({TYPE_PERMISSION, TYPE_CONFIRM})
+ public @interface DialogType {}
+ public static final int TYPE_PERMISSION = 0;
+ public static final int TYPE_CONFIRM = 1;
+
+ private int mDialogType;
+ private UsbDialogHelper mDialogHelper;
+
+ @Inject
+ public UsbAudioWarningDialogMessage() {
+ }
+
+ /**
+ * Initialize USB audio warning dialog message type and helper class.
+ * @param type Dialog type for Activity.
+ * @param usbDialogHelper Helper class for getting USB permission and confirm dialogs
+ */
+ public void init(@DialogType int type, UsbDialogHelper usbDialogHelper) {
+ mDialogType = type;
+ mDialogHelper = usbDialogHelper;
+ }
+
+ boolean hasRecordPermission() {
+ return mDialogHelper.packageHasAudioRecordingPermission();
+ }
+
+ boolean isUsbAudioDevice() {
+ return mDialogHelper.isUsbDevice() && (mDialogHelper.deviceHasAudioCapture()
+ || (mDialogHelper.deviceHasAudioPlayback()));
+ }
+
+ boolean hasAudioPlayback() {
+ return mDialogHelper.deviceHasAudioPlayback();
+ }
+
+ boolean hasAudioCapture() {
+ return mDialogHelper.deviceHasAudioCapture();
+ }
+
+ /**
+ * According to USB audio warning dialog matrix table to return warning message id.
+ * @return string resId for USB audio warning dialog message, otherwise {ID_NULL}.
+ * See usb_audio.md for USB audio Permission and Confirmation warning dialog resource
+ * string id matrix table.
+ */
+ public int getMessageId() {
+ if (!mDialogHelper.isUsbDevice()) {
+ return getUsbAccessoryPromptId();
+ }
+
+ if (hasRecordPermission() && isUsbAudioDevice()) {
+ // case# 1, 2, 3
+ return R.string.usb_audio_device_prompt;
+ } else if (!hasRecordPermission() && isUsbAudioDevice() && hasAudioPlayback()
+ && !hasAudioCapture()) {
+ // case# 5
+ return R.string.usb_audio_device_prompt;
+ }
+
+ if (!hasRecordPermission() && isUsbAudioDevice() && hasAudioCapture()) {
+ // case# 6,7
+ return R.string.usb_audio_device_prompt_warn;
+ }
+
+ Log.w(TAG, "Only shows title with empty content description!");
+ return Resources.ID_NULL;
+ }
+
+ /**
+ * Gets prompt dialog title.
+ * @return string id for USB prompt dialog title.
+ */
+ public int getPromptTitleId() {
+ return (mDialogType == TYPE_PERMISSION)
+ ? R.string.usb_audio_device_permission_prompt_title
+ : R.string.usb_audio_device_confirm_prompt_title;
+ }
+
+ /**
+ * Gets USB Accessory prompt message id.
+ * @return string id for USB Accessory prompt message.
+ */
+ public int getUsbAccessoryPromptId() {
+ return (mDialogType == TYPE_PERMISSION)
+ ? R.string.usb_accessory_permission_prompt : R.string.usb_accessory_confirm_prompt;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java
index f4558fe..6e523d8 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java
@@ -16,7 +16,10 @@
package com.android.systemui.usb;
-import com.android.systemui.R;
+import android.content.res.Resources;
+import android.os.Bundle;
+
+import javax.inject.Inject;
/**
* Dialog shown to confirm the package to start when a USB device or accessory is attached and there
@@ -24,23 +27,35 @@
*/
public class UsbConfirmActivity extends UsbDialogActivity {
+ private UsbAudioWarningDialogMessage mUsbConfirmMessageHandler;
+
+ @Inject
+ public UsbConfirmActivity(UsbAudioWarningDialogMessage usbAudioWarningDialogMessage) {
+ mUsbConfirmMessageHandler = usbAudioWarningDialogMessage;
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mUsbConfirmMessageHandler.init(UsbAudioWarningDialogMessage.TYPE_CONFIRM, mDialogHelper);
+ }
+
@Override
protected void onResume() {
super.onResume();
- final int strId;
- boolean useRecordWarning = false;
- if (mDialogHelper.isUsbDevice()) {
- useRecordWarning = mDialogHelper.deviceHasAudioCapture()
- && !mDialogHelper.packageHasAudioRecordingPermission();
- strId = useRecordWarning
- ? R.string.usb_device_confirm_prompt_warn
- : R.string.usb_device_confirm_prompt;
- } else {
- // UsbAccessory case
- strId = R.string.usb_accessory_confirm_prompt;
- }
- setAlertParams(strId);
// Only show the "always use" checkbox if there is no USB/Record warning
+ final boolean useRecordWarning = mDialogHelper.isUsbDevice()
+ && (mDialogHelper.deviceHasAudioCapture()
+ && !mDialogHelper.packageHasAudioRecordingPermission());
+
+ final int titleId = mUsbConfirmMessageHandler.getPromptTitleId();
+ final String title = getString(titleId, mDialogHelper.getAppName(),
+ mDialogHelper.getDeviceDescription());
+ final int messageId = mUsbConfirmMessageHandler.getMessageId();
+ String message = (messageId != Resources.ID_NULL)
+ ? getString(messageId, mDialogHelper.getAppName(),
+ mDialogHelper.getDeviceDescription()) : null;
+ setAlertParams(title, message);
if (!useRecordWarning) {
addAlwaysUseCheckbox();
}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java
index 930bc33..55dec5f 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDialogActivity.java
@@ -41,7 +41,7 @@
private TextView mClearDefaultHint;
@Override
- protected final void onCreate(Bundle savedInstanceState) {
+ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addSystemFlags(
WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
@@ -87,11 +87,10 @@
}
}
- void setAlertParams(int strId) {
+ void setAlertParams(String title, String message) {
final AlertController.AlertParams ap = mAlertParams;
- ap.mTitle = mDialogHelper.getAppName();
- ap.mMessage = getString(strId, mDialogHelper.getAppName(),
- mDialogHelper.getDeviceDescription());
+ ap.mTitle = title;
+ ap.mMessage = message;
ap.mPositiveButtonText = getString(android.R.string.ok);
ap.mNegativeButtonText = getString(android.R.string.cancel);
ap.mPositiveButtonListener = this;
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDialogHelper.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDialogHelper.java
index d63fb86..3f061d3 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDialogHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDialogHelper.java
@@ -134,6 +134,13 @@
}
/**
+ * @return True if the intent contains a UsbDevice which can play audio.
+ */
+ public boolean deviceHasAudioPlayback() {
+ return mDevice != null && mDevice.getHasAudioPlayback();
+ }
+
+ /**
* @return True if the package has RECORD_AUDIO permission specified in its manifest.
*/
public boolean packageHasAudioRecordingPermission() {
@@ -272,15 +279,15 @@
return desc;
}
- /**
- * Whether the calling package can set as default handler of the USB device or accessory.
- * In case of a UsbAccessory this is the case if the calling package has an intent filter for
- * {@link UsbManager#ACTION_USB_ACCESSORY_ATTACHED} with a usb-accessory filter matching the
- * attached accessory. In case of a UsbDevice this is the case if the calling package has an
- * intent filter for {@link UsbManager#ACTION_USB_DEVICE_ATTACHED} with a usb-device filter
- * matching the attached device.
- *
- * @return True if the package can be default for the USB device.
+ /**
+ * Whether the calling package can set as default handler of the USB device or accessory.
+ * In case of a UsbAccessory this is the case if the calling package has an intent filter for
+ * {@link UsbManager#ACTION_USB_ACCESSORY_ATTACHED} with a usb-accessory filter matching the
+ * attached accessory. In case of a UsbDevice this is the case if the calling package has an
+ * intent filter for {@link UsbManager#ACTION_USB_DEVICE_ATTACHED} with a usb-device filter
+ * matching the attached device.
+ *
+ * @return True if the package can be default for the USB device.
*/
public boolean canBeDefault() {
return mCanBeDefault;
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
index 38d6347..9484d3a 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
@@ -16,7 +16,10 @@
package com.android.systemui.usb;
-import com.android.systemui.R;
+import android.content.res.Resources;
+import android.os.Bundle;
+
+import javax.inject.Inject;
/**
* Dialog shown when a package requests access to a USB device or accessory.
@@ -24,23 +27,36 @@
public class UsbPermissionActivity extends UsbDialogActivity {
private boolean mPermissionGranted = false;
+ private UsbAudioWarningDialogMessage mUsbPermissionMessageHandler;
+
+ @Inject
+ public UsbPermissionActivity(UsbAudioWarningDialogMessage usbAudioWarningDialogMessage) {
+ mUsbPermissionMessageHandler = usbAudioWarningDialogMessage;
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mUsbPermissionMessageHandler.init(UsbAudioWarningDialogMessage.TYPE_PERMISSION,
+ mDialogHelper);
+ }
@Override
protected void onResume() {
super.onResume();
- final int strId;
- boolean useRecordWarning = false;
- if (mDialogHelper.isUsbDevice()) {
- useRecordWarning = mDialogHelper.deviceHasAudioCapture()
- && !mDialogHelper.packageHasAudioRecordingPermission();
- strId = useRecordWarning
- ? R.string.usb_device_permission_prompt_warn
- : R.string.usb_device_permission_prompt;
- } else {
- // UsbAccessory case
- strId = R.string.usb_accessory_permission_prompt;
- }
- setAlertParams(strId);
+ final boolean useRecordWarning = mDialogHelper.isUsbDevice()
+ && (mDialogHelper.deviceHasAudioCapture()
+ && !mDialogHelper.packageHasAudioRecordingPermission());
+
+ final int titleId = mUsbPermissionMessageHandler.getPromptTitleId();
+ final String title = getString(titleId, mDialogHelper.getAppName(),
+ mDialogHelper.getDeviceDescription());
+ final int messageId = mUsbPermissionMessageHandler.getMessageId();
+ String message = (messageId != Resources.ID_NULL)
+ ? getString(messageId, mDialogHelper.getAppName(),
+ mDialogHelper.getDeviceDescription()) : null;
+ setAlertParams(title, message);
+
// Only show the "always use" checkbox if there is no USB/Record warning
if (!useRecordWarning && mDialogHelper.canBeDefault()) {
addAlwaysUseCheckbox();
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
index 9b2702f..1243c47 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
@@ -215,6 +215,7 @@
logoView.setImageDrawable(mContext.getDrawable(R.drawable.ic_qs_plus));
mEmptyStateView.<TextView>requireViewById(R.id.empty_state_title).setText(label);
mEmptyStateView.setOnClickListener(clickListener);
+ mAppButton.setOnClickListener(clickListener);
}
void showErrorMessage(@Nullable CharSequence message) {
@@ -256,6 +257,11 @@
}
@VisibleForTesting
+ Button getAppButton() {
+ return mAppButton;
+ }
+
+ @VisibleForTesting
TextView getErrorView() {
return mErrorView;
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
index cc606de..b1e2012 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
@@ -97,5 +97,6 @@
primaryUser = false,
scanningAllowedByStrongAuth = false,
secureCameraLaunched = false,
- switchingUser = false
+ switchingUser = false,
+ udfpsBouncerShowing = false
)
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
index 14c903c..ba058c7 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
@@ -291,7 +291,9 @@
@Test
public void testTwoOrMoreUsersDoesAllowDropDown() {
// GIVEN one user has been setup
- when(mUserSwitcherController.getUsers()).thenReturn(buildUserRecords(2));
+ ArrayList<UserRecord> records = buildUserRecords(2);
+ when(mUserSwitcherController.getCurrentUserRecord()).thenReturn(records.get(0));
+ when(mUserSwitcherController.getUsers()).thenReturn(records);
// WHEN UserSwitcherViewMode is initialized
setupUserSwitcher();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 775addd..86a4f5a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -269,7 +269,7 @@
mKeyguardUpdateMonitor.registerCallback(mTestCallback);
mTestableLooper.processAllMessages();
- when(mAuthController.areAllAuthenticatorsRegistered()).thenReturn(true);
+ when(mAuthController.areAllFingerprintAuthenticatorsRegistered()).thenReturn(true);
}
@After
@@ -499,7 +499,7 @@
@Test
public void test_doesNotTryToAuthenticateFingerprint_whenAuthenticatorsNotRegistered() {
- when(mAuthController.areAllAuthenticatorsRegistered()).thenReturn(false);
+ when(mAuthController.areAllFingerprintAuthenticatorsRegistered()).thenReturn(false);
mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */);
mTestableLooper.processAllMessages();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 4858ab5..28da2f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -50,6 +50,7 @@
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricPrompt;
+import android.hardware.biometrics.BiometricStateListener;
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.IBiometricContextListener;
import android.hardware.biometrics.IBiometricSysuiReceiver;
@@ -60,7 +61,6 @@
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.hardware.fingerprint.FingerprintStateListener;
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
import android.os.Bundle;
import android.os.Handler;
@@ -151,7 +151,7 @@
@Captor
ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mAuthenticatorsRegisteredCaptor;
@Captor
- ArgumentCaptor<FingerprintStateListener> mFingerprintStateCaptor;
+ ArgumentCaptor<BiometricStateListener> mBiometricStateCaptor;
@Captor
ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
@@ -226,7 +226,7 @@
// Callback tests
@Test
- public void testRegistersFingerprintStateListener_afterAllAuthenticatorsAreRegistered()
+ public void testRegistersBiometricStateListener_afterAllAuthenticatorsAreRegistered()
throws RemoteException {
// This test is sensitive to prior FingerprintManager interactions.
reset(mFingerprintManager);
@@ -242,12 +242,12 @@
mAuthenticatorsRegisteredCaptor.capture());
mTestableLooper.processAllMessages();
- verify(mFingerprintManager, never()).registerFingerprintStateListener(any());
+ verify(mFingerprintManager, never()).registerBiometricStateListener(any());
mAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(new ArrayList<>());
mTestableLooper.processAllMessages();
- verify(mFingerprintManager).registerFingerprintStateListener(any());
+ verify(mFingerprintManager).registerBiometricStateListener(any());
}
@Test
@@ -269,11 +269,11 @@
mAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(new ArrayList<>());
mTestableLooper.processAllMessages();
- verify(mFingerprintManager).registerFingerprintStateListener(
- mFingerprintStateCaptor.capture());
+ verify(mFingerprintManager).registerBiometricStateListener(
+ mBiometricStateCaptor.capture());
// Enrollments changed for an unknown sensor.
- mFingerprintStateCaptor.getValue().onEnrollmentsChanged(0 /* userId */,
+ mBiometricStateCaptor.getValue().onEnrollmentsChanged(0 /* userId */,
0xbeef /* sensorId */, true /* hasEnrollments */);
mTestableLooper.processAllMessages();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferHelper.kt b/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferHelper.kt
index 2cb1939..0720bdb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferHelper.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferHelper.kt
@@ -30,6 +30,7 @@
* A [LogcatEchoTracker] that always allows echoing to the logcat.
*/
class LogcatEchoTrackerAlways : LogcatEchoTracker {
+ override val logInBackgroundThread = false
override fun isBufferLoggable(bufferName: String, level: LogLevel): Boolean = true
override fun isTagLoggable(tagName: String, level: LogLevel): Boolean = true
}
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 6626bbe..b43856a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
@@ -24,7 +24,11 @@
import com.android.internal.statusbar.IStatusBarService
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.commandline.Command
+import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.nullable
import com.android.systemui.util.mockito.withArgCaptor
@@ -37,10 +41,12 @@
import org.mockito.Mock
import org.mockito.Mockito.anyBoolean
import org.mockito.Mockito.anyString
+import org.mockito.Mockito.atLeastOnce
import org.mockito.Mockito.inOrder
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.MockitoAnnotations
import java.io.PrintWriter
import java.io.Serializable
@@ -56,16 +62,18 @@
class FeatureFlagsDebugTest : SysuiTestCase() {
private lateinit var mFeatureFlagsDebug: FeatureFlagsDebug
- @Mock private lateinit var mFlagManager: FlagManager
- @Mock private lateinit var mMockContext: Context
- @Mock private lateinit var mSecureSettings: SecureSettings
- @Mock private lateinit var mSystemProperties: SystemPropertiesHelper
- @Mock private lateinit var mResources: Resources
- @Mock private lateinit var mDumpManager: DumpManager
- @Mock private lateinit var mBarService: IStatusBarService
- private val mFlagMap = mutableMapOf<Int, Flag<*>>()
- private lateinit var mBroadcastReceiver: BroadcastReceiver
- private lateinit var mClearCacheAction: Consumer<Int>
+ @Mock private lateinit var flagManager: FlagManager
+ @Mock private lateinit var mockContext: Context
+ @Mock private lateinit var secureSettings: SecureSettings
+ @Mock private lateinit var systemProperties: SystemPropertiesHelper
+ @Mock private lateinit var resources: Resources
+ @Mock private lateinit var dumpManager: DumpManager
+ @Mock private lateinit var commandRegistry: CommandRegistry
+ @Mock private lateinit var barService: IStatusBarService
+ @Mock private lateinit var pw: PrintWriter
+ private val flagMap = mutableMapOf<Int, Flag<*>>()
+ private lateinit var broadcastReceiver: BroadcastReceiver
+ private lateinit var clearCacheAction: Consumer<Int>
private val teamfoodableFlagA = BooleanFlag(500, false, true)
private val teamfoodableFlagB = BooleanFlag(501, true, true)
@@ -73,34 +81,35 @@
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
- mFlagMap.put(teamfoodableFlagA.id, teamfoodableFlagA)
- mFlagMap.put(teamfoodableFlagB.id, teamfoodableFlagB)
+ flagMap.put(teamfoodableFlagA.id, teamfoodableFlagA)
+ flagMap.put(teamfoodableFlagB.id, teamfoodableFlagB)
mFeatureFlagsDebug = FeatureFlagsDebug(
- mFlagManager,
- mMockContext,
- mSecureSettings,
- mSystemProperties,
- mResources,
- mDumpManager,
- mFlagMap,
- mBarService
+ flagManager,
+ mockContext,
+ secureSettings,
+ systemProperties,
+ resources,
+ dumpManager,
+ flagMap,
+ commandRegistry,
+ barService
)
- verify(mFlagManager).onSettingsChangedAction = any()
- mBroadcastReceiver = withArgCaptor {
- verify(mMockContext).registerReceiver(capture(), any(), nullable(), nullable(),
+ verify(flagManager).onSettingsChangedAction = any()
+ broadcastReceiver = withArgCaptor {
+ verify(mockContext).registerReceiver(capture(), any(), nullable(), nullable(),
any())
}
- mClearCacheAction = withArgCaptor {
- verify(mFlagManager).clearCacheAction = capture()
+ clearCacheAction = withArgCaptor {
+ verify(flagManager).clearCacheAction = capture()
}
- whenever(mFlagManager.idToSettingsKey(any())).thenAnswer { "key-${it.arguments[0]}" }
+ whenever(flagManager.idToSettingsKey(any())).thenAnswer { "key-${it.arguments[0]}" }
}
@Test
fun testReadBooleanFlag() {
// Remember that the TEAMFOOD flag is id#1 and has special behavior.
- whenever(mFlagManager.readFlagValue<Boolean>(eq(3), any())).thenReturn(true)
- whenever(mFlagManager.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(BooleanFlag(2, true))).isTrue()
assertThat(mFeatureFlagsDebug.isEnabled(BooleanFlag(3, false))).isTrue()
assertThat(mFeatureFlagsDebug.isEnabled(BooleanFlag(4, true))).isFalse()
@@ -109,7 +118,7 @@
@Test
fun testTeamFoodFlag_False() {
- whenever(mFlagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(false)
+ whenever(flagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(false)
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isFalse()
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue()
@@ -120,7 +129,7 @@
@Test
fun testTeamFoodFlag_True() {
- whenever(mFlagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(true)
+ whenever(flagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(true)
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue()
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue()
@@ -131,11 +140,11 @@
@Test
fun testTeamFoodFlag_Overridden() {
- whenever(mFlagManager.readFlagValue<Boolean>(eq(teamfoodableFlagA.id), any()))
+ whenever(flagManager.readFlagValue<Boolean>(eq(teamfoodableFlagA.id), any()))
.thenReturn(true)
- whenever(mFlagManager.readFlagValue<Boolean>(eq(teamfoodableFlagB.id), any()))
+ whenever(flagManager.readFlagValue<Boolean>(eq(teamfoodableFlagB.id), any()))
.thenReturn(false)
- whenever(mFlagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(true)
+ whenever(flagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(true)
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue()
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isFalse()
@@ -146,14 +155,14 @@
@Test
fun testReadResourceBooleanFlag() {
- whenever(mResources.getBoolean(1001)).thenReturn(false)
- whenever(mResources.getBoolean(1002)).thenReturn(true)
- whenever(mResources.getBoolean(1003)).thenReturn(false)
- whenever(mResources.getBoolean(1004)).thenAnswer { throw NameNotFoundException() }
- whenever(mResources.getBoolean(1005)).thenAnswer { throw NameNotFoundException() }
+ whenever(resources.getBoolean(1001)).thenReturn(false)
+ whenever(resources.getBoolean(1002)).thenReturn(true)
+ whenever(resources.getBoolean(1003)).thenReturn(false)
+ whenever(resources.getBoolean(1004)).thenAnswer { throw NameNotFoundException() }
+ whenever(resources.getBoolean(1005)).thenAnswer { throw NameNotFoundException() }
- whenever(mFlagManager.readFlagValue<Boolean>(eq(3), any())).thenReturn(true)
- whenever(mFlagManager.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(ResourceBooleanFlag(1, 1001))).isFalse()
assertThat(mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(2, 1002))).isTrue()
@@ -171,7 +180,7 @@
@Test
fun testReadSysPropBooleanFlag() {
- whenever(mSystemProperties.getBoolean(anyString(), anyBoolean())).thenAnswer {
+ whenever(systemProperties.getBoolean(anyString(), anyBoolean())).thenAnswer {
if ("b".equals(it.getArgument<String?>(0))) {
return@thenAnswer true
}
@@ -187,8 +196,8 @@
@Test
fun testReadStringFlag() {
- whenever(mFlagManager.readFlagValue<String>(eq(3), any())).thenReturn("foo")
- whenever(mFlagManager.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, "biz"))).isEqualTo("biz")
assertThat(mFeatureFlagsDebug.getString(StringFlag(2, "baz"))).isEqualTo("baz")
assertThat(mFeatureFlagsDebug.getString(StringFlag(3, "buz"))).isEqualTo("foo")
@@ -197,16 +206,16 @@
@Test
fun testReadResourceStringFlag() {
- whenever(mResources.getString(1001)).thenReturn("")
- whenever(mResources.getString(1002)).thenReturn("resource2")
- whenever(mResources.getString(1003)).thenReturn("resource3")
- whenever(mResources.getString(1004)).thenReturn(null)
- whenever(mResources.getString(1005)).thenAnswer { throw NameNotFoundException() }
- whenever(mResources.getString(1006)).thenAnswer { throw NameNotFoundException() }
+ whenever(resources.getString(1001)).thenReturn("")
+ whenever(resources.getString(1002)).thenReturn("resource2")
+ whenever(resources.getString(1003)).thenReturn("resource3")
+ whenever(resources.getString(1004)).thenReturn(null)
+ whenever(resources.getString(1005)).thenAnswer { throw NameNotFoundException() }
+ whenever(resources.getString(1006)).thenAnswer { throw NameNotFoundException() }
- whenever(mFlagManager.readFlagValue<String>(eq(3), any())).thenReturn("override3")
- whenever(mFlagManager.readFlagValue<String>(eq(4), any())).thenReturn("override4")
- whenever(mFlagManager.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(ResourceStringFlag(1, 1001))).isEqualTo("")
assertThat(mFeatureFlagsDebug.getString(ResourceStringFlag(2, 1002))).isEqualTo("resource2")
@@ -232,16 +241,16 @@
addFlag(StringFlag(3, "flag3"))
addFlag(ResourceStringFlag(4, 1004))
- mBroadcastReceiver.onReceive(mMockContext, null)
- mBroadcastReceiver.onReceive(mMockContext, Intent())
- mBroadcastReceiver.onReceive(mMockContext, Intent("invalid action"))
- mBroadcastReceiver.onReceive(mMockContext, Intent(FlagManager.ACTION_SET_FLAG))
+ broadcastReceiver.onReceive(mockContext, null)
+ 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(mFlagManager, mSecureSettings)
+ verifyNoMoreInteractions(flagManager, secureSettings)
}
@Test
@@ -249,15 +258,15 @@
addFlag(BooleanFlag(1, false))
// trying to erase an id not in the map does noting
- mBroadcastReceiver.onReceive(
- mMockContext,
+ broadcastReceiver.onReceive(
+ mockContext,
Intent(FlagManager.ACTION_SET_FLAG).putExtra(FlagManager.EXTRA_ID, 0)
)
- verifyNoMoreInteractions(mFlagManager, mSecureSettings)
+ verifyNoMoreInteractions(flagManager, secureSettings)
// valid id with no value puts empty string in the setting
- mBroadcastReceiver.onReceive(
- mMockContext,
+ broadcastReceiver.onReceive(
+ mockContext,
Intent(FlagManager.ACTION_SET_FLAG).putExtra(FlagManager.EXTRA_ID, 1)
)
verifyPutData(1, "", numReads = 0)
@@ -298,48 +307,102 @@
@Test
fun testSetFlagClearsCache() {
val flag1 = addFlag(StringFlag(1, "flag1"))
- whenever(mFlagManager.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(mFlagManager).readFlagValue(eq(1), eq(StringFlagSerializer))
+ verify(flagManager).readFlagValue(eq(1), eq(StringFlagSerializer))
// hit the cache
assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("original")
- verifyNoMoreInteractions(mFlagManager)
+ verifyNoMoreInteractions(flagManager)
// set the flag
setByBroadcast(1, "new")
verifyPutData(1, "{\"type\":\"string\",\"value\":\"new\"}", numReads = 2)
- whenever(mFlagManager.readFlagValue<String>(eq(1), any())).thenReturn("new")
+ whenever(flagManager.readFlagValue<String>(eq(1), any())).thenReturn("new")
assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("new")
- verify(mFlagManager, times(3)).readFlagValue(eq(1), eq(StringFlagSerializer))
+ verify(flagManager, times(3)).readFlagValue(eq(1), eq(StringFlagSerializer))
+ }
+
+ @Test
+ fun testRegisterCommand() {
+ verify(commandRegistry).registerCommand(anyString(), any())
+ }
+
+ @Test
+ fun testNoOpCommand() {
+ val cmd = captureCommand()
+
+ cmd.execute(pw, ArrayList())
+ verify(pw, atLeastOnce()).println()
+ verify(flagManager).readFlagValue<Boolean>(eq(1), any())
+ verifyZeroInteractions(secureSettings)
+ }
+
+ @Test
+ fun testReadFlagCommand() {
+ addFlag(BooleanFlag(1, false))
+ val cmd = captureCommand()
+ cmd.execute(pw, listOf("1"))
+ verify(flagManager).readFlagValue<Boolean>(eq(1), any())
+ }
+
+ @Test
+ fun testSetFlagCommand() {
+ addFlag(BooleanFlag(1, false))
+ val cmd = captureCommand()
+ cmd.execute(pw, listOf("1", "on"))
+ verifyPutData(1, "{\"type\":\"boolean\",\"value\":true}")
+ }
+
+ @Test
+ fun testToggleFlagCommand() {
+ addFlag(BooleanFlag(1, true))
+ val cmd = captureCommand()
+ cmd.execute(pw, listOf("1", "toggle"))
+ verifyPutData(1, "{\"type\":\"boolean\",\"value\":false}", 2)
+ }
+
+ @Test
+ fun testEraseFlagCommand() {
+ addFlag(BooleanFlag(1, true))
+ val cmd = captureCommand()
+ cmd.execute(pw, listOf("1", "erase"))
+ verify(secureSettings).putStringForUser(eq("key-1"), eq(""), anyInt())
}
private fun verifyPutData(id: Int, data: String, numReads: Int = 1) {
- inOrder(mFlagManager, mSecureSettings).apply {
- verify(mFlagManager, times(numReads)).readFlagValue(eq(id), any<FlagSerializer<*>>())
- verify(mFlagManager).idToSettingsKey(eq(id))
- verify(mSecureSettings).putStringForUser(eq("key-$id"), eq(data), anyInt())
- verify(mFlagManager).dispatchListenersAndMaybeRestart(eq(id), any())
+ 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())
}.verifyNoMoreInteractions()
- verifyNoMoreInteractions(mFlagManager, mSecureSettings)
+ verifyNoMoreInteractions(flagManager, secureSettings)
}
private fun setByBroadcast(id: Int, value: Serializable?) {
val intent = Intent(FlagManager.ACTION_SET_FLAG)
intent.putExtra(FlagManager.EXTRA_ID, id)
intent.putExtra(FlagManager.EXTRA_VALUE, value)
- mBroadcastReceiver.onReceive(mMockContext, intent)
+ broadcastReceiver.onReceive(mockContext, intent)
}
private fun <F : Flag<*>> addFlag(flag: F): F {
- val old = mFlagMap.put(flag.id, flag)
+ val old = flagMap.put(flag.id, flag)
check(old == null) { "Flag ${flag.id} already registered" }
return flag
}
+ private fun captureCommand(): Command {
+ val captor = argumentCaptor<Function0<Command>>()
+ verify(commandRegistry).registerCommand(anyString(), capture(captor))
+
+ return captor.value.invoke()
+ }
+
@Test
fun testDump() {
val flag1 = BooleanFlag(1, true)
@@ -350,10 +413,10 @@
val flag6 = ResourceStringFlag(6, 1006)
val flag7 = ResourceStringFlag(7, 1007)
- whenever(mResources.getBoolean(1002)).thenReturn(true)
- whenever(mResources.getString(1006)).thenReturn("resource1006")
- whenever(mResources.getString(1007)).thenReturn("resource1007")
- whenever(mFlagManager.readFlagValue(eq(7), eq(StringFlagSerializer)))
+ whenever(resources.getBoolean(1002)).thenReturn(true)
+ whenever(resources.getString(1006)).thenReturn("resource1006")
+ whenever(resources.getString(1007)).thenReturn("resource1007")
+ whenever(flagManager.readFlagValue(eq(7), eq(StringFlagSerializer)))
.thenReturn("override7")
// WHEN the flags have been accessed
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/AnimationBindHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/AnimationBindHandlerTest.kt
new file mode 100644
index 0000000..e4cab18
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/AnimationBindHandlerTest.kt
@@ -0,0 +1,144 @@
+/*
+ * 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.media
+
+import org.mockito.Mockito.`when` as whenever
+import android.graphics.drawable.Animatable2
+import android.graphics.drawable.Drawable
+import android.test.suitebuilder.annotation.SmallTest
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import com.android.systemui.SysuiTestCase
+import junit.framework.Assert.assertTrue
+import junit.framework.Assert.assertFalse
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.times
+import org.mockito.Mockito.never
+import org.mockito.junit.MockitoJUnit
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class AnimationBindHandlerTest : SysuiTestCase() {
+
+ private interface Callback : () -> Unit
+ private abstract class AnimatedDrawable : Drawable(), Animatable2
+ private lateinit var handler: AnimationBindHandler
+
+ @Mock private lateinit var animatable: AnimatedDrawable
+ @Mock private lateinit var animatable2: AnimatedDrawable
+ @Mock private lateinit var callback: Callback
+
+ @JvmField @Rule val mockito = MockitoJUnit.rule()
+
+ @Before
+ fun setUp() {
+ handler = AnimationBindHandler()
+ }
+
+ @After
+ fun tearDown() {}
+
+ @Test
+ fun registerNoAnimations_executeCallbackImmediately() {
+ handler.tryExecute(callback)
+ verify(callback).invoke()
+ }
+
+ @Test
+ fun registerStoppedAnimations_executeCallbackImmediately() {
+ whenever(animatable.isRunning).thenReturn(false)
+ whenever(animatable2.isRunning).thenReturn(false)
+
+ handler.tryExecute(callback)
+ verify(callback).invoke()
+ }
+
+ @Test
+ fun registerRunningAnimations_executeCallbackDelayed() {
+ whenever(animatable.isRunning).thenReturn(true)
+ whenever(animatable2.isRunning).thenReturn(true)
+
+ handler.tryRegister(animatable)
+ handler.tryRegister(animatable2)
+ handler.tryExecute(callback)
+
+ verify(callback, never()).invoke()
+
+ whenever(animatable.isRunning).thenReturn(false)
+ handler.onAnimationEnd(animatable)
+ verify(callback, never()).invoke()
+
+ whenever(animatable2.isRunning).thenReturn(false)
+ handler.onAnimationEnd(animatable2)
+ verify(callback, times(1)).invoke()
+ }
+
+ @Test
+ fun repeatedEndCallback_executeSingleCallback() {
+ whenever(animatable.isRunning).thenReturn(true)
+
+ handler.tryRegister(animatable)
+ handler.tryExecute(callback)
+
+ verify(callback, never()).invoke()
+
+ whenever(animatable.isRunning).thenReturn(false)
+ handler.onAnimationEnd(animatable)
+ handler.onAnimationEnd(animatable)
+ handler.onAnimationEnd(animatable)
+ verify(callback, times(1)).invoke()
+ }
+
+ @Test
+ fun registerUnregister_executeImmediately() {
+ whenever(animatable.isRunning).thenReturn(true)
+
+ handler.tryRegister(animatable)
+ handler.unregisterAll()
+ handler.tryExecute(callback)
+
+ verify(callback).invoke()
+ }
+
+ @Test
+ fun updateRebindId_returnsAsExpected() {
+ // Previous or current call is null, returns true
+ assertTrue(handler.updateRebindId(null))
+ assertTrue(handler.updateRebindId(null))
+ assertTrue(handler.updateRebindId(null))
+ assertTrue(handler.updateRebindId(10))
+ assertTrue(handler.updateRebindId(null))
+ assertTrue(handler.updateRebindId(20))
+
+ // Different integer from prevoius, returns true
+ assertTrue(handler.updateRebindId(10))
+ assertTrue(handler.updateRebindId(20))
+
+ // Matches previous call, returns false
+ assertFalse(handler.updateRebindId(20))
+ assertFalse(handler.updateRebindId(20))
+ assertTrue(handler.updateRebindId(10))
+ assertFalse(handler.updateRebindId(10))
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/ColorSchemeTransitionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/ColorSchemeTransitionTest.kt
new file mode 100644
index 0000000..8f967ab
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/ColorSchemeTransitionTest.kt
@@ -0,0 +1,147 @@
+/*
+ * 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.media
+
+import org.mockito.Mockito.`when` as whenever
+import android.animation.ValueAnimator
+import android.graphics.Color
+import android.test.suitebuilder.annotation.SmallTest
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.monet.ColorScheme
+import junit.framework.Assert.assertEquals
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+
+private const val DEFAULT_COLOR = Color.RED
+private const val TARGET_COLOR = Color.BLUE
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class ColorSchemeTransitionTest : SysuiTestCase() {
+
+ private interface ExtractCB : (ColorScheme) -> Int
+ private interface ApplyCB : (Int) -> Unit
+ private lateinit var colorTransition: ColorTransition
+ private lateinit var colorSchemeTransition: ColorSchemeTransition
+
+ @Mock private lateinit var mockTransition: ColorTransition
+ @Mock private lateinit var valueAnimator: ValueAnimator
+ @Mock private lateinit var colorScheme: ColorScheme
+ @Mock private lateinit var extractColor: ExtractCB
+ @Mock private lateinit var applyColor: ApplyCB
+
+ private lateinit var transitionFactory: ColorTransitionFactory
+ @Mock private lateinit var mediaViewHolder: MediaViewHolder
+
+ @JvmField @Rule val mockitoRule = MockitoJUnit.rule()
+
+ @Before
+ fun setUp() {
+ transitionFactory = { default, extractColor, applyColor -> mockTransition }
+ whenever(extractColor.invoke(colorScheme)).thenReturn(TARGET_COLOR)
+
+ colorSchemeTransition = ColorSchemeTransition(context, mediaViewHolder, transitionFactory)
+
+ colorTransition = object : ColorTransition(DEFAULT_COLOR, extractColor, applyColor) {
+ override fun buildAnimator(): ValueAnimator {
+ return valueAnimator
+ }
+ }
+ }
+
+ @After
+ fun tearDown() {}
+
+ @Test
+ fun testColorTransition_nullColorScheme_keepsDefault() {
+ colorTransition.updateColorScheme(null)
+ verify(applyColor, times(1)).invoke(DEFAULT_COLOR)
+ verify(valueAnimator, never()).start()
+ assertEquals(DEFAULT_COLOR, colorTransition.sourceColor)
+ assertEquals(DEFAULT_COLOR, colorTransition.targetColor)
+ }
+
+ @Test
+ fun testColorTransition_newColor_startsAnimation() {
+ colorTransition.updateColorScheme(colorScheme)
+ verify(applyColor, times(1)).invoke(DEFAULT_COLOR)
+ verify(valueAnimator, times(1)).start()
+ assertEquals(DEFAULT_COLOR, colorTransition.sourceColor)
+ assertEquals(TARGET_COLOR, colorTransition.targetColor)
+ }
+
+ @Test
+ fun testColorTransition_sameColor_noAnimation() {
+ whenever(extractColor.invoke(colorScheme)).thenReturn(DEFAULT_COLOR)
+ colorTransition.updateColorScheme(colorScheme)
+ verify(valueAnimator, never()).start()
+ assertEquals(DEFAULT_COLOR, colorTransition.sourceColor)
+ assertEquals(DEFAULT_COLOR, colorTransition.targetColor)
+ }
+
+ @Test
+ fun testColorTransition_colorAnimation_startValues() {
+ val expectedColor = DEFAULT_COLOR
+ whenever(valueAnimator.animatedFraction).thenReturn(0f)
+ colorTransition.updateColorScheme(colorScheme)
+ colorTransition.onAnimationUpdate(valueAnimator)
+
+ assertEquals(expectedColor, colorTransition.currentColor)
+ assertEquals(expectedColor, colorTransition.sourceColor)
+ verify(applyColor, times(2)).invoke(expectedColor) // applied once in constructor
+ }
+
+ @Test
+ fun testColorTransition_colorAnimation_endValues() {
+ val expectedColor = TARGET_COLOR
+ whenever(valueAnimator.animatedFraction).thenReturn(1f)
+ colorTransition.updateColorScheme(colorScheme)
+ colorTransition.onAnimationUpdate(valueAnimator)
+
+ assertEquals(expectedColor, colorTransition.currentColor)
+ assertEquals(expectedColor, colorTransition.targetColor)
+ verify(applyColor).invoke(expectedColor)
+ }
+
+ @Test
+ fun testColorTransition_colorAnimation_interpolatedMidpoint() {
+ val expectedColor = Color.rgb(186, 0, 186)
+ whenever(valueAnimator.animatedFraction).thenReturn(0.5f)
+ colorTransition.updateColorScheme(colorScheme)
+ colorTransition.onAnimationUpdate(valueAnimator)
+
+ assertEquals(expectedColor, colorTransition.currentColor)
+ verify(applyColor).invoke(expectedColor)
+ }
+
+ @Test
+ fun testColorSchemeTransition_update() {
+ colorSchemeTransition.updateColorScheme(colorScheme)
+ verify(mockTransition, times(6)).updateColorScheme(colorScheme)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index a58a28e..33db993 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -16,6 +16,8 @@
package com.android.systemui.media
+import android.animation.Animator
+import android.animation.AnimatorSet
import android.app.PendingIntent
import android.app.smartspace.SmartspaceAction
import android.content.Context
@@ -39,6 +41,7 @@
import android.testing.TestableLooper
import android.view.View
import android.view.ViewGroup
+import android.view.animation.Interpolator
import android.widget.FrameLayout
import android.widget.ImageButton
import android.widget.ImageView
@@ -49,16 +52,22 @@
import androidx.lifecycle.LiveData
import androidx.test.filters.SmallTest
import com.android.internal.logging.InstanceId
+import com.android.systemui.ActivityIntentHelper
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastSender
import com.android.systemui.media.dialog.MediaOutputDialogFactory
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.statusbar.NotificationLockscreenUserManager
+import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.animation.TransitionLayout
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.KotlinArgumentCaptor
+import com.android.systemui.util.mockito.argumentCaptor
+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.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
@@ -72,7 +81,6 @@
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyLong
import org.mockito.Mock
-import org.mockito.Mockito.any
import org.mockito.Mockito.anyString
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
@@ -82,7 +90,6 @@
import org.mockito.junit.MockitoJUnit
private const val KEY = "TEST_KEY"
-private const val BG_COLOR = Color.RED
private const val PACKAGE = "PKG"
private const val ARTIST = "ARTIST"
private const val TITLE = "TITLE"
@@ -140,6 +147,7 @@
private lateinit var actionsTopBarrier: Barrier
@Mock private lateinit var longPressText: TextView
@Mock private lateinit var handler: Handler
+ @Mock private lateinit var mockAnimator: AnimatorSet
private lateinit var settings: ImageButton
private lateinit var cancel: View
private lateinit var cancelText: TextView
@@ -155,12 +163,25 @@
@Mock private lateinit var instanceId: InstanceId
@Mock private lateinit var packageManager: PackageManager
@Mock private lateinit var applicationInfo: ApplicationInfo
+ @Mock private lateinit var keyguardStateController: KeyguardStateController
+ @Mock private lateinit var activityIntentHelper: ActivityIntentHelper
+ @Mock private lateinit var lockscreenUserManager: NotificationLockscreenUserManager
@Mock private lateinit var recommendationViewHolder: RecommendationViewHolder
@Mock private lateinit var smartspaceAction: SmartspaceAction
private lateinit var smartspaceData: SmartspaceMediaData
- @Mock private lateinit var coverContainer: ViewGroup
- private lateinit var coverItem: ImageView
+ @Mock private lateinit var coverContainer1: ViewGroup
+ @Mock private lateinit var coverContainer2: ViewGroup
+ @Mock private lateinit var coverContainer3: ViewGroup
+ private lateinit var coverItem1: ImageView
+ private lateinit var coverItem2: ImageView
+ private lateinit var coverItem3: ImageView
+ private lateinit var recTitle1: TextView
+ private lateinit var recTitle2: TextView
+ private lateinit var recTitle3: TextView
+ private lateinit var recSubtitle1: TextView
+ private lateinit var recSubtitle2: TextView
+ private lateinit var recSubtitle3: TextView
@JvmField @Rule val mockito = MockitoJUnit.rule()
@@ -181,7 +202,7 @@
whenever(packageManager.getApplicationLabel(any())).thenReturn(PACKAGE)
context.setMockPackageManager(packageManager)
- player = MediaControlPanel(
+ player = object : MediaControlPanel(
context,
bgExecutor,
mainExecutor,
@@ -194,8 +215,18 @@
mediaCarouselController,
falsingManager,
clock,
- logger
- )
+ logger,
+ keyguardStateController,
+ activityIntentHelper,
+ lockscreenUserManager) {
+ override fun loadAnimator(
+ animId: Int,
+ otionInterpolator: Interpolator,
+ vararg targets: View
+ ): AnimatorSet {
+ return mockAnimator
+ }
+ }
initMediaViewHolderMocks()
@@ -215,7 +246,6 @@
session.setActive(true)
mediaData = MediaTestUtils.emptyMediaData.copy(
- backgroundColor = BG_COLOR,
artist = ARTIST,
song = TITLE,
packageName = PACKAGE,
@@ -349,19 +379,30 @@
* Initialize elements for the recommendation view holder
*/
private fun initRecommendationViewHolderMocks() {
+ recTitle1 = TextView(context)
+ recTitle2 = TextView(context)
+ recTitle3 = TextView(context)
+ recSubtitle1 = TextView(context)
+ recSubtitle2 = TextView(context)
+ recSubtitle3 = TextView(context)
+
whenever(recommendationViewHolder.recommendations).thenReturn(view)
whenever(recommendationViewHolder.cardIcon).thenReturn(appIcon)
- whenever(recommendationViewHolder.cardText).thenReturn(titleText)
// Add a recommendation item
- coverItem = ImageView(context).also { it.setId(R.id.media_cover1) }
- whenever(coverContainer.id).thenReturn(R.id.media_cover1_container)
- whenever(recommendationViewHolder.mediaCoverItems).thenReturn(listOf(coverItem))
- whenever(recommendationViewHolder.mediaCoverContainers).thenReturn(listOf(coverContainer))
- whenever(recommendationViewHolder.mediaCoverItemsResIds)
- .thenReturn(listOf(R.id.media_cover1))
- whenever(recommendationViewHolder.mediaCoverContainersResIds)
- .thenReturn(listOf(R.id.media_cover1_container))
+ coverItem1 = ImageView(context).also { it.setId(R.id.media_cover1) }
+ coverItem2 = ImageView(context).also { it.setId(R.id.media_cover2) }
+ coverItem3 = ImageView(context).also { it.setId(R.id.media_cover3) }
+
+ whenever(recommendationViewHolder.mediaCoverItems)
+ .thenReturn(listOf(coverItem1, coverItem2, coverItem3))
+ whenever(recommendationViewHolder.mediaCoverContainers)
+ .thenReturn(listOf(coverContainer1, coverContainer2, coverContainer3))
+ whenever(recommendationViewHolder.mediaTitles)
+ .thenReturn(listOf(recTitle1, recTitle2, recTitle3))
+ whenever(recommendationViewHolder.mediaSubtitles).thenReturn(
+ listOf(recSubtitle1, recSubtitle2, recSubtitle3)
+ )
// Long press menu
whenever(recommendationViewHolder.settings).thenReturn(settings)
@@ -374,7 +415,10 @@
// Needed for card and item action click
val mockContext = mock(Context::class.java)
whenever(view.context).thenReturn(mockContext)
- whenever(coverContainer.context).thenReturn(mockContext)
+ whenever(coverContainer1.context).thenReturn(mockContext)
+ whenever(coverContainer2.context).thenReturn(mockContext)
+ whenever(coverContainer3.context).thenReturn(mockContext)
+
}
@After
@@ -437,6 +481,64 @@
}
@Test
+ fun bindSemanticActions_reservedPrev() {
+ val icon = context.getDrawable(android.R.drawable.ic_media_play)
+ val bg = context.getDrawable(R.drawable.qs_media_round_button_background)
+
+ // Setup button state: no prev or next button and their slots reserved
+ val semanticActions = MediaButton(
+ playOrPause = MediaAction(icon, Runnable {}, "play", bg),
+ nextOrCustom = null,
+ prevOrCustom = null,
+ custom0 = MediaAction(icon, null, "custom 0", bg),
+ custom1 = MediaAction(icon, null, "custom 1", bg),
+ false,
+ true
+ )
+ val state = mediaData.copy(semanticActions = semanticActions)
+
+ player.attachPlayer(viewHolder)
+ player.bindPlayer(state, PACKAGE)
+
+ assertThat(actionPrev.isEnabled()).isFalse()
+ assertThat(actionPrev.drawable).isNull()
+ verify(expandedSet).setVisibility(R.id.actionPrev, ConstraintSet.INVISIBLE)
+
+ assertThat(actionNext.isEnabled()).isFalse()
+ assertThat(actionNext.drawable).isNull()
+ verify(expandedSet).setVisibility(R.id.actionNext, ConstraintSet.GONE)
+ }
+
+ @Test
+ fun bindSemanticActions_reservedNext() {
+ val icon = context.getDrawable(android.R.drawable.ic_media_play)
+ val bg = context.getDrawable(R.drawable.qs_media_round_button_background)
+
+ // Setup button state: no prev or next button and their slots reserved
+ val semanticActions = MediaButton(
+ playOrPause = MediaAction(icon, Runnable {}, "play", bg),
+ nextOrCustom = null,
+ prevOrCustom = null,
+ custom0 = MediaAction(icon, null, "custom 0", bg),
+ custom1 = MediaAction(icon, null, "custom 1", bg),
+ true,
+ false
+ )
+ val state = mediaData.copy(semanticActions = semanticActions)
+
+ player.attachPlayer(viewHolder)
+ player.bindPlayer(state, PACKAGE)
+
+ assertThat(actionPrev.isEnabled()).isFalse()
+ assertThat(actionPrev.drawable).isNull()
+ verify(expandedSet).setVisibility(R.id.actionPrev, ConstraintSet.GONE)
+
+ assertThat(actionNext.isEnabled()).isFalse()
+ assertThat(actionNext.drawable).isNull()
+ verify(expandedSet).setVisibility(R.id.actionNext, ConstraintSet.INVISIBLE)
+ }
+
+ @Test
fun bind_seekBarDisabled_seekBarVisibilityIsSetToInvisible() {
whenever(seekBarViewModel.getEnabled()).thenReturn(false)
@@ -470,7 +572,7 @@
val icon = context.getDrawable(android.R.drawable.ic_media_play)
val semanticActions = MediaButton(
prevOrCustom = MediaAction(icon, {}, "prev", null),
- nextOrCustom = MediaAction(icon, {}, "next", null),
+ nextOrCustom = MediaAction(icon, {}, "next", null)
)
val state = mediaData.copy(semanticActions = semanticActions)
@@ -504,7 +606,7 @@
val icon = context.getDrawable(android.R.drawable.ic_media_play)
val semanticActions = MediaButton(
prevOrCustom = null,
- nextOrCustom = MediaAction(icon, {}, "next", null),
+ nextOrCustom = MediaAction(icon, {}, "next", null)
)
val state = mediaData.copy(semanticActions = semanticActions)
player.attachPlayer(viewHolder)
@@ -524,7 +626,7 @@
val icon = context.getDrawable(android.R.drawable.ic_media_play)
val semanticActions = MediaButton(
prevOrCustom = MediaAction(icon, {}, "prev", null),
- nextOrCustom = null,
+ nextOrCustom = null
)
val state = mediaData.copy(semanticActions = semanticActions)
player.attachPlayer(viewHolder)
@@ -544,7 +646,7 @@
val icon = context.getDrawable(android.R.drawable.ic_media_play)
val semanticActions = MediaButton(
prevOrCustom = MediaAction(icon, {}, "prev", null),
- nextOrCustom = MediaAction(icon, {}, "next", null),
+ nextOrCustom = MediaAction(icon, {}, "next", null)
)
val state = mediaData.copy(semanticActions = semanticActions)
player.attachPlayer(viewHolder)
@@ -566,7 +668,7 @@
val icon = context.getDrawable(android.R.drawable.ic_media_play)
val semanticActions = MediaButton(
prevOrCustom = MediaAction(icon, {}, "prev", null),
- nextOrCustom = MediaAction(icon, {}, "next", null),
+ nextOrCustom = MediaAction(icon, {}, "next", null)
)
val state = mediaData.copy(semanticActions = semanticActions)
@@ -598,9 +700,11 @@
MediaAction(icon, null, "custom 0", bg),
MediaAction(icon, Runnable {}, "custom 1", bg)
)
- val state = mediaData.copy(actions = actions,
+ val state = mediaData.copy(
+ actions = actions,
actionsToShowInCompact = listOf(1, 2),
- semanticActions = null)
+ semanticActions = null
+ )
player.attachPlayer(viewHolder)
player.bindPlayer(state, PACKAGE)
@@ -649,11 +753,14 @@
val icon = context.getDrawable(R.drawable.ic_media_play)
val bg = context.getDrawable(R.drawable.ic_media_play_container)
val semanticActions0 = MediaButton(
- playOrPause = MediaAction(mockAvd0, Runnable {}, "play", null))
+ playOrPause = MediaAction(mockAvd0, Runnable {}, "play", null)
+ )
val semanticActions1 = MediaButton(
- playOrPause = MediaAction(mockAvd1, Runnable {}, "pause", null))
+ playOrPause = MediaAction(mockAvd1, Runnable {}, "pause", null)
+ )
val semanticActions2 = MediaButton(
- playOrPause = MediaAction(mockAvd2, Runnable {}, "loading", null))
+ playOrPause = MediaAction(mockAvd2, Runnable {}, "loading", null)
+ )
val state0 = mediaData.copy(semanticActions = semanticActions0)
val state1 = mediaData.copy(semanticActions = semanticActions1)
val state2 = mediaData.copy(semanticActions = semanticActions2)
@@ -693,8 +800,8 @@
assertThat(actionPlayPause.getBackground()).isNull()
verify(mockAvd0, times(1))
.registerAnimationCallback(any(Animatable2.AnimationCallback::class.java))
- verify(mockAvd1, times(1)
- ).registerAnimationCallback(any(Animatable2.AnimationCallback::class.java))
+ verify(mockAvd1, times(1))
+ .registerAnimationCallback(any(Animatable2.AnimationCallback::class.java))
verify(mockAvd2, times(1))
.registerAnimationCallback(any(Animatable2.AnimationCallback::class.java))
verify(mockAvd0, times(1))
@@ -709,8 +816,53 @@
fun bindText() {
player.attachPlayer(viewHolder)
player.bindPlayer(mediaData, PACKAGE)
+
+ // Capture animation handler
+ val captor = argumentCaptor<Animator.AnimatorListener>()
+ verify(mockAnimator, times(2)).addListener(captor.capture())
+ val handler = captor.value
+
+ // Validate text views unchanged but animation started
+ assertThat(titleText.getText()).isEqualTo("")
+ assertThat(artistText.getText()).isEqualTo("")
+ verify(mockAnimator, times(1)).start()
+
+ // Binding only after animator runs
+ handler.onAnimationEnd(mockAnimator)
assertThat(titleText.getText()).isEqualTo(TITLE)
assertThat(artistText.getText()).isEqualTo(ARTIST)
+
+ // Rebinding should not trigger animation
+ player.bindPlayer(mediaData, PACKAGE)
+ verify(mockAnimator, times(1)).start()
+ }
+
+ @Test
+ fun bindTextInterrupted() {
+ val data0 = mediaData.copy(artist = "ARTIST_0")
+ val data1 = mediaData.copy(artist = "ARTIST_1")
+ val data2 = mediaData.copy(artist = "ARTIST_2")
+
+ player.attachPlayer(viewHolder)
+ player.bindPlayer(data0, PACKAGE)
+
+ // Capture animation handler
+ val captor = argumentCaptor<Animator.AnimatorListener>()
+ verify(mockAnimator, times(2)).addListener(captor.capture())
+ val handler = captor.value
+
+ handler.onAnimationEnd(mockAnimator)
+ assertThat(artistText.getText()).isEqualTo("ARTIST_0")
+
+ // Bind trigges new animation
+ player.bindPlayer(data1, PACKAGE)
+ verify(mockAnimator, times(2)).start()
+ whenever(mockAnimator.isRunning()).thenReturn(true)
+
+ // Rebind before animation end binds corrct data
+ player.bindPlayer(data2, PACKAGE)
+ handler.onAnimationEnd(mockAnimator)
+ assertThat(artistText.getText()).isEqualTo("ARTIST_2")
}
@Test
@@ -1004,6 +1156,47 @@
}
@Test
+ fun tapContentView_showOverLockscreen_openActivity() {
+ // WHEN we are on lockscreen and this activity can show over lockscreen
+ whenever(keyguardStateController.isShowing).thenReturn(true)
+ whenever(activityIntentHelper.wouldShowOverLockscreen(any(), any())).thenReturn(true)
+
+ val clickIntent = mock(Intent::class.java)
+ val pendingIntent = mock(PendingIntent::class.java)
+ whenever(pendingIntent.intent).thenReturn(clickIntent)
+ val captor = ArgumentCaptor.forClass(View.OnClickListener::class.java)
+ val data = mediaData.copy(clickIntent = pendingIntent)
+ player.attachPlayer(viewHolder)
+ player.bindPlayer(data, KEY)
+ verify(viewHolder.player).setOnClickListener(captor.capture())
+
+ // THEN it shows without dismissing keyguard first
+ captor.value.onClick(viewHolder.player)
+ verify(activityStarter).startActivity(eq(clickIntent), eq(true),
+ nullable(), eq(true))
+ }
+
+ @Test
+ fun tapContentView_noShowOverLockscreen_dismissKeyguard() {
+ // WHEN we are on lockscreen and the activity cannot show over lockscreen
+ whenever(keyguardStateController.isShowing).thenReturn(true)
+ whenever(activityIntentHelper.wouldShowOverLockscreen(any(), any())).thenReturn(false)
+
+ val clickIntent = mock(Intent::class.java)
+ val pendingIntent = mock(PendingIntent::class.java)
+ whenever(pendingIntent.intent).thenReturn(clickIntent)
+ val captor = ArgumentCaptor.forClass(View.OnClickListener::class.java)
+ val data = mediaData.copy(clickIntent = pendingIntent)
+ player.attachPlayer(viewHolder)
+ player.bindPlayer(data, KEY)
+ verify(viewHolder.player).setOnClickListener(captor.capture())
+
+ // THEN keyguard has to be dismissed
+ captor.value.onClick(viewHolder.player)
+ verify(activityStarter).postStartActivityDismissingKeyguard(eq(pendingIntent), any())
+ }
+
+ @Test
fun recommendation_gutsClosed_longPressOpens() {
player.attachRecommendation(recommendationViewHolder)
player.bindRecommendation(smartspaceData)
@@ -1058,12 +1251,70 @@
player.attachRecommendation(recommendationViewHolder)
player.bindRecommendation(smartspaceData)
- verify(coverContainer).setOnClickListener(captor.capture())
+ verify(coverContainer1).setOnClickListener(captor.capture())
captor.value.onClick(recommendationViewHolder.recommendations)
verify(logger).logRecommendationItemTap(eq(PACKAGE), eq(instanceId), eq(0))
}
+ @Test
+ fun bindRecommendation_hasTitlesAndSubtitles() {
+ player.attachRecommendation(recommendationViewHolder)
+
+ val title1 = "Title1"
+ val title2 = "Title2"
+ val title3 = "Title3"
+ val subtitle1 = "Subtitle1"
+ val subtitle2 = "Subtitle2"
+ val subtitle3 = "Subtitle3"
+
+ val data = smartspaceData.copy(
+ recommendations = listOf(
+ SmartspaceAction.Builder("id1", title1)
+ .setSubtitle(subtitle1)
+ .setIcon(Icon.createWithResource(context, R.drawable.ic_1x_mobiledata))
+ .setExtras(Bundle.EMPTY)
+ .build(),
+ SmartspaceAction.Builder("id2", title2)
+ .setSubtitle(subtitle2)
+ .setIcon(Icon.createWithResource(context, R.drawable.ic_alarm))
+ .setExtras(Bundle.EMPTY)
+ .build(),
+ SmartspaceAction.Builder("id3", title3)
+ .setSubtitle(subtitle3)
+ .setIcon(Icon.createWithResource(context, R.drawable.ic_3g_mobiledata))
+ .setExtras(Bundle.EMPTY)
+ .build()
+ )
+ )
+ player.bindRecommendation(data)
+
+ assertThat(recTitle1.text).isEqualTo(title1)
+ assertThat(recTitle2.text).isEqualTo(title2)
+ assertThat(recTitle3.text).isEqualTo(title3)
+ assertThat(recSubtitle1.text).isEqualTo(subtitle1)
+ assertThat(recSubtitle2.text).isEqualTo(subtitle2)
+ assertThat(recSubtitle3.text).isEqualTo(subtitle3)
+ }
+
+ @Test
+ fun bindRecommendation_noTitle_subtitleNotShown() {
+ player.attachRecommendation(recommendationViewHolder)
+
+ val data = smartspaceData.copy(
+ recommendations = listOf(
+ SmartspaceAction.Builder("id1", "")
+ .setSubtitle("fake subtitle")
+ .setIcon(Icon.createWithResource(context, R.drawable.ic_1x_mobiledata))
+ .setExtras(Bundle.EMPTY)
+ .build()
+ )
+ )
+ player.bindRecommendation(data)
+
+ assertThat(recSubtitle1.text).isEqualTo("")
+ }
+
private fun getScrubbingChangeListener(): SeekBarViewModel.ScrubbingChangeListener =
withArgCaptor { verify(seekBarViewModel).setScrubbingChangeListener(capture()) }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
index eacec20..3e335c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
@@ -57,7 +57,6 @@
private static final String OLD_KEY = "TEST_KEY_OLD";
private static final String APP = "APP";
private static final String PACKAGE = "PKG";
- private static final int BG_COLOR = Color.RED;
private static final String ARTIST = "ARTIST";
private static final String TITLE = "TITLE";
private static final String DEVICE_NAME = "DEVICE_NAME";
@@ -76,7 +75,7 @@
mManager.addListener(mListener);
mMediaData = new MediaData(
- USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null,
+ USER_ID, true, APP, null, ARTIST, TITLE, null,
new ArrayList<>(), new ArrayList<>(), null, PACKAGE, null, null, null, true, null,
MediaData.PLAYBACK_LOCAL, false, KEY, false, false, false, 0L,
InstanceId.fakeInstanceId(-1), -1);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
index 8582499..ca2fd6b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
@@ -277,6 +277,49 @@
}
@Test
+ fun testLoadMediaDataInBg_invalidTokenNoCrash() {
+ val bundle = Bundle()
+ // wrong data type
+ bundle.putParcelable(Notification.EXTRA_MEDIA_SESSION, Bundle())
+ val rcn = SbnBuilder().run {
+ setPkg(SYSTEM_PACKAGE_NAME)
+ modifyNotification(context).also {
+ it.setSmallIcon(android.R.drawable.ic_media_pause)
+ it.addExtras(bundle)
+ it.setStyle(MediaStyle().apply {
+ setRemotePlaybackInfo("Remote device", 0, null)
+ })
+ }
+ build()
+ }
+
+ mediaDataManager.loadMediaDataInBg(KEY, rcn, null)
+ // no crash even though the data structure is incorrect
+ }
+
+ @Test
+ fun testLoadMediaDataInBg_invalidMediaRemoteIntentNoCrash() {
+ val bundle = Bundle()
+ // wrong data type
+ bundle.putParcelable(Notification.EXTRA_MEDIA_REMOTE_INTENT, Bundle())
+ val rcn = SbnBuilder().run {
+ setPkg(SYSTEM_PACKAGE_NAME)
+ modifyNotification(context).also {
+ it.setSmallIcon(android.R.drawable.ic_media_pause)
+ it.addExtras(bundle)
+ it.setStyle(MediaStyle().apply {
+ setMediaSession(session.sessionToken)
+ setRemotePlaybackInfo("Remote device", 0, null)
+ })
+ }
+ build()
+ }
+
+ mediaDataManager.loadMediaDataInBg(KEY, rcn, null)
+ // no crash even though the data structure is incorrect
+ }
+
+ @Test
fun testOnNotificationRemoved_callsListener() {
addNotificationAndLoad()
val data = mediaDataCaptor.value
@@ -838,6 +881,9 @@
assertThat(actions.custom1).isNotNull()
assertThat(actions.custom1!!.contentDescription).isEqualTo(customDesc[1])
+
+ assertThat(actions.reserveNext).isTrue()
+ assertThat(actions.reservePrev).isTrue()
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaTestUtils.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaTestUtils.kt
index c7ef94e..ae58fe6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaTestUtils.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaTestUtils.kt
@@ -7,7 +7,6 @@
val emptyMediaData = MediaData(
userId = 0,
initialized = true,
- backgroundColor = 0,
app = null,
appIcon = null,
artist = null,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MetadataAnimationHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MetadataAnimationHandlerTest.kt
new file mode 100644
index 0000000..52cb902
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MetadataAnimationHandlerTest.kt
@@ -0,0 +1,177 @@
+/*
+ * 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.media
+
+import org.mockito.Mockito.`when` as whenever
+import android.animation.Animator
+import android.animation.AnimatorSet
+import android.test.suitebuilder.annotation.SmallTest
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import com.android.systemui.SysuiTestCase
+import junit.framework.Assert.fail
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.times
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.junit.MockitoJUnit
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class MetadataAnimationHandlerTest : SysuiTestCase() {
+
+ private interface Callback : () -> Unit
+ private lateinit var handler: MetadataAnimationHandler
+
+ @Mock private lateinit var animatorSet: AnimatorSet
+ @Mock private lateinit var enterAnimator: Animator
+ @Mock private lateinit var exitAnimator: Animator
+ @Mock private lateinit var postExitCB: Callback
+ @Mock private lateinit var postEnterCB: Callback
+
+ @JvmField @Rule val mockito = MockitoJUnit.rule()
+
+ @Before
+ fun setUp() {
+ handler = object : MetadataAnimationHandler(exitAnimator, enterAnimator) {
+ override fun buildAnimatorSet(exit: Animator, enter: Animator): AnimatorSet {
+ return animatorSet
+ }
+ }
+ }
+
+ @After
+ fun tearDown() {}
+
+ @Test
+ fun firstBind_startsAnimationSet() {
+ val cb = { fail("Unexpected callback") }
+ handler.setNext("data-1", cb, cb)
+
+ verify(animatorSet).start()
+ }
+
+ @Test
+ fun executeAnimationEnd_runsCallacks() {
+ handler.setNext("data-1", postExitCB, postEnterCB)
+ verify(animatorSet, times(1)).start()
+ verify(postExitCB, never()).invoke()
+
+ handler.onAnimationEnd(exitAnimator)
+ verify(animatorSet, times(1)).start()
+ verify(postExitCB, times(1)).invoke()
+ verify(postEnterCB, never()).invoke()
+
+ handler.onAnimationEnd(enterAnimator)
+ verify(animatorSet, times(1)).start()
+ verify(postExitCB, times(1)).invoke()
+ verify(postEnterCB, times(1)).invoke()
+ }
+
+ @Test
+ fun rebindSameData_executesFirstCallback() {
+ val postExitCB2 = mock(Callback::class.java)
+
+ handler.setNext("data-1", postExitCB, postEnterCB)
+ handler.setNext("data-1", postExitCB2, postEnterCB)
+ handler.onAnimationEnd(exitAnimator)
+
+ verify(postExitCB, times(1)).invoke()
+ verify(postExitCB2, never()).invoke()
+ verify(postEnterCB, never()).invoke()
+ }
+
+ @Test
+ fun rebindDifferentData_executesSecondCallback() {
+ val postExitCB2 = mock(Callback::class.java)
+
+ handler.setNext("data-1", postExitCB, postEnterCB)
+ handler.setNext("data-2", postExitCB2, postEnterCB)
+ handler.onAnimationEnd(exitAnimator)
+
+ verify(postExitCB, never()).invoke()
+ verify(postExitCB2, times(1)).invoke()
+ verify(postEnterCB, never()).invoke()
+ }
+
+ @Test
+ fun rebindBeforeEnterComplete_animationRestarts() {
+ val postExitCB2 = mock(Callback::class.java)
+ val postEnterCB2 = mock(Callback::class.java)
+
+ handler.setNext("data-1", postExitCB, postEnterCB)
+ verify(animatorSet, times(1)).start()
+ verify(postExitCB, never()).invoke()
+ verify(postExitCB2, never()).invoke()
+ verify(postEnterCB, never()).invoke()
+ verify(postEnterCB2, never()).invoke()
+
+ whenever(animatorSet.isRunning()).thenReturn(true)
+ handler.onAnimationEnd(exitAnimator)
+ verify(animatorSet, times(1)).start()
+ verify(postExitCB, times(1)).invoke()
+ verify(postExitCB2, never()).invoke()
+ verify(postEnterCB, never()).invoke()
+ verify(postEnterCB2, never()).invoke()
+
+ handler.setNext("data-2", postExitCB2, postEnterCB2)
+ handler.onAnimationEnd(enterAnimator)
+ verify(animatorSet, times(2)).start()
+ verify(postExitCB, times(1)).invoke()
+ verify(postExitCB2, never()).invoke()
+ verify(postEnterCB, never()).invoke()
+ verify(postEnterCB2, never()).invoke()
+
+ handler.onAnimationEnd(exitAnimator)
+ verify(animatorSet, times(2)).start()
+ verify(postExitCB, times(1)).invoke()
+ verify(postExitCB2, times(1)).invoke()
+ verify(postEnterCB, never()).invoke()
+ verify(postEnterCB2, never()).invoke()
+
+ handler.onAnimationEnd(enterAnimator)
+ verify(animatorSet, times(2)).start()
+ verify(postExitCB, times(1)).invoke()
+ verify(postExitCB2, times(1)).invoke()
+ verify(postEnterCB, never()).invoke()
+ verify(postEnterCB2, times(1)).invoke()
+ }
+
+ @Test
+ fun exitAnimationEndMultipleCalls_singleCallbackExecution() {
+ handler.setNext("data-1", postExitCB, postEnterCB)
+ handler.onAnimationEnd(exitAnimator)
+ handler.onAnimationEnd(exitAnimator)
+ handler.onAnimationEnd(exitAnimator)
+
+ verify(postExitCB, times(1)).invoke()
+ }
+
+ @Test
+ fun enterAnimatorEndsWithoutCallback_noAnimatiorStart() {
+ handler.onAnimationEnd(enterAnimator)
+
+ verify(animatorSet, never()).start()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
index c48d846..49be669 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
@@ -16,6 +16,8 @@
package com.android.systemui.media
+import android.animation.Animator
+import android.animation.ObjectAnimator
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View
@@ -43,6 +45,7 @@
private val enabledHeight = 2
private lateinit var observer: SeekBarObserver
+ @Mock private lateinit var mockSeekbarAnimator: ObjectAnimator
@Mock private lateinit var mockHolder: MediaViewHolder
@Mock private lateinit var mockSquigglyProgress: SquigglyProgress
private lateinit var seekBarView: SeekBar
@@ -66,7 +69,11 @@
whenever(mockHolder.scrubbingElapsedTimeView).thenReturn(scrubbingElapsedTimeView)
whenever(mockHolder.scrubbingTotalTimeView).thenReturn(scrubbingTotalTimeView)
- observer = SeekBarObserver(mockHolder)
+ observer = object : SeekBarObserver(mockHolder) {
+ override fun buildResetAnimator(targetTime: Int): Animator {
+ return mockSeekbarAnimator
+ }
+ }
}
@Test
@@ -189,4 +196,20 @@
assertThat(scrubbingElapsedTimeView.text).isEqualTo("")
assertThat(scrubbingTotalTimeView.text).isEqualTo("")
}
+
+ @Test
+ fun seekBarJumpAnimation() {
+ val data0 = SeekBarViewModel.Progress(true, true, true, false, 4000, 120000)
+ val data1 = SeekBarViewModel.Progress(true, true, true, false, 10, 120000)
+
+ // Set initial position of progress bar
+ observer.onChanged(data0)
+ assertThat(seekBarView.progress).isEqualTo(4000)
+ assertThat(seekBarView.max).isEqualTo(120000)
+
+ // Change to second data & confirm no change to position (due to animation delay)
+ observer.onChanged(data1)
+ assertThat(seekBarView.progress).isEqualTo(4000)
+ verify(mockSeekbarAnimator).start()
+ }
}
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 f5b006d..4a740f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
@@ -205,10 +205,9 @@
when(mNavigationBarView.getAccessibilityButton()).thenReturn(mAccessibilityButton);
when(mNavigationBarView.getImeSwitchButton()).thenReturn(mImeSwitchButton);
when(mNavigationBarView.getBackButton()).thenReturn(mBackButton);
- when(mNavigationBarView.getBarTransitions()).thenReturn(mNavigationBarTransitions);
when(mNavigationBarView.getRotationButtonController())
.thenReturn(mRotationButtonController);
- when(mNavigationBarView.getLightTransitionsController())
+ when(mNavigationBarTransitions.getLightTransitionsController())
.thenReturn(mLightBarTransitionsController);
when(mStatusBarKeyguardViewManager.isNavBarVisible()).thenReturn(true);
setupSysuiDependency();
@@ -459,6 +458,7 @@
mInputMethodManager,
mDeadZone,
mDeviceConfigProxyFake,
+ mNavigationBarTransitions,
Optional.of(mock(BackAnimation.class))));
}
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 6a2a78b..084eca8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java
@@ -21,7 +21,6 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
@@ -37,8 +36,8 @@
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.BarTransitions;
+import com.android.systemui.statusbar.phone.LightBarTransitionsController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
@@ -53,6 +52,10 @@
public class NavigationBarTransitionsTest extends SysuiTestCase {
@Mock
+ LightBarTransitionsController.Factory mLightBarTransitionsFactory;
+ @Mock
+ LightBarTransitionsController mLightBarTransitions;
+ @Mock
EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
@Mock
EdgeBackGestureHandler mEdgeBackGestureHandler;
@@ -76,10 +79,11 @@
.when(mDependency.injectMockDependency(NavigationModeController.class))
.getCurrentUserContext();
+ when(mLightBarTransitionsFactory.create(any())).thenReturn(mLightBarTransitions);
NavigationBarView navBar = spy(new NavigationBarView(mContext, null));
when(navBar.getCurrentView()).thenReturn(navBar);
when(navBar.findViewById(anyInt())).thenReturn(navBar);
- mTransitions = new NavigationBarTransitions(navBar, mock(CommandQueue.class));
+ mTransitions = new NavigationBarTransitions(navBar, mLightBarTransitionsFactory);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
index b4b4597..e6b960d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
@@ -33,8 +33,12 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.people.ConversationStatus;
@@ -44,6 +48,7 @@
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.UserHandle;
@@ -581,6 +586,27 @@
}
@Test
+ public void testCreateRemoteViewsWithNotificationContent() throws Exception {
+ PeopleTileViewHelper helper = spy(getPeopleTileViewHelper(PERSON_TILE));
+ doReturn(new BitmapDrawable()).when(helper).resolveImage(any(), any());
+ RemoteViews views = helper.getViews();
+ View result = views.apply(mContext, null);
+
+ assertEquals(View.VISIBLE, result.findViewById(R.id.image).getVisibility());
+ }
+
+ @Test
+ public void testCreateRemoteViewsWithInvalidNotificationContent() throws Exception {
+ PeopleTileViewHelper helper = spy(getPeopleTileViewHelper(PERSON_TILE));
+ doThrow(SecurityException.class).when(helper).resolveImage(any(), any());
+ RemoteViews views = helper.getViews();
+ View result = views.apply(mContext, null);
+
+ assertEquals(View.GONE, result.findViewById(R.id.image).getVisibility());
+ assertEquals(View.VISIBLE, result.findViewById(R.id.text_content).getVisibility());
+ }
+
+ @Test
public void testCreateRemoteViewsWithUserQuieted() {
PeopleSpaceTile tile = PERSON_TILE.toBuilder()
.setIsUserQuieted(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
index 1ffa9dd..26e4d9d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
@@ -46,6 +46,7 @@
import android.testing.TestableLooper;
import android.view.View;
+import com.android.internal.logging.UiEventLogger;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.settingslib.fuelgauge.BatterySaverUtils;
import com.android.systemui.SysuiTestCase;
@@ -79,6 +80,8 @@
@Mock
private DialogLaunchAnimator mDialogLaunchAnimator;
@Mock
+ private UiEventLogger mUiEventLogger;
+ @Mock
private View mView;
private BroadcastReceiver mReceiver;
@@ -101,7 +104,7 @@
ActivityStarter starter = mDependency.injectMockDependency(ActivityStarter.class);
BroadcastSender broadcastSender = mDependency.injectMockDependency(BroadcastSender.class);
mPowerNotificationWarnings = new PowerNotificationWarnings(wrapper, starter,
- broadcastSender, () -> mBatteryController, mDialogLaunchAnimator);
+ broadcastSender, () -> mBatteryController, mDialogLaunchAnimator, mUiEventLogger);
BatteryStateSnapshot snapshot = new BatteryStateSnapshot(100, false, false, 1,
BatteryManager.BATTERY_HEALTH_GOOD, 5, 15);
mPowerNotificationWarnings.updateSnapshot(snapshot);
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 f5d19e2..a518b80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -190,7 +190,7 @@
QSFragment fragment = resumeAndGetFragment();
enableSplitShade();
setStatusBarState(StatusBarState.KEYGUARD);
- when(mQSPanelController.bouncerInTransit()).thenReturn(false);
+ when(mQSPanelController.isBouncerInTransit()).thenReturn(false);
int transitionPxAmount = 123;
float transitionProgress = 0.5f;
@@ -206,7 +206,7 @@
QSFragment fragment = resumeAndGetFragment();
enableSplitShade();
setStatusBarState(StatusBarState.KEYGUARD);
- when(mQSPanelController.bouncerInTransit()).thenReturn(true);
+ when(mQSPanelController.isBouncerInTransit()).thenReturn(true);
int transitionPxAmount = 123;
float transitionProgress = 0.5f;
@@ -315,6 +315,24 @@
verify(mQuickQSPanelController).setCollapseExpandAction(action);
}
+ @Test
+ public void setOverScrollAmount_setsTranslationOnView() {
+ QSFragment fragment = resumeAndGetFragment();
+
+ fragment.setOverScrollAmount(123);
+
+ assertThat(mQsFragmentView.getTranslationY()).isEqualTo(123);
+ }
+
+ @Test
+ public void setOverScrollAmount_beforeViewCreated_translationIsNotSet() {
+ QSFragment fragment = getFragment();
+
+ fragment.setOverScrollAmount(123);
+
+ assertThat(mQsFragmentView.getTranslationY()).isEqualTo(0);
+ }
+
@Override
protected Fragment instantiate(Context context, String className, Bundle arguments) {
MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
index 689de50..69d3f8b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
@@ -61,7 +61,7 @@
whenever(brightnessSliderFactory.create(any(), any())).thenReturn(brightnessSlider)
whenever(brightnessControllerFactory.create(any())).thenReturn(brightnessController)
whenever(qsPanel.resources).thenReturn(mContext.orCreateTestableResources.resources)
- whenever(statusBarKeyguardViewManager.bouncerIsInTransit()).thenReturn(false)
+ whenever(statusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(false)
controller = QSPanelController(
qsPanel,
@@ -109,10 +109,10 @@
}
@Test
- fun testBouncerIsInTransit() {
- whenever(statusBarKeyguardViewManager.bouncerIsInTransit()).thenReturn(true)
- assertThat(controller.bouncerInTransit()).isEqualTo(true)
- whenever(statusBarKeyguardViewManager.bouncerIsInTransit()).thenReturn(false)
- assertThat(controller.bouncerInTransit()).isEqualTo(false)
+ fun testIsBouncerInTransit() {
+ whenever(statusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(true)
+ assertThat(controller.isBouncerInTransit()).isEqualTo(true)
+ whenever(statusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(false)
+ assertThat(controller.isBouncerInTransit()).isEqualTo(false)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
index 03c22b3..1b1f4e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
@@ -32,6 +32,7 @@
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
+import android.app.Notification;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.ApplicationInfo;
@@ -41,6 +42,7 @@
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Icon;
+import android.os.Bundle;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
@@ -170,4 +172,16 @@
mIconView.getIcon(largeIcon);
// No crash? good
}
+
+ @Test
+ public void testContentDescForNotification_invalidAi_noCrash() {
+ Notification n = new Notification.Builder(mContext, "test")
+ .setSmallIcon(0)
+ .build();
+ // should be ApplicationInfo
+ n.extras.putParcelable(Notification.EXTRA_BUILDER_APPLICATION_INFO, new Bundle());
+ StatusBarIconView.contentDescForNotification(mContext, n);
+
+ // no crash, good
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
index 241451e..5804ad4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
@@ -229,6 +229,41 @@
assertTrue(entry.isLastMessageFromReply());
}
+ @Test
+ public void notificationDataEntry_testIsLastMessageFromReply_invalidPerson_noCrash() {
+ Person.Builder person = new Person.Builder()
+ .setName("name")
+ .setKey("abc")
+ .setUri("uri")
+ .setBot(true);
+
+ Bundle bundle = new Bundle();
+ // should be Person.class
+ bundle.putParcelable(Notification.EXTRA_MESSAGING_PERSON, new Bundle());
+ Bundle[] messagesBundle = new Bundle[]{new Notification.MessagingStyle.Message(
+ "text", 0, person.build()).toBundle()};
+ bundle.putParcelableArray(Notification.EXTRA_MESSAGES, messagesBundle);
+
+ Notification notification = new Notification.Builder(mContext, "test")
+ .addExtras(bundle)
+ .build();
+
+ NotificationEntry entry = new NotificationEntryBuilder()
+ .setPkg("pkg")
+ .setOpPkg("pkg")
+ .setTag("tag")
+ .setNotification(notification)
+ .setUser(mContext.getUser())
+ .setOverrideGroupKey("")
+ .build();
+ entry.setHasSentReply();
+
+ entry.isLastMessageFromReply();
+
+ // no crash, good
+ }
+
+
private Notification.Action createContextualAction(String title) {
return new Notification.Action.Builder(
Icon.createWithResource(getContext(), android.R.drawable.sym_def_app_icon),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapperTest.java
new file mode 100644
index 0000000..509ba41
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapperTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.statusbar.notification.row.wrapper;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.Notification;
+import android.content.Context;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+@RunWithLooper
+public class NotificationBigPictureTemplateViewWrapperTest extends SysuiTestCase {
+
+ private View mView;
+ private ExpandableNotificationRow mRow;
+
+
+ @Before
+ public void setup() throws Exception {
+ allowTestableLooperAsMainThread();
+ NotificationTestHelper helper = new NotificationTestHelper(
+ mContext,
+ mDependency,
+ TestableLooper.get(this));
+ mView = LayoutInflater.from(mContext).inflate(
+ com.android.internal.R.layout.notification_template_material_big_picture, null);
+ mRow = helper.createRow();
+ }
+
+ @Test
+ public void invalidLargeIconBig_noCrash() {
+ NotificationViewWrapper wrapper = new NotificationBigPictureTemplateViewWrapper(
+ mContext, mView, mRow);
+ // should be Icon.class
+ mRow.getEntry().getSbn().getNotification().setSmallIcon(
+ Icon.createWithResource(mContext, 0));
+ mRow.getEntry().getSbn().getNotification().extras.putParcelable(
+ Notification.EXTRA_LARGE_ICON_BIG, new Bundle());
+ wrapper.onContentUpdated(mRow);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 7a92b96..077f6bf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -64,6 +64,7 @@
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import org.junit.Assert;
@@ -104,6 +105,7 @@
@Mock private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
@Mock private NotificationShelf mNotificationShelf;
@Mock private NotificationStackSizeCalculator mNotificationStackSizeCalculator;
+ @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Before
@UiThreadTest
@@ -111,7 +113,8 @@
allowTestableLooperAsMainThread();
// Interact with real instance of AmbientState.
- mAmbientState = new AmbientState(mContext, mNotificationSectionsManager, mBypassController);
+ mAmbientState = new AmbientState(mContext, mNotificationSectionsManager, mBypassController,
+ mStatusBarKeyguardViewManager);
// Inject dependencies before initializing the layout
mDependency.injectTestDependency(SysuiStatusBarStateController.class, mBarState);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
index dfd70a2..968e16a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.stack
+import android.annotation.DimenRes
import android.service.notification.StatusBarNotification
import android.testing.AndroidTestingRunner
import android.view.View.VISIBLE
@@ -27,6 +28,7 @@
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.nullable
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -34,8 +36,8 @@
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.mock
-import org.mockito.MockitoAnnotations
import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -49,17 +51,15 @@
private lateinit var sizeCalculator: NotificationStackSizeCalculator
+ private val gapHeight = px(R.dimen.notification_section_divider_height)
+ private val dividerHeight = px(R.dimen.notification_divider_height)
+ private val shelfHeight = px(R.dimen.notification_shelf_height)
+ private val rowHeight = px(R.dimen.notification_max_height)
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- whenever(stackLayout.calculateGapHeight(nullable(), nullable(), any()))
- .thenReturn(GAP_HEIGHT)
- with(testableResources) {
- addOverride(R.integer.keyguard_max_notification_count, -1)
- addOverride(R.dimen.notification_divider_height, DIVIDER_HEIGHT.toInt())
- }
-
sizeCalculator =
NotificationStackSizeCalculator(
statusBarStateController = sysuiStatusBarStateController,
@@ -68,7 +68,7 @@
@Test
fun computeMaxKeyguardNotifications_zeroSpace_returnZero() {
- val rows = listOf(createMockRow(height = ROW_HEIGHT))
+ val rows = listOf(createMockRow(height = rowHeight))
val maxNotifications =
computeMaxKeyguardNotifications(rows, availableSpace = 0f, shelfHeight = 0f)
@@ -87,105 +87,78 @@
}
@Test
- fun computeMaxKeyguardNotifications_spaceForOne_returnsOne() {
- val rowHeight = ROW_HEIGHT
- val totalSpaceForEachRow = GAP_HEIGHT + rowHeight
- val shelfHeight =
- totalSpaceForEachRow / 2 // In this way shelf absence will not leave room for another.
- val spaceForOne = totalSpaceForEachRow
- val rows =
- listOf(
- createMockRow(rowHeight),
- createMockRow(rowHeight))
+ fun computeMaxKeyguardNotifications_spaceForOneAndShelf_returnsOne() {
+ setGapHeight(gapHeight)
+ val shelfHeight = rowHeight / 2 // Shelf absence won't leave room for another row.
+ val availableSpace =
+ listOf(rowHeight + dividerHeight, gapHeight + dividerHeight + shelfHeight).sum()
+ val rows = listOf(createMockRow(rowHeight), createMockRow(rowHeight))
- val maxNotifications =
- computeMaxKeyguardNotifications(
- rows, availableSpace = spaceForOne, shelfHeight = shelfHeight)
-
- assertThat(maxNotifications).isEqualTo(1)
- }
-
- @Test
- fun computeMaxKeyguardNotifications_spaceForOne_shelfUsableForLastNotification_returnsTwo() {
- val rowHeight = ROW_HEIGHT
- val totalSpaceForEachRow = GAP_HEIGHT + rowHeight
- val shelfHeight = totalSpaceForEachRow + DIVIDER_HEIGHT
- val spaceForOne = totalSpaceForEachRow
- val rows =
- listOf(
- createMockRow(rowHeight),
- createMockRow(rowHeight))
-
- val maxNotifications =
- computeMaxKeyguardNotifications(
- rows, availableSpace = spaceForOne, shelfHeight = shelfHeight)
+ val maxNotifications = computeMaxKeyguardNotifications(rows, availableSpace, shelfHeight)
assertThat(maxNotifications).isEqualTo(1)
}
@Test
fun computeMaxKeyguardNotifications_spaceForTwo_returnsTwo() {
- val rowHeight = ROW_HEIGHT
- val totalSpaceForEachRow = GAP_HEIGHT + rowHeight
- val spaceForTwo = totalSpaceForEachRow * 2 + DIVIDER_HEIGHT
- val rows =
+ setGapHeight(gapHeight)
+ val shelfHeight = shelfHeight + dividerHeight
+ val availableSpace =
listOf(
- createMockRow(rowHeight),
- createMockRow(rowHeight),
- createMockRow(rowHeight))
+ rowHeight + dividerHeight,
+ gapHeight + rowHeight + dividerHeight,
+ gapHeight + dividerHeight + shelfHeight)
+ .sum()
+ val rows =
+ listOf(createMockRow(rowHeight), createMockRow(rowHeight), createMockRow(rowHeight))
- val maxNotifications = computeMaxKeyguardNotifications(rows, spaceForTwo, shelfHeight = 0f)
+ val maxNotifications = computeMaxKeyguardNotifications(rows, availableSpace, shelfHeight)
assertThat(maxNotifications).isEqualTo(2)
}
@Test
fun computeHeight_returnsAtMostSpaceAvailable_withGapBeforeShelf() {
- val rowHeight = ROW_HEIGHT
- val shelfHeight = SHELF_HEIGHT
- val totalSpaceForEachRow = GAP_HEIGHT + rowHeight + DIVIDER_HEIGHT
- val availableSpace = totalSpaceForEachRow * 2
+ setGapHeight(gapHeight)
+ val shelfHeight = shelfHeight
+ val availableSpace =
+ listOf(
+ rowHeight + dividerHeight,
+ gapHeight + rowHeight + dividerHeight,
+ gapHeight + dividerHeight + shelfHeight)
+ .sum()
// All rows in separate sections (default setup).
val rows =
- listOf(
- createMockRow(rowHeight),
- createMockRow(rowHeight),
- createMockRow(rowHeight))
+ listOf(createMockRow(rowHeight), createMockRow(rowHeight), createMockRow(rowHeight))
val maxNotifications = computeMaxKeyguardNotifications(rows, availableSpace, shelfHeight)
assertThat(maxNotifications).isEqualTo(2)
- val height = sizeCalculator.computeHeight(stackLayout, maxNotifications, SHELF_HEIGHT)
- assertThat(height).isAtMost(availableSpace + GAP_HEIGHT + SHELF_HEIGHT)
+ val height = sizeCalculator.computeHeight(stackLayout, maxNotifications, this.shelfHeight)
+ assertThat(height).isAtMost(availableSpace)
}
@Test
- fun computeHeight_returnsAtMostSpaceAvailable_noGapBeforeShelf() {
- val rowHeight = ROW_HEIGHT
- val shelfHeight = SHELF_HEIGHT
- val totalSpaceForEachRow = GAP_HEIGHT + rowHeight + DIVIDER_HEIGHT
- val availableSpace = totalSpaceForEachRow * 1
-
+ fun computeHeight_noGapBeforeShelf_returnsAtMostSpaceAvailable() {
// Both rows are in the same section.
- whenever(stackLayout.calculateGapHeight(nullable(), nullable(), any()))
- .thenReturn(0f)
- val rows =
- listOf(
- createMockRow(rowHeight),
- createMockRow(rowHeight))
+ setGapHeight(0f)
+ val rowHeight = rowHeight
+ val shelfHeight = shelfHeight
+ val availableSpace = listOf(rowHeight + dividerHeight, dividerHeight + shelfHeight).sum()
+ val rows = listOf(createMockRow(rowHeight), createMockRow(rowHeight))
val maxNotifications = computeMaxKeyguardNotifications(rows, availableSpace, shelfHeight)
assertThat(maxNotifications).isEqualTo(1)
- val height = sizeCalculator.computeHeight(stackLayout, maxNotifications, SHELF_HEIGHT)
- assertThat(height).isAtMost(availableSpace + SHELF_HEIGHT)
+ val height = sizeCalculator.computeHeight(stackLayout, maxNotifications, this.shelfHeight)
+ assertThat(height).isAtMost(availableSpace)
}
private fun computeMaxKeyguardNotifications(
rows: List<ExpandableView>,
availableSpace: Float,
- shelfHeight: Float = SHELF_HEIGHT
+ shelfHeight: Float = this.shelfHeight
): Int {
setupChildren(rows)
return sizeCalculator.computeMaxKeyguardNotifications(
@@ -204,9 +177,9 @@
(1..number).map { createMockRow() }.toList()
private fun createMockRow(
- height: Float = ROW_HEIGHT,
+ height: Float = rowHeight,
isRemoved: Boolean = false,
- visibility: Int = VISIBLE,
+ visibility: Int = VISIBLE
): ExpandableNotificationRow {
val row = mock(ExpandableNotificationRow::class.java)
val entry = mock(NotificationEntry::class.java)
@@ -220,11 +193,12 @@
return row
}
- /** Default dimensions for tests that don't overwrite them. */
- companion object {
- const val GAP_HEIGHT = 12f
- const val DIVIDER_HEIGHT = 3f
- const val SHELF_HEIGHT = 14f
- const val ROW_HEIGHT = SHELF_HEIGHT * 3
+ private fun setGapHeight(height: Float) {
+ whenever(stackLayout.calculateGapHeight(nullable(), nullable(), any())).thenReturn(height)
+ whenever(stackLayout.calculateGapHeight(nullable(), nullable(), /* visibleIndex= */ eq(0)))
+ .thenReturn(0f)
}
+
+ private fun px(@DimenRes id: Int): Float =
+ testableResources.resources.getDimensionPixelSize(id).toFloat()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index 1da9bbc..6b4dc58 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -8,6 +8,7 @@
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.BypassController
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
@@ -21,10 +22,14 @@
private val stackScrollAlgorithm = StackScrollAlgorithm(context, hostView)
private val expandableViewState = ExpandableViewState()
private val notificationRow = mock(ExpandableNotificationRow::class.java)
+ private val mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager::class.java)
+
private val ambientState = AmbientState(
- context,
- SectionProvider { _, _ -> false },
- BypassController { false })
+ context,
+ SectionProvider { _, _ -> false },
+ BypassController { false },
+ mStatusBarKeyguardViewManager
+ )
@Before
fun setUp() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 0e12c2a..03a6c19 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -58,6 +58,7 @@
import com.android.systemui.statusbar.policy.DataSaverController;
import com.android.systemui.statusbar.policy.DeviceControlsController;
import com.android.systemui.statusbar.policy.HotspotController;
+import com.android.systemui.statusbar.policy.SafetyController;
import com.android.systemui.statusbar.policy.WalletController;
import com.android.systemui.util.settings.FakeSettings;
import com.android.systemui.util.settings.SecureSettings;
@@ -101,6 +102,7 @@
@Mock private ReduceBrightColorsController mReduceBrightColorsController;
@Mock private DeviceControlsController mDeviceControlsController;
@Mock private WalletController mWalletController;
+ @Mock private SafetyController mSafetyController;
@Mock(answer = Answers.RETURNS_SELF)
private AutoAddTracker.Builder mAutoAddTrackerBuilder;
@Mock private Context mUserContext;
@@ -150,6 +152,7 @@
ReduceBrightColorsController reduceBrightColorsController,
DeviceControlsController deviceControlsController,
WalletController walletController,
+ SafetyController safetyController,
@Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) {
return new AutoTileManager(context, autoAddTrackerBuilder, mQsTileHost,
Handler.createAsync(TestableLooper.get(this).getLooper()),
@@ -162,6 +165,7 @@
reduceBrightColorsController,
deviceControlsController,
walletController,
+ safetyController,
isReduceBrightColorsAvailable);
}
@@ -169,7 +173,7 @@
return createAutoTileManager(context, mAutoAddTrackerBuilder, mHotspotController,
mDataSaverController, mManagedProfileController, mNightDisplayListener,
mCastController, mReduceBrightColorsController, mDeviceControlsController,
- mWalletController, mIsReduceBrightColorsAvailable);
+ mWalletController, mSafetyController, mIsReduceBrightColorsAvailable);
}
@Test
@@ -185,10 +189,11 @@
ReduceBrightColorsController rBC = mock(ReduceBrightColorsController.class);
DeviceControlsController dCC = mock(DeviceControlsController.class);
WalletController wC = mock(WalletController.class);
+ SafetyController sC = mock(SafetyController.class);
AutoTileManager manager =
createAutoTileManager(mock(Context.class), builder, hC, dSC, mPC, nDS, cC, rBC,
- dCC, wC, true);
+ dCC, wC, sC, true);
verify(tracker, never()).initialize();
verify(hC, never()).addCallback(any());
@@ -199,6 +204,7 @@
verify(rBC, never()).addCallback(any());
verify(dCC, never()).setCallback(any());
verify(wC, never()).getWalletPosition();
+ verify(sC, never()).addCallback(any());
assertNull(manager.getSecureSettingForKey(TEST_SETTING));
assertNull(manager.getSecureSettingForKey(TEST_SETTING_COMPONENT));
}
@@ -253,6 +259,10 @@
verify(mWalletController, times(2)).getWalletPosition();
+ InOrder inOrderSafety = inOrder(mSafetyController);
+ inOrderSafety.verify(mSafetyController).removeCallback(any());
+ inOrderSafety.verify(mSafetyController).addCallback(any());
+
SettingObserver setting = mAutoTileManager.getSecureSettingForKey(TEST_SETTING);
assertEquals(USER + 1, setting.getCurrentUser());
assertTrue(setting.isListening());
@@ -303,6 +313,10 @@
verify(mWalletController, times(2)).getWalletPosition();
+ InOrder inOrderSafety = inOrder(mSafetyController);
+ inOrderSafety.verify(mSafetyController).removeCallback(any());
+ inOrderSafety.verify(mSafetyController).addCallback(any());
+
SettingObserver setting = mAutoTileManager.getSecureSettingForKey(TEST_SETTING);
assertEquals(USER + 1, setting.getCurrentUser());
assertFalse(setting.isListening());
@@ -457,6 +471,26 @@
mAutoTileManager.changeUser(UserHandle.of(USER + 1));
verify(mQsTileHost, times(2)).addTile(safetyComponent, true);
}
+
+ @Test
+ public void testSafetyTileRemoved_onSafetyCenterDisable() {
+ ComponentName safetyComponent = CustomTile.getComponentFromSpec(TEST_CUSTOM_SAFETY_SPEC);
+ mAutoTileManager.init();
+ when(mAutoAddTracker.isAdded(TEST_CUSTOM_SAFETY_SPEC)).thenReturn(true);
+ mAutoTileManager.mSafetyCallback.onSafetyCenterEnableChanged(false);
+ verify(mQsTileHost, times(1)).removeTile(safetyComponent);
+ }
+
+ @Test
+ public void testSafetyTileAdded_onSafetyCenterEnable() {
+ ComponentName safetyComponent = CustomTile.getComponentFromSpec(TEST_CUSTOM_SAFETY_SPEC);
+ mAutoTileManager.init();
+ verify(mQsTileHost, times(1)).addTile(safetyComponent, true);
+ mAutoTileManager.mSafetyCallback.onSafetyCenterEnableChanged(false);
+ mAutoTileManager.mSafetyCallback.onSafetyCenterEnableChanged(true);
+ verify(mQsTileHost, times(2)).addTile(safetyComponent, true);
+ }
+
@Test
public void testEmptyArray_doesNotCrash() {
mContext.getOrCreateTestableResources().addOverride(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
index 09773d3..05fb1f59 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
@@ -80,6 +80,7 @@
import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
+import com.android.systemui.DejankUtils;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.AuthController;
@@ -352,6 +353,7 @@
mKeyguardStatusView = new KeyguardStatusView(mContext);
mKeyguardStatusView.setId(R.id.keyguard_status_view);
+ DejankUtils.setImmediate(true);
when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false);
when(mHeadsUpCallback.getContext()).thenReturn(mContext);
@@ -942,6 +944,29 @@
}
@Test
+ public void testUnlockHintAnimation_runs_whenNotInPowerSaveMode_andDozeAmountIsZero() {
+ when(mPowerManager.isPowerSaveMode()).thenReturn(false);
+ when(mAmbientState.getDozeAmount()).thenReturn(0f);
+ mNotificationPanelViewController.startUnlockHintAnimation();
+ assertThat(mNotificationPanelViewController.mHintAnimationRunning).isTrue();
+ }
+
+ @Test
+ public void testUnlockHintAnimation_doesNotRun_inPowerSaveMode() {
+ when(mPowerManager.isPowerSaveMode()).thenReturn(true);
+ mNotificationPanelViewController.startUnlockHintAnimation();
+ assertThat(mNotificationPanelViewController.mHintAnimationRunning).isFalse();
+ }
+
+ @Test
+ public void testUnlockHintAnimation_doesNotRun_whenDozeAmountNotZero() {
+ when(mPowerManager.isPowerSaveMode()).thenReturn(false);
+ when(mAmbientState.getDozeAmount()).thenReturn(0.5f);
+ mNotificationPanelViewController.startUnlockHintAnimation();
+ assertThat(mNotificationPanelViewController.mHintAnimationRunning).isFalse();
+ }
+
+ @Test
public void setKeyguardStatusBarAlpha_setsAlphaOnKeyguardStatusBarController() {
float statusBarAlpha = 0.5f;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 69d7932..ff2c05b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -1238,7 +1238,7 @@
@Test
public void expansionNotificationAlpha_shadeLocked_bouncerActive_usesBouncerInterpolator() {
- when(mStatusBarKeyguardViewManager.bouncerIsInTransit()).thenReturn(true);
+ when(mStatusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(true);
mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
@@ -1254,7 +1254,7 @@
@Test
public void expansionNotificationAlpha_shadeLocked_bouncerNotActive_usesShadeInterpolator() {
- when(mStatusBarKeyguardViewManager.bouncerIsInTransit()).thenReturn(false);
+ when(mStatusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(false);
mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
@@ -1269,7 +1269,7 @@
@Test
public void notificationAlpha_unnocclusionAnimating_bouncerActive_usesKeyguardNotifAlpha() {
- when(mStatusBarKeyguardViewManager.bouncerIsInTransit()).thenReturn(true);
+ when(mStatusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(true);
mScrimController.transitionTo(ScrimState.KEYGUARD);
mScrimController.setUnocclusionAnimationRunning(true);
@@ -1290,7 +1290,7 @@
@Test
public void notificationAlpha_unnocclusionAnimating_bouncerNotActive_usesKeyguardNotifAlpha() {
- when(mStatusBarKeyguardViewManager.bouncerIsInTransit()).thenReturn(false);
+ when(mStatusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(false);
mScrimController.transitionTo(ScrimState.KEYGUARD);
mScrimController.setUnocclusionAnimationRunning(true);
@@ -1311,7 +1311,7 @@
@Test
public void notificationAlpha_inKeyguardState_bouncerActive_usesInvertedBouncerInterpolator() {
- when(mStatusBarKeyguardViewManager.bouncerIsInTransit()).thenReturn(true);
+ when(mStatusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(true);
mScrimController.transitionTo(ScrimState.KEYGUARD);
@@ -1330,7 +1330,7 @@
@Test
public void notificationAlpha_inKeyguardState_bouncerNotActive_usesInvertedShadeInterpolator() {
- when(mStatusBarKeyguardViewManager.bouncerIsInTransit()).thenReturn(false);
+ when(mStatusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(false);
mScrimController.transitionTo(ScrimState.KEYGUARD);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 90cbf54..2b01872 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -438,12 +438,12 @@
}
@Test
- public void testBouncerIsInTransit() {
+ public void testIsBouncerInTransit() {
when(mBouncer.inTransit()).thenReturn(true);
- Truth.assertThat(mStatusBarKeyguardViewManager.bouncerIsInTransit()).isTrue();
+ Truth.assertThat(mStatusBarKeyguardViewManager.isBouncerInTransit()).isTrue();
when(mBouncer.inTransit()).thenReturn(false);
- Truth.assertThat(mStatusBarKeyguardViewManager.bouncerIsInTransit()).isFalse();
+ Truth.assertThat(mStatusBarKeyguardViewManager.isBouncerInTransit()).isFalse();
mBouncer = null;
- Truth.assertThat(mStatusBarKeyguardViewManager.bouncerIsInTransit()).isFalse();
+ Truth.assertThat(mStatusBarKeyguardViewManager.isBouncerInTransit()).isFalse();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt
new file mode 100644
index 0000000..89989ce
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt
@@ -0,0 +1,133 @@
+/*
+ * 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.statusbar.policy
+
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.content.pm.PackageManager
+import android.net.Uri
+import android.os.Handler
+import android.safetycenter.SafetyCenterManager
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.any
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.ArgumentMatchers.same
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class SafetyControllerTest : SysuiTestCase() {
+
+ private val TEST_PC_PKG = "testPermissionControllerPackageName"
+ private val OTHER_PKG = "otherPackageName"
+
+ @Mock
+ private lateinit var context: Context
+ @Mock
+ private lateinit var scm: SafetyCenterManager
+ @Mock
+ private lateinit var pm: PackageManager
+ @Mock
+ private lateinit var handler: Handler
+ @Mock
+ private lateinit var listener: SafetyController.Listener
+
+ private val packageDataScheme = "package"
+
+ private lateinit var controller: SafetyController
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ `when`(pm.permissionControllerPackageName).thenReturn(TEST_PC_PKG)
+ `when`(scm.isSafetyCenterEnabled).thenReturn(false)
+ `when`(handler.post(any(Runnable::class.java))).thenAnswer {
+ (it.arguments[0] as Runnable).run()
+ true
+ }
+
+ controller = SafetyController(context, pm, scm, handler)
+ }
+
+ @Test
+ fun addingFirstListenerRegistersReceiver() {
+ `when`(scm.isSafetyCenterEnabled).thenReturn(true)
+ controller.addCallback(listener)
+ verify(listener, times(1)).onSafetyCenterEnableChanged(true)
+ val filter = ArgumentCaptor.forClass(IntentFilter::class.java)
+ verify(context, times(1)).registerReceiver(
+ same(controller.mPermControllerChangeReceiver), filter.capture())
+ assertEquals(Intent.ACTION_PACKAGE_CHANGED, filter.value.getAction(0))
+ assertEquals(packageDataScheme, filter.value.getDataScheme(0))
+ }
+
+ @Test
+ fun removingLastListenerDeregistersReceiver() {
+ controller.addCallback(listener)
+ controller.removeCallback(listener)
+ verify(context, times(1)).unregisterReceiver(
+ eq(controller.mPermControllerChangeReceiver))
+ }
+
+ @Test
+ fun listenersCalledWhenBroadcastReceivedWithPCPackageAndStateChange() {
+ `when`(scm.isSafetyCenterEnabled).thenReturn(false)
+ controller.addCallback(listener)
+ reset(listener)
+ `when`(scm.isSafetyCenterEnabled).thenReturn(true)
+ val testIntent = Intent(Intent.ACTION_PACKAGE_CHANGED)
+ testIntent.data = Uri.parse("package:$TEST_PC_PKG")
+ controller.mPermControllerChangeReceiver.onReceive(context, testIntent)
+ verify(listener, times(1)).onSafetyCenterEnableChanged(true)
+ }
+
+ @Test
+ fun listenersNotCalledWhenBroadcastReceivedWithOtherPackage() {
+ `when`(scm.isSafetyCenterEnabled).thenReturn(true)
+ controller.addCallback(listener)
+ reset(listener)
+ val testIntent = Intent(Intent.ACTION_PACKAGE_CHANGED)
+ testIntent.data = Uri.parse("package:$OTHER_PKG")
+ controller.mPermControllerChangeReceiver.onReceive(context, testIntent)
+ verify(listener, never()).onSafetyCenterEnableChanged(true)
+ }
+
+ @Test
+ fun listenersNotCalledWhenBroadcastReceivedWithNoStateChange() {
+ `when`(scm.isSafetyCenterEnabled).thenReturn(false)
+ controller.addCallback(listener)
+ reset(listener)
+ val testIntent = Intent(Intent.ACTION_PACKAGE_CHANGED)
+ testIntent.data = Uri.parse("package:$TEST_PC_PKG")
+ controller.mPermControllerChangeReceiver.onReceive(context, testIntent)
+ verify(listener, never()).onSafetyCenterEnableChanged(true)
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
index 7ac2434..05a8f0a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
@@ -78,6 +78,9 @@
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
+ overrideResource(
+ com.android.internal.R.integer.config_unfoldTransitionHalfFoldedTimeout,
+ HALF_OPENED_TIMEOUT_MILLIS.toInt())
deviceStates = FoldableTestUtils.findDeviceStates(context)
foldStateProvider =
@@ -319,4 +322,8 @@
private fun sendHingeAngleEvent(angle: Int) {
hingeAngleCaptor.value.accept(angle.toFloat())
}
+
+ companion object {
+ private const val HALF_OPENED_TIMEOUT_MILLIS = 300L
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
index 3d55488..b30c20d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
@@ -21,11 +21,16 @@
import android.hardware.usb.UsbAccessory
import android.hardware.usb.UsbManager
import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
import android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS
import androidx.test.filters.SmallTest
import androidx.test.rule.ActivityTestRule
+import androidx.test.runner.intercepting.SingleActivityFactory
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
+
+import javax.inject.Inject
+
import org.junit.After
import org.junit.Before
import org.junit.Rule
@@ -37,14 +42,26 @@
*/
@RunWith(AndroidTestingRunner::class)
@SmallTest
+@TestableLooper.RunWithLooper
class UsbPermissionActivityTest : SysuiTestCase() {
- class UsbPermissionActivityTestable : UsbPermissionActivity()
+ private var mMessage: UsbAudioWarningDialogMessage = UsbAudioWarningDialogMessage()
+
+ open class UsbPermissionActivityTestable @Inject constructor (
+ val message: UsbAudioWarningDialogMessage
+ )
+ : UsbPermissionActivity(UsbAudioWarningDialogMessage())
@Rule
@JvmField
var activityRule = ActivityTestRule<UsbPermissionActivityTestable>(
- UsbPermissionActivityTestable::class.java, false, false)
+ object : SingleActivityFactory<UsbPermissionActivityTestable>(
+ UsbPermissionActivityTestable::class.java
+ ) {
+ override fun create(intent: Intent?): UsbPermissionActivityTestable {
+ return UsbPermissionActivityTestable(mMessage)
+ }
+ }, false, false)
private val activityIntent = Intent(mContext, UsbPermissionActivityTestable::class.java)
.apply {
@@ -72,6 +89,7 @@
@Before
fun setUp() {
+ UsbPermissionActivityTestable(mMessage)
activityRule.launchActivity(activityIntent)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java
index 01769e5..b1950ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java
@@ -20,6 +20,7 @@
import static android.view.View.VISIBLE;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -323,6 +324,7 @@
assertEquals(GONE, mWalletView.getCardCarousel().getVisibility());
assertEquals(VISIBLE, mWalletView.getEmptyStateView().getVisibility());
assertEquals(GONE, mWalletView.getErrorView().getVisibility());
+ assertTrue(mWalletView.getAppButton().hasOnClickListeners());
}
@Test
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 5ef1008..562d11a 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -69,6 +69,7 @@
import android.os.SystemClock;
import android.os.Trace;
import android.provider.Settings;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
@@ -218,12 +219,6 @@
@NonNull KeyEventDispatcher getKeyEventDispatcher();
/**
- * @param windowId The id of the window of interest
- * @return The magnification spec for the window, or {@code null} if none is available
- */
- @Nullable MagnificationSpec getCompatibleMagnificationSpecLocked(int windowId);
-
- /**
* @param displayId The display id.
* @return The current injector of motion events used on the display, if one exists.
*/
@@ -557,7 +552,8 @@
final int resolvedWindowId;
RemoteAccessibilityConnection connection;
Region partialInteractiveRegion = Region.obtain();
- MagnificationSpec spec;
+ final MagnificationSpec spec;
+ final float[] transformMatrix;
synchronized (mLock) {
mUsesAccessibilityCache = true;
if (!hasRightsToCurrentUserLocked()) {
@@ -581,7 +577,10 @@
partialInteractiveRegion.recycle();
partialInteractiveRegion = null;
}
- spec = mSystemSupport.getCompatibleMagnificationSpecLocked(resolvedWindowId);
+ final Pair<float[], MagnificationSpec> transformMatrixAndSpec =
+ getTransformMatrixAndSpecLocked(resolvedWindowId);
+ transformMatrix = transformMatrixAndSpec.first;
+ spec = transformMatrixAndSpec.second;
}
if (!mSecurityPolicy.checkAccessibilityAccess(this)) {
return null;
@@ -594,12 +593,12 @@
logTraceIntConn("findAccessibilityNodeInfosByViewId",
accessibilityNodeId + ";" + viewIdResName + ";" + partialInteractiveRegion + ";"
+ interactionId + ";" + callback + ";" + mFetchFlags + ";" + interrogatingPid
- + ";" + interrogatingTid + ";" + spec);
+ + ";" + interrogatingTid + ";" + spec + ";" + Arrays.toString(transformMatrix));
}
try {
connection.getRemote().findAccessibilityNodeInfosByViewId(accessibilityNodeId,
viewIdResName, partialInteractiveRegion, interactionId, callback, mFetchFlags,
- interrogatingPid, interrogatingTid, spec);
+ interrogatingPid, interrogatingTid, spec, transformMatrix);
return mSecurityPolicy.computeValidReportedPackages(
connection.getPackageName(), connection.getUid());
} catch (RemoteException re) {
@@ -630,7 +629,8 @@
final int resolvedWindowId;
RemoteAccessibilityConnection connection;
Region partialInteractiveRegion = Region.obtain();
- MagnificationSpec spec;
+ final MagnificationSpec spec;
+ final float [] transformMatrix;
synchronized (mLock) {
mUsesAccessibilityCache = true;
if (!hasRightsToCurrentUserLocked()) {
@@ -654,7 +654,10 @@
partialInteractiveRegion.recycle();
partialInteractiveRegion = null;
}
- spec = mSystemSupport.getCompatibleMagnificationSpecLocked(resolvedWindowId);
+ final Pair<float[], MagnificationSpec> transformMatrixAndSpec =
+ getTransformMatrixAndSpecLocked(resolvedWindowId);
+ transformMatrix = transformMatrixAndSpec.first;
+ spec = transformMatrixAndSpec.second;
}
if (!mSecurityPolicy.checkAccessibilityAccess(this)) {
return null;
@@ -667,12 +670,12 @@
logTraceIntConn("findAccessibilityNodeInfosByText",
accessibilityNodeId + ";" + text + ";" + partialInteractiveRegion + ";"
+ interactionId + ";" + callback + ";" + mFetchFlags + ";" + interrogatingPid
- + ";" + interrogatingTid + ";" + spec);
+ + ";" + interrogatingTid + ";" + spec + ";" + Arrays.toString(transformMatrix));
}
try {
connection.getRemote().findAccessibilityNodeInfosByText(accessibilityNodeId,
text, partialInteractiveRegion, interactionId, callback, mFetchFlags,
- interrogatingPid, interrogatingTid, spec);
+ interrogatingPid, interrogatingTid, spec, transformMatrix);
return mSecurityPolicy.computeValidReportedPackages(
connection.getPackageName(), connection.getUid());
} catch (RemoteException re) {
@@ -704,7 +707,8 @@
final int resolvedWindowId;
RemoteAccessibilityConnection connection;
Region partialInteractiveRegion = Region.obtain();
- MagnificationSpec spec;
+ final MagnificationSpec spec;
+ final float[] transformMatrix;
synchronized (mLock) {
mUsesAccessibilityCache = true;
if (!hasRightsToCurrentUserLocked()) {
@@ -728,7 +732,10 @@
partialInteractiveRegion.recycle();
partialInteractiveRegion = null;
}
- spec = mSystemSupport.getCompatibleMagnificationSpecLocked(resolvedWindowId);
+ final Pair<float[], MagnificationSpec> transformMatrixAndSpec =
+ getTransformMatrixAndSpecLocked(resolvedWindowId);
+ transformMatrix = transformMatrixAndSpec.first;
+ spec = transformMatrixAndSpec.second;
}
if (!mSecurityPolicy.checkAccessibilityAccess(this)) {
return null;
@@ -741,12 +748,14 @@
logTraceIntConn("findAccessibilityNodeInfoByAccessibilityId",
accessibilityNodeId + ";" + partialInteractiveRegion + ";" + interactionId + ";"
+ callback + ";" + (mFetchFlags | flags) + ";" + interrogatingPid + ";"
- + interrogatingTid + ";" + spec + ";" + arguments);
+ + interrogatingTid + ";" + spec + ";" + Arrays.toString(transformMatrix)
+ + ";" + arguments);
}
try {
connection.getRemote().findAccessibilityNodeInfoByAccessibilityId(
accessibilityNodeId, partialInteractiveRegion, interactionId, callback,
- mFetchFlags | flags, interrogatingPid, interrogatingTid, spec, arguments);
+ mFetchFlags | flags, interrogatingPid, interrogatingTid, spec, transformMatrix,
+ arguments);
return mSecurityPolicy.computeValidReportedPackages(
connection.getPackageName(), connection.getUid());
} catch (RemoteException re) {
@@ -778,7 +787,8 @@
final int resolvedWindowId;
RemoteAccessibilityConnection connection;
Region partialInteractiveRegion = Region.obtain();
- MagnificationSpec spec;
+ final MagnificationSpec spec;
+ final float[] transformMatrix;
synchronized (mLock) {
if (!hasRightsToCurrentUserLocked()) {
return null;
@@ -802,7 +812,10 @@
partialInteractiveRegion.recycle();
partialInteractiveRegion = null;
}
- spec = mSystemSupport.getCompatibleMagnificationSpecLocked(resolvedWindowId);
+ final Pair<float[], MagnificationSpec> transformMatrixAndSpec =
+ getTransformMatrixAndSpecLocked(resolvedWindowId);
+ transformMatrix = transformMatrixAndSpec.first;
+ spec = transformMatrixAndSpec.second;
}
if (!mSecurityPolicy.checkAccessibilityAccess(this)) {
return null;
@@ -815,12 +828,13 @@
logTraceIntConn("findFocus",
accessibilityNodeId + ";" + focusType + ";" + partialInteractiveRegion + ";"
+ interactionId + ";" + callback + ";" + mFetchFlags + ";" + interrogatingPid
- + ";" + interrogatingTid + ";" + spec);
+ + ";" + interrogatingTid + ";" + spec + ";"
+ + Arrays.toString(transformMatrix));
}
try {
connection.getRemote().findFocus(accessibilityNodeId, focusType,
partialInteractiveRegion, interactionId, callback, mFetchFlags,
- interrogatingPid, interrogatingTid, spec);
+ interrogatingPid, interrogatingTid, spec, transformMatrix);
return mSecurityPolicy.computeValidReportedPackages(
connection.getPackageName(), connection.getUid());
} catch (RemoteException re) {
@@ -852,7 +866,8 @@
final int resolvedWindowId;
RemoteAccessibilityConnection connection;
Region partialInteractiveRegion = Region.obtain();
- MagnificationSpec spec;
+ final MagnificationSpec spec;
+ final float[] transformMatrix;
synchronized (mLock) {
if (!hasRightsToCurrentUserLocked()) {
return null;
@@ -875,7 +890,11 @@
partialInteractiveRegion.recycle();
partialInteractiveRegion = null;
}
- spec = mSystemSupport.getCompatibleMagnificationSpecLocked(resolvedWindowId);
+
+ final Pair<float[], MagnificationSpec> transformMatrixAndSpec =
+ getTransformMatrixAndSpecLocked(resolvedWindowId);
+ transformMatrix = transformMatrixAndSpec.first;
+ spec = transformMatrixAndSpec.second;
}
if (!mSecurityPolicy.checkAccessibilityAccess(this)) {
return null;
@@ -888,12 +907,13 @@
logTraceIntConn("focusSearch",
accessibilityNodeId + ";" + direction + ";" + partialInteractiveRegion
+ ";" + interactionId + ";" + callback + ";" + mFetchFlags + ";"
- + interrogatingPid + ";" + interrogatingTid + ";" + spec);
+ + interrogatingPid + ";" + interrogatingTid + ";" + spec + ";"
+ + Arrays.toString(transformMatrix));
}
try {
connection.getRemote().focusSearch(accessibilityNodeId, direction,
partialInteractiveRegion, interactionId, callback, mFetchFlags,
- interrogatingPid, interrogatingTid, spec);
+ interrogatingPid, interrogatingTid, spec, transformMatrix);
return mSecurityPolicy.computeValidReportedPackages(
connection.getPackageName(), connection.getUid());
} catch (RemoteException re) {
@@ -1652,6 +1672,23 @@
mInvocationHandler.startInputLocked(startInputToken, inputContext, editorInfo, restarting);
}
+
+
+ @Nullable
+ Pair<float[], MagnificationSpec> getTransformMatrixAndSpecLocked(int resolvedWindowId) {
+ final WindowInfo windowInfo =
+ mA11yWindowManager.findWindowInfoByIdLocked(resolvedWindowId);
+ if (windowInfo == null) {
+ Slog.w(LOG_TAG, "getTransformMatrixAndSpec, windowInfo is null window id = "
+ + resolvedWindowId);
+ return new Pair<>(null, null);
+ }
+
+ final MagnificationSpec spec = new MagnificationSpec();
+ spec.setTo(windowInfo.mMagnificationSpec);
+ return new Pair<>(windowInfo.mTransformMatrix, spec);
+ }
+
/**
* Called by the invocation handler to notify the service that the
* state of magnification has changed.
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index e3226c7..ac0c051 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -106,6 +106,7 @@
import android.view.KeyEvent;
import android.view.MagnificationSpec;
import android.view.MotionEvent;
+import android.view.WindowInfo;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityInteractionClient;
@@ -3045,22 +3046,6 @@
userState.setInteractiveUiTimeoutLocked(newInteractiveUiTimeout);
}
- @GuardedBy("mLock")
- @Override
- public MagnificationSpec getCompatibleMagnificationSpecLocked(int windowId) {
- IBinder windowToken = mA11yWindowManager.getWindowTokenForUserAndWindowIdLocked(
- mCurrentUserId, windowId);
- if (windowToken != null) {
- if (mTraceManager.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MANAGER_INTERNAL)) {
- mTraceManager.logTrace(LOG_TAG + ".getCompatibleMagnificationSpecForWindow",
- FLAGS_WINDOW_MANAGER_INTERNAL, "windowToken=" + windowToken);
- }
-
- return mWindowManagerService.getCompatibleMagnificationSpecForWindow(windowToken);
- }
- return null;
- }
-
@Override
public KeyEventDispatcher getKeyEventDispatcher() {
if (mKeyEventDispatcher == null) {
@@ -3741,7 +3726,14 @@
boundsInScreenBeforeMagnification.centerY());
// Invert magnification if needed.
- MagnificationSpec spec = getCompatibleMagnificationSpecLocked(focus.getWindowId());
+ final WindowInfo windowInfo = mA11yWindowManager.findWindowInfoByIdLocked(
+ focus.getWindowId());
+ MagnificationSpec spec = null;
+ if (windowInfo != null) {
+ spec = new MagnificationSpec();
+ spec.setTo(windowInfo.mMagnificationSpec);
+ }
+
if (spec != null && !spec.isNop()) {
boundsInScreenBeforeMagnification.offset((int) -spec.offsetX,
(int) -spec.offsetY);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index aba32ec..e30639c 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -52,6 +52,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -478,6 +479,9 @@
if (oldWindow.taskId != newWindow.taskId) {
return true;
}
+ if (!Arrays.equals(oldWindow.mTransformMatrix, newWindow.mTransformMatrix)) {
+ return true;
+ }
return false;
}
@@ -800,14 +804,24 @@
pw.append(',');
pw.println();
}
- pw.append("Window[");
+ pw.append("A11yWindow[");
AccessibilityWindowInfo window = mWindows.get(j);
pw.append(window.toString());
pw.append(']');
+ pw.println();
+ final WindowInfo windowInfo = findWindowInfoByIdLocked(window.getId());
+ if (windowInfo != null) {
+ pw.append("WindowInfo[");
+ pw.append(windowInfo.toString());
+ pw.append("]");
+ pw.println();
+ }
+
}
pw.println();
}
}
+
}
/**
* Interface to send {@link AccessibilityEvent}.
diff --git a/services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java b/services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java
index 6828dd9..6958b66 100644
--- a/services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java
+++ b/services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java
@@ -83,7 +83,7 @@
mConnectionWithReplacementActions.findAccessibilityNodeInfoByAccessibilityId(
AccessibilityNodeInfo.ROOT_NODE_ID, null,
mNodeWithReplacementActionsInteractionId, this, 0,
- interrogatingPid, interrogatingTid, null, null);
+ interrogatingPid, interrogatingTid, null, null, null);
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfoByAccessibilityId()");
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index bc4b2a6..5acae48 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -154,7 +154,7 @@
private static final String TAG = "AppWidgetServiceImpl";
private static final boolean DEBUG = false;
- private static final boolean DEBUG_PROVIDER_INFO_CACHE = true;
+ static final boolean DEBUG_PROVIDER_INFO_CACHE = true;
private static final String OLD_KEYGUARD_HOST_PACKAGE = "android";
private static final String NEW_KEYGUARD_HOST_PACKAGE = "com.android.keyguard";
@@ -2001,6 +2001,7 @@
}
}
+ @GuardedBy("mLock")
private void scheduleNotifyProviderChangedLocked(Widget widget) {
long requestId = UPDATE_COUNTER.incrementAndGet();
if (widget != null) {
@@ -2330,6 +2331,7 @@
sendBroadcastAsUser(intent, widget.provider.id.getProfile());
}
+ @GuardedBy("mLock")
private void registerForBroadcastsLocked(Provider provider, int[] appWidgetIds) {
AppWidgetProviderInfo info = provider.getInfoLocked(mContext);
if (info.updatePeriodMillis > 0) {
@@ -3433,6 +3435,7 @@
*
* @return whether any providers were updated
*/
+ @GuardedBy("mLock")
private boolean updateProvidersForPackageLocked(String packageName, int userId,
Set<ProviderId> removedProviders) {
boolean providersUpdated = false;
@@ -4218,6 +4221,7 @@
/**
* Adds all pending updates in {@param outUpdates} keys by the update time.
*/
+ @GuardedBy("mLock")
public void getPendingUpdatesForIdLocked(Context context, int appWidgetId,
LongSparseArray<PendingHostUpdate> outUpdates) {
long updateSequenceNo = lastWidgetUpdateSequenceNo;
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetXmlUtil.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetXmlUtil.java
index 297575c..6a5dcc8 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetXmlUtil.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetXmlUtil.java
@@ -22,6 +22,7 @@
import android.content.ComponentName;
import android.os.Build;
import android.text.TextUtils;
+import android.util.Slog;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
@@ -33,6 +34,8 @@
*/
public class AppWidgetXmlUtil {
+ private static final String TAG = "AppWidgetXmlUtil";
+
private static final String ATTR_MIN_WIDTH = "min_width";
private static final String ATTR_MIN_HEIGHT = "min_height";
private static final String ATTR_MIN_RESIZE_WIDTH = "min_resize_width";
@@ -77,7 +80,11 @@
if (info.configure != null) {
out.attribute(null, ATTR_CONFIGURE, info.configure.flattenToShortString());
}
- out.attribute(null, ATTR_LABEL, info.label);
+ if (info.label != null) {
+ out.attribute(null, ATTR_LABEL, info.label);
+ } else if (AppWidgetServiceImpl.DEBUG_PROVIDER_INFO_CACHE) {
+ Slog.e(TAG, "Label is empty in " + info.provider);
+ }
out.attributeInt(null, ATTR_ICON, info.icon);
out.attributeInt(null, ATTR_PREVIEW_IMAGE, info.previewImage);
out.attributeInt(null, ATTR_PREVIEW_LAYOUT, info.previewLayout);
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index ac0944b..b4c107c 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -671,6 +671,9 @@
association = AssociationInfo.builder(association)
.setNotifyOnDeviceNearby(active)
.build();
+ // Do not need to call {@link BleCompanionDeviceScanner#restartScan()} since it will
+ // trigger {@link BleCompanionDeviceScanner#restartScan(int, AssociationInfo)} when
+ // an application sets/unsets the mNotifyOnDeviceNearby flag.
mAssociationStore.updateAssociation(association);
// TODO(b/218615198): correctly handle the case when the device is currently present.
diff --git a/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java b/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java
index 33301b1..ad09f7c 100644
--- a/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java
+++ b/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java
@@ -194,6 +194,8 @@
// Collect MAC addresses from all associations.
final Set<String> macAddresses = new HashSet<>();
for (AssociationInfo association : mAssociationStore.getAssociations()) {
+ if (!association.isNotifyOnDeviceNearby()) continue;
+
// Beware that BT stack does not consider low-case MAC addresses valid, while
// MacAddress.toString() return a low-case String.
final String macAddress = association.getDeviceMacAddressAsString();
diff --git a/services/core/java/com/android/server/BinaryTransparencyService.java b/services/core/java/com/android/server/BinaryTransparencyService.java
index 1f8ef82..877ee82 100644
--- a/services/core/java/com/android/server/BinaryTransparencyService.java
+++ b/services/core/java/com/android/server/BinaryTransparencyService.java
@@ -441,6 +441,7 @@
final JobInfo jobInfo = new JobInfo.Builder(COMPUTE_APEX_MODULE_SHA256_JOB_ID,
new ComponentName(context, UpdateMeasurementsJobService.class))
.setRequiresDeviceIdle(true)
+ .setRequiresCharging(true)
.build();
if (jobScheduler.schedule(jobInfo) != JobScheduler.RESULT_SUCCESS) {
Slog.e(TAG, "Failed to schedule job to update binary measurements.");
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index f944d4f..e529010 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -75,6 +75,13 @@
@VisibleForTesting static final long CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS = 300;
/**
+ * Min time in milliseconds to complete the emergency gesture for it count. If the gesture is
+ * completed faster than this, we assume it's not performed by human and the
+ * event gets ignored.
+ */
+ @VisibleForTesting static final int EMERGENCY_GESTURE_TAP_DETECTION_MIN_TIME_MS = 160;
+
+ /**
* Interval in milliseconds in which the power button must be depressed in succession to be
* considered part of an extended sequence of taps. Note that this is a looser threshold than
* the camera launch gesture, because the purpose of this threshold is to measure the
@@ -184,6 +191,7 @@
private int mEmergencyGesturePowerButtonCooldownPeriodMs;
private long mLastPowerDown;
+ private long mFirstPowerDown;
private long mLastEmergencyGestureTriggered;
private int mPowerButtonConsecutiveTaps;
private int mPowerButtonSlowConsecutiveTaps;
@@ -553,10 +561,12 @@
mLastPowerDown = event.getEventTime();
if (powerTapInterval >= POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS) {
// Tap too slow, reset consecutive tap counts.
+ mFirstPowerDown = event.getEventTime();
mPowerButtonConsecutiveTaps = 1;
mPowerButtonSlowConsecutiveTaps = 1;
} else if (powerTapInterval >= CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS) {
// Tap too slow for shortcuts
+ mFirstPowerDown = event.getEventTime();
mPowerButtonConsecutiveTaps = 1;
mPowerButtonSlowConsecutiveTaps++;
} else {
@@ -575,7 +585,26 @@
intercept = interactive;
}
if (mPowerButtonConsecutiveTaps == EMERGENCY_GESTURE_POWER_TAP_COUNT_THRESHOLD) {
- launchEmergencyGesture = true;
+ long emergencyGestureSpentTime = event.getEventTime() - mFirstPowerDown;
+ long emergencyGestureTapDetectionMinTimeMs = Settings.Global.getInt(
+ mContext.getContentResolver(),
+ Settings.Global.EMERGENCY_GESTURE_TAP_DETECTION_MIN_TIME_MS,
+ EMERGENCY_GESTURE_TAP_DETECTION_MIN_TIME_MS);
+ if (emergencyGestureSpentTime <= emergencyGestureTapDetectionMinTimeMs) {
+ Slog.i(TAG, "Emergency gesture detected but it's too fast. Gesture time: "
+ + emergencyGestureSpentTime + " ms");
+ // Reset consecutive tap counts.
+ mFirstPowerDown = event.getEventTime();
+ mPowerButtonConsecutiveTaps = 1;
+ mPowerButtonSlowConsecutiveTaps = 1;
+ } else {
+ Slog.i(TAG, "Emergency gesture detected. Gesture time: "
+ + emergencyGestureSpentTime + " ms");
+ launchEmergencyGesture = true;
+ mMetricsLogger.histogram("emergency_gesture_spent_time",
+ (int) emergencyGestureSpentTime);
+
+ }
}
}
if (mCameraDoubleTapPowerEnabled
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 210532a..eefeee3 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -87,6 +87,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -172,7 +173,7 @@
@NonNull private final VcnNetworkProvider mNetworkProvider;
@NonNull private final TelephonySubscriptionTrackerCallback mTelephonySubscriptionTrackerCb;
@NonNull private final TelephonySubscriptionTracker mTelephonySubscriptionTracker;
- @NonNull private final BroadcastReceiver mPkgChangeReceiver;
+ @NonNull private final BroadcastReceiver mVcnBroadcastReceiver;
@NonNull
private final TrackingNetworkCallback mTrackingNetworkCallback = new TrackingNetworkCallback();
@@ -217,28 +218,17 @@
mConfigDiskRwHelper = mDeps.newPersistableBundleLockingReadWriteHelper(VCN_CONFIG_FILE);
- mPkgChangeReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
-
- if (Intent.ACTION_PACKAGE_ADDED.equals(action)
- || Intent.ACTION_PACKAGE_REPLACED.equals(action)
- || Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
- mTelephonySubscriptionTracker.handleSubscriptionsChanged();
- } else {
- Log.wtf(TAG, "received unexpected intent: " + action);
- }
- }
- };
+ mVcnBroadcastReceiver = new VcnBroadcastReceiver();
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ intentFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
+ intentFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
intentFilter.addDataScheme("package");
mContext.registerReceiver(
- mPkgChangeReceiver, intentFilter, null /* broadcastPermission */, mHandler);
+ mVcnBroadcastReceiver, intentFilter, null /* broadcastPermission */, mHandler);
// Run on handler to ensure I/O does not block system server startup
mHandler.post(() -> {
@@ -443,6 +433,53 @@
return Objects.equals(subGrp, snapshot.getActiveDataSubscriptionGroup());
}
+ private class VcnBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+
+ switch (action) {
+ case Intent.ACTION_PACKAGE_ADDED: // Fallthrough
+ case Intent.ACTION_PACKAGE_REPLACED: // Fallthrough
+ case Intent.ACTION_PACKAGE_REMOVED:
+ // Reevaluate subscriptions
+ mTelephonySubscriptionTracker.handleSubscriptionsChanged();
+
+ break;
+ case Intent.ACTION_PACKAGE_FULLY_REMOVED:
+ case Intent.ACTION_PACKAGE_DATA_CLEARED:
+ final String pkgName = intent.getData().getSchemeSpecificPart();
+
+ if (pkgName == null || pkgName.isEmpty()) {
+ logWtf("Package name was empty or null for intent with action" + action);
+ return;
+ }
+
+ // Clear configs for the packages that had data cleared, or removed.
+ synchronized (mLock) {
+ final List<ParcelUuid> toRemove = new ArrayList<>();
+ for (Entry<ParcelUuid, VcnConfig> entry : mConfigs.entrySet()) {
+ if (pkgName.equals(entry.getValue().getProvisioningPackageName())) {
+ toRemove.add(entry.getKey());
+ }
+ }
+
+ for (ParcelUuid subGrp : toRemove) {
+ stopAndClearVcnConfigInternalLocked(subGrp);
+ }
+
+ if (!toRemove.isEmpty()) {
+ writeConfigsToDiskLocked();
+ }
+ }
+
+ break;
+ default:
+ Slog.wtf(TAG, "received unexpected intent: " + action);
+ }
+ }
+ }
+
private class VcnSubscriptionTrackerCallback implements TelephonySubscriptionTrackerCallback {
/**
* Handles subscription group changes, as notified by {@link TelephonySubscriptionTracker}
@@ -504,6 +541,7 @@
final Map<ParcelUuid, Set<Integer>> currSubGrpMappings =
getSubGroupToSubIdMappings(mLastSnapshot);
if (!currSubGrpMappings.equals(oldSubGrpMappings)) {
+ garbageCollectAndWriteVcnConfigsLocked();
notifyAllPolicyListenersLocked();
}
}
@@ -645,6 +683,39 @@
});
}
+ private void enforceCarrierPrivilegeOrProvisioningPackage(
+ @NonNull ParcelUuid subscriptionGroup, @NonNull String pkg) {
+ // Only apps running in the primary (system) user are allowed to configure the VCN. This is
+ // in line with Telephony's behavior with regards to binding to a Carrier App provided
+ // CarrierConfigService.
+ enforcePrimaryUser();
+
+ if (isProvisioningPackageForConfig(subscriptionGroup, pkg)) {
+ return;
+ }
+
+ // Must NOT be called from cleared binder identity, since this checks user calling identity
+ enforceCallingUserAndCarrierPrivilege(subscriptionGroup, pkg);
+ }
+
+ private boolean isProvisioningPackageForConfig(
+ @NonNull ParcelUuid subscriptionGroup, @NonNull String pkg) {
+ // Try-finally to return early if matching owned subscription found.
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ final VcnConfig config = mConfigs.get(subscriptionGroup);
+ if (config != null && pkg.equals(config.getProvisioningPackageName())) {
+ return true;
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+
+ return false;
+ }
+
/**
* Clears the VcnManagementService for a given subscription group.
*
@@ -658,31 +729,56 @@
mContext.getSystemService(AppOpsManager.class)
.checkPackage(mDeps.getBinderCallingUid(), opPkgName);
- enforceCallingUserAndCarrierPrivilege(subscriptionGroup, opPkgName);
+ enforceCarrierPrivilegeOrProvisioningPackage(subscriptionGroup, opPkgName);
Binder.withCleanCallingIdentity(() -> {
synchronized (mLock) {
- mConfigs.remove(subscriptionGroup);
- final boolean vcnExists = mVcns.containsKey(subscriptionGroup);
-
- stopVcnLocked(subscriptionGroup);
-
- if (vcnExists) {
- // TODO(b/181789060): invoke asynchronously after Vcn notifies through
- // VcnCallback
- notifyAllPermissionedStatusCallbacksLocked(
- subscriptionGroup, VCN_STATUS_CODE_NOT_CONFIGURED);
- }
-
+ stopAndClearVcnConfigInternalLocked(subscriptionGroup);
writeConfigsToDiskLocked();
}
});
}
+ private void stopAndClearVcnConfigInternalLocked(@NonNull ParcelUuid subscriptionGroup) {
+ mConfigs.remove(subscriptionGroup);
+ final boolean vcnExists = mVcns.containsKey(subscriptionGroup);
+
+ stopVcnLocked(subscriptionGroup);
+
+ if (vcnExists) {
+ // TODO(b/181789060): invoke asynchronously after Vcn notifies through
+ // VcnCallback
+ notifyAllPermissionedStatusCallbacksLocked(
+ subscriptionGroup, VCN_STATUS_CODE_NOT_CONFIGURED);
+ }
+ }
+
+ private void garbageCollectAndWriteVcnConfigsLocked() {
+ final SubscriptionManager subMgr = mContext.getSystemService(SubscriptionManager.class);
+
+ boolean shouldWrite = false;
+
+ final Iterator<ParcelUuid> configsIterator = mConfigs.keySet().iterator();
+ while (configsIterator.hasNext()) {
+ final ParcelUuid subGrp = configsIterator.next();
+
+ final List<SubscriptionInfo> subscriptions = subMgr.getSubscriptionsInGroup(subGrp);
+ if (subscriptions == null || subscriptions.isEmpty()) {
+ // Trim subGrps with no more subscriptions; must have moved to another subGrp
+ configsIterator.remove();
+ shouldWrite = true;
+ }
+ }
+
+ if (shouldWrite) {
+ writeConfigsToDiskLocked();
+ }
+ }
+
/**
* Retrieves the list of subscription groups with configured VcnConfigs
*
- * <p>Limited to subscription groups for which the caller is carrier privileged.
+ * <p>Limited to subscription groups for which the caller had configured.
*
* <p>Implements the IVcnManagementService Binder interface.
*/
@@ -698,7 +794,8 @@
final List<ParcelUuid> result = new ArrayList<>();
synchronized (mLock) {
for (ParcelUuid subGrp : mConfigs.keySet()) {
- if (mLastSnapshot.packageHasPermissionsForSubscriptionGroup(subGrp, opPkgName)) {
+ if (mLastSnapshot.packageHasPermissionsForSubscriptionGroup(subGrp, opPkgName)
+ || isProvisioningPackageForConfig(subGrp, opPkgName)) {
result.add(subGrp);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e29f11a..35f7e06 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4821,7 +4821,7 @@
}
checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
- bindApplicationTimeMillis = SystemClock.elapsedRealtime();
+ bindApplicationTimeMillis = SystemClock.uptimeMillis();
mAtmInternal.preBindApplication(app.getWindowProcessController());
final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
if (mPlatformCompat != null) {
@@ -4969,9 +4969,9 @@
pid,
app.info.packageName,
FrameworkStatsLog.PROCESS_START_TIME__TYPE__COLD,
- app.getStartTime(),
- (int) (bindApplicationTimeMillis - app.getStartTime()),
- (int) (SystemClock.elapsedRealtime() - app.getStartTime()),
+ app.getStartElapsedTime(),
+ (int) (bindApplicationTimeMillis - app.getStartUptime()),
+ (int) (SystemClock.uptimeMillis() - app.getStartUptime()),
app.getHostingRecord().getType(),
(app.getHostingRecord().getName() != null ? app.getHostingRecord().getName() : ""));
return true;
diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java
index 64ff532..8c42d4d 100644
--- a/services/core/java/com/android/server/am/AppBatteryTracker.java
+++ b/services/core/java/com/android/server/am/AppBatteryTracker.java
@@ -266,22 +266,16 @@
}
FrameworkStatsLog.write(FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO,
uid,
- FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_UNKNOWN,
- FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__THRESHOLD__THRESHOLD_UNKNOWN,
- FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__UNKNOWN_TRACKER,
+ AppBackgroundRestrictionsInfo.LEVEL_UNKNOWN, // RestrictionLevel
+ AppBackgroundRestrictionsInfo.THRESHOLD_UNKNOWN,
+ AppBackgroundRestrictionsInfo.UNKNOWN_TRACKER,
null /*byte[] fgs_tracker_info*/,
getBatteryTrackerInfoProtoLocked(uid) /*byte[] battery_tracker_info*/,
null /*byte[] broadcast_events_tracker_info*/,
null /*byte[] bind_service_events_tracker_info*/,
- FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_UNKNOWN,
- FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__UNKNOWN,
- FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_UNKNOWN,
+ AppBackgroundRestrictionsInfo.REASON_UNKNOWN, // ExemptionReason
+ AppBackgroundRestrictionsInfo.UNKNOWN, // OptimizationLevel
+ AppBackgroundRestrictionsInfo.SDK_UNKNOWN, // TargetSdk
isLowRamDeviceStatic());
}
}
@@ -654,7 +648,7 @@
final long start = stats.getStatsStartTimestamp();
final long end = stats.getStatsEndTimestamp();
final double scale = expectedDuration > 0
- ? (expectedDuration * 1.0d) / (end - start) : 1.0d;
+ ? Math.min((expectedDuration * 1.0d) / (end - start), 1.0d) : 1.0d;
final AppBatteryPolicy bgPolicy = mInjector.getPolicy();
for (UidBatteryConsumer uidConsumer : uidConsumers) {
// TODO: b/200326767 - as we are not supporting per proc state attribution yet,
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index 798647e..d70404f 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -116,6 +116,7 @@
import android.database.ContentObserver;
import android.graphics.drawable.Icon;
import android.net.Uri;
+import android.os.AppBackgroundRestrictionsInfo;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
@@ -123,7 +124,6 @@
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
-import android.os.PowerExemptionManager.ExemptionReason;
import android.os.PowerExemptionManager.ReasonCode;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -223,6 +223,11 @@
private static final String ATTR_LEVEL_TS = "levelts";
private static final String ATTR_REASON = "reason";
+ private static final String[] ROLES_IN_INTEREST = {
+ RoleManager.ROLE_DIALER,
+ RoleManager.ROLE_EMERGENCY,
+ };
+
private final Context mContext;
private final HandlerThread mBgHandlerThread;
private final BgHandler mBgHandler;
@@ -1090,6 +1095,14 @@
DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "restriction_exempted_packages";
/**
+ * Whether or not to show the notification for abusive apps, i.e. when the system
+ * detects it's draining significant amount of battery in the background.
+ * {@code true} - we'll show the prompt to user, {@code false} - we'll not show it.
+ */
+ static final String KEY_BG_PROMPT_ABUSIVE_APPS_TO_BG_RESTRICTED =
+ DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "prompt_abusive_apps_to_bg_restricted";
+
+ /**
* Default value to {@link #mBgAutoRestrictedBucket}.
*/
static final boolean DEFAULT_BG_AUTO_RESTRICTED_BUCKET_ON_BG_RESTRICTION = false;
@@ -1114,6 +1127,11 @@
*/
final boolean mDefaultBgPromptFgsWithNotiToBgRestricted;
+ /**
+ * Default value to {@link #mBgPromptAbusiveAppsToBgRestricted}.
+ */
+ final boolean mDefaultBgPromptAbusiveAppToBgRestricted;
+
volatile boolean mBgAutoRestrictedBucket;
volatile boolean mRestrictedBucketEnabled;
@@ -1139,10 +1157,17 @@
*/
volatile boolean mBgPromptFgsWithNotiOnLongRunning;
+ /**
+ * @see #KEY_BG_PROMPT_ABUSIVE_APPS_TO_BG_RESTRICTED.
+ */
+ volatile boolean mBgPromptAbusiveAppsToBgRestricted;
+
ConstantsObserver(Handler handler, Context context) {
super(handler);
mDefaultBgPromptFgsWithNotiToBgRestricted = context.getResources().getBoolean(
com.android.internal.R.bool.config_bg_prompt_fgs_with_noti_to_bg_restricted);
+ mDefaultBgPromptAbusiveAppToBgRestricted = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_bg_prompt_abusive_apps_to_bg_restricted);
}
@Override
@@ -1167,6 +1192,9 @@
case KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING:
updateBgPromptFgsWithNotiOnLongRunning();
break;
+ case KEY_BG_PROMPT_ABUSIVE_APPS_TO_BG_RESTRICTED:
+ updateBgPromptAbusiveAppToBgRestricted();
+ break;
case KEY_BG_RESTRICTION_EXEMPTED_PACKAGES:
updateBgRestrictionExemptedPackages();
break;
@@ -1204,6 +1232,7 @@
updateBgLongFgsNotificationMinimalInterval();
updateBgPromptFgsWithNotiToBgRestricted();
updateBgPromptFgsWithNotiOnLongRunning();
+ updateBgPromptAbusiveAppToBgRestricted();
updateBgRestrictionExemptedPackages();
}
@@ -1246,6 +1275,13 @@
DEFAULT_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING);
}
+ private void updateBgPromptAbusiveAppToBgRestricted() {
+ mBgPromptAbusiveAppsToBgRestricted = DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_BG_PROMPT_ABUSIVE_APPS_TO_BG_RESTRICTED,
+ mDefaultBgPromptAbusiveAppToBgRestricted);
+ }
+
private void updateBgRestrictionExemptedPackages() {
final String settings = DeviceConfig.getString(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -1285,6 +1321,10 @@
pw.print('=');
pw.println(mBgPromptFgsWithNotiToBgRestricted);
pw.print(prefix);
+ pw.print(KEY_BG_PROMPT_ABUSIVE_APPS_TO_BG_RESTRICTED);
+ pw.print('=');
+ pw.println(mBgPromptAbusiveAppsToBgRestricted);
+ pw.print(prefix);
pw.print(KEY_BG_RESTRICTION_EXEMPTED_PACKAGES);
pw.print('=');
pw.println(mBgRestrictionExemptedPackages.toString());
@@ -1386,6 +1426,7 @@
initBgRestrictionExemptioFromSysConfig();
initRestrictionStates();
initSystemModuleNames();
+ initRolesInInterest();
registerForUidObservers();
registerForSystemBroadcasts();
mNotificationHelper.onSystemReady();
@@ -1875,76 +1916,59 @@
private int getRestrictionLevelStatsd(@RestrictionLevel int level) {
switch (level) {
case RESTRICTION_LEVEL_UNKNOWN:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_UNKNOWN;
+ return AppBackgroundRestrictionsInfo.LEVEL_UNKNOWN;
case RESTRICTION_LEVEL_UNRESTRICTED:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_UNRESTRICTED;
+ return AppBackgroundRestrictionsInfo.LEVEL_UNRESTRICTED;
case RESTRICTION_LEVEL_EXEMPTED:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_EXEMPTED;
+ return AppBackgroundRestrictionsInfo.LEVEL_EXEMPTED;
case RESTRICTION_LEVEL_ADAPTIVE_BUCKET:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_ADAPTIVE_BUCKET;
+ return AppBackgroundRestrictionsInfo.LEVEL_ADAPTIVE_BUCKET;
case RESTRICTION_LEVEL_RESTRICTED_BUCKET:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_RESTRICTED_BUCKET;
+ return AppBackgroundRestrictionsInfo.LEVEL_RESTRICTED_BUCKET;
case RESTRICTION_LEVEL_BACKGROUND_RESTRICTED:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_BACKGROUND_RESTRICTED;
+ return AppBackgroundRestrictionsInfo.LEVEL_BACKGROUND_RESTRICTED;
case RESTRICTION_LEVEL_HIBERNATION:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_HIBERNATION;
+ return AppBackgroundRestrictionsInfo.LEVEL_HIBERNATION;
default:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__RESTRICTION_LEVEL__LEVEL_UNKNOWN;
+ return AppBackgroundRestrictionsInfo.LEVEL_UNKNOWN;
}
}
private int getThresholdStatsd(int reason) {
switch (reason) {
case REASON_MAIN_FORCED_BY_SYSTEM:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__THRESHOLD__THRESHOLD_RESTRICTED;
+ return AppBackgroundRestrictionsInfo.THRESHOLD_RESTRICTED;
case REASON_MAIN_FORCED_BY_USER:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__THRESHOLD__THRESHOLD_USER;
+ return AppBackgroundRestrictionsInfo.THRESHOLD_USER;
default:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__THRESHOLD__THRESHOLD_UNKNOWN;
+ return AppBackgroundRestrictionsInfo.THRESHOLD_UNKNOWN;
}
}
private int getTrackerTypeStatsd(@TrackerType int type) {
switch (type) {
case TRACKER_TYPE_BATTERY:
- return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__BATTERY_TRACKER;
+ return AppBackgroundRestrictionsInfo.BATTERY_TRACKER;
case TRACKER_TYPE_BATTERY_EXEMPTION:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__BATTERY_EXEMPTION_TRACKER;
+ return AppBackgroundRestrictionsInfo.BATTERY_EXEMPTION_TRACKER;
case TRACKER_TYPE_FGS:
- return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__FGS_TRACKER;
+ return AppBackgroundRestrictionsInfo.FGS_TRACKER;
case TRACKER_TYPE_MEDIA_SESSION:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__MEDIA_SESSION_TRACKER;
+ return AppBackgroundRestrictionsInfo.MEDIA_SESSION_TRACKER;
case TRACKER_TYPE_PERMISSION:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__PERMISSION_TRACKER;
+ return AppBackgroundRestrictionsInfo.PERMISSION_TRACKER;
case TRACKER_TYPE_BROADCAST_EVENTS:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__BROADCAST_EVENTS_TRACKER;
+ return AppBackgroundRestrictionsInfo.BROADCAST_EVENTS_TRACKER;
case TRACKER_TYPE_BIND_SERVICE_EVENTS:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__BIND_SERVICE_EVENTS_TRACKER;
+ return AppBackgroundRestrictionsInfo.BIND_SERVICE_EVENTS_TRACKER;
default:
- return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TRACKER__UNKNOWN_TRACKER;
+ return AppBackgroundRestrictionsInfo.UNKNOWN_TRACKER;
}
}
- private @ExemptionReason int getExemptionReasonStatsd(int uid, @RestrictionLevel int level) {
+ private int getExemptionReasonStatsd(int uid, @RestrictionLevel int level) {
if (level != RESTRICTION_LEVEL_EXEMPTED) {
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__EXEMPTION_REASON__REASON_DENIED;
+ return AppBackgroundRestrictionsInfo.REASON_DENIED;
}
@ReasonCode final int reasonCode = getBackgroundRestrictionExemptionReason(uid);
@@ -1954,16 +1978,15 @@
private int getOptimizationLevelStatsd(@RestrictionLevel int level) {
switch (level) {
case RESTRICTION_LEVEL_UNKNOWN:
- return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__UNKNOWN;
+ return AppBackgroundRestrictionsInfo.UNKNOWN;
case RESTRICTION_LEVEL_UNRESTRICTED:
- return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__NOT_OPTIMIZED;
+ return AppBackgroundRestrictionsInfo.NOT_OPTIMIZED;
case RESTRICTION_LEVEL_ADAPTIVE_BUCKET:
- return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__OPTIMIZED;
+ return AppBackgroundRestrictionsInfo.OPTIMIZED;
case RESTRICTION_LEVEL_BACKGROUND_RESTRICTED:
- return FrameworkStatsLog
- .APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__BACKGROUND_RESTRICTED;
+ return AppBackgroundRestrictionsInfo.BACKGROUND_RESTRICTED;
default:
- return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__OPT_LEVEL__UNKNOWN;
+ return AppBackgroundRestrictionsInfo.UNKNOWN;
}
}
@@ -1971,26 +1994,26 @@
private int getTargetSdkStatsd(String packageName) {
final PackageManager pm = mInjector.getPackageManager();
if (pm == null) {
- return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_UNKNOWN;
+ return AppBackgroundRestrictionsInfo.SDK_UNKNOWN;
}
try {
final PackageInfo pkg = pm.getPackageInfo(packageName, 0 /* flags */);
if (pkg == null || pkg.applicationInfo == null) {
- return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_UNKNOWN;
+ return AppBackgroundRestrictionsInfo.SDK_UNKNOWN;
}
final int targetSdk = pkg.applicationInfo.targetSdkVersion;
if (targetSdk < Build.VERSION_CODES.S) {
- return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_PRE_S;
+ return AppBackgroundRestrictionsInfo.SDK_PRE_S;
} else if (targetSdk < Build.VERSION_CODES.TIRAMISU) {
- return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_S;
+ return AppBackgroundRestrictionsInfo.SDK_S;
} else if (targetSdk == Build.VERSION_CODES.TIRAMISU) {
- return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_T;
+ return AppBackgroundRestrictionsInfo.SDK_T;
} else {
- return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_UNKNOWN;
+ return AppBackgroundRestrictionsInfo.SDK_UNKNOWN;
}
} catch (PackageManager.NameNotFoundException ignored) {
}
- return FrameworkStatsLog.APP_BACKGROUND_RESTRICTIONS_INFO__TARGET_SDK__SDK_UNKNOWN;
+ return AppBackgroundRestrictionsInfo.SDK_UNKNOWN;
}
private void applyRestrictionLevel(String pkgName, int uid,
@@ -2290,9 +2313,16 @@
}
void postRequestBgRestrictedIfNecessary(String packageName, int uid) {
+ if (!mBgController.mConstantsObserver.mBgPromptAbusiveAppsToBgRestricted) {
+ if (DEBUG_BG_RESTRICTION_CONTROLLER) {
+ Slog.i(TAG, "Not requesting bg-restriction due to config");
+ }
+ return;
+ }
+
final Intent intent = new Intent(Settings.ACTION_VIEW_ADVANCED_POWER_USAGE_DETAIL);
intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
final PendingIntent pendingIntent = PendingIntent.getActivityAsUser(mContext, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE, null,
@@ -2356,7 +2386,7 @@
} else {
final Intent intent = new Intent(Settings.ACTION_VIEW_ADVANCED_POWER_USAGE_DETAIL);
intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
pendingIntent = PendingIntent.getActivityAsUser(mContext, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE,
null, UserHandle.of(UserHandle.getUserId(uid)));
@@ -2666,6 +2696,18 @@
}
}
+ private void initRolesInInterest() {
+ final int[] allUsers = mInjector.getUserManagerInternal().getUserIds();
+ for (String role : ROLES_IN_INTEREST) {
+ if (mInjector.getRoleManager().isRoleAvailable(role)) {
+ for (int userId : allUsers) {
+ final UserHandle user = UserHandle.of(userId);
+ onRoleHoldersChanged(role, user);
+ }
+ }
+ }
+ }
+
private void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
final List<String> rolePkgs = mInjector.getRoleManager().getRoleHoldersAsUser(
roleName, user);
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 0518899..8a7fece 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -61,7 +61,6 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
-import android.os.PowerExemptionManager;
import android.os.PowerExemptionManager.ReasonCode;
import android.os.PowerExemptionManager.TempAllowListType;
import android.os.Process;
@@ -1934,9 +1933,6 @@
}
private void maybeReportBroadcastDispatchedEventLocked(BroadcastRecord r, int targetUid) {
- // STOPSHIP (217251579): Temporarily use temp-allowlist reason to identify
- // push messages and record response events.
- useTemporaryAllowlistReasonAsSignal(r);
if (r.options == null || r.options.getIdForResponseEvent() <= 0) {
return;
}
@@ -1951,17 +1947,6 @@
mService.getUidStateLocked(targetUid));
}
- private void useTemporaryAllowlistReasonAsSignal(BroadcastRecord r) {
- if (r.options == null || r.options.getIdForResponseEvent() > 0) {
- return;
- }
- final int reasonCode = r.options.getTemporaryAppAllowlistReasonCode();
- if (reasonCode == PowerExemptionManager.REASON_PUSH_MESSAGING
- || reasonCode == PowerExemptionManager.REASON_PUSH_MESSAGING_OVER_QUOTA) {
- r.options.recordResponseEventWhileInBackground(reasonCode);
- }
- }
-
@NonNull
private UsageStatsManagerInternal getUsageStatsManagerInternal() {
final UsageStatsManagerInternal usageStatsManagerInternal =
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java b/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java
new file mode 100644
index 0000000..1b24aa8
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics.sensors;
+
+import static android.hardware.biometrics.BiometricStateListener.STATE_AUTH_OTHER;
+import static android.hardware.biometrics.BiometricStateListener.STATE_BP_AUTH;
+import static android.hardware.biometrics.BiometricStateListener.STATE_ENROLLING;
+import static android.hardware.biometrics.BiometricStateListener.STATE_IDLE;
+import static android.hardware.biometrics.BiometricStateListener.STATE_KEYGUARD_AUTH;
+
+import android.annotation.NonNull;
+import android.hardware.biometrics.BiometricStateListener;
+import android.hardware.biometrics.IBiometricStateListener;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.server.biometrics.Utils;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * A callback for receiving notifications about biometric sensor state changes.
+ */
+public class BiometricStateCallback implements ClientMonitorCallback {
+
+ private static final String TAG = "BiometricStateCallback";
+
+ @NonNull
+ private final CopyOnWriteArrayList<IBiometricStateListener>
+ mBiometricStateListeners = new CopyOnWriteArrayList<>();
+
+ private @BiometricStateListener.State int mBiometricState;
+
+ public BiometricStateCallback() {
+ mBiometricState = STATE_IDLE;
+ }
+
+ public int getBiometricState() {
+ return mBiometricState;
+ }
+
+ @Override
+ public void onClientStarted(@NonNull BaseClientMonitor client) {
+ final int previousBiometricState = mBiometricState;
+
+ if (client instanceof AuthenticationClient) {
+ final AuthenticationClient<?> authClient = (AuthenticationClient<?>) client;
+ if (authClient.isKeyguard()) {
+ mBiometricState = STATE_KEYGUARD_AUTH;
+ } else if (authClient.isBiometricPrompt()) {
+ mBiometricState = STATE_BP_AUTH;
+ } else {
+ mBiometricState = STATE_AUTH_OTHER;
+ }
+ } else if (client instanceof EnrollClient) {
+ mBiometricState = STATE_ENROLLING;
+ } else {
+ Slog.w(TAG, "Other authentication client: " + Utils.getClientName(client));
+ mBiometricState = STATE_IDLE;
+ }
+
+ Slog.d(TAG, "State updated from " + previousBiometricState + " to " + mBiometricState
+ + ", client " + client);
+ notifyBiometricStateListeners(mBiometricState);
+ }
+
+ @Override
+ public void onClientFinished(@NonNull BaseClientMonitor client, boolean success) {
+ mBiometricState = STATE_IDLE;
+ Slog.d(TAG, "Client finished, state updated to " + mBiometricState + ", client "
+ + client);
+
+ if (client instanceof EnrollmentModifier) {
+ EnrollmentModifier enrollmentModifier = (EnrollmentModifier) client;
+ final boolean enrollmentStateChanged = enrollmentModifier.hasEnrollmentStateChanged();
+ Slog.d(TAG, "Enrollment state changed: " + enrollmentStateChanged);
+ if (enrollmentStateChanged) {
+ notifyAllEnrollmentStateChanged(client.getTargetUserId(),
+ client.getSensorId(),
+ enrollmentModifier.hasEnrollments());
+ }
+ }
+
+ notifyBiometricStateListeners(mBiometricState);
+ }
+
+ private void notifyBiometricStateListeners(@BiometricStateListener.State int newState) {
+ for (IBiometricStateListener listener : mBiometricStateListeners) {
+ try {
+ listener.onStateChanged(newState);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception in biometric state change", e);
+ }
+ }
+ }
+
+ /**
+ * This should be invoked when:
+ * 1) Enrolled --> None-enrolled
+ * 2) None-enrolled --> enrolled
+ * 3) HAL becomes ready
+ * 4) Listener is registered
+ */
+ public void notifyAllEnrollmentStateChanged(int userId, int sensorId,
+ boolean hasEnrollments) {
+ for (IBiometricStateListener listener : mBiometricStateListeners) {
+ notifyEnrollmentStateChanged(listener, userId, sensorId, hasEnrollments);
+ }
+ }
+
+ /**
+ * Notifies the listener of enrollment state changes.
+ */
+ public void notifyEnrollmentStateChanged(@NonNull IBiometricStateListener listener,
+ int userId, int sensorId, boolean hasEnrollments) {
+ try {
+ listener.onEnrollmentsChanged(userId, sensorId, hasEnrollments);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception", e);
+ }
+ }
+
+ /**
+ * Enables clients to register a BiometricStateListener. For example, this is used to forward
+ * fingerprint sensor state changes to SideFpsEventHandler.
+ *
+ * @param listener
+ */
+ public void registerBiometricStateListener(@NonNull IBiometricStateListener listener) {
+ mBiometricStateListeners.add(listener);
+ }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 5727ffc..97efc78 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -42,6 +42,7 @@
import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
+import android.hardware.biometrics.IBiometricStateListener;
import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.ITestSessionCallback;
@@ -55,7 +56,6 @@
import android.hardware.fingerprint.IFingerprintClientActiveCallback;
import android.hardware.fingerprint.IFingerprintService;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
-import android.hardware.fingerprint.IFingerprintStateListener;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.Binder;
@@ -84,6 +84,7 @@
import com.android.server.SystemService;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.log.BiometricContext;
+import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
import com.android.server.biometrics.sensors.LockoutTracker;
@@ -114,7 +115,7 @@
private final LockPatternUtils mLockPatternUtils;
private final FingerprintServiceWrapper mServiceWrapper;
@NonNull private final List<ServiceProvider> mServiceProviders;
- @NonNull private final FingerprintStateCallback mFingerprintStateCallback;
+ @NonNull private final BiometricStateCallback mBiometricStateCallback;
@NonNull private final Handler mHandler;
@GuardedBy("mLock")
@@ -125,20 +126,20 @@
@NonNull private final List<FingerprintSensorPropertiesInternal> mSensorProps;
/**
- * Registers FingerprintStateListener in list stored by FingerprintService
- * @param listener new FingerprintStateListener being added
+ * Registers BiometricStateListener in list stored by FingerprintService
+ * @param listener new BiometricStateListener being added
*/
- public void registerFingerprintStateListener(@NonNull IFingerprintStateListener listener) {
- mFingerprintStateCallback.registerFingerprintStateListener(listener);
+ public void registerBiometricStateListener(@NonNull IBiometricStateListener listener) {
+ mBiometricStateCallback.registerBiometricStateListener(listener);
broadcastCurrentEnrollmentState(listener);
}
/**
* @param listener if non-null, notifies only this listener. if null, notifies all listeners
- * in {@link FingerprintStateCallback}. This is slightly ugly, but reduces
+ * in {@link BiometricStateCallback}. This is slightly ugly, but reduces
* redundant code.
*/
- private void broadcastCurrentEnrollmentState(@Nullable IFingerprintStateListener listener) {
+ private void broadcastCurrentEnrollmentState(@Nullable IBiometricStateListener listener) {
final UserManager um = UserManager.get(getContext());
synchronized (mLock) {
// Update the new listener with current state of all sensors
@@ -151,10 +152,10 @@
// Defer this work and allow the loop to release the lock sooner
mHandler.post(() -> {
if (listener != null) {
- mFingerprintStateCallback.notifyFingerprintEnrollmentStateChanged(
+ mBiometricStateCallback.notifyEnrollmentStateChanged(
listener, userInfo.id, prop.sensorId, enrolled);
} else {
- mFingerprintStateCallback.notifyAllFingerprintEnrollmentStateChanged(
+ mBiometricStateCallback.notifyAllEnrollmentStateChanged(
userInfo.id, prop.sensorId, enrolled);
}
});
@@ -651,7 +652,7 @@
pw.println("Dumping for sensorId: " + props.sensorId
+ ", provider: " + provider.getClass().getSimpleName());
pw.println("Fps state: "
- + mFingerprintStateCallback.getFingerprintState());
+ + mBiometricStateCallback.getBiometricState());
provider.dumpInternal(props.sensorId, pw);
pw.println();
}
@@ -847,12 +848,12 @@
Fingerprint21UdfpsMock.CONFIG_ENABLE_TEST_UDFPS, 0 /* default */,
UserHandle.USER_CURRENT) != 0) {
fingerprint21 = Fingerprint21UdfpsMock.newInstance(getContext(),
- mFingerprintStateCallback, hidlSensor,
+ mBiometricStateCallback, hidlSensor,
mLockoutResetDispatcher, mGestureAvailabilityDispatcher,
BiometricContext.getInstance(getContext()));
} else {
fingerprint21 = Fingerprint21.newInstance(getContext(),
- mFingerprintStateCallback, hidlSensor, mHandler,
+ mBiometricStateCallback, hidlSensor, mHandler,
mLockoutResetDispatcher, mGestureAvailabilityDispatcher);
}
mServiceProviders.add(fingerprint21);
@@ -875,7 +876,7 @@
try {
final SensorProps[] props = fp.getSensorProps();
final FingerprintProvider provider =
- new FingerprintProvider(getContext(), mFingerprintStateCallback, props,
+ new FingerprintProvider(getContext(), mBiometricStateCallback, props,
instance, mLockoutResetDispatcher,
mGestureAvailabilityDispatcher,
BiometricContext.getInstance(getContext()));
@@ -1015,8 +1016,8 @@
}
@Override
- public void registerFingerprintStateListener(@NonNull IFingerprintStateListener listener) {
- FingerprintService.this.registerFingerprintStateListener(listener);
+ public void registerBiometricStateListener(@NonNull IBiometricStateListener listener) {
+ FingerprintService.this.registerBiometricStateListener(listener);
}
}
@@ -1028,7 +1029,7 @@
mLockoutResetDispatcher = new LockoutResetDispatcher(context);
mLockPatternUtils = new LockPatternUtils(context);
mServiceProviders = new ArrayList<>();
- mFingerprintStateCallback = new FingerprintStateCallback();
+ mBiometricStateCallback = new BiometricStateCallback();
mAuthenticatorsRegisteredCallbacks = new RemoteCallbackList<>();
mSensorProps = new ArrayList<>();
mHandler = new Handler(Looper.getMainLooper());
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintStateCallback.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintStateCallback.java
deleted file mode 100644
index 04fd534..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintStateCallback.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint;
-
-import static android.hardware.fingerprint.FingerprintStateListener.STATE_AUTH_OTHER;
-import static android.hardware.fingerprint.FingerprintStateListener.STATE_BP_AUTH;
-import static android.hardware.fingerprint.FingerprintStateListener.STATE_ENROLLING;
-import static android.hardware.fingerprint.FingerprintStateListener.STATE_IDLE;
-import static android.hardware.fingerprint.FingerprintStateListener.STATE_KEYGUARD_AUTH;
-
-import android.annotation.NonNull;
-import android.hardware.fingerprint.FingerprintStateListener;
-import android.hardware.fingerprint.IFingerprintStateListener;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import com.android.server.biometrics.Utils;
-import com.android.server.biometrics.sensors.AuthenticationClient;
-import com.android.server.biometrics.sensors.BaseClientMonitor;
-import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.EnrollClient;
-import com.android.server.biometrics.sensors.EnrollmentModifier;
-
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * A callback for receiving notifications about changes in fingerprint state.
- */
-public class FingerprintStateCallback implements ClientMonitorCallback {
-
- @NonNull private final CopyOnWriteArrayList<IFingerprintStateListener>
- mFingerprintStateListeners = new CopyOnWriteArrayList<>();
-
- private @FingerprintStateListener.State int mFingerprintState;
-
- public FingerprintStateCallback() {
- mFingerprintState = STATE_IDLE;
- }
-
- public int getFingerprintState() {
- return mFingerprintState;
- }
-
- @Override
- public void onClientStarted(@NonNull BaseClientMonitor client) {
- final int previousFingerprintState = mFingerprintState;
-
- if (client instanceof AuthenticationClient) {
- final AuthenticationClient<?> authClient = (AuthenticationClient<?>) client;
- if (authClient.isKeyguard()) {
- mFingerprintState = STATE_KEYGUARD_AUTH;
- } else if (authClient.isBiometricPrompt()) {
- mFingerprintState = STATE_BP_AUTH;
- } else {
- mFingerprintState = STATE_AUTH_OTHER;
- }
- } else if (client instanceof EnrollClient) {
- mFingerprintState = STATE_ENROLLING;
- } else {
- Slog.w(FingerprintService.TAG,
- "Other authentication client: " + Utils.getClientName(client));
- mFingerprintState = STATE_IDLE;
- }
-
- Slog.d(FingerprintService.TAG, "Fps state updated from " + previousFingerprintState
- + " to " + mFingerprintState + ", client " + client);
- notifyFingerprintStateListeners(mFingerprintState);
- }
-
- @Override
- public void onClientFinished(@NonNull BaseClientMonitor client, boolean success) {
- mFingerprintState = STATE_IDLE;
- Slog.d(FingerprintService.TAG,
- "Client finished, fps state updated to " + mFingerprintState + ", client "
- + client);
-
- if (client instanceof EnrollmentModifier) {
- EnrollmentModifier enrollmentModifier = (EnrollmentModifier) client;
- final boolean enrollmentStateChanged = enrollmentModifier.hasEnrollmentStateChanged();
- Slog.d(FingerprintService.TAG, "Enrollment state changed: " + enrollmentStateChanged);
- if (enrollmentStateChanged) {
- notifyAllFingerprintEnrollmentStateChanged(client.getTargetUserId(),
- client.getSensorId(),
- enrollmentModifier.hasEnrollments());
- }
- }
-
- notifyFingerprintStateListeners(mFingerprintState);
- }
-
- private void notifyFingerprintStateListeners(@FingerprintStateListener.State int newState) {
- for (IFingerprintStateListener listener : mFingerprintStateListeners) {
- try {
- listener.onStateChanged(newState);
- } catch (RemoteException e) {
- Slog.e(FingerprintService.TAG, "Remote exception in fingerprint state change", e);
- }
- }
- }
-
- /**
- * This should be invoked when:
- * 1) Enrolled --> None-enrolled
- * 2) None-enrolled --> enrolled
- * 3) HAL becomes ready
- * 4) Listener is registered
- */
- void notifyAllFingerprintEnrollmentStateChanged(int userId, int sensorId,
- boolean hasEnrollments) {
- for (IFingerprintStateListener listener : mFingerprintStateListeners) {
- notifyFingerprintEnrollmentStateChanged(listener, userId, sensorId, hasEnrollments);
- }
- }
-
- /**
- * Notifies the listener of enrollment state changes.
- */
- void notifyFingerprintEnrollmentStateChanged(@NonNull IFingerprintStateListener listener,
- int userId, int sensorId, boolean hasEnrollments) {
- try {
- listener.onEnrollmentsChanged(userId, sensorId, hasEnrollments);
- } catch (RemoteException e) {
- Slog.e(FingerprintService.TAG, "Remote exception", e);
- }
- }
-
- /**
- * Enables clients to register a FingerprintStateListener. Used by FingerprintService to forward
- * updates in fingerprint sensor state to the SideFpNsEventHandler
- *
- * @param listener
- */
- public void registerFingerprintStateListener(@NonNull IFingerprintStateListener listener) {
- mFingerprintStateListeners.add(listener);
- }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
index 0528cd4..ba7202f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
@@ -32,8 +32,8 @@
import com.android.server.biometrics.HardwareAuthTokenUtils;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.sensors.BaseClientMonitor;
+import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.fingerprint.FingerprintStateCallback;
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
import java.util.HashSet;
@@ -52,7 +52,7 @@
@NonNull private final Context mContext;
private final int mSensorId;
@NonNull private final ITestSessionCallback mCallback;
- @NonNull private final FingerprintStateCallback mFingerprintStateCallback;
+ @NonNull private final BiometricStateCallback mBiometricStateCallback;
@NonNull private final FingerprintProvider mProvider;
@NonNull private final Sensor mSensor;
@NonNull private final Set<Integer> mEnrollmentIds;
@@ -118,13 +118,13 @@
BiometricTestSessionImpl(@NonNull Context context, int sensorId,
@NonNull ITestSessionCallback callback,
- @NonNull FingerprintStateCallback fingerprintStateCallback,
+ @NonNull BiometricStateCallback biometricStateCallback,
@NonNull FingerprintProvider provider,
@NonNull Sensor sensor) {
mContext = context;
mSensorId = sensorId;
mCallback = callback;
- mFingerprintStateCallback = fingerprintStateCallback;
+ mBiometricStateCallback = biometricStateCallback;
mProvider = provider;
mSensor = sensor;
mEnrollmentIds = new HashSet<>();
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index 1fac8a8..7d5b77c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -58,13 +58,13 @@
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.sensors.AuthenticationClient;
import com.android.server.biometrics.sensors.BaseClientMonitor;
+import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
import com.android.server.biometrics.sensors.InvalidationRequesterClient;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
import com.android.server.biometrics.sensors.PerformanceTracker;
-import com.android.server.biometrics.sensors.fingerprint.FingerprintStateCallback;
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
import com.android.server.biometrics.sensors.fingerprint.ServiceProvider;
@@ -91,7 +91,7 @@
private boolean mTestHalEnabled;
@NonNull private final Context mContext;
- @NonNull private final FingerprintStateCallback mFingerprintStateCallback;
+ @NonNull private final BiometricStateCallback mBiometricStateCallback;
@NonNull private final String mHalInstanceName;
@NonNull @VisibleForTesting
final SparseArray<Sensor> mSensors; // Map of sensors that this HAL supports
@@ -141,13 +141,13 @@
}
public FingerprintProvider(@NonNull Context context,
- @NonNull FingerprintStateCallback fingerprintStateCallback,
+ @NonNull BiometricStateCallback biometricStateCallback,
@NonNull SensorProps[] props, @NonNull String halInstanceName,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
@NonNull BiometricContext biometricContext) {
mContext = context;
- mFingerprintStateCallback = fingerprintStateCallback;
+ mBiometricStateCallback = biometricStateCallback;
mHalInstanceName = halInstanceName;
mSensors = new SparseArray<>();
mHandler = new Handler(Looper.getMainLooper());
@@ -389,13 +389,13 @@
@Override
public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
- mFingerprintStateCallback.onClientStarted(clientMonitor);
+ mBiometricStateCallback.onClientStarted(clientMonitor);
}
@Override
public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
boolean success) {
- mFingerprintStateCallback.onClientFinished(clientMonitor, success);
+ mBiometricStateCallback.onClientFinished(clientMonitor, success);
if (success) {
scheduleLoadAuthenticatorIdsForUser(sensorId, userId);
scheduleInvalidationRequest(sensorId, userId);
@@ -425,7 +425,7 @@
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
mBiometricContext,
mUdfpsOverlayController, isStrongBiometric);
- scheduleForSensor(sensorId, client, mFingerprintStateCallback);
+ scheduleForSensor(sensorId, client, mBiometricStateCallback);
});
return id;
@@ -447,7 +447,7 @@
mTaskStackListener, mSensors.get(sensorId).getLockoutCache(),
mUdfpsOverlayController, mSidefpsController, allowBackgroundAuthentication,
mSensors.get(sensorId).getSensorProperties());
- scheduleForSensor(sensorId, client, mFingerprintStateCallback);
+ scheduleForSensor(sensorId, client, mBiometricStateCallback);
});
}
@@ -509,7 +509,7 @@
BiometricsProtoEnums.CLIENT_UNKNOWN),
mBiometricContext,
mSensors.get(sensorId).getAuthenticatorIds());
- scheduleForSensor(sensorId, client, mFingerprintStateCallback);
+ scheduleForSensor(sensorId, client, mBiometricStateCallback);
});
}
@@ -528,7 +528,7 @@
enrolledList, FingerprintUtils.getInstance(sensorId),
mSensors.get(sensorId).getAuthenticatorIds());
scheduleForSensor(sensorId, client, new ClientMonitorCompositeCallback(callback,
- mFingerprintStateCallback));
+ mBiometricStateCallback));
});
}
@@ -680,7 +680,7 @@
@Override
public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
@NonNull String opPackageName) {
- return mSensors.get(sensorId).createTestSession(callback, mFingerprintStateCallback);
+ return mSensors.get(sensorId).createTestSession(callback, mBiometricStateCallback);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
index 024d611..1dcf4e9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
@@ -55,6 +55,7 @@
import com.android.server.biometrics.sensors.AuthenticationConsumer;
import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.BiometricScheduler;
+import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.EnumerateConsumer;
import com.android.server.biometrics.sensors.ErrorConsumer;
import com.android.server.biometrics.sensors.LockoutCache;
@@ -64,7 +65,6 @@
import com.android.server.biometrics.sensors.StartUserClient;
import com.android.server.biometrics.sensors.StopUserClient;
import com.android.server.biometrics.sensors.UserAwareBiometricScheduler;
-import com.android.server.biometrics.sensors.fingerprint.FingerprintStateCallback;
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
@@ -527,9 +527,9 @@
}
@NonNull ITestSession createTestSession(@NonNull ITestSessionCallback callback,
- @NonNull FingerprintStateCallback fingerprintStateCallback) {
+ @NonNull BiometricStateCallback biometricStateCallback) {
return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, callback,
- fingerprintStateCallback, mProvider, this);
+ biometricStateCallback, mProvider, this);
}
@NonNull BiometricScheduler getScheduler() {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
index 033855f..a58bb89 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
@@ -31,8 +31,8 @@
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.sensors.BaseClientMonitor;
+import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallback;
-import com.android.server.biometrics.sensors.fingerprint.FingerprintStateCallback;
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
import java.util.ArrayList;
@@ -53,7 +53,7 @@
@NonNull private final Context mContext;
private final int mSensorId;
@NonNull private final ITestSessionCallback mCallback;
- @NonNull private final FingerprintStateCallback mFingerprintStateCallback;
+ @NonNull private final BiometricStateCallback mBiometricStateCallback;
@NonNull private final Fingerprint21 mFingerprint21;
@NonNull private final Fingerprint21.HalResultController mHalResultController;
@NonNull private final Set<Integer> mEnrollmentIds;
@@ -119,14 +119,14 @@
BiometricTestSessionImpl(@NonNull Context context, int sensorId,
@NonNull ITestSessionCallback callback,
- @NonNull FingerprintStateCallback fingerprintStateCallback,
+ @NonNull BiometricStateCallback biometricStateCallback,
@NonNull Fingerprint21 fingerprint21,
@NonNull Fingerprint21.HalResultController halResultController) {
mContext = context;
mSensorId = sensorId;
mCallback = callback;
mFingerprint21 = fingerprint21;
- mFingerprintStateCallback = fingerprintStateCallback;
+ mBiometricStateCallback = biometricStateCallback;
mHalResultController = halResultController;
mEnrollmentIds = new HashSet<>();
mRandom = new Random();
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index 1d2a365..52dbe24 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -64,6 +64,7 @@
import com.android.server.biometrics.sensors.AuthenticationConsumer;
import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.BiometricScheduler;
+import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback;
@@ -73,7 +74,6 @@
import com.android.server.biometrics.sensors.LockoutTracker;
import com.android.server.biometrics.sensors.PerformanceTracker;
import com.android.server.biometrics.sensors.RemovalConsumer;
-import com.android.server.biometrics.sensors.fingerprint.FingerprintStateCallback;
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
import com.android.server.biometrics.sensors.fingerprint.ServiceProvider;
@@ -105,7 +105,7 @@
private boolean mTestHalEnabled;
final Context mContext;
- @NonNull private final FingerprintStateCallback mFingerprintStateCallback;
+ @NonNull private final BiometricStateCallback mBiometricStateCallback;
private final ActivityTaskManager mActivityTaskManager;
@NonNull private final FingerprintSensorPropertiesInternal mSensorProperties;
private final BiometricScheduler mScheduler;
@@ -323,7 +323,7 @@
@VisibleForTesting
Fingerprint21(@NonNull Context context,
- @NonNull FingerprintStateCallback fingerprintStateCallback,
+ @NonNull BiometricStateCallback biometricStateCallback,
@NonNull FingerprintSensorPropertiesInternal sensorProps,
@NonNull BiometricScheduler scheduler,
@NonNull Handler handler,
@@ -331,7 +331,7 @@
@NonNull HalResultController controller,
@NonNull BiometricContext biometricContext) {
mContext = context;
- mFingerprintStateCallback = fingerprintStateCallback;
+ mBiometricStateCallback = biometricStateCallback;
mBiometricContext = biometricContext;
mSensorProperties = sensorProps;
@@ -362,7 +362,7 @@
}
public static Fingerprint21 newInstance(@NonNull Context context,
- @NonNull FingerprintStateCallback fingerprintStateCallback,
+ @NonNull BiometricStateCallback biometricStateCallback,
@NonNull FingerprintSensorPropertiesInternal sensorProps,
@NonNull Handler handler,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@@ -373,7 +373,7 @@
gestureAvailabilityDispatcher);
final HalResultController controller = new HalResultController(sensorProps.sensorId,
context, handler, scheduler);
- return new Fingerprint21(context, fingerprintStateCallback, sensorProps, scheduler, handler,
+ return new Fingerprint21(context, biometricStateCallback, sensorProps, scheduler, handler,
lockoutResetDispatcher, controller, BiometricContext.getInstance(context));
}
@@ -604,13 +604,13 @@
mScheduler.scheduleClientMonitor(client, new ClientMonitorCallback() {
@Override
public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
- mFingerprintStateCallback.onClientStarted(clientMonitor);
+ mBiometricStateCallback.onClientStarted(clientMonitor);
}
@Override
public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
boolean success) {
- mFingerprintStateCallback.onClientFinished(clientMonitor, success);
+ mBiometricStateCallback.onClientFinished(clientMonitor, success);
if (success) {
// Update authenticatorIds
scheduleUpdateActiveUserWithoutHandler(clientMonitor.getTargetUserId(),
@@ -642,7 +642,7 @@
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
mBiometricContext, mUdfpsOverlayController,
isStrongBiometric);
- mScheduler.scheduleClientMonitor(client, mFingerprintStateCallback);
+ mScheduler.scheduleClientMonitor(client, mBiometricStateCallback);
});
return id;
@@ -666,7 +666,7 @@
mTaskStackListener, mLockoutTracker,
mUdfpsOverlayController, mSidefpsController,
allowBackgroundAuthentication, mSensorProperties);
- mScheduler.scheduleClientMonitor(client, mFingerprintStateCallback);
+ mScheduler.scheduleClientMonitor(client, mBiometricStateCallback);
});
}
@@ -708,7 +708,7 @@
createLogger(BiometricsProtoEnums.ACTION_REMOVE,
BiometricsProtoEnums.CLIENT_UNKNOWN),
mBiometricContext, mAuthenticatorIds);
- mScheduler.scheduleClientMonitor(client, mFingerprintStateCallback);
+ mScheduler.scheduleClientMonitor(client, mBiometricStateCallback);
});
}
@@ -728,7 +728,7 @@
createLogger(BiometricsProtoEnums.ACTION_REMOVE,
BiometricsProtoEnums.CLIENT_UNKNOWN),
mBiometricContext, mAuthenticatorIds);
- mScheduler.scheduleClientMonitor(client, mFingerprintStateCallback);
+ mScheduler.scheduleClientMonitor(client, mBiometricStateCallback);
});
}
@@ -754,7 +754,7 @@
public void scheduleInternalCleanup(int sensorId, int userId,
@Nullable ClientMonitorCallback callback) {
scheduleInternalCleanup(userId, new ClientMonitorCompositeCallback(callback,
- mFingerprintStateCallback));
+ mBiometricStateCallback));
}
private BiometricLogger createLogger(int statsAction, int statsClient) {
@@ -967,6 +967,6 @@
public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback,
@NonNull String opPackageName) {
return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, callback,
- mFingerprintStateCallback, this, mHalResultController);
+ mBiometricStateCallback, this, mHalResultController);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
index a4e343e..485a674 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
@@ -41,9 +41,9 @@
import com.android.server.biometrics.sensors.AuthenticationConsumer;
import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.BiometricScheduler;
+import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
-import com.android.server.biometrics.sensors.fingerprint.FingerprintStateCallback;
import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
import java.util.ArrayList;
@@ -245,7 +245,7 @@
}
public static Fingerprint21UdfpsMock newInstance(@NonNull Context context,
- @NonNull FingerprintStateCallback fingerprintStateCallback,
+ @NonNull BiometricStateCallback biometricStateCallback,
@NonNull FingerprintSensorPropertiesInternal sensorProps,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
@@ -257,7 +257,7 @@
new TestableBiometricScheduler(TAG, handler, gestureAvailabilityDispatcher);
final MockHalResultController controller =
new MockHalResultController(sensorProps.sensorId, context, handler, scheduler);
- return new Fingerprint21UdfpsMock(context, fingerprintStateCallback, sensorProps, scheduler,
+ return new Fingerprint21UdfpsMock(context, biometricStateCallback, sensorProps, scheduler,
handler, lockoutResetDispatcher, controller, biometricContext);
}
@@ -382,14 +382,14 @@
}
private Fingerprint21UdfpsMock(@NonNull Context context,
- @NonNull FingerprintStateCallback fingerprintStateCallback,
+ @NonNull BiometricStateCallback biometricStateCallback,
@NonNull FingerprintSensorPropertiesInternal sensorProps,
@NonNull TestableBiometricScheduler scheduler,
@NonNull Handler handler,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull MockHalResultController controller,
@NonNull BiometricContext biometricContext) {
- super(context, fingerprintStateCallback, sensorProps, scheduler, handler,
+ super(context, biometricStateCallback, sensorProps, scheduler, handler,
lockoutResetDispatcher, controller, biometricContext);
mScheduler = scheduler;
mScheduler.init(this);
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index 7db99f1..be11253 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -239,6 +239,8 @@
public long mResultErrorCount;
public boolean mDeviceError;
public List<CameraStreamStats> mStreamStats;
+ public String mUserTag;
+
private long mDurationOrStartTimeMs; // Either start time, or duration once completed
CameraUsageEvent(String cameraId, int facing, String clientName, int apiLevel,
@@ -257,7 +259,7 @@
public void markCompleted(int internalReconfigure, long requestCount,
long resultErrorCount, boolean deviceError,
- List<CameraStreamStats> streamStats) {
+ List<CameraStreamStats> streamStats, String userTag) {
if (mCompleted) {
return;
}
@@ -268,6 +270,7 @@
mResultErrorCount = resultErrorCount;
mDeviceError = deviceError;
mStreamStats = streamStats;
+ mUserTag = userTag;
if (CameraServiceProxy.DEBUG) {
Slog.v(TAG, "A camera facing " + cameraFacingToString(mCameraFacing) +
" was in use by " + mClientName + " for " +
@@ -794,7 +797,8 @@
+ ", requestCount " + e.mRequestCount
+ ", resultErrorCount " + e.mResultErrorCount
+ ", deviceError " + e.mDeviceError
- + ", streamCount is " + streamCount);
+ + ", streamCount is " + streamCount
+ + ", userTag is " + e.mUserTag);
}
// Convert from CameraStreamStats to CameraStreamProto
CameraStreamProto[] streamProtos = new CameraStreamProto[MAX_STREAM_STATISTICS];
@@ -851,7 +855,8 @@
MessageNano.toByteArray(streamProtos[1]),
MessageNano.toByteArray(streamProtos[2]),
MessageNano.toByteArray(streamProtos[3]),
- MessageNano.toByteArray(streamProtos[4]));
+ MessageNano.toByteArray(streamProtos[4]),
+ e.mUserTag);
}
}
@@ -1038,6 +1043,7 @@
long resultErrorCount = cameraState.getResultErrorCount();
boolean deviceError = cameraState.getDeviceErrorFlag();
List<CameraStreamStats> streamStats = cameraState.getStreamStats();
+ String userTag = cameraState.getUserTag();
synchronized(mLock) {
// Update active camera list and notify NFC if necessary
boolean wasEmpty = mActiveCameraUsage.isEmpty();
@@ -1091,7 +1097,8 @@
if (oldEvent != null) {
Slog.w(TAG, "Camera " + cameraId + " was already marked as active");
oldEvent.markCompleted(/*internalReconfigure*/0, /*requestCount*/0,
- /*resultErrorCount*/0, /*deviceError*/false, streamStats);
+ /*resultErrorCount*/0, /*deviceError*/false, streamStats,
+ /*userTag*/"");
mCameraUsageHistory.add(oldEvent);
}
break;
@@ -1101,7 +1108,7 @@
if (doneEvent != null) {
doneEvent.markCompleted(internalReconfigureCount, requestCount,
- resultErrorCount, deviceError, streamStats);
+ resultErrorCount, deviceError, streamStats, userTag);
mCameraUsageHistory.add(doneEvent);
// Check current active camera IDs to see if this package is still
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 af87677..1fa56bc 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
@@ -47,6 +47,7 @@
import java.lang.annotation.Target;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.TimeUnit;
/**
* Entry point for most GNSS HAL commands and callbacks.
@@ -1271,7 +1272,8 @@
@NativeEntryPoint
boolean isInEmergencySession() {
return Binder.withCleanCallingIdentity(
- () -> mEmergencyHelper.isInEmergency(mConfiguration.getEsExtensionSec()));
+ () -> mEmergencyHelper.isInEmergency(
+ TimeUnit.SECONDS.toMillis(mConfiguration.getEsExtensionSec())));
}
/**
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 42fed36..9e5da45 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -1179,8 +1179,15 @@
@Override
public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
- (new MediaShellCommand()).exec(this, in, out, err, args, callback,
- resultReceiver);
+ String[] packageNames =
+ mContext.getPackageManager().getPackagesForUid(Binder.getCallingUid());
+ String packageName = packageNames != null && packageNames.length > 0
+ ? packageNames[0]
+ : "com.android.shell"; // We should not need this branch, but defaulting to the
+ // current shell package name for robustness. See
+ // b/227109905.
+ new MediaShellCommand(packageName)
+ .exec(this, in, out, err, args, callback, resultReceiver);
}
@Override
diff --git a/services/core/java/com/android/server/media/MediaShellCommand.java b/services/core/java/com/android/server/media/MediaShellCommand.java
index 103cdd9..d175d87 100644
--- a/services/core/java/com/android/server/media/MediaShellCommand.java
+++ b/services/core/java/com/android/server/media/MediaShellCommand.java
@@ -47,15 +47,19 @@
* ShellCommand for MediaSessionService.
*/
public class MediaShellCommand extends ShellCommand {
- // This doesn't belongs to any package. Setting the package name to empty string.
- private static final String PACKAGE_NAME = "";
private static ActivityThread sThread;
private static MediaSessionManager sMediaSessionManager;
+
+ private final String mPackageName;
private ISessionManager mSessionService;
private PrintWriter mWriter;
private PrintWriter mErrorWriter;
private InputStream mInput;
+ public MediaShellCommand(String packageName) {
+ mPackageName = packageName;
+ }
+
@Override
public int onCommand(String cmd) {
mWriter = getOutPrintWriter();
@@ -110,7 +114,7 @@
mWriter.println();
mWriter.println("media_session dispatch: dispatch a media key to the system.");
mWriter.println(" KEY may be: play, pause, play-pause, mute, headsethook,");
- mWriter.println(" stop, next, previous, rewind, record, fast-forword.");
+ mWriter.println(" stop, next, previous, rewind, record, fast-forward.");
mWriter.println("media_session list-sessions: print a list of the current sessions.");
mWriter.println("media_session monitor: monitor updates to the specified session.");
mWriter.println(" Use the tag from list-sessions.");
@@ -120,7 +124,8 @@
private void sendMediaKey(KeyEvent event) {
try {
- mSessionService.dispatchMediaKeyEvent(PACKAGE_NAME, false, event, false);
+ mSessionService.dispatchMediaKeyEvent(
+ mPackageName, /* asSystemService= */ false, event, /* needWakeLock= */ false);
} catch (RemoteException e) {
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 8ed145c..3eee572 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -5827,7 +5827,7 @@
// Add summary
final ApplicationInfo appInfo =
adjustedSbn.getNotification().extras.getParcelable(
- Notification.EXTRA_BUILDER_APPLICATION_INFO);
+ Notification.EXTRA_BUILDER_APPLICATION_INFO, ApplicationInfo.class);
final Bundle extras = new Bundle();
extras.putParcelable(Notification.EXTRA_BUILDER_APPLICATION_INFO, appInfo);
final String channelId = notificationRecord.getChannel().getId();
diff --git a/services/core/java/com/android/server/pm/AppsFilterImpl.java b/services/core/java/com/android/server/pm/AppsFilterImpl.java
index b4ddda5..dff7100 100644
--- a/services/core/java/com/android/server/pm/AppsFilterImpl.java
+++ b/services/core/java/com/android/server/pm/AppsFilterImpl.java
@@ -228,15 +228,6 @@
* Watchable machinery
*/
private final WatchableImpl mWatchable = new WatchableImpl();
- /**
- * The observer that watches for changes from array members
- */
- private final Watcher mObserver = new Watcher() {
- @Override
- public void onChange(@Nullable Watchable what) {
- AppsFilterImpl.this.dispatchChange(what);
- }
- };
/**
* Ensures an observer is in the list, exactly once. The observer cannot be null. The
@@ -331,8 +322,6 @@
mProtectedBroadcastsSnapshot = new SnapshotCache.Auto<>(
mProtectedBroadcasts, mProtectedBroadcasts, "AppsFilter.mProtectedBroadcasts");
- registerObservers();
- Watchable.verifyWatchedAttributes(this, mObserver);
mSnapshot = makeCache();
}
@@ -375,18 +364,6 @@
mSystemReady = true;
}
- @SuppressWarnings("GuardedBy")
- private void registerObservers() {
- mImplicitlyQueryable.registerObserver(mObserver);
- mRetainedImplicitlyQueryable.registerObserver(mObserver);
- mQueriesViaPackage.registerObserver(mObserver);
- mQueriesViaComponent.registerObserver(mObserver);
- mQueryableViaUsesLibrary.registerObserver(mObserver);
- mForceQueryable.registerObserver(mObserver);
- mProtectedBroadcasts.registerObserver(mObserver);
- mShouldFilterCache.registerObserver(mObserver);
- }
-
/**
* Return a snapshot. If the cached snapshot is null, build a new one. The logic in
* the function ensures that this function returns a valid snapshot even if a race
@@ -773,9 +750,7 @@
mShouldFilterCache.put(recipientUid, visibleUid, false);
}
}
- if (changed) {
- onChanged();
- }
+ onChanged();
return changed;
}
@@ -986,6 +961,7 @@
}
updateEntireShouldFilterCacheInner(settings, users, userId);
});
+ onChanged();
}
private void updateEntireShouldFilterCacheInner(
@@ -1008,8 +984,7 @@
private void updateEntireShouldFilterCacheAsync() {
mBackgroundExecutor.execute(() -> {
final ArrayMap<String, PackageStateInternal> settingsCopy = new ArrayMap<>();
- final Collection<SharedUserSetting> sharedUserSettingsCopy =
- new ArraySet<SharedUserSetting>();
+ final Collection<SharedUserSetting> sharedUserSettingsCopy = new ArraySet<>();
final ArrayMap<String, AndroidPackage> packagesCache = new ArrayMap<>();
final UserInfo[][] usersRef = new UserInfo[1][];
mStateProvider.runWithState((settings, sharedUserSettings, users) -> {
@@ -1049,6 +1024,7 @@
} else {
updateEntireShouldFilterCacheInner(settingsCopy,
usersRef[0], USER_ALL);
+ onChanged();
}
});
}
@@ -1058,7 +1034,6 @@
return;
}
updateEntireShouldFilterCache(newUserId);
- onChanged();
}
public void onUserDeleted(@UserIdInt int userId) {
@@ -1078,6 +1053,7 @@
settings.get(packageName), settings, users, USER_ALL,
settings.size() /*maxIndex*/);
});
+ onChanged();
}
private void updateShouldFilterCacheForPackage(
@@ -1389,9 +1365,8 @@
}
}
}
-
- onChanged();
});
+ onChanged();
}
private ArraySet<? extends PackageStateInternal> getSharedUserPackages(int sharedUserAppId,
@@ -1495,6 +1470,7 @@
mStateProvider.runWithState((settings, sharedUserSettings, users) ->
callingSharedPkgSettings.addAll(getSharedUserPackages(
packageState.getSharedUserAppId(), sharedUserSettings)));
+
} else {
callingPkgSetting = packageState;
}
@@ -1624,9 +1600,12 @@
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueriesViaComponent");
}
if (mQueriesViaComponentRequireRecompute) {
+ final ArrayMap<String, PackageStateInternal> settingsCopy = new ArrayMap<>();
mStateProvider.runWithState((settings, sharedUserSettings, users) -> {
- recomputeComponentVisibility(settings);
+ settingsCopy.putAll(settings);
});
+ recomputeComponentVisibility(settingsCopy);
+ onChanged();
}
synchronized (mLock) {
if (mQueriesViaComponent.contains(callingAppId, targetAppId)) {
diff --git a/services/core/java/com/android/server/pm/ChangedPackagesTracker.java b/services/core/java/com/android/server/pm/ChangedPackagesTracker.java
index bd12981..3802135 100644
--- a/services/core/java/com/android/server/pm/ChangedPackagesTracker.java
+++ b/services/core/java/com/android/server/pm/ChangedPackagesTracker.java
@@ -90,25 +90,27 @@
}
void updateSequenceNumber(@NonNull String packageName, int[] userList) {
- for (int i = userList.length - 1; i >= 0; --i) {
- final int userId = userList[i];
- SparseArray<String> changedPackages = mUserIdToSequenceToPackage.get(userId);
- if (changedPackages == null) {
- changedPackages = new SparseArray<>();
- mUserIdToSequenceToPackage.put(userId, changedPackages);
+ synchronized (mLock) {
+ for (int i = userList.length - 1; i >= 0; --i) {
+ final int userId = userList[i];
+ SparseArray<String> changedPackages = mUserIdToSequenceToPackage.get(userId);
+ if (changedPackages == null) {
+ changedPackages = new SparseArray<>();
+ mUserIdToSequenceToPackage.put(userId, changedPackages);
+ }
+ Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
+ if (sequenceNumbers == null) {
+ sequenceNumbers = new HashMap<>();
+ mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
+ }
+ final Integer sequenceNumber = sequenceNumbers.get(packageName);
+ if (sequenceNumber != null) {
+ changedPackages.remove(sequenceNumber);
+ }
+ changedPackages.put(mChangedPackagesSequenceNumber, packageName);
+ sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber);
}
- Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
- if (sequenceNumbers == null) {
- sequenceNumbers = new HashMap<>();
- mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
- }
- final Integer sequenceNumber = sequenceNumbers.get(packageName);
- if (sequenceNumber != null) {
- changedPackages.remove(sequenceNumber);
- }
- changedPackages.put(mChangedPackagesSequenceNumber, packageName);
- sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber);
+ mChangedPackagesSequenceNumber++;
}
- mChangedPackagesSequenceNumber++;
}
}
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 77d37dc..bbdb7eb 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -266,8 +266,11 @@
// Prune unused SharedUserSetting
if (mPm.mSettings.checkAndPruneSharedUserLPw(requestSharedUserSetting, false)) {
// Set the app ID in removed info for UID_REMOVED broadcasts
- reconciledPkg.mInstallResult.mRemovedInfo.mRemovedAppId =
- requestSharedUserSetting.mAppId;
+ if (reconciledPkg.mInstallResult != null
+ && reconciledPkg.mInstallResult.mRemovedInfo != null) {
+ reconciledPkg.mInstallResult.mRemovedInfo.mRemovedAppId =
+ requestSharedUserSetting.mAppId;
+ }
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d5e2a63..ffd924e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1543,6 +1543,7 @@
}
// Link watchables to the class
+ @SuppressWarnings("GuardedBy")
private void registerObservers(boolean verify) {
// Null check to handle nullable test parameters
if (mPackages != null) {
@@ -2256,7 +2257,7 @@
@GuardedBy("mLock")
void updateInstantAppInstallerLocked(String modifiedPackage) {
- // we're only interested in updating the installer appliction when 1) it's not
+ // we're only interested in updating the installer application when 1) it's not
// already set or 2) the modified package is the installer
if (mInstantAppInstallerActivity != null
&& !mInstantAppInstallerActivity.getComponentName().getPackageName()
@@ -2740,7 +2741,6 @@
return mModuleInfoProvider.getModuleInfo(packageName, flags);
}
- @GuardedBy("mLock")
void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
mChangedPackagesTracker.updateSequenceNumber(pkgSetting.getPackageName(), userList);
}
@@ -3074,8 +3074,8 @@
userId);
}
- private void enforceCanSetDistractingPackageRestrictionsAsUser(@NonNull Computer snapshot,
- int callingUid, int userId, String callingMethod) {
+ private void enforceCanSetDistractingPackageRestrictionsAsUser(int callingUid, int userId,
+ String callingMethod) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
callingMethod);
@@ -3159,6 +3159,7 @@
}
}
+ @SuppressWarnings("GuardedBy")
VersionInfo getSettingsVersionForPackage(AndroidPackage pkg) {
if (pkg.isExternalStorage()) {
if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
@@ -3288,6 +3289,7 @@
* Update component enabled settings to {@link PackageManager#COMPONENT_ENABLED_STATE_DEFAULT}
* if the resetEnabledSettingsOnAppDataCleared is {@code true}.
*/
+ @GuardedBy("mLock")
private void resetComponentEnabledSettingsIfNeededLPw(String packageName, int userId) {
final AndroidPackage pkg = packageName != null ? mPackages.get(packageName) : null;
if (pkg == null || !pkg.isResetEnabledSettingsOnAppDataCleared()) {
@@ -3879,6 +3881,7 @@
}
}
+ @GuardedBy("mLock")
private boolean setEnabledSettingInternalLocked(@NonNull Computer computer,
PackageSetting pkgSetting, ComponentEnabledSetting setting, @UserIdInt int userId,
String callingPackage) {
@@ -4554,7 +4557,9 @@
final Computer snapshot = snapshotComputer();
unsuspendForSuspendingPackage(snapshot, packageName, userId);
removeAllDistractingPackageRestrictions(snapshot, userId);
- flushPackageRestrictionsAsUserInternalLocked(userId);
+ synchronized (mLock) {
+ flushPackageRestrictionsAsUserInternalLocked(userId);
+ }
}
}
if (observer != null) {
@@ -4972,6 +4977,7 @@
}
@Override
+ @SuppressWarnings("GuardedBy")
public int getRuntimePermissionsVersion(@UserIdInt int userId) {
Preconditions.checkArgumentNonnegative(userId);
enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
@@ -5576,7 +5582,7 @@
int restrictionFlags, int userId) {
final int callingUid = Binder.getCallingUid();
final Computer snapshot = snapshotComputer();
- enforceCanSetDistractingPackageRestrictionsAsUser(snapshot, callingUid, userId,
+ enforceCanSetDistractingPackageRestrictionsAsUser(callingUid, userId,
"setDistractingPackageRestrictionsAsUser");
Objects.requireNonNull(packageNames, "packageNames cannot be null");
return mDistractingPackageHelper.setDistractingPackageRestrictionsAsUser(snapshot,
@@ -5845,6 +5851,7 @@
}
@Override
+ @SuppressWarnings("GuardedBy")
public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) {
Preconditions.checkArgumentNonnegative(version);
Preconditions.checkArgumentNonnegative(userId);
@@ -6363,6 +6370,7 @@
}
@Override
+ @SuppressWarnings("GuardedBy")
public void updateRuntimePermissionsFingerprint(@UserIdInt int userId) {
mSettings.updateRuntimePermissionsFingerprint(userId);
}
@@ -6397,6 +6405,7 @@
}
@Override
+ @SuppressWarnings("GuardedBy")
public boolean isPermissionUpgradeNeeded(int userId) {
return mSettings.isPermissionUpgradeNeeded(userId);
}
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 056f255..9627c43 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -105,6 +105,7 @@
import android.util.Xml;
import android.view.IWindowManager;
+import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
@@ -455,6 +456,8 @@
private final boolean mIsAppSearchEnabled;
+ private ComponentName mChooserActivity;
+
static class InvalidFileFormatException extends Exception {
public InvalidFileFormatException(String message, Throwable cause) {
super(message, cause);
@@ -1646,6 +1649,26 @@
return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID;
}
+ @VisibleForTesting
+ ComponentName injectChooserActivity() {
+ if (mChooserActivity == null) {
+ mChooserActivity = ComponentName.unflattenFromString(
+ mContext.getResources().getString(R.string.config_chooserActivity));
+ }
+ return mChooserActivity;
+ }
+
+ private boolean isCallerChooserActivity() {
+ // TODO(b/228975502): Migrate this check to a proper permission or role check
+ final int callingUid = injectBinderCallingUid();
+ ComponentName systemChooser = injectChooserActivity();
+ if (systemChooser == null) {
+ return false;
+ }
+ int uid = injectGetPackageUid(systemChooser.getPackageName(), UserHandle.USER_SYSTEM);
+ return uid == callingUid;
+ }
+
private void enforceSystemOrShell() {
if (!(isCallerSystem() || isCallerShell())) {
throw new SecurityException("Caller must be system or shell");
@@ -2525,7 +2548,9 @@
IntentFilter filter, @UserIdInt int userId) {
Preconditions.checkStringNotEmpty(packageName, "packageName");
Objects.requireNonNull(filter, "intentFilter");
- verifyCaller(packageName, userId);
+ if (!isCallerChooserActivity()) {
+ verifyCaller(packageName, userId);
+ }
enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_APP_PREDICTIONS,
"getShareTargets");
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java
index 0e6d5e5..8dc9428 100644
--- a/services/core/java/com/android/server/pm/UserManagerInternal.java
+++ b/services/core/java/com/android/server/pm/UserManagerInternal.java
@@ -92,21 +92,6 @@
public abstract void setDevicePolicyUserRestrictions(int originatingUserId,
@Nullable Bundle global, @Nullable RestrictionsSet local, boolean isDeviceOwner);
- /**
- * Returns the "base" user restrictions.
- *
- * Used by {@link com.android.server.devicepolicy.DevicePolicyManagerService} for upgrading
- * from MNC.
- */
- public abstract Bundle getBaseUserRestrictions(int userId);
-
- /**
- * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} for upgrading
- * from MNC.
- */
- public abstract void setBaseUserRestrictionsByDpmsForMigration(int userId,
- Bundle baseRestrictions);
-
/** Return a user restriction. */
public abstract boolean getUserRestriction(int userId, String key);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index cb08c79..358e71a 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -5900,33 +5900,6 @@
}
@Override
- public Bundle getBaseUserRestrictions(@UserIdInt int userId) {
- synchronized (mRestrictionsLock) {
- return mBaseUserRestrictions.getRestrictions(userId);
- }
- }
-
- @Override
- public void setBaseUserRestrictionsByDpmsForMigration(
- @UserIdInt int userId, Bundle baseRestrictions) {
- synchronized (mRestrictionsLock) {
- if (mBaseUserRestrictions.updateRestrictions(userId,
- new Bundle(baseRestrictions))) {
- invalidateEffectiveUserRestrictionsLR(userId);
- }
- }
-
- final UserData userData = getUserDataNoChecks(userId);
- synchronized (mPackagesLock) {
- if (userData != null) {
- writeUserLP(userData);
- } else {
- Slog.w(LOG_TAG, "UserInfo not found for " + userId);
- }
- }
- }
-
- @Override
public boolean getUserRestriction(@UserIdInt int userId, String key) {
return getUserRestrictions(userId).getBoolean(key);
}
diff --git a/services/core/java/com/android/server/pm/resolution/ComponentResolver.java b/services/core/java/com/android/server/pm/resolution/ComponentResolver.java
index 9aa53f1..7baec62 100644
--- a/services/core/java/com/android/server/pm/resolution/ComponentResolver.java
+++ b/services/core/java/com/android/server/pm/resolution/ComponentResolver.java
@@ -79,7 +79,8 @@
import java.util.function.Function;
/** Resolves all Android component types [activities, services, providers and receivers]. */
-public class ComponentResolver extends ComponentResolverLocked implements Snappable {
+public class ComponentResolver extends ComponentResolverLocked implements
+ Snappable<ComponentResolverApi> {
private static final boolean DEBUG = false;
private static final String TAG = "PackageManager";
private static final boolean DEBUG_FILTERS = false;
@@ -166,11 +167,13 @@
mProvidersByAuthority = new ArrayMap<>();
mDeferProtectedFilters = true;
- mSnapshot = new SnapshotCache<ComponentResolverApi>(this, this) {
+ mSnapshot = new SnapshotCache<>(this, this) {
@Override
public ComponentResolverApi createSnapshot() {
- return new ComponentResolverSnapshot(ComponentResolver.this,
- userNeedsBadgingCache);
+ synchronized (mLock) {
+ return new ComponentResolverSnapshot(ComponentResolver.this,
+ userNeedsBadgingCache);
+ }
}};
}
diff --git a/services/core/java/com/android/server/policy/SideFpsEventHandler.java b/services/core/java/com/android/server/policy/SideFpsEventHandler.java
index f368698..41d0272 100644
--- a/services/core/java/com/android/server/policy/SideFpsEventHandler.java
+++ b/services/core/java/com/android/server/policy/SideFpsEventHandler.java
@@ -16,9 +16,9 @@
package com.android.server.policy;
-import static android.hardware.fingerprint.FingerprintStateListener.STATE_BP_AUTH;
-import static android.hardware.fingerprint.FingerprintStateListener.STATE_ENROLLING;
-import static android.hardware.fingerprint.FingerprintStateListener.STATE_IDLE;
+import static android.hardware.biometrics.BiometricStateListener.STATE_BP_AUTH;
+import static android.hardware.biometrics.BiometricStateListener.STATE_ENROLLING;
+import static android.hardware.biometrics.BiometricStateListener.STATE_IDLE;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -30,9 +30,9 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.hardware.biometrics.BiometricStateListener;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.hardware.fingerprint.FingerprintStateListener;
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
import android.os.Handler;
import android.os.PowerManager;
@@ -67,7 +67,7 @@
}
};
- private @FingerprintStateListener.State int mFingerprintState;
+ private @BiometricStateListener.State int mBiometricState;
SideFpsEventHandler(Context context, Handler handler, PowerManager powerManager) {
this(context, handler, powerManager, () -> new AlertDialog.Builder(context));
@@ -80,7 +80,7 @@
mHandler = handler;
mPowerManager = powerManager;
mDialogSupplier = dialogSupplier;
- mFingerprintState = STATE_IDLE;
+ mBiometricState = STATE_IDLE;
mSideFpsEventHandlerReady = new AtomicBoolean(false);
// ensure dialog is dismissed if screen goes off for unrelated reasons
@@ -108,7 +108,7 @@
return false;
}
- switch (mFingerprintState) {
+ switch (mBiometricState) {
case STATE_ENROLLING:
case STATE_BP_AUTH:
mHandler.post(() -> {
@@ -116,7 +116,7 @@
mDialog.dismiss();
}
mDialog = showConfirmDialog(mDialogSupplier.get(),
- mPowerManager, eventTime, mFingerprintState, mDialogDismissListener);
+ mPowerManager, eventTime, mBiometricState, mDialogDismissListener);
});
return true;
default:
@@ -127,9 +127,9 @@
@NonNull
private static Dialog showConfirmDialog(@NonNull AlertDialog.Builder dialogBuilder,
@NonNull PowerManager powerManager, long eventTime,
- @FingerprintStateListener.State int fingerprintState,
+ @BiometricStateListener.State int biometricState,
@NonNull DialogInterface.OnDismissListener dismissListener) {
- final boolean enrolling = fingerprintState == STATE_ENROLLING;
+ final boolean enrolling = biometricState == STATE_ENROLLING;
final int title = enrolling ? R.string.fp_power_button_enrollment_title
: R.string.fp_power_button_bp_title;
final int message = enrolling ? R.string.fp_power_button_enrollment_message
@@ -165,8 +165,8 @@
/**
* Awaits notification from PhoneWindowManager that fingerprint service is ready
* to send updates about power button fps sensor state. Then configures a
- * FingerprintStateListener to receive and record updates to fps state, and
- * registers the FingerprintStateListener in FingerprintManager.
+ * BiometricStateListener to receive and record updates to fps state, and
+ * registers the BiometricStateListener in FingerprintManager.
*/
public void onFingerprintSensorReady() {
final PackageManager pm = mContext.getPackageManager();
@@ -182,13 +182,14 @@
public void onAllAuthenticatorsRegistered(
List<FingerprintSensorPropertiesInternal> sensors) {
if (fingerprintManager.isPowerbuttonFps()) {
- fingerprintManager.registerFingerprintStateListener(
- new FingerprintStateListener() {
- @Nullable private Runnable mStateRunnable = null;
+ fingerprintManager.registerBiometricStateListener(
+ new BiometricStateListener() {
+ @Nullable
+ private Runnable mStateRunnable = null;
@Override
public void onStateChanged(
- @FingerprintStateListener.State int newState) {
+ @BiometricStateListener.State int newState) {
if (mStateRunnable != null) {
mHandler.removeCallbacks(mStateRunnable);
mStateRunnable = null;
@@ -198,11 +199,11 @@
// arrive in any order (success auth & power). Add a
// damper when moving to idle in case auth is first
if (newState == STATE_IDLE) {
- mStateRunnable = () -> mFingerprintState = newState;
+ mStateRunnable = () -> mBiometricState = newState;
mHandler.postDelayed(mStateRunnable,
DEBOUNCE_DELAY_MILLIS);
} else {
- mFingerprintState = newState;
+ mBiometricState = newState;
}
}
});
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index aede4b1..685b744 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -64,6 +64,8 @@
import com.android.server.statusbar.StatusBarManagerInternal;
import java.io.PrintWriter;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* Sends broadcasts about important power state changes.
@@ -133,6 +135,7 @@
private final DisplayManagerInternal mDisplayManagerInternal;
private final NotifierHandler mHandler;
+ private final Executor mBackgroundExecutor;
private final Intent mScreenOnIntent;
private final Intent mScreenOffIntent;
@@ -169,9 +172,12 @@
// True if a user activity message should be sent.
private boolean mUserActivityPending;
+ private final AtomicBoolean mIsPlayingChargingStartedFeedback = new AtomicBoolean(false);
+
public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
- FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector) {
+ FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector,
+ Executor backgroundExecutor) {
mContext = context;
mBatteryStats = batteryStats;
mAppOps = mContext.getSystemService(AppOpsManager.class);
@@ -188,6 +194,7 @@
mVibrator = mContext.getSystemService(Vibrator.class);
mHandler = new NotifierHandler(looper);
+ mBackgroundExecutor = backgroundExecutor;
mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
mScreenOnIntent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND
@@ -824,25 +831,36 @@
return;
}
- // vibrate
- final boolean vibrate = Settings.Secure.getIntForUser(mContext.getContentResolver(),
- Settings.Secure.CHARGING_VIBRATION_ENABLED, 1, userId) != 0;
- if (vibrate) {
- mVibrator.vibrate(CHARGING_VIBRATION_EFFECT, HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
+ if (!mIsPlayingChargingStartedFeedback.compareAndSet(false, true)) {
+ // there's already a charging started feedback Runnable scheduled to run on the
+ // background thread, so let's not execute another
+ return;
}
- // play sound
- final String soundPath = Settings.Global.getString(mContext.getContentResolver(),
- wireless ? Settings.Global.WIRELESS_CHARGING_STARTED_SOUND
- : Settings.Global.CHARGING_STARTED_SOUND);
- final Uri soundUri = Uri.parse("file://" + soundPath);
- if (soundUri != null) {
- final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
- if (sfx != null) {
- sfx.setStreamType(AudioManager.STREAM_SYSTEM);
- sfx.play();
+ // vibrate & play sound on a background thread
+ mBackgroundExecutor.execute(() -> {
+ // vibrate
+ final boolean vibrate = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.CHARGING_VIBRATION_ENABLED, 1, userId) != 0;
+ if (vibrate) {
+ mVibrator.vibrate(CHARGING_VIBRATION_EFFECT,
+ HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
}
- }
+
+ // play sound
+ final String soundPath = Settings.Global.getString(mContext.getContentResolver(),
+ wireless ? Settings.Global.WIRELESS_CHARGING_STARTED_SOUND
+ : Settings.Global.CHARGING_STARTED_SOUND);
+ final Uri soundUri = Uri.parse("file://" + soundPath);
+ if (soundUri != null) {
+ final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
+ if (sfx != null) {
+ sfx.setStreamType(AudioManager.STREAM_SYSTEM);
+ sfx.play();
+ }
+ }
+ mIsPlayingChargingStartedFeedback.set(false);
+ });
}
private void showWirelessChargingStarted(int batteryLevel, @UserIdInt int userId) {
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 6e78ecb..e0da0e8 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -140,6 +140,7 @@
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
+import java.util.concurrent.Executor;
/**
* The power manager service is responsible for coordinating power management
@@ -905,10 +906,11 @@
static class Injector {
Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
- FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector) {
+ FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector,
+ Executor backgroundExecutor) {
return new Notifier(
looper, context, batteryStats, suspendBlocker, policy, faceDownDetector,
- screenUndimDetector);
+ screenUndimDetector, backgroundExecutor);
}
SuspendBlocker createSuspendBlocker(PowerManagerService service, String name) {
@@ -1227,7 +1229,8 @@
mBatteryStats = BatteryStatsService.getService();
mNotifier = mInjector.createNotifier(Looper.getMainLooper(), mContext, mBatteryStats,
mInjector.createSuspendBlocker(this, "PowerManagerService.Broadcasts"),
- mPolicy, mFaceDownDetector, mScreenUndimDetector);
+ mPolicy, mFaceDownDetector, mScreenUndimDetector,
+ BackgroundThread.getExecutor());
mPowerGroups.append(Display.DEFAULT_DISPLAY_GROUP,
new PowerGroup(WAKEFULNESS_AWAKE, mPowerGroupWakefulnessChangeListener,
diff --git a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
index bce1cce..0834417 100644
--- a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
@@ -560,7 +560,7 @@
+ " sensors");
return;
}
- mContext.startActivityAsUser(dialogIntent, options.toBundle(), info.mUser);
+ mContext.startActivityAsUser(dialogIntent, options.toBundle(), UserHandle.SYSTEM);
}
/**
diff --git a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java
index ae52912..7173f60 100644
--- a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java
@@ -59,6 +59,8 @@
*/
private static final Set<String> CONFIGURATION_INTERNAL_SERVER_FLAGS_KEYS_TO_WATCH = Set.of(
ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_FEATURE_SUPPORTED,
+ ServerFlags.KEY_PRIMARY_LTZP_MODE_OVERRIDE,
+ ServerFlags.KEY_SECONDARY_LTZP_MODE_OVERRIDE,
ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_RUN_IN_BACKGROUND_ENABLED,
ServerFlags.KEY_ENHANCED_METRICS_COLLECTION_ENABLED,
ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT,
@@ -443,6 +445,9 @@
mTestPrimaryLocationTimeZoneProviderMode =
mTestPrimaryLocationTimeZoneProviderPackageName == null
? PROVIDER_MODE_DISABLED : PROVIDER_MODE_ENABLED;
+ // Changing this state can affect the content of ConfigurationInternal, so listeners need to
+ // be informed.
+ mContext.getMainThreadHandler().post(this::handleConfigurationInternalChangeOnMainThread);
}
@Override
@@ -469,6 +474,9 @@
mTestSecondaryLocationTimeZoneProviderMode =
mTestSecondaryLocationTimeZoneProviderPackageName == null
? PROVIDER_MODE_DISABLED : PROVIDER_MODE_ENABLED;
+ // Changing this state can affect the content of ConfigurationInternal, so listeners need to
+ // be informed.
+ mContext.getMainThreadHandler().post(this::handleConfigurationInternalChangeOnMainThread);
}
@Override
@@ -573,6 +581,10 @@
mTestSecondaryLocationTimeZoneProviderPackageName = null;
mTestSecondaryLocationTimeZoneProviderMode = null;
mRecordStateChangesForTests = false;
+
+ // Changing LTZP config can affect the content of ConfigurationInternal, so listeners
+ // need to be informed.
+ mContext.getMainThreadHandler().post(this::handleConfigurationInternalChangeOnMainThread);
}
private boolean isTelephonyFallbackSupported() {
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
index f75608e..898d02e 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
@@ -336,13 +336,13 @@
boolean isTelephonyTimeZoneDetectionSupported() {
enforceManageTimeZoneDetectorPermission();
- return mServiceConfigAccessor.isTelephonyTimeZoneDetectionFeatureSupported();
+ return mTimeZoneDetectorStrategy.isTelephonyTimeZoneDetectionSupported();
}
boolean isGeoTimeZoneDetectionSupported() {
enforceManageTimeZoneDetectorPermission();
- return mServiceConfigAccessor.isGeoTimeZoneDetectionFeatureSupported();
+ return mTimeZoneDetectorStrategy.isGeoTimeZoneDetectionSupported();
}
/**
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
index 6b04adf..95ebd68 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
@@ -124,4 +124,10 @@
/** Generates a state snapshot for metrics. */
@NonNull
MetricsTimeZoneDetectorState generateMetricsState();
+
+ /** Returns {@code true} if the device supports telephony time zone detection. */
+ boolean isTelephonyTimeZoneDetectionSupported();
+
+ /** Returns {@code true} if the device supports geolocation time zone detection. */
+ boolean isGeoTimeZoneDetectionSupported();
}
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
index e21d0e4..66c23f5 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
@@ -396,6 +396,20 @@
getLatestGeolocationSuggestion());
}
+ @Override
+ public boolean isTelephonyTimeZoneDetectionSupported() {
+ synchronized (this) {
+ return mCurrentConfigurationInternal.isTelephonyDetectionSupported();
+ }
+ }
+
+ @Override
+ public boolean isGeoTimeZoneDetectionSupported() {
+ synchronized (this) {
+ return mCurrentConfigurationInternal.isGeoDetectionSupported();
+ }
+ }
+
private static int scoreTelephonySuggestion(@NonNull TelephonyTimeZoneSuggestion suggestion) {
int score;
if (suggestion.getZoneId() == null) {
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index c52a4e4..63619e5 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -446,20 +446,6 @@
// Not relevant for the window observer.
}
- MagnificationSpec getMagnificationSpecForWindow(WindowState windowState) {
- if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
- mAccessibilityTracing.logTrace(TAG + ".getMagnificationSpecForWindow",
- FLAGS_MAGNIFICATION_CALLBACK,
- "windowState={" + windowState + "}");
- }
- final int displayId = windowState.getDisplayId();
- final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId);
- if (displayMagnifier != null) {
- return displayMagnifier.getMagnificationSpecForWindow(windowState);
- }
- return null;
- }
-
boolean hasCallbacks() {
if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK
| FLAGS_WINDOWS_FOR_ACCESSIBILITY_CALLBACK)) {
diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
index ca636b3..6e5011d 100644
--- a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
+++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
@@ -596,8 +596,6 @@
* surface flinger to the accessibility framework.
*/
public static class AccessibilityWindow {
- private static final Region TEMP_REGION = new Region();
- private static final RectF TEMP_RECTF = new RectF();
// Data
private IWindow mWindow;
private int mDisplayId;
@@ -615,15 +613,16 @@
private final Region mLetterBoxBounds = new Region();
private WindowInfo mWindowInfo;
+
/**
* Returns the instance after initializing the internal data.
* @param service The window manager service.
* @param inputWindowHandle The window from the surface flinger.
- * @param inverseMatrix The magnification spec inverse matrix.
+ * @param magnificationInverseMatrix The magnification spec inverse matrix.
*/
public static AccessibilityWindow initializeData(WindowManagerService service,
- InputWindowHandle inputWindowHandle, Matrix inverseMatrix, IBinder pipIBinder,
- Matrix displayMatrix) {
+ InputWindowHandle inputWindowHandle, Matrix magnificationInverseMatrix,
+ IBinder pipIBinder, Matrix displayMatrix) {
final IWindow window = inputWindowHandle.getWindow();
final WindowState windowState = window != null ? service.mWindowMap.get(
window.asBinder()) : null;
@@ -655,13 +654,35 @@
inputWindowHandle.frameTop, inputWindowHandle.frameRight,
inputWindowHandle.frameBottom);
getTouchableRegionInWindow(instance.mShouldMagnify, inputWindowHandle.touchableRegion,
- instance.mTouchableRegionInWindow, windowFrame, inverseMatrix, displayMatrix);
+ instance.mTouchableRegionInWindow, windowFrame, magnificationInverseMatrix,
+ displayMatrix);
getUnMagnifiedTouchableRegion(instance.mShouldMagnify,
inputWindowHandle.touchableRegion, instance.mTouchableRegionInScreen,
- inverseMatrix, displayMatrix);
+ magnificationInverseMatrix, displayMatrix);
instance.mWindowInfo = windowState != null
? windowState.getWindowInfo() : getWindowInfoForWindowlessWindows(instance);
+ // Compute the transform matrix that will transform bounds from the window
+ // coordinates to screen coordinates.
+ final Matrix inverseTransform = new Matrix();
+ inputWindowHandle.transform.invert(inverseTransform);
+ inverseTransform.postConcat(displayMatrix);
+ inverseTransform.getValues(instance.mWindowInfo.mTransformMatrix);
+
+ // Compute the magnification spec matrix.
+ final Matrix magnificationSpecMatrix = new Matrix();
+ if (instance.shouldMagnify() && magnificationInverseMatrix != null
+ && !magnificationInverseMatrix.isIdentity()) {
+ if (magnificationInverseMatrix.invert(magnificationSpecMatrix)) {
+ magnificationSpecMatrix.getValues(sTempFloats);
+ final MagnificationSpec spec = instance.mWindowInfo.mMagnificationSpec;
+ spec.scale = sTempFloats[Matrix.MSCALE_X];
+ spec.offsetX = sTempFloats[Matrix.MTRANS_X];
+ spec.offsetY = sTempFloats[Matrix.MTRANS_Y];
+ } else {
+ Slog.w(TAG, "can't find spec");
+ }
+ }
return instance;
}
@@ -779,7 +800,7 @@
// for the consistency and match developers expectation.
// So we need to make the intersection between the frame and touchable region to
// obtain the real touch region in the screen.
- Region touchRegion = TEMP_REGION;
+ Region touchRegion = new Region();
touchRegion.set(inRegion);
touchRegion.op(frame, Region.Op.INTERSECT);
@@ -807,8 +828,7 @@
forEachRect(inRegion, rect -> {
// Move to origin as all transforms are captured by the matrix.
- RectF windowFrame = TEMP_RECTF;
- windowFrame.set(rect);
+ RectF windowFrame = new RectF(rect);
displayMatrix.mapRect(windowFrame);
inverseMatrix.mapRect(windowFrame);
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 36a7c77..75d4621 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2644,14 +2644,16 @@
Slog.w(TAG, "startActivity called from finishing " + mSourceRecord
+ "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
- mNewTaskInfo = mSourceRecord.info;
- // It is not guaranteed that the source record will have a task associated with it. For,
- // example, if this method is being called for processing a pending activity launch, it
- // is possible that the activity has been removed from the task after the launch was
- // enqueued.
+ // It is not guaranteed that the source record will have a task associated with it.
+ // For example, if this method is being called for processing a pending activity
+ // launch, it is possible that the activity has been removed from the task after the
+ // launch was enqueued.
final Task sourceTask = mSourceRecord.getTask();
- mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
+ if (sourceTask == null || sourceTask.getTopNonFinishingActivity() == null) {
+ mNewTaskInfo = mSourceRecord.info;
+ mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
+ }
}
mSourceRecord = null;
mSourceRootTask = null;
diff --git a/services/core/java/com/android/server/wm/BLASTSync.md b/services/core/java/com/android/server/wm/BLASTSync.md
index 2f39d6d..dbb28d4 100644
--- a/services/core/java/com/android/server/wm/BLASTSync.md
+++ b/services/core/java/com/android/server/wm/BLASTSync.md
@@ -106,3 +106,88 @@
at the same time as the state? We solve this by pushing all client communication through a handler thread that has to
acquire the lock. This ensures we uphold requirement 2.
+= Transaction ordering =
+
+Applying transactions from different process, and in to different server side transaction queues
+raises various questions about transaction ordering. There are two tricky questions in this
+domain that we address here:
+ 1. The ordering of Transactions from a single BLASTBufferQueue wrt to eachother
+ 2. The ordering of non synced WM updates to syncable state, wrt a BLASTSyncEngine
+ transaction
+
+== Ordering of Transactions in a single BBQ ==
+
+We can see if sync is never involved, there are never any real questions about ordering.
+Even using one-way setTransactionState, the calls are from a single thread to a single
+interface on another, and will be ordered. When we hand out transactions for sync
+is where issues can start to arise. Obviously if we apply another transaction
+immediately after handing out the sync transaction it could arrive first, and this would
+cause an ordering issue. It's also possible that the sync transaction arrives before the
+transaction applied before it (since setTransactionState is one way from BBQ). Even if
+the transactions are applied in the right order, it's possible for them to be
+commited out of sync, as the BBQ and SyncConsumer may be using different apply tokens
+resulting in the transaction being placed in different server side queues.
+
+To solve these issues, we use a scheme involving "barrier transactions". We show how
+this scheme handles every permutation of (Sync, NotSync).
+
+1. NotSync, NotSync: This is the trivial case. As long as both buffers are submitted from
+ the same thread, they will arrive in SF in order, and SF will place them in the same
+ queue (since there is a shared apply token), which it will process in order.
+2. Sync, NotSync: For sync transactions we register a commit callback, and require it to
+ be fired before applying the next transaction. Since the commit callback is only
+ fired when the transaction has latched on the server side, any transaction applied
+ later, must occur later.
+3. Sync, Sync: Ordering of consecutive sync transactions is delegated to the sync
+ consumer
+4. NotSync, Sync: This is the trickiest case, as we don't want to set a commit callback
+ on not sync transactions (as this would incur an unacceptable performance overhead).
+ Further complicating matters, we want to apply them with one-way binder, since
+ this is the hot path for all graphical updates. To solve this we use a
+ "setBufferHasBarrier" system. Sync transactions (before they are handed out)
+ are tagged with a barrier, referring to the frame number of the last
+ non sync transaction. SurfaceFlinger will ensure the correct ordering
+ by stalling transactions in the queue until barriers are fulfilled. This barrier
+ primitive is dangerous, because it could result in deadlocking, but its ok in
+ this scenario since only BBQ uses its apply token.
+
+We can see from this that all frames are in order.
+
+== Ordering of WM updates to syncable state ==
+
+A second interesting question, is about the ordering of WM updates to syncable-state. In
+the WM we frequently write code like
+ getPendingTransaction/getSyncTransaction().show(mSurfaceControl).
+In normal operation, getSyncTransaction and getPendingTransaction both refer to the same
+transaction which is the displaycontent pendingtransaction, applied by the WindowManager.
+During sync, each syncing container will instead use its mSyncTransaction, which will
+eventually be merged to be applied by the WindowManager. We can see that we have a congruent
+"problem" to BLASTBufferQueue transaction ordering. Namely, earlier state updates which were
+given to SysUI could end up being applied later than state updates which were made later but
+directly applied by the WM. We can break this down in to two cases:
+=== getPendingTransaction() and getSyncTransaction() ordering ===
+It's possible for code like this to occur:
+getSyncTransaction().OP1
+getPendingTransaction().OP2
+applyPendingTransaction
+applySyncTransaction
+
+in this case the change in OP2 was made later, but occurs first. We define this case as
+intended behavior, and say there is no ordering guarantee between the pending
+and sync transactions. This means the pending transaction is only useful in
+some marginal cases and should probably be considered a deprecated primitive.
+=== getSyncTransaction() and getSyncTransaction() ordering ===
+However, we take great care to ensure usage of getSyncTransaction() reflects
+the ordering the developer would expect. BLASTSyncEngine will register
+a commit callback on all transactions it hands out. In the interval between
+receiving this commit callback and sending out the transaction, we may have other
+data enter getSyncTransaction. If we returned the pending transaction
+(as we do in normal time), then we could create ordering issues, since the pending
+transactions ordering is undefined. Instead we continue to return the sync transaction
+during this interval. If no second sync has started by the time we receive
+the commit callback, then we directly apply this left over data in the sync transaction
+guaranteed it will be ordered correctly, and return to using the pending
+transaction. If a second sync has started, then we just allow the data
+to persist in the mSyncTransaction, potentially to be overwritten
+by the new sync. It will eventually apply with SysUI's apply token and
+ordering will be maintained.
diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
index 6e205be..3f300bc 100644
--- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java
+++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
@@ -19,6 +19,7 @@
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SYNC_ENGINE;
+import static com.android.server.wm.WindowManagerService.H.WINDOW_STATE_BLAST_SYNC_TIMEOUT;
import android.annotation.NonNull;
import android.os.Trace;
@@ -147,6 +148,33 @@
for (WindowContainer wc : mRootMembers) {
wc.finishSync(merged, false /* cancel */);
}
+
+ final ArraySet<WindowContainer> wcAwaitingCommit = new ArraySet<>();
+ for (WindowContainer wc : mRootMembers) {
+ wc.waitForSyncTransactionCommit(wcAwaitingCommit);
+ }
+ final Runnable callback = new Runnable() {
+ // Can run a second time if the action completes after the timeout.
+ boolean ran = false;
+ public void run() {
+ synchronized (mWm.mGlobalLock) {
+ if (ran) {
+ return;
+ }
+ mWm.mH.removeCallbacks(this);
+ ran = true;
+ SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ for (WindowContainer wc : wcAwaitingCommit) {
+ wc.onSyncTransactionCommitted(t);
+ }
+ t.apply();
+ wcAwaitingCommit.clear();
+ }
+ }
+ };
+ merged.addTransactionCommittedListener((r) -> { r.run(); }, callback::run);
+ mWm.mH.postDelayed(callback, WINDOW_STATE_BLAST_SYNC_TIMEOUT);
+
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "onTransactionReady");
mListener.onTransactionReady(mSyncId, merged);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index b37f980..0ed6718 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -167,6 +167,23 @@
currentActivity = window.mActivityRecord;
currentTask = window.getTask();
callbackInfo = window.getOnBackInvokedCallbackInfo();
+ final DisplayContent displayContent = window.getDisplayContent();
+
+ // When IME is shown, return the more prioritized callback between IME and app.
+ // Priority ordering follows: OVERLAY, IME, DEFAULT.
+ if (displayContent != null && displayContent.getImeContainer().isVisible()) {
+ WindowState imeWindow = displayContent.getImeContainer().getWindow(
+ windowState -> windowState.getOnBackInvokedCallbackInfo() != null);
+ if (imeWindow != null) {
+ OnBackInvokedCallbackInfo imeCallbackInfo =
+ imeWindow.getOnBackInvokedCallbackInfo();
+ if (imeCallbackInfo != null && (callbackInfo == null
+ || callbackInfo.getPriority() <= imeCallbackInfo.getPriority())) {
+ callbackInfo = imeCallbackInfo;
+ }
+ }
+ }
+
if (callbackInfo == null) {
Slog.e(TAG, "No callback registered, returning null.");
return null;
@@ -189,12 +206,10 @@
// If we don't need to set up the animation, we return early. This is the case when
// - We have an application callback.
// - We don't have any ActivityRecord or Task to animate.
- // - The IME is opened, and we just need to close it.
// - The home activity is the focused activity.
if (backType == BackNavigationInfo.TYPE_CALLBACK
|| currentActivity == null
|| currentTask == null
- || currentTask.getDisplayContent().getImeContainer().isVisible()
|| currentActivity.isActivityTypeHome()) {
return infoBuilder
.setType(backType)
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index a7b3728..6162f12 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -289,6 +289,23 @@
return adjustVisibilityForTransientTypes(originalState);
}
+ /**
+ * @param type the internal type of the insets.
+ * @return {@code true} if the given type is controllable, {@code false} otherwise.
+ */
+ static boolean isInsetsTypeControllable(@InternalInsetsType int type) {
+ switch (type) {
+ case ITYPE_STATUS_BAR:
+ case ITYPE_NAVIGATION_BAR:
+ case ITYPE_IME:
+ case ITYPE_CLIMATE_BAR:
+ case ITYPE_EXTRA_NAVIGATION_BAR:
+ return true;
+ default:
+ return false;
+ }
+ }
+
private static @InternalInsetsType int getInsetsTypeForLayoutParams(
WindowManager.LayoutParams attrs) {
@WindowManager.LayoutParams.WindowType int type = attrs.type;
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index f3f08b2..e04644c 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -16,11 +16,7 @@
package com.android.server.wm;
-import static android.view.InsetsState.ITYPE_CLIMATE_BAR;
-import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_IME;
-import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_INSETS;
import static com.android.server.wm.InsetsSourceProviderProto.CAPTURED_LEASH;
@@ -128,18 +124,7 @@
mStateController = stateController;
mFakeControl = new InsetsSourceControl(
source.getType(), null /* leash */, new Point(), Insets.NONE);
-
- switch (source.getType()) {
- case ITYPE_STATUS_BAR:
- case ITYPE_NAVIGATION_BAR:
- case ITYPE_IME:
- case ITYPE_CLIMATE_BAR:
- case ITYPE_EXTRA_NAVIGATION_BAR:
- mControllable = true;
- break;
- default:
- mControllable = false;
- }
+ mControllable = InsetsPolicy.isInsetsTypeControllable(source.getType());
}
InsetsSource getSource() {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index d460616..6f69e03 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2006,6 +2006,7 @@
// of the activity entering PIP
r.getDisplayContent().prepareAppTransition(TRANSIT_NONE);
+ final TaskFragment organizedTf = r.getOrganizedTaskFragment();
// TODO: Does it make sense to only count non-finishing activities?
final boolean singleActivity = task.getActivityCount() == 1;
final Task rootTask;
@@ -2043,6 +2044,14 @@
task.clearLastRecentsAnimationTransaction(false /* forceRemoveOverlay */);
}
+ // The organized TaskFragment is becoming empty because this activity is reparented
+ // to a new PIP Task. In this case, we should notify the organizer about why the
+ // TaskFragment becomes empty.
+ if (organizedTf != null && organizedTf.getNonFinishingActivityCount() == 1
+ && organizedTf.getTopNonFinishingActivity() == r) {
+ organizedTf.mClearedTaskFragmentForPip = true;
+ }
+
// There are multiple activities in the task and moving the top activity should
// reveal/leave the other activities in their original task.
// On the other hand, ActivityRecord#onParentChanged takes care of setting the
@@ -2107,6 +2116,13 @@
// Reset the state that indicates it can enter PiP while pausing after we've moved it
// to the root pinned task
r.supportsEnterPipOnTaskSwitch = false;
+
+ if (organizedTf != null && organizedTf.mClearedTaskFragmentForPip) {
+ // Dispatch the pending info to TaskFragmentOrganizer before PIP animation.
+ // Otherwise, it will keep waiting for the empty TaskFragment to be non-empty.
+ mService.mTaskFragmentOrganizerController.dispatchPendingInfoChangedEvent(
+ organizedTf);
+ }
} finally {
mService.continueWindowLayout();
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index ac04843..bd078d8 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -2043,7 +2043,7 @@
Rect outOverrideBounds = getResolvedOverrideConfiguration().windowConfiguration.getBounds();
if (windowingMode == WINDOWING_MODE_FULLSCREEN) {
- if (!mCreatedByOrganizer) {
+ if (!isOrganized()) {
// Use empty bounds to indicate "fill parent".
outOverrideBounds.setEmpty();
}
@@ -2788,9 +2788,11 @@
}
final Rect visibleFrame = sTmpBounds;
+ final WindowManager.LayoutParams attrs = win.mAttrs;
visibleFrame.set(win.getFrame());
visibleFrame.inset(win.getInsetsStateWithVisibilityOverride().calculateVisibleInsets(
- visibleFrame, win.mAttrs.softInputMode));
+ visibleFrame, attrs.type, win.getWindowingMode(), attrs.softInputMode,
+ attrs.flags));
out.union(visibleFrame);
}
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 83bd979..4e0d84c 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -193,6 +193,12 @@
boolean mClearedTaskForReuse;
/**
+ * The last running activity of the TaskFragment was reparented to a different Task because it
+ * is entering PiP.
+ */
+ boolean mClearedTaskFragmentForPip;
+
+ /**
* When we are in the process of pausing an activity, before starting the
* next one, this variable holds the activity that is currently being paused.
*
@@ -847,6 +853,16 @@
return getActivity((r) -> r.canBeTopRunning() && r.getTask() == this.getTask());
}
+ int getNonFinishingActivityCount() {
+ final int[] runningActivityCount = new int[1];
+ forAllActivities(a -> {
+ if (!a.finishing) {
+ runningActivityCount[0]++;
+ }
+ });
+ return runningActivityCount[0];
+ }
+
boolean isTopActivityFocusable() {
final ActivityRecord r = topRunningActivity();
return r != null ? r.isFocusable()
@@ -1709,6 +1725,7 @@
void addChild(WindowContainer child, int index) {
ActivityRecord r = topRunningActivity();
mClearedTaskForReuse = false;
+ mClearedTaskFragmentForPip = false;
boolean isAddingActivity = child.asActivityRecord() != null;
final Task task = isAddingActivity ? getTask() : null;
@@ -2253,22 +2270,16 @@
}
final Point positionInParent = new Point();
getRelativePosition(positionInParent);
- final int[] runningActivityCount = new int[1];
- forAllActivities(a -> {
- if (!a.finishing) {
- runningActivityCount[0]++;
- }
- });
return new TaskFragmentInfo(
mFragmentToken,
mRemoteToken.toWindowContainerToken(),
getConfiguration(),
- runningActivityCount[0] == 0,
- runningActivityCount[0],
+ getNonFinishingActivityCount(),
isVisible(),
childActivities,
positionInParent,
- mClearedTaskForReuse);
+ mClearedTaskForReuse,
+ mClearedTaskFragmentForPip);
}
@Nullable
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 8a0ae65..9bf988f 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -38,6 +38,7 @@
import android.os.RemoteException;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
+import android.view.Display;
import android.view.SurfaceControl;
import android.window.ITaskOrganizer;
import android.window.ITaskOrganizerController;
@@ -526,17 +527,17 @@
}
final StartingWindowRemovalInfo removalInfo = new StartingWindowRemovalInfo();
removalInfo.taskId = task.mTaskId;
- removalInfo.playRevealAnimation = prepareAnimation;
+ removalInfo.playRevealAnimation = prepareAnimation
+ && task.getDisplayInfo().state == Display.STATE_ON;
final boolean playShiftUpAnimation = !task.inMultiWindowMode();
final ActivityRecord topActivity = task.topActivityContainsStartingWindow();
if (topActivity != null) {
removalInfo.deferRemoveForIme = topActivity.mDisplayContent
.mayImeShowOnLaunchingActivity(topActivity);
- if (prepareAnimation && playShiftUpAnimation) {
+ if (removalInfo.playRevealAnimation && playShiftUpAnimation) {
final WindowState mainWindow =
topActivity.findMainWindow(false/* includeStartingApp */);
if (mainWindow != null) {
- final SurfaceControl.Transaction t = mainWindow.getPendingTransaction();
removalInfo.windowAnimationLeash = applyStartingWindowAnimation(mainWindow);
removalInfo.mainFrame = mainWindow.getRelativeFrame();
}
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 4dbcea1..f5af2b4 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -236,6 +236,8 @@
*/
private boolean mCommittedReparentToAnimationLeash;
+ private int mSyncTransactionCommitCallbackDepth = 0;
+
/** Interface for {@link #isAnimating} to check which cases for the container is animating. */
public interface AnimationFlags {
/**
@@ -2688,6 +2690,9 @@
* {@link #getPendingTransaction()}
*/
public Transaction getSyncTransaction() {
+ if (mSyncTransactionCommitCallbackDepth > 0) {
+ return mSyncTransaction;
+ }
if (mSyncState != SYNC_STATE_NONE) {
return mSyncTransaction;
}
@@ -3909,4 +3914,29 @@
p.updateOverlayInsetsState(originalChange);
}
}
+
+ void waitForSyncTransactionCommit(ArraySet<WindowContainer> wcAwaitingCommit) {
+ if (wcAwaitingCommit.contains(this)) {
+ return;
+ }
+ mSyncTransactionCommitCallbackDepth++;
+ wcAwaitingCommit.add(this);
+
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ mChildren.get(i).waitForSyncTransactionCommit(wcAwaitingCommit);
+ }
+ }
+
+ void onSyncTransactionCommitted(SurfaceControl.Transaction t) {
+ mSyncTransactionCommitCallbackDepth--;
+ if (mSyncTransactionCommitCallbackDepth > 0) {
+ return;
+ }
+ if (mSyncState != SYNC_STATE_NONE) {
+ return;
+ }
+
+ t.merge(mSyncTransaction);
+ }
+
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index be74596..42fad6d 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -409,21 +409,6 @@
public abstract void getMagnificationRegion(int displayId, @NonNull Region magnificationRegion);
/**
- * Gets the magnification and translation applied to a window given its token.
- * Not all windows are magnified and the window manager policy determines which
- * windows are magnified. The returned result also takes into account the compat
- * scale if necessary.
- *
- * @param windowToken The window's token.
- *
- * @return The magnification spec for the window.
- *
- * @see #setMagnificationCallbacks(int, MagnificationCallbacks)
- */
- public abstract MagnificationSpec getCompatibleMagnificationSpecForWindow(
- IBinder windowToken);
-
- /**
* Sets a callback for observing which windows are touchable for the purposes
* of accessibility on specified display.
*
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 4d262ef..2f4dc51 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1976,8 +1976,10 @@
// We use the visible frame, because we want the animation to morph the window from what
// was visible to the user to the final destination of the new window.
final Rect frame = new Rect(replacedWindow.getFrame());
+ final WindowManager.LayoutParams attrs = replacedWindow.mAttrs;
frame.inset(replacedWindow.getInsetsStateWithVisibilityOverride().calculateVisibleInsets(
- frame, replacedWindow.mAttrs.softInputMode));
+ frame, attrs.type, replacedWindow.getWindowingMode(), attrs.softInputMode,
+ attrs.flags));
// We treat this as if this activity was opening, so we can trigger the app transition
// animation and piggy-back on existing transition animation infrastructure.
final DisplayContent dc = activity.getDisplayContent();
@@ -7621,29 +7623,6 @@
}
@Override
- public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) {
- synchronized (mGlobalLock) {
- WindowState windowState = mWindowMap.get(windowToken);
- if (windowState == null) {
- return null;
- }
- MagnificationSpec spec = null;
- if (mAccessibilityController.hasCallbacks()) {
- spec = mAccessibilityController.getMagnificationSpecForWindow(windowState);
- }
- if ((spec == null || spec.isNop()) && windowState.mGlobalScale == 1.0f) {
- return null;
- }
- MagnificationSpec result = new MagnificationSpec();
- if (spec != null) {
- result.setTo(spec);
- }
- result.scale *= windowState.mGlobalScale;
- return result;
- }
- }
-
- @Override
public boolean setMagnificationCallbacks(int displayId,
@Nullable MagnificationCallbacks callbacks) {
synchronized (mGlobalLock) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index e7d4877..238f96f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1851,7 +1851,7 @@
bounds.set(mWindowFrames.mFrame);
bounds.inset(getInsetsStateWithVisibilityOverride().calculateVisibleInsets(
- bounds, mAttrs.softInputMode));
+ bounds, mAttrs.type, getWindowingMode(), mAttrs.softInputMode, mAttrs.flags));
if (intersectWithRootTaskBounds) {
bounds.intersect(mTmpRect);
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 35dbb15..18bffeb 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -382,8 +382,6 @@
import com.android.server.utils.Slogf;
import com.android.server.wm.ActivityTaskManagerInternal;
-import com.google.android.collect.Sets;
-
import org.xmlpull.v1.XmlPullParserException;
import java.io.ByteArrayInputStream;
@@ -2002,7 +2000,6 @@
synchronized (getLockObject()) {
mOwners.load();
setDeviceOwnershipSystemPropertyLocked();
- findOwnerComponentIfNecessaryLocked();
}
}
@@ -2387,139 +2384,6 @@
}
}
- private void findOwnerComponentIfNecessaryLocked() {
- if (!mOwners.hasDeviceOwner()) {
- return;
- }
- final ComponentName doComponentName = mOwners.getDeviceOwnerComponent();
-
- if (!TextUtils.isEmpty(doComponentName.getClassName())) {
- return; // Already a full component name.
- }
-
- final ComponentName doComponent = findAdminComponentWithPackageLocked(
- doComponentName.getPackageName(),
- mOwners.getDeviceOwnerUserId());
- if (doComponent == null) {
- Slogf.e(LOG_TAG, "Device-owner isn't registered as device-admin");
- } else {
- mOwners.setDeviceOwnerWithRestrictionsMigrated(
- doComponent,
- mOwners.getDeviceOwnerName(),
- mOwners.getDeviceOwnerUserId(),
- !mOwners.getDeviceOwnerUserRestrictionsNeedsMigration());
- mOwners.writeDeviceOwner();
- if (VERBOSE_LOG) {
- Slogf.v(LOG_TAG, "Device owner component filled in");
- }
- }
- }
-
- /**
- * We didn't use to persist user restrictions for each owners but only persisted in user
- * manager.
- */
- private void migrateUserRestrictionsIfNecessaryLocked() {
- boolean migrated = false;
- // Migrate for the DO. Basically all restrictions should be considered to be set by DO,
- // except for the "system controlled" ones.
- if (mOwners.getDeviceOwnerUserRestrictionsNeedsMigration()) {
- if (VERBOSE_LOG) {
- Slogf.v(LOG_TAG, "Migrating DO user restrictions");
- }
- migrated = true;
-
- // Migrate user 0 restrictions to DO.
- final ActiveAdmin deviceOwnerAdmin = getDeviceOwnerAdminLocked();
-
- migrateUserRestrictionsForUser(UserHandle.SYSTEM, deviceOwnerAdmin,
- /* exceptionList =*/ null, /* isDeviceOwner =*/ true);
-
- // Push DO user restrictions to user manager.
- pushUserRestrictions(UserHandle.USER_SYSTEM);
-
- mOwners.setDeviceOwnerUserRestrictionsMigrated();
- }
-
- // Migrate for POs.
-
- // The following restrictions can be set on secondary users by the device owner, so we
- // assume they're not from the PO.
- final Set<String> secondaryUserExceptionList = Sets.newArraySet(
- UserManager.DISALLOW_OUTGOING_CALLS,
- UserManager.DISALLOW_SMS);
-
- for (UserInfo ui : mUserManager.getUsers()) {
- final int userId = ui.id;
- if (mOwners.getProfileOwnerUserRestrictionsNeedsMigration(userId)) {
- if (VERBOSE_LOG) {
- Slogf.v(LOG_TAG, "Migrating PO user restrictions for user %d", userId);
- }
- migrated = true;
-
- final ActiveAdmin profileOwnerAdmin = getProfileOwnerAdminLocked(userId);
-
- final Set<String> exceptionList =
- (userId == UserHandle.USER_SYSTEM) ? null : secondaryUserExceptionList;
-
- migrateUserRestrictionsForUser(ui.getUserHandle(), profileOwnerAdmin,
- exceptionList, /* isDeviceOwner =*/ false);
-
- // Note if a secondary user has no PO but has a DA that disables camera, we
- // don't get here and won't push the camera user restriction to UserManager
- // here. That's okay because we'll push user restrictions anyway when a user
- // starts. But we still do it because we want to let user manager persist
- // upon migration.
- pushUserRestrictions(userId);
-
- mOwners.setProfileOwnerUserRestrictionsMigrated(userId);
- }
- }
- if (VERBOSE_LOG && migrated) {
- Slogf.v(LOG_TAG, "User restrictions migrated.");
- }
- }
-
- private void migrateUserRestrictionsForUser(UserHandle user, ActiveAdmin admin,
- Set<String> exceptionList, boolean isDeviceOwner) {
- final Bundle origRestrictions = mUserManagerInternal.getBaseUserRestrictions(
- user.getIdentifier());
-
- final Bundle newBaseRestrictions = new Bundle();
- final Bundle newOwnerRestrictions = new Bundle();
-
- for (String key : origRestrictions.keySet()) {
- if (!origRestrictions.getBoolean(key)) {
- continue;
- }
- final boolean canOwnerChange = isDeviceOwner
- ? UserRestrictionsUtils.canDeviceOwnerChange(key)
- : UserRestrictionsUtils.canProfileOwnerChange(key, user.getIdentifier());
-
- if (!canOwnerChange || (exceptionList!= null && exceptionList.contains(key))) {
- newBaseRestrictions.putBoolean(key, true);
- } else {
- newOwnerRestrictions.putBoolean(key, true);
- }
- }
-
- if (VERBOSE_LOG) {
- Slogf.v(LOG_TAG, "origRestrictions=%s", origRestrictions);
- Slogf.v(LOG_TAG, "newBaseRestrictions=%s", newBaseRestrictions);
- Slogf.v(LOG_TAG, "newOwnerRestrictions=%s", newOwnerRestrictions);
- }
- mUserManagerInternal.setBaseUserRestrictionsByDpmsForMigration(user.getIdentifier(),
- newBaseRestrictions);
-
- if (admin != null) {
- admin.ensureUserRestrictions().clear();
- admin.ensureUserRestrictions().putAll(newOwnerRestrictions);
- } else {
- Slogf.w(LOG_TAG, "ActiveAdmin for DO/PO not found. user=" + user.getIdentifier());
- }
- saveSettingsLocked(user.getIdentifier());
- }
-
/**
* Fix left-over restrictions and auto-time policy during COMP -> COPE migration.
*
@@ -2555,27 +2419,6 @@
}
}
- private ComponentName findAdminComponentWithPackageLocked(String packageName, int userId) {
- final DevicePolicyData policy = getUserData(userId);
- final int n = policy.mAdminList.size();
- ComponentName found = null;
- int nFound = 0;
- for (int i = 0; i < n; i++) {
- final ActiveAdmin admin = policy.mAdminList.get(i);
- if (packageName.equals(admin.info.getPackageName())) {
- // Found!
- if (nFound == 0) {
- found = admin.info.getComponent();
- }
- nFound++;
- }
- }
- if (nFound > 1) {
- Slogf.w(LOG_TAG, "Multiple DA found; assume the first one is DO.");
- }
- return found;
- }
-
/**
* Set an alarm for an upcoming event - expiration warning, expiration, or post-expiration
* reminders. Clears alarm if no expirations are configured.
@@ -3197,7 +3040,6 @@
private void onLockSettingsReady() {
synchronized (getLockObject()) {
- migrateUserRestrictionsIfNecessaryLocked();
fixupAutoTimeRestrictionDuringOrganizationOwnedDeviceMigration();
}
getUserData(UserHandle.USER_SYSTEM);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index 37da7b4..859183c 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -79,8 +79,6 @@
private static final boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE
- private static final String DEVICE_OWNER_XML_LEGACY = "device_owner.xml";
-
// XML storing device owner info, system update policy and pending OTA update information.
private static final String DEVICE_OWNER_XML = "device_owner_2.xml";
@@ -89,7 +87,6 @@
private static final String TAG_ROOT = "root";
private static final String TAG_DEVICE_OWNER = "device-owner";
- private static final String TAG_DEVICE_INITIALIZER = "device-initializer";
private static final String TAG_SYSTEM_UPDATE_POLICY = "system-update-policy";
private static final String TAG_FREEZE_PERIOD_RECORD = "freeze-record";
private static final String TAG_PENDING_OTA_INFO = "pending-ota-info";
@@ -107,7 +104,6 @@
private static final String ATTR_REMOTE_BUGREPORT_URI = "remoteBugreportUri";
private static final String ATTR_REMOTE_BUGREPORT_HASH = "remoteBugreportHash";
private static final String ATTR_USERID = "userId";
- private static final String ATTR_USER_RESTRICTIONS_MIGRATED = "userRestrictionsMigrated";
private static final String ATTR_FREEZE_RECORD_START = "start";
private static final String ATTR_FREEZE_RECORD_END = "end";
// Legacy attribute, its presence would mean the profile owner associated with it is
@@ -180,35 +176,14 @@
*/
void load() {
synchronized (mLock) {
- // First, try to read from the legacy file.
- final File legacy = getLegacyConfigFile();
-
final List<UserInfo> users = mUserManager.getAliveUsers();
- if (readLegacyOwnerFileLocked(legacy)) {
- if (DEBUG) {
- Log.d(TAG, "Legacy config file found.");
- }
+ new DeviceOwnerReadWriter().readFromFileLocked();
- // Legacy file exists, write to new files and remove the legacy one.
- writeDeviceOwner();
- for (int userId : getProfileOwnerKeys()) {
- writeProfileOwner(userId);
- }
- if (DEBUG) {
- Log.d(TAG, "Deleting legacy config file");
- }
- if (!legacy.delete()) {
- Slog.e(TAG, "Failed to remove the legacy setting file");
- }
- } else {
- // No legacy file, read from the new format files.
- new DeviceOwnerReadWriter().readFromFileLocked();
-
- for (UserInfo ui : users) {
- new ProfileOwnerReadWriter(ui.id).readFromFileLocked();
- }
+ for (UserInfo ui : users) {
+ new ProfileOwnerReadWriter(ui.id).readFromFileLocked();
}
+
mUserManagerInternal.setDeviceManaged(hasDeviceOwner());
for (UserInfo ui : users) {
mUserManagerInternal.setUserManaged(ui.id, hasProfileOwner(ui.id));
@@ -338,23 +313,11 @@
return;
}
synchronized (mLock) {
- // For a newly set DO, there's no need for migration.
- setDeviceOwnerWithRestrictionsMigrated(admin, ownerName, userId,
- /* userRestrictionsMigrated =*/ true);
- }
- }
-
- // Note this should be only called during migration. Normally when DO is set,
- // userRestrictionsMigrated should always be true.
- void setDeviceOwnerWithRestrictionsMigrated(ComponentName admin, String ownerName, int userId,
- boolean userRestrictionsMigrated) {
- synchronized (mLock) {
// A device owner is allowed to access device identifiers. Even though this flag
// is not currently checked for device owner, it is set to true here so that it is
// semantically compatible with the meaning of this flag.
- mDeviceOwner = new OwnerInfo(ownerName, admin, userRestrictionsMigrated,
- /* remoteBugreportUri =*/ null, /* remoteBugreportHash =*/
- null, /* isOrganizationOwnedDevice =*/true);
+ mDeviceOwner = new OwnerInfo(ownerName, admin, /* remoteBugreportUri =*/ null,
+ /* remoteBugreportHash =*/ null, /* isOrganizationOwnedDevice =*/ true);
mDeviceOwnerUserId = userId;
mUserManagerInternal.setDeviceManaged(true);
@@ -385,8 +348,8 @@
synchronized (mLock) {
// For a newly set PO, there's no need for migration.
mProfileOwners.put(userId, new OwnerInfo(ownerName, admin,
- /* userRestrictionsMigrated =*/ true, /* remoteBugreportUri =*/ null,
- /* remoteBugreportHash =*/ null, /* isOrganizationOwnedDevice =*/ false));
+ /* remoteBugreportUri =*/ null, /* remoteBugreportHash =*/ null,
+ /* isOrganizationOwnedDevice =*/ false));
mUserManagerInternal.setUserManaged(userId, true);
notifyChangeLocked();
}
@@ -404,8 +367,7 @@
synchronized (mLock) {
final OwnerInfo ownerInfo = mProfileOwners.get(userId);
final OwnerInfo newOwnerInfo = new OwnerInfo(target.getPackageName(), target,
- ownerInfo.userRestrictionsMigrated, ownerInfo.remoteBugreportUri,
- ownerInfo.remoteBugreportHash, /* isOrganizationOwnedDevice =*/
+ ownerInfo.remoteBugreportUri, ownerInfo.remoteBugreportHash,
ownerInfo.isOrganizationOwnedDevice);
mProfileOwners.put(userId, newOwnerInfo);
notifyChangeLocked();
@@ -423,10 +385,8 @@
}
// We don't set a name because it's not used anyway.
// See DevicePolicyManagerService#getDeviceOwnerName
- mDeviceOwner = new OwnerInfo(null, target,
- mDeviceOwner.userRestrictionsMigrated, mDeviceOwner.remoteBugreportUri,
- mDeviceOwner.remoteBugreportHash, /* isOrganizationOwnedDevice =*/
- mDeviceOwner.isOrganizationOwnedDevice);
+ mDeviceOwner = new OwnerInfo(null, target, mDeviceOwner.remoteBugreportUri,
+ mDeviceOwner.remoteBugreportHash, mDeviceOwner.isOrganizationOwnedDevice);
if (previousDeviceOwnerType != null) {
mDeviceOwnerTypes.put(mDeviceOwner.packageName, previousDeviceOwnerType);
}
@@ -570,35 +530,6 @@
}
}
- /**
- * @return true if user restrictions need to be migrated for DO.
- */
- boolean getDeviceOwnerUserRestrictionsNeedsMigration() {
- synchronized (mLock) {
- return mDeviceOwner != null && !mDeviceOwner.userRestrictionsMigrated;
- }
- }
-
- /**
- * @return true if user restrictions need to be migrated for PO.
- */
- boolean getProfileOwnerUserRestrictionsNeedsMigration(int userId) {
- synchronized (mLock) {
- OwnerInfo profileOwner = mProfileOwners.get(userId);
- return profileOwner != null && !profileOwner.userRestrictionsMigrated;
- }
- }
-
- /** Sets the user restrictions migrated flag, and also writes to the file. */
- void setDeviceOwnerUserRestrictionsMigrated() {
- synchronized (mLock) {
- if (mDeviceOwner != null) {
- mDeviceOwner.userRestrictionsMigrated = true;
- }
- writeDeviceOwner();
- }
- }
-
/** Sets the remote bugreport uri and hash, and also writes to the file. */
void setDeviceOwnerRemoteBugreportUriAndHash(String remoteBugreportUri,
String remoteBugreportHash) {
@@ -611,17 +542,6 @@
}
}
- /** Sets the user restrictions migrated flag, and also writes to the file. */
- void setProfileOwnerUserRestrictionsMigrated(int userId) {
- synchronized (mLock) {
- OwnerInfo profileOwner = mProfileOwners.get(userId);
- if (profileOwner != null) {
- profileOwner.userRestrictionsMigrated = true;
- }
- writeProfileOwner(userId);
- }
- }
-
/** Set whether the profile owner manages an organization-owned device, then write to file. */
void setProfileOwnerOfOrganizationOwnedDevice(int userId, boolean isOrganizationOwnedDevice) {
synchronized (mLock) {
@@ -696,72 +616,6 @@
}
}
- private boolean readLegacyOwnerFileLocked(File file) {
- if (!file.exists()) {
- // Already migrated or the device has no owners.
- return false;
- }
- try {
- InputStream input = new AtomicFile(file).openRead();
- TypedXmlPullParser parser = Xml.resolvePullParser(input);
- int type;
- while ((type = parser.next()) != TypedXmlPullParser.END_DOCUMENT) {
- if (type != TypedXmlPullParser.START_TAG) {
- continue;
- }
-
- String tag = parser.getName();
- if (tag.equals(TAG_DEVICE_OWNER)) {
- String name = parser.getAttributeValue(null, ATTR_NAME);
- String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
- mDeviceOwner = new OwnerInfo(name, packageName,
- /* userRestrictionsMigrated =*/ false, /* remoteBugreportUri =*/ null,
- /* remoteBugreportHash =*/ null, /* isOrganizationOwnedDevice =*/ true);
- mDeviceOwnerUserId = UserHandle.USER_SYSTEM;
- } else if (tag.equals(TAG_DEVICE_INITIALIZER)) {
- // Deprecated tag
- } else if (tag.equals(TAG_PROFILE_OWNER)) {
- String profileOwnerPackageName = parser.getAttributeValue(null, ATTR_PACKAGE);
- String profileOwnerName = parser.getAttributeValue(null, ATTR_NAME);
- String profileOwnerComponentStr =
- parser.getAttributeValue(null, ATTR_COMPONENT_NAME);
- int userId = parser.getAttributeInt(null, ATTR_USERID);
- OwnerInfo profileOwnerInfo = null;
- if (profileOwnerComponentStr != null) {
- ComponentName admin = ComponentName.unflattenFromString(
- profileOwnerComponentStr);
- if (admin != null) {
- profileOwnerInfo = new OwnerInfo(profileOwnerName, admin,
- /* userRestrictionsMigrated =*/ false, null,
- null, /* isOrganizationOwnedDevice =*/ false);
- } else {
- // This shouldn't happen but switch from package name -> component name
- // might have written bad device owner files. b/17652534
- Slog.e(TAG, "Error parsing device-owner file. Bad component name " +
- profileOwnerComponentStr);
- }
- }
- if (profileOwnerInfo == null) {
- profileOwnerInfo = new OwnerInfo(profileOwnerName, profileOwnerPackageName,
- /* userRestrictionsMigrated =*/ false,
- /* remoteBugreportUri =*/ null, /* remoteBugreportHash =*/
- null, /* isOrganizationOwnedDevice =*/ false);
- }
- mProfileOwners.put(userId, profileOwnerInfo);
- } else if (TAG_SYSTEM_UPDATE_POLICY.equals(tag)) {
- mSystemUpdatePolicy = SystemUpdatePolicy.restoreFromXml(parser);
- } else {
- throw new XmlPullParserException(
- "Unexpected tag in device owner file: " + tag);
- }
- }
- input.close();
- } catch (XmlPullParserException | IOException e) {
- Slog.e(TAG, "Error parsing device-owner file", e);
- }
- return true;
- }
-
void writeDeviceOwner() {
synchronized (mLock) {
if (DEBUG) {
@@ -1047,9 +901,6 @@
mDeviceOwnerUserId);
break;
}
- case TAG_DEVICE_INITIALIZER:
- // Deprecated tag
- break;
case TAG_SYSTEM_UPDATE_POLICY:
mSystemUpdatePolicy = SystemUpdatePolicy.restoreFromXml(parser);
break;
@@ -1087,7 +938,6 @@
default:
Slog.e(TAG, "Unexpected tag: " + tag);
return false;
-
}
return true;
}
@@ -1136,30 +986,16 @@
public final String name;
public final String packageName;
public final ComponentName admin;
- public boolean userRestrictionsMigrated;
public String remoteBugreportUri;
public String remoteBugreportHash;
public boolean isOrganizationOwnedDevice;
- public OwnerInfo(String name, String packageName, boolean userRestrictionsMigrated,
- String remoteBugreportUri, String remoteBugreportHash,
- boolean isOrganizationOwnedDevice) {
- this.name = name;
- this.packageName = packageName;
- this.admin = new ComponentName(packageName, "");
- this.userRestrictionsMigrated = userRestrictionsMigrated;
- this.remoteBugreportUri = remoteBugreportUri;
- this.remoteBugreportHash = remoteBugreportHash;
- this.isOrganizationOwnedDevice = isOrganizationOwnedDevice;
- }
-
- public OwnerInfo(String name, ComponentName admin, boolean userRestrictionsMigrated,
+ OwnerInfo(String name, ComponentName admin,
String remoteBugreportUri, String remoteBugreportHash,
boolean isOrganizationOwnedDevice) {
this.name = name;
this.admin = admin;
this.packageName = admin.getPackageName();
- this.userRestrictionsMigrated = userRestrictionsMigrated;
this.remoteBugreportUri = remoteBugreportUri;
this.remoteBugreportHash = remoteBugreportHash;
this.isOrganizationOwnedDevice = isOrganizationOwnedDevice;
@@ -1167,14 +1003,12 @@
public void writeToXml(TypedXmlSerializer out, String tag) throws IOException {
out.startTag(null, tag);
- out.attribute(null, ATTR_PACKAGE, packageName);
if (name != null) {
out.attribute(null, ATTR_NAME, name);
}
if (admin != null) {
out.attribute(null, ATTR_COMPONENT_NAME, admin.flattenToString());
}
- out.attributeBoolean(null, ATTR_USER_RESTRICTIONS_MIGRATED, userRestrictionsMigrated);
if (remoteBugreportUri != null) {
out.attribute(null, ATTR_REMOTE_BUGREPORT_URI, remoteBugreportUri);
}
@@ -1189,14 +1023,9 @@
}
public static OwnerInfo readFromXml(TypedXmlPullParser parser) {
- final String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
final String name = parser.getAttributeValue(null, ATTR_NAME);
final String componentName =
parser.getAttributeValue(null, ATTR_COMPONENT_NAME);
- final String userRestrictionsMigratedStr =
- parser.getAttributeValue(null, ATTR_USER_RESTRICTIONS_MIGRATED);
- final boolean userRestrictionsMigrated =
- ("true".equals(userRestrictionsMigratedStr));
final String remoteBugreportUri = parser.getAttributeValue(null,
ATTR_REMOTE_BUGREPORT_URI);
final String remoteBugreportHash = parser.getAttributeValue(null,
@@ -1210,23 +1039,18 @@
final boolean isOrgOwnedDevice =
("true".equals(isOrgOwnedDeviceStr)) | canAccessDeviceIds;
- // Has component name? If so, return [name, component]
- if (componentName != null) {
- final ComponentName admin = ComponentName.unflattenFromString(componentName);
- if (admin != null) {
- return new OwnerInfo(name, admin, userRestrictionsMigrated,
- remoteBugreportUri, remoteBugreportHash, isOrgOwnedDevice);
- } else {
- // This shouldn't happen but switch from package name -> component name
- // might have written bad device owner files. b/17652534
- Slog.e(TAG, "Error parsing owner file. Bad component name " +
- componentName);
- }
+ if (componentName == null) {
+ Slog.e(TAG, "Owner component not found");
+ return null;
+ }
+ final ComponentName admin = ComponentName.unflattenFromString(componentName);
+ if (admin == null) {
+ Slog.e(TAG, "Owner component not parsable: " + componentName);
+ return null;
}
- // Else, build with [name, package]
- return new OwnerInfo(name, packageName, userRestrictionsMigrated, remoteBugreportUri,
- remoteBugreportHash, isOrgOwnedDevice);
+ return new OwnerInfo(
+ name, admin, remoteBugreportUri, remoteBugreportHash, isOrgOwnedDevice);
}
public void dump(IndentingPrintWriter pw) {
@@ -1284,11 +1108,6 @@
}
@VisibleForTesting
- File getLegacyConfigFile() {
- return new File(mInjector.environmentGetDataSystemDirectory(), DEVICE_OWNER_XML_LEGACY);
- }
-
- @VisibleForTesting
File getDeviceOwnerFile() {
return new File(mInjector.environmentGetDataSystemDirectory(), DEVICE_OWNER_XML);
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
index c0b4f0f..ac54293 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
@@ -585,6 +585,7 @@
DeviceConfigSession<Float> bgCurrentDrainRestrictedBucketThreshold = null;
DeviceConfigSession<Float> bgCurrentDrainBgRestrictedThreshold = null;
DeviceConfigSession<Boolean> bgPromptFgsWithNotiToBgRestricted = null;
+ DeviceConfigSession<Boolean> bgPromptAbusiveAppToBgRestricted = null;
DeviceConfigSession<Long> bgNotificationMinInterval = null;
DeviceConfigSession<Integer> bgBatteryExemptionTypes = null;
DeviceConfigSession<Boolean> bgCurrentDrainDecoupleThresholds = null;
@@ -642,6 +643,14 @@
R.bool.config_bg_prompt_fgs_with_noti_to_bg_restricted));
bgPromptFgsWithNotiToBgRestricted.set(true);
+ bgPromptAbusiveAppToBgRestricted = new DeviceConfigSession<>(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ ConstantsObserver.KEY_BG_PROMPT_ABUSIVE_APPS_TO_BG_RESTRICTED,
+ DeviceConfig::getBoolean,
+ mContext.getResources().getBoolean(
+ R.bool.config_bg_prompt_abusive_apps_to_bg_restricted));
+ bgPromptAbusiveAppToBgRestricted.set(true);
+
bgNotificationMinInterval = new DeviceConfigSession<>(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
ConstantsObserver.KEY_BG_ABUSIVE_NOTIFICATION_MINIMAL_INTERVAL,
@@ -1055,6 +1064,7 @@
closeIfNotNull(bgCurrentDrainRestrictedBucketThreshold);
closeIfNotNull(bgCurrentDrainBgRestrictedThreshold);
closeIfNotNull(bgPromptFgsWithNotiToBgRestricted);
+ closeIfNotNull(bgPromptAbusiveAppToBgRestricted);
closeIfNotNull(bgNotificationMinInterval);
closeIfNotNull(bgBatteryExemptionTypes);
closeIfNotNull(bgCurrentDrainDecoupleThresholds);
@@ -1613,6 +1623,7 @@
DeviceConfigSession<String> bgPermissionsInMonitor = null;
DeviceConfigSession<Boolean> bgCurrentDrainHighThresholdByBgLocation = null;
DeviceConfigSession<Boolean> bgCurrentDrainDecoupleThresholds = null;
+ DeviceConfigSession<Boolean> bgPromptAbusiveAppToBgRestricted = null;
mBgRestrictionController.addAppBackgroundRestrictionListener(listener);
@@ -1751,6 +1762,14 @@
AppBatteryPolicy.DEFAULT_BG_CURRENT_DRAIN_DECOUPLE_THRESHOLD);
bgCurrentDrainDecoupleThresholds.set(true);
+ bgPromptAbusiveAppToBgRestricted = new DeviceConfigSession<>(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ ConstantsObserver.KEY_BG_PROMPT_ABUSIVE_APPS_TO_BG_RESTRICTED,
+ DeviceConfig::getBoolean,
+ mContext.getResources().getBoolean(
+ R.bool.config_bg_prompt_abusive_apps_to_bg_restricted));
+ bgPromptAbusiveAppToBgRestricted.set(true);
+
mCurrentTimeMillis = 10_000L;
doReturn(mCurrentTimeMillis - windowMs).when(stats).getStatsStartTimestamp();
doReturn(mCurrentTimeMillis).when(stats).getStatsEndTimestamp();
@@ -2168,6 +2187,7 @@
closeIfNotNull(bgBatteryExemptionTypes);
closeIfNotNull(bgPermissionMonitorEnabled);
closeIfNotNull(bgPermissionsInMonitor);
+ closeIfNotNull(bgPromptAbusiveAppToBgRestricted);
closeIfNotNull(bgCurrentDrainHighThresholdByBgLocation);
closeIfNotNull(bgCurrentDrainDecoupleThresholds);
}
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 6a27ecc..1753fc7 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
@@ -737,6 +737,101 @@
assertEquals(nextWindowEndTime, rescheduledJob.getLatestRunTimeElapsed());
}
+ @Test
+ public void testGetRescheduleJobForPeriodic_outsideWindow_flex_failedJob_longPeriod() {
+ JobStatus job = createJobStatus(
+ "testGetRescheduleJobForPeriodic_outsideWindow_flex_failedJob_longPeriod",
+ createJobInfo().setPeriodic(7 * DAY_IN_MILLIS, 9 * HOUR_IN_MILLIS));
+ JobStatus failedJob = mService.getRescheduleJobForFailureLocked(job);
+ // First window starts 6.625 days from now.
+ advanceElapsedClock(6 * DAY_IN_MILLIS + 15 * HOUR_IN_MILLIS);
+ long now = sElapsedRealtimeClock.millis();
+ long nextWindowStartTime = now + 7 * DAY_IN_MILLIS;
+ long nextWindowEndTime = nextWindowStartTime + 9 * HOUR_IN_MILLIS;
+
+ advanceElapsedClock(6 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS);
+ // Say the job ran at the very end of its previous window. The intended JSS behavior is to
+ // have consistent windows, so the new window should start as soon as the previous window
+ // ended and end PERIOD time after the previous window ended.
+ JobStatus rescheduledJob = mService.getRescheduleJobForPeriodic(failedJob);
+ assertEquals(nextWindowStartTime, rescheduledJob.getEarliestRunTime());
+ assertEquals(nextWindowEndTime, rescheduledJob.getLatestRunTimeElapsed());
+
+ advanceElapsedClock(DAY_IN_MILLIS);
+ // Say the job ran a day late. Since the period is massive compared to the flex, JSS should
+ // put the rescheduled job in the original window.
+ rescheduledJob = mService.getRescheduleJobForPeriodic(failedJob);
+ assertEquals(nextWindowStartTime, rescheduledJob.getEarliestRunTime());
+ assertEquals(nextWindowEndTime, rescheduledJob.getLatestRunTimeElapsed());
+
+ // 1 day before the start of the next window. Given the large period, respect the original
+ // next window.
+ advanceElapsedClock(nextWindowStartTime - sElapsedRealtimeClock.millis() - DAY_IN_MILLIS);
+ rescheduledJob = mService.getRescheduleJobForPeriodic(job);
+ assertEquals(nextWindowStartTime, rescheduledJob.getEarliestRunTime());
+ assertEquals(nextWindowEndTime, rescheduledJob.getLatestRunTimeElapsed());
+
+ // 1 hour before the start of the next window. It's too close to the next window, so the
+ // returned job should be for the window after.
+ long oneHourBeforeNextWindow =
+ nextWindowStartTime - sElapsedRealtimeClock.millis() - HOUR_IN_MILLIS;
+ long fiveMinsBeforeNextWindow =
+ nextWindowStartTime - sElapsedRealtimeClock.millis() - 5 * MINUTE_IN_MILLIS;
+ advanceElapsedClock(oneHourBeforeNextWindow);
+ nextWindowStartTime += 7 * DAY_IN_MILLIS;
+ nextWindowEndTime += 7 * DAY_IN_MILLIS;
+ rescheduledJob = mService.getRescheduleJobForPeriodic(job);
+ assertEquals(nextWindowStartTime, rescheduledJob.getEarliestRunTime());
+ assertEquals(nextWindowEndTime, rescheduledJob.getLatestRunTimeElapsed());
+
+ // 5 minutes before the start of the next window. It's too close to the next window, so the
+ // returned job should be for the window after.
+ advanceElapsedClock(fiveMinsBeforeNextWindow);
+ rescheduledJob = mService.getRescheduleJobForPeriodic(job);
+ assertEquals(nextWindowStartTime, rescheduledJob.getEarliestRunTime());
+ assertEquals(nextWindowEndTime, rescheduledJob.getLatestRunTimeElapsed());
+
+ advanceElapsedClock(14 * DAY_IN_MILLIS);
+ // Say that the job ran at this point, probably because the phone was off the entire time.
+ // The next window should be consistent (start and end at the time it would have had the job
+ // run normally in previous windows).
+ nextWindowStartTime += 14 * DAY_IN_MILLIS;
+ nextWindowEndTime += 14 * DAY_IN_MILLIS;
+
+ rescheduledJob = mService.getRescheduleJobForPeriodic(failedJob);
+ assertEquals(nextWindowStartTime, rescheduledJob.getEarliestRunTime());
+ assertEquals(nextWindowEndTime, rescheduledJob.getLatestRunTimeElapsed());
+
+ // Test original job again but with a huge delay from the original execution window
+
+ // 1 day before the start of the next window. Given the large period, respect the original
+ // next window.
+ advanceElapsedClock(nextWindowStartTime - sElapsedRealtimeClock.millis() - DAY_IN_MILLIS);
+ rescheduledJob = mService.getRescheduleJobForPeriodic(job);
+ assertEquals(nextWindowStartTime, rescheduledJob.getEarliestRunTime());
+ assertEquals(nextWindowEndTime, rescheduledJob.getLatestRunTimeElapsed());
+
+ // 1 hour before the start of the next window. It's too close to the next window, so the
+ // returned job should be for the window after.
+ oneHourBeforeNextWindow =
+ nextWindowStartTime - sElapsedRealtimeClock.millis() - HOUR_IN_MILLIS;
+ fiveMinsBeforeNextWindow =
+ nextWindowStartTime - sElapsedRealtimeClock.millis() - 5 * MINUTE_IN_MILLIS;
+ advanceElapsedClock(oneHourBeforeNextWindow);
+ nextWindowStartTime += 7 * DAY_IN_MILLIS;
+ nextWindowEndTime += 7 * DAY_IN_MILLIS;
+ rescheduledJob = mService.getRescheduleJobForPeriodic(job);
+ assertEquals(nextWindowStartTime, rescheduledJob.getEarliestRunTime());
+ assertEquals(nextWindowEndTime, rescheduledJob.getLatestRunTimeElapsed());
+
+ // 5 minutes before the start of the next window. It's too close to the next window, so the
+ // returned job should be for the window after.
+ advanceElapsedClock(fiveMinsBeforeNextWindow);
+ rescheduledJob = mService.getRescheduleJobForPeriodic(job);
+ assertEquals(nextWindowStartTime, rescheduledJob.getEarliestRunTime());
+ assertEquals(nextWindowEndTime, rescheduledJob.getLatestRunTimeElapsed());
+ }
+
/** Tests that rare job batching works as expected. */
@Test
public void testRareJobBatching() {
diff --git a/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java b/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java
index 9cf6c03..5c4657f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java
@@ -67,6 +67,8 @@
import com.android.server.power.batterysaver.BatterySavingStats;
import com.android.server.testutils.OffsettableClock;
+import java.util.concurrent.Executor;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -164,7 +166,8 @@
@Override
Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
- FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector) {
+ FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector,
+ Executor executor) {
return mNotifierMock;
}
diff --git a/services/tests/servicestests/assets/OwnersTest/device_owner_1.xml b/services/tests/servicestests/assets/OwnersTest/device_owner_1.xml
new file mode 100644
index 0000000..d150b29
--- /dev/null
+++ b/services/tests/servicestests/assets/OwnersTest/device_owner_1.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
+<root>
+ <device-owner package="com.afwsamples.testdpc" name="" component="com.afwsamples.testdpc/com.afwsamples.testdpc.DeviceAdminReceiver" isPoOrganizationOwnedDevice="true" />
+ <device-owner-context userId="0" />
+ <system-update-policy policy_type="2" install_window_start="0" install_window_end="540" />
+</root>
\ No newline at end of file
diff --git a/services/tests/servicestests/assets/OwnersTest/profile_owner_1.xml b/services/tests/servicestests/assets/OwnersTest/profile_owner_1.xml
new file mode 100644
index 0000000..1f78b71
--- /dev/null
+++ b/services/tests/servicestests/assets/OwnersTest/profile_owner_1.xml
@@ -0,0 +1,4 @@
+<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
+<root>
+ <profile-owner package="com.afwsamples.testdpc" name="com.afwsamples.testdpc" component="com.afwsamples.testdpc/com.afwsamples.testdpc.DeviceAdminReceiver" />
+</root>
\ No newline at end of file
diff --git a/services/tests/servicestests/assets/OwnersTest/test01/input.xml b/services/tests/servicestests/assets/OwnersTest/test01/input.xml
deleted file mode 100644
index db3e974..0000000
--- a/services/tests/servicestests/assets/OwnersTest/test01/input.xml
+++ /dev/null
@@ -1 +0,0 @@
-<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
diff --git a/services/tests/servicestests/assets/OwnersTest/test02/input.xml b/services/tests/servicestests/assets/OwnersTest/test02/input.xml
deleted file mode 100644
index 321842b..0000000
--- a/services/tests/servicestests/assets/OwnersTest/test02/input.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
-<device-owner package="com.google.android.testdpc" />
diff --git a/services/tests/servicestests/assets/OwnersTest/test03/input.xml b/services/tests/servicestests/assets/OwnersTest/test03/input.xml
deleted file mode 100644
index 1bbfdadf..0000000
--- a/services/tests/servicestests/assets/OwnersTest/test03/input.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
-<profile-owner package="com.google.android.testdpc0" name="0" userId="10" component="com.google.android.testdpc/com.google.android.testdpc.DeviceAdminReceiver0" />
-<profile-owner package="com.google.android.testdpc1" name="1" userId="11" />
diff --git a/services/tests/servicestests/assets/OwnersTest/test04/input.xml b/services/tests/servicestests/assets/OwnersTest/test04/input.xml
deleted file mode 100644
index 8be51d9..0000000
--- a/services/tests/servicestests/assets/OwnersTest/test04/input.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
-<device-owner package="com.google.android.testdpc" />
-<profile-owner package="com.google.android.testdpc0" name="0" userId="10" component="com.google.android.testdpc/com.google.android.testdpc.DeviceAdminReceiver0" />
-<profile-owner package="com.google.android.testdpc1" name="1" userId="11" />
-<device-initializer package="com.google.android.testdpcx" name="di" component="com.google.android.testdpcx/receiver" />
-<system-update-policy policy_type="5" />
diff --git a/services/tests/servicestests/assets/OwnersTest/test05/input.xml b/services/tests/servicestests/assets/OwnersTest/test05/input.xml
deleted file mode 100644
index dbcb858..0000000
--- a/services/tests/servicestests/assets/OwnersTest/test05/input.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
-<device-initializer package="com.google.android.testdpcx" name="di" component="com.google.android.testdpcx/receiver" />
-
diff --git a/services/tests/servicestests/assets/OwnersTest/test06/input.xml b/services/tests/servicestests/assets/OwnersTest/test06/input.xml
deleted file mode 100644
index 794622b..0000000
--- a/services/tests/servicestests/assets/OwnersTest/test06/input.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
-<system-update-policy policy_type="5" />
diff --git a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
index 3d3c1ab..4e059b4 100644
--- a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
@@ -16,6 +16,9 @@
package com.android.server;
+import static com.android.server.GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
+import static com.android.server.GestureLauncherService.EMERGENCY_GESTURE_TAP_DETECTION_MIN_TIME_MS;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -248,7 +251,7 @@
mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
long eventTime = INITIAL_EVENT_TIME_MILLIS +
- GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
boolean interactive = true;
@@ -296,7 +299,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -341,7 +344,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
+ final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -435,7 +438,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -489,7 +492,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
// 2nd button triggers camera
eventTime += interval;
@@ -578,7 +581,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
// 3 more button presses which should not trigger any gesture (camera gesture disabled)
for (int i = 0; i < 3; i++) {
eventTime += interval;
@@ -632,7 +635,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
// 3 more button presses which should not trigger any gesture, but intercepts action.
for (int i = 0; i < 3; i++) {
eventTime += interval;
@@ -735,7 +738,7 @@
interactive, outLaunched);
assertTrue(intercepted);
assertFalse(outLaunched.value);
- interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
}
}
@@ -763,12 +766,33 @@
interactive, outLaunched);
assertTrue(intercepted);
assertFalse(outLaunched.value);
- interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
}
}
@Test
+ public void testInterceptPowerKeyDown_triggerEmergency_fiveFastTaps_gestureIgnored() {
+ // Trigger emergency by tapping button 5 times
+ long eventTime = triggerEmergencyGesture(/* tapIntervalMs= */ 1);
+
+ // Add 1 more millisecond and send the event again.
+ eventTime += 1;
+
+ // Subsequent long press is intercepted, but should not trigger any gesture
+ KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+ IGNORED_REPEAT, IGNORED_META_STATE, IGNORED_DEVICE_ID, IGNORED_SCANCODE,
+ KeyEvent.FLAG_LONG_PRESS);
+ MutableBoolean outLaunched = new MutableBoolean(true);
+ boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(
+ keyEvent,
+ /* interactive= */ true,
+ outLaunched);
+ assertFalse(intercepted);
+ assertFalse(outLaunched.value);
+ }
+
+ @Test
public void testInterceptPowerKeyDown_triggerEmergency_longPress_cooldownTriggered() {
// Enable power button cooldown
withEmergencyGesturePowerButtonCooldownPeriodMsValue(3000);
@@ -890,7 +914,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT, IGNORED_META_STATE, IGNORED_DEVICE_ID, IGNORED_SCANCODE,
@@ -936,7 +960,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -983,7 +1007,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
+ final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -1075,7 +1099,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -1120,7 +1144,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
+ final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -1212,7 +1236,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -1261,7 +1285,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+ final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -1306,7 +1330,7 @@
assertFalse(intercepted);
assertFalse(outLaunched.value);
- final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
+ final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
eventTime += interval;
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
@@ -1384,9 +1408,20 @@
/**
* Helper method to trigger emergency gesture by pressing button for 5 times.
+ *
* @return last event time.
*/
private long triggerEmergencyGesture() {
+ return triggerEmergencyGesture(CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1);
+ }
+
+ /**
+ * Helper method to trigger emergency gesture by pressing button for 5 times with
+ * specified interval between each tap
+ *
+ * @return last event time.
+ */
+ private long triggerEmergencyGesture(long tapIntervalMs) {
// Enable emergency power gesture
withEmergencyGestureEnabledConfigValue(true);
withEmergencyGestureEnabledSettingValue(true);
@@ -1402,8 +1437,7 @@
keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
IGNORED_REPEAT);
mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, outLaunched);
- final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
- eventTime += interval;
+ eventTime += tapIntervalMs;
}
// 5th button press should trigger the emergency flow
@@ -1412,12 +1446,22 @@
outLaunched.value = false;
boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
outLaunched);
- assertTrue(outLaunched.value);
+ long emergencyGestureTapDetectionMinTimeMs = Settings.Global.getInt(
+ mContext.getContentResolver(),
+ Settings.Global.EMERGENCY_GESTURE_TAP_DETECTION_MIN_TIME_MS,
+ EMERGENCY_GESTURE_TAP_DETECTION_MIN_TIME_MS);
assertTrue(intercepted);
- verify(mUiEventLogger, times(1))
- .log(GestureLauncherService.GestureLauncherEvent.GESTURE_EMERGENCY_TAP_POWER);
- verify(mStatusBarManagerInternal).onEmergencyActionLaunchGestureDetected();
-
+ if (tapIntervalMs * 4 > emergencyGestureTapDetectionMinTimeMs) {
+ assertTrue(outLaunched.value);
+ verify(mUiEventLogger, times(1))
+ .log(GestureLauncherService.GestureLauncherEvent.GESTURE_EMERGENCY_TAP_POWER);
+ verify(mStatusBarManagerInternal).onEmergencyActionLaunchGestureDetected();
+ } else {
+ assertFalse(outLaunched.value);
+ verify(mUiEventLogger, never())
+ .log(GestureLauncherService.GestureLauncherEvent.GESTURE_EMERGENCY_TAP_POWER);
+ verify(mStatusBarManagerInternal, never()).onEmergencyActionLaunchGestureDetected();
+ }
return eventTime;
}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
index 97ebdd4..08df438 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
@@ -58,6 +58,7 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -435,7 +436,7 @@
VIEWID_RESOURCE_NAME, INTERACTION_ID, mMockCallback, TID);
verify(mMockIA11yInteractionConnection).findAccessibilityNodeInfosByViewId(
eq(ROOT_NODE_ID), eq(VIEWID_RESOURCE_NAME), any(), eq(INTERACTION_ID),
- captor.capture(), anyInt(), eq(PID), eq(TID), any());
+ captor.capture(), anyInt(), eq(PID), eq(TID), any(), nullable(float[].class));
verify(mMockSecurityPolicy).computeValidReportedPackages(any(), anyInt());
verifyReplaceActions(captor.getValue());
}
@@ -449,7 +450,7 @@
VIEW_TEXT, INTERACTION_ID, mMockCallback, TID);
verify(mMockIA11yInteractionConnection).findAccessibilityNodeInfosByText(
eq(ROOT_NODE_ID), eq(VIEW_TEXT), any(), eq(INTERACTION_ID),
- captor.capture(), anyInt(), eq(PID), eq(TID), any());
+ captor.capture(), anyInt(), eq(PID), eq(TID), any(), nullable(float[].class));
verify(mMockSecurityPolicy).computeValidReportedPackages(any(), anyInt());
verifyReplaceActions(captor.getValue());
}
@@ -463,7 +464,7 @@
INTERACTION_ID, mMockCallback, 0, TID, null);
verify(mMockIA11yInteractionConnection).findAccessibilityNodeInfoByAccessibilityId(
eq(ROOT_NODE_ID), any(), eq(INTERACTION_ID), captor.capture(), anyInt(),
- eq(PID), eq(TID), any(), any());
+ eq(PID), eq(TID), any(), nullable(float[].class), any());
verify(mMockSecurityPolicy).computeValidReportedPackages(any(), anyInt());
verifyReplaceActions(captor.getValue());
}
@@ -476,7 +477,8 @@
mServiceConnection.findFocus(PIP_WINDOWID, ROOT_NODE_ID, FOCUS_INPUT, INTERACTION_ID,
mMockCallback, TID);
verify(mMockIA11yInteractionConnection).findFocus(eq(ROOT_NODE_ID), eq(FOCUS_INPUT),
- any(), eq(INTERACTION_ID), captor.capture(), anyInt(), eq(PID), eq(TID), any());
+ any(), eq(INTERACTION_ID), captor.capture(), anyInt(), eq(PID), eq(TID), any(),
+ nullable(float[].class));
verify(mMockSecurityPolicy).computeValidReportedPackages(any(), anyInt());
verifyReplaceActions(captor.getValue());
}
@@ -489,7 +491,8 @@
mServiceConnection.focusSearch(PIP_WINDOWID, ROOT_NODE_ID, FOCUS_DOWN, INTERACTION_ID,
mMockCallback, TID);
verify(mMockIA11yInteractionConnection).focusSearch(eq(ROOT_NODE_ID), eq(FOCUS_DOWN),
- any(), eq(INTERACTION_ID), captor.capture(), anyInt(), eq(PID), eq(TID), any());
+ any(), eq(INTERACTION_ID), captor.capture(), anyInt(), eq(PID), eq(TID), any(),
+ nullable(float[].class));
verify(mMockSecurityPolicy).computeValidReportedPackages(any(), anyInt());
verifyReplaceActions(captor.getValue());
}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInteractionControllerNodeRequestsTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInteractionControllerNodeRequestsTest.java
index 022c137..842b23c 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInteractionControllerNodeRequestsTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInteractionControllerNodeRequestsTest.java
@@ -842,7 +842,7 @@
null, interactionId,
callback, prefetchFlags,
processAndThreadId,
- processAndThreadId, null, null);
+ processAndThreadId, null, null, null);
}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/ActionReplacingCallbackTest.java b/services/tests/servicestests/src/com/android/server/accessibility/ActionReplacingCallbackTest.java
index 72820f1..c16f3d3f 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/ActionReplacingCallbackTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/ActionReplacingCallbackTest.java
@@ -16,6 +16,27 @@
package com.android.server.accessibility;
+import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS;
+import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
+import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK;
+import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE;
+import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_CONTEXT_CLICK;
+import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND;
+
+import static junit.framework.TestCase.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.MockitoAnnotations.initMocks;
+
import android.graphics.Region;
import android.os.RemoteException;
import android.view.MagnificationSpec;
@@ -35,28 +56,8 @@
import org.mockito.Mock;
import java.util.Arrays;
-import java.util.HashSet;
import java.util.List;
-import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS;
-import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
-import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK;
-import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE;
-import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND;
-import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_CONTEXT_CLICK;
-import static junit.framework.TestCase.assertTrue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.MockitoAnnotations.initMocks;
-
/**
* Tests for ActionReplacingCallback
*/
@@ -130,8 +131,8 @@
verify(mMockReplacerConnection).findAccessibilityNodeInfoByAccessibilityId(
eq(AccessibilityNodeInfo.ROOT_NODE_ID), (Region) anyObject(),
mInteractionIdCaptor.capture(), eq(mActionReplacingCallback), eq(0),
- eq(INTERROGATING_PID), eq(INTERROGATING_TID), (MagnificationSpec) anyObject(),
- eq(null));
+ eq(INTERROGATING_PID), eq(INTERROGATING_TID), nullable(MagnificationSpec.class),
+ nullable(float[].class), eq(null));
mReplacerInteractionId = mInteractionIdCaptor.getValue().intValue();
}
@@ -247,7 +248,7 @@
.findAccessibilityNodeInfoByAccessibilityId(eq(AccessibilityNodeInfo.ROOT_NODE_ID),
(Region) anyObject(), anyInt(), (ActionReplacingCallback) anyObject(),
eq(0), eq(INTERROGATING_PID), eq(INTERROGATING_TID),
- (MagnificationSpec) anyObject(), eq(null));
+ (MagnificationSpec) anyObject(), nullable(float[].class), eq(null));
ActionReplacingCallback actionReplacingCallback = new ActionReplacingCallback(
mMockServiceCallback, mMockReplacerConnection, INTERACTION_ID, INTERROGATING_PID,
INTERROGATING_TID);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintStateCallbackTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java
similarity index 82%
rename from services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintStateCallbackTest.java
rename to services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java
index 38e8dfa..5f88c99 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintStateCallbackTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java
@@ -24,12 +24,13 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.hardware.fingerprint.FingerprintStateListener;
+import android.hardware.biometrics.BiometricStateListener;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
import com.android.server.biometrics.sensors.AuthenticationClient;
+import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.EnrollClient;
import org.junit.Before;
@@ -39,19 +40,19 @@
@Presubmit
@SmallTest
-public class FingerprintStateCallbackTest {
+public class BiometricStateCallbackTest {
- private FingerprintStateCallback mCallback;
+ private BiometricStateCallback mCallback;
@Mock
- FingerprintStateListener mFingerprintStateListener;
+ BiometricStateListener mBiometricStateListener;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- mCallback = new FingerprintStateCallback();
- mCallback.registerFingerprintStateListener(mFingerprintStateListener);
+ mCallback = new BiometricStateCallback();
+ mCallback.registerBiometricStateListener(mBiometricStateListener);
}
@Test
@@ -86,10 +87,10 @@
mCallback.onClientFinished(client, true /* success */);
if (expectCallback) {
- verify(mFingerprintStateListener).onEnrollmentsChanged(eq(userId), eq(sensorId),
+ verify(mBiometricStateListener).onEnrollmentsChanged(eq(userId), eq(sensorId),
eq(expectedCallbackValue));
} else {
- verify(mFingerprintStateListener, never()).onEnrollmentsChanged(anyInt(), anyInt(),
+ verify(mBiometricStateListener, never()).onEnrollmentsChanged(anyInt(), anyInt(),
anyBoolean());
}
}
@@ -98,7 +99,7 @@
public void testAuthentication_enrollmentCallbackNeverNotified() {
AuthenticationClient<?> client = mock(AuthenticationClient.class);
mCallback.onClientFinished(client, true /* success */);
- verify(mFingerprintStateListener, never()).onEnrollmentsChanged(anyInt(), anyInt(),
+ verify(mBiometricStateListener, never()).onEnrollmentsChanged(anyInt(), anyInt(),
anyBoolean());
}
}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProviderTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProviderTest.java
index 5a1a02e..c6ddf27 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProviderTest.java
@@ -42,9 +42,9 @@
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.sensors.BiometricScheduler;
+import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.HalClientMonitor;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
-import com.android.server.biometrics.sensors.fingerprint.FingerprintStateCallback;
import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
import org.junit.Before;
@@ -71,7 +71,7 @@
@Mock
private GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
@Mock
- private FingerprintStateCallback mFingerprintStateCallback;
+ private BiometricStateCallback mBiometricStateCallback;
@Mock
private BiometricContext mBiometricContext;
@@ -107,7 +107,7 @@
mLockoutResetDispatcher = new LockoutResetDispatcher(mContext);
mFingerprintProvider = new TestableFingerprintProvider(mDaemon, mContext,
- mFingerprintStateCallback, mSensorProps, TAG, mLockoutResetDispatcher,
+ mBiometricStateCallback, mSensorProps, TAG, mLockoutResetDispatcher,
mGestureAvailabilityDispatcher, mBiometricContext);
}
@@ -156,13 +156,13 @@
TestableFingerprintProvider(@NonNull IFingerprint daemon,
@NonNull Context context,
- @NonNull FingerprintStateCallback fingerprintStateCallback,
+ @NonNull BiometricStateCallback biometricStateCallback,
@NonNull SensorProps[] props,
@NonNull String halInstanceName,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
@NonNull BiometricContext biometricContext) {
- super(context, fingerprintStateCallback, props, halInstanceName, lockoutResetDispatcher,
+ super(context, biometricStateCallback, props, halInstanceName, lockoutResetDispatcher,
gestureAvailabilityDispatcher, biometricContext);
mDaemon = daemon;
}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21Test.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21Test.java
index 529f994..b32b89a 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21Test.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21Test.java
@@ -41,8 +41,8 @@
import com.android.internal.R;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.sensors.BiometricScheduler;
+import com.android.server.biometrics.sensors.BiometricStateCallback;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
-import com.android.server.biometrics.sensors.fingerprint.FingerprintStateCallback;
import org.junit.Before;
import org.junit.Test;
@@ -70,7 +70,7 @@
@Mock
private BiometricScheduler mScheduler;
@Mock
- private FingerprintStateCallback mFingerprintStateCallback;
+ private BiometricStateCallback mBiometricStateCallback;
@Mock
private BiometricContext mBiometricContext;
@@ -102,7 +102,7 @@
componentInfo, FingerprintSensorProperties.TYPE_UNKNOWN,
resetLockoutRequiresHardwareAuthToken);
- mFingerprint21 = new TestableFingerprint21(mContext, mFingerprintStateCallback, sensorProps,
+ mFingerprint21 = new TestableFingerprint21(mContext, mBiometricStateCallback, sensorProps,
mScheduler, new Handler(Looper.getMainLooper()), mLockoutResetDispatcher,
mHalResultController, mBiometricContext);
}
@@ -125,13 +125,13 @@
private static class TestableFingerprint21 extends Fingerprint21 {
TestableFingerprint21(@NonNull Context context,
- @NonNull FingerprintStateCallback fingerprintStateCallback,
+ @NonNull BiometricStateCallback biometricStateCallback,
@NonNull FingerprintSensorPropertiesInternal sensorProps,
@NonNull BiometricScheduler scheduler, @NonNull Handler handler,
@NonNull LockoutResetDispatcher lockoutResetDispatcher,
@NonNull HalResultController controller,
@NonNull BiometricContext biometricContext) {
- super(context, fingerprintStateCallback, sensorProps, scheduler, handler,
+ super(context, biometricStateCallback, sensorProps, scheduler, handler,
lockoutResetDispatcher, controller, biometricContext);
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
index 9ba7a9a..8bb619f 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
@@ -27,7 +27,6 @@
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -37,7 +36,6 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
-import android.os.Bundle;
import android.os.IpcDataCache;
import android.os.UserHandle;
import android.os.UserManager;
@@ -55,8 +53,6 @@
import org.junit.runner.RunWith;
import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
import java.util.Set;
@Presubmit
@@ -87,226 +83,9 @@
.thenReturn(true);
}
- @Test
- public void testMigration() throws Exception {
- final File user10dir = getServices().addUser(10, 0, USER_TYPE_EMPTY);
- final File user11dir = getServices().addUser(11, 0,
- UserManager.USER_TYPE_PROFILE_MANAGED);
- getServices().addUser(12, 0, USER_TYPE_EMPTY);
-
- setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
- setUpPackageManagerForAdmin(admin2, UserHandle.getUid(10, 123));
- setUpPackageManagerForAdmin(admin3, UserHandle.getUid(11, 456));
-
- // Create the legacy owners & policies file.
- DpmTestUtils.writeToFile(
- (new File(getServices().dataDir, "device_owner.xml")).getAbsoluteFile(),
- DpmTestUtils.readAsset(mRealTestContext,
- "DevicePolicyManagerServiceMigrationTest/legacy_device_owner.xml"));
-
- DpmTestUtils.writeToFile(
- (new File(getServices().systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
- DpmTestUtils.readAsset(mRealTestContext,
- "DevicePolicyManagerServiceMigrationTest/legacy_device_policies.xml"));
-
- DpmTestUtils.writeToFile(
- (new File(user10dir, "device_policies.xml")).getAbsoluteFile(),
- DpmTestUtils.readAsset(mRealTestContext,
- "DevicePolicyManagerServiceMigrationTest/legacy_device_policies_10.xml"));
- DpmTestUtils.writeToFile(
- (new File(user11dir, "device_policies.xml")).getAbsoluteFile(),
- DpmTestUtils.readAsset(mRealTestContext,
- "DevicePolicyManagerServiceMigrationTest/legacy_device_policies_11.xml"));
-
- // Set up UserManager
- when(getServices().userManagerInternal.getBaseUserRestrictions(
- eq(USER_SYSTEM))).thenReturn(DpmTestUtils.newRestrictions(
- UserManager.DISALLOW_ADD_USER,
- UserManager.DISALLOW_RECORD_AUDIO));
-
- when(getServices().userManagerInternal.getBaseUserRestrictions(
- eq(10))).thenReturn(DpmTestUtils.newRestrictions(
- UserManager.DISALLOW_REMOVE_USER,
- UserManager.DISALLOW_ADD_USER,
- UserManager.DISALLOW_SMS,
- UserManager.DISALLOW_OUTGOING_CALLS,
- UserManager.DISALLOW_WALLPAPER,
- UserManager.DISALLOW_RECORD_AUDIO));
-
- when(getServices().userManagerInternal.getBaseUserRestrictions(
- eq(11))).thenReturn(DpmTestUtils.newRestrictions(
- UserManager.DISALLOW_REMOVE_USER,
- UserManager.DISALLOW_ADD_USER,
- UserManager.DISALLOW_SMS,
- UserManager.DISALLOW_OUTGOING_CALLS,
- UserManager.DISALLOW_WALLPAPER,
- UserManager.DISALLOW_RECORD_AUDIO));
-
- final Map<Integer, Bundle> newBaseRestrictions = new HashMap<>();
-
- doAnswer(invocation -> {
- Integer userId = (Integer) invocation.getArguments()[0];
- Bundle bundle = (Bundle) invocation.getArguments()[1];
-
- newBaseRestrictions.put(userId, bundle);
-
- return null;
- }).when(getServices().userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
- anyInt(), any(Bundle.class));
-
- // Initialize DPM/DPMS and let it migrate the persisted information.
- // (Need clearCallingIdentity() to pass permission checks.)
-
- final DevicePolicyManagerServiceTestable dpms;
-
- final long ident = mContext.binder.clearCallingIdentity();
- try {
- dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
-
- dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
- dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
- } finally {
- mContext.binder.restoreCallingIdentity(ident);
- }
-
- assertThat(dpms.mOwners.hasDeviceOwner()).isTrue();
- assertThat(dpms.mOwners.hasProfileOwner(USER_SYSTEM)).isFalse();
- assertThat(dpms.mOwners.hasProfileOwner(10)).isTrue();
- assertThat(dpms.mOwners.hasProfileOwner(11)).isTrue();
- assertThat(dpms.mOwners.hasProfileOwner(12)).isFalse();
-
- // Now all information should be migrated.
- assertThat(dpms.mOwners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
- assertThat(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(USER_SYSTEM))
- .isFalse();
- assertThat(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
- assertThat(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
- assertThat(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(12)).isFalse();
-
- // Check the new base restrictions.
- DpmTestUtils.assertRestrictions(
- DpmTestUtils.newRestrictions(
- UserManager.DISALLOW_RECORD_AUDIO
- ),
- newBaseRestrictions.get(USER_SYSTEM));
-
- DpmTestUtils.assertRestrictions(
- DpmTestUtils.newRestrictions(
- UserManager.DISALLOW_ADD_USER,
- UserManager.DISALLOW_SMS,
- UserManager.DISALLOW_OUTGOING_CALLS,
- UserManager.DISALLOW_RECORD_AUDIO,
- UserManager.DISALLOW_WALLPAPER
- ),
- newBaseRestrictions.get(10));
-
- DpmTestUtils.assertRestrictions(
- DpmTestUtils.newRestrictions(
- UserManager.DISALLOW_ADD_USER,
- UserManager.DISALLOW_SMS,
- UserManager.DISALLOW_OUTGOING_CALLS,
- UserManager.DISALLOW_WALLPAPER,
- UserManager.DISALLOW_RECORD_AUDIO
- ),
- newBaseRestrictions.get(11));
-
- // Check the new owner restrictions.
- DpmTestUtils.assertRestrictions(
- DpmTestUtils.newRestrictions(
- UserManager.DISALLOW_ADD_USER
- ),
- dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions());
-
- DpmTestUtils.assertRestrictions(
- DpmTestUtils.newRestrictions(
- UserManager.DISALLOW_REMOVE_USER
- ),
- dpms.getProfileOwnerAdminLocked(10).ensureUserRestrictions());
-
- DpmTestUtils.assertRestrictions(
- DpmTestUtils.newRestrictions(
- UserManager.DISALLOW_REMOVE_USER
- ),
- dpms.getProfileOwnerAdminLocked(11).ensureUserRestrictions());
- }
-
- @Test
- public void testMigration2_profileOwnerOnUser0() throws Exception {
- setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID);
-
- // Create the legacy owners & policies file.
- DpmTestUtils.writeToFile(
- (new File(getServices().dataDir, "device_owner.xml")).getAbsoluteFile(),
- DpmTestUtils.readAsset(mRealTestContext,
- "DevicePolicyManagerServiceMigrationTest2/legacy_device_owner.xml"));
-
- DpmTestUtils.writeToFile(
- (new File(getServices().systemUserDataDir, "device_policies.xml")).getAbsoluteFile(),
- DpmTestUtils.readAsset(mRealTestContext,
- "DevicePolicyManagerServiceMigrationTest2/legacy_device_policies.xml"));
-
- // Set up UserManager
- when(getServices().userManagerInternal.getBaseUserRestrictions(
- eq(USER_SYSTEM))).thenReturn(DpmTestUtils.newRestrictions(
- UserManager.DISALLOW_ADD_USER,
- UserManager.DISALLOW_RECORD_AUDIO,
- UserManager.DISALLOW_SMS,
- UserManager.DISALLOW_OUTGOING_CALLS));
-
- final Map<Integer, Bundle> newBaseRestrictions = new HashMap<>();
-
- doAnswer(invocation -> {
- Integer userId = (Integer) invocation.getArguments()[0];
- Bundle bundle = (Bundle) invocation.getArguments()[1];
-
- newBaseRestrictions.put(userId, bundle);
-
- return null;
- }).when(getServices().userManagerInternal).setBaseUserRestrictionsByDpmsForMigration(
- anyInt(), any(Bundle.class));
-
- // Initialize DPM/DPMS and let it migrate the persisted information.
- // (Need clearCallingIdentity() to pass permission checks.)
-
- final DevicePolicyManagerServiceTestable dpms;
-
- final long ident = mContext.binder.clearCallingIdentity();
- try {
- dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext);
-
- dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
- dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
- } finally {
- mContext.binder.restoreCallingIdentity(ident);
- }
- assertThat(dpms.mOwners.hasDeviceOwner()).isFalse();
- assertThat(dpms.mOwners.hasProfileOwner(USER_SYSTEM)).isTrue();
-
- // Now all information should be migrated.
- assertThat(dpms.mOwners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
- assertThat(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(USER_SYSTEM))
- .isFalse();
-
- // Check the new base restrictions.
- DpmTestUtils.assertRestrictions(
- DpmTestUtils.newRestrictions(
- UserManager.DISALLOW_RECORD_AUDIO
- ),
- newBaseRestrictions.get(USER_SYSTEM));
-
- // Check the new owner restrictions.
- DpmTestUtils.assertRestrictions(
- DpmTestUtils.newRestrictions(
- UserManager.DISALLOW_ADD_USER,
- UserManager.DISALLOW_SMS,
- UserManager.DISALLOW_OUTGOING_CALLS
- ),
- dpms.getProfileOwnerAdminLocked(USER_SYSTEM).ensureUserRestrictions());
- }
-
// Test setting default restrictions for managed profile.
@Test
- public void testMigration3_managedProfileOwner() throws Exception {
+ public void testMigration_managedProfileOwner() throws Exception {
// Create a managed profile user.
final File user10dir = getServices().addUser(10, 0,
UserManager.USER_TYPE_PROFILE_MANAGED);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 7b11876d0..45d101a 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -1665,39 +1665,6 @@
assertThat(deviceOwner.getUid()).isEqualTo(DpmMockContext.CALLER_SYSTEM_USER_UID);
}
- /**
- * This essentially tests
- * {@code DevicePolicyManagerService.findOwnerComponentIfNecessaryLocked()}. (which is
- * private.)
- *
- * We didn't use to persist the DO component class name, but now we do, and the above method
- * finds the right component from a package name upon migration.
- */
- @Test
- public void testDeviceOwnerMigration() throws Exception {
- checkDeviceOwnerWithMultipleDeviceAdmins();
-
- // Overwrite the device owner setting and clears the class name.
- dpms.mOwners.setDeviceOwner(
- new ComponentName(admin2.getPackageName(), ""),
- "owner-name", CALLER_USER_HANDLE);
- dpms.mOwners.writeDeviceOwner();
-
- // Make sure the DO component name doesn't have a class name.
- assertThat(dpms.getDeviceOwnerComponent(/* callingUserOnly= */ false).getClassName())
- .isEmpty();
-
- // Then create a new DPMS to have it load the settings from files.
- when(getServices().userManager.getUserRestrictions(any(UserHandle.class)))
- .thenReturn(new Bundle());
- initializeDpms();
-
- // Now the DO component name is a full name.
- // *BUT* because both admin1 and admin2 belong to the same package, we think admin1 is the
- // DO.
- assertThat(dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false)).isEqualTo(admin1);
- }
-
@Test
public void testSetGetApplicationRestriction() {
setAsProfileOwner(admin1);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
index d1706f8..37ba8a4 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
@@ -18,29 +18,22 @@
import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
+import static android.app.admin.SystemUpdatePolicy.TYPE_INSTALL_WINDOWED;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.verify;
-
import android.content.ComponentName;
import android.os.IpcDataCache;
-import android.os.UserHandle;
import android.test.suitebuilder.annotation.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.server.devicepolicy.DevicePolicyManagerServiceTestable.OwnersTestable;
-import com.google.android.collect.Lists;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Tests for the DeviceOwner object that saves & loads device and policy owner information.
*
@@ -52,8 +45,7 @@
@RunWith(AndroidJUnit4.class)
public class OwnersTest extends DpmTestBase {
- private static final List<String> DEVICE_OWNER_PROTECTED_PACKAGES =
- Lists.newArrayList("package_1", "package_2");
+ private static final String TESTDPC_PACKAGE = "com.afwsamples.testdpc";
@Before
public void setUp() throws Exception {
@@ -63,572 +55,66 @@
}
@Test
- public void testUpgrade01() throws Exception {
- getServices().addUsers(10, 11, 20, 21);
-
- // First, migrate.
- {
- final OwnersTestable owners = new OwnersTestable(getServices());
-
- DpmTestUtils.writeToFile(owners.getLegacyConfigFile(),
- DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test01/input.xml"));
-
- owners.load();
-
- // The legacy file should be removed.
- assertThat(owners.getLegacyConfigFile().exists()).isFalse();
-
- // File was empty, so no new files should be created.
- assertThat(owners.getDeviceOwnerFile().exists()).isFalse();
-
- assertThat(owners.getProfileOwnerFile(10).exists()).isFalse();
- assertThat(owners.getProfileOwnerFile(11).exists()).isFalse();
- assertThat(owners.getProfileOwnerFile(20).exists()).isFalse();
- assertThat(owners.getProfileOwnerFile(21).exists()).isFalse();
-
- assertThat(owners.hasDeviceOwner()).isFalse();
- assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_DEFAULT);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEmpty();
- assertThat(owners.getSystemUpdatePolicy()).isNull();
- assertThat(owners.getProfileOwnerKeys()).isEmpty();
-
- assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
-
- owners.setDeviceOwnerType(owners.getDeviceOwnerPackageName(),
- DEVICE_OWNER_TYPE_FINANCED, /* isAdminTestOnly= */ false);
- // There is no device owner, so the default owner type should be returned.
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_DEFAULT);
- }
-
- // Then re-read and check.
- {
- final OwnersTestable owners = new OwnersTestable(getServices());
- owners.load();
-
- assertThat(owners.hasDeviceOwner()).isFalse();
- assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_DEFAULT);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEmpty();
- assertThat(owners.getSystemUpdatePolicy()).isNull();
- assertThat(owners.getProfileOwnerKeys()).isEmpty();
-
- assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
- }
- }
-
- @Test
- public void testUpgrade02() throws Exception {
- getServices().addUsers(10, 11, 20, 21);
-
- // First, migrate.
- {
- final OwnersTestable owners = new OwnersTestable(getServices());
-
- DpmTestUtils.writeToFile(owners.getLegacyConfigFile(),
- DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test02/input.xml"));
-
- owners.load();
-
- // The legacy file should be removed.
- assertThat(owners.getLegacyConfigFile().exists()).isFalse();
-
- assertThat(owners.getDeviceOwnerFile().exists()).isTrue(); // TODO Check content
-
- assertThat(owners.getProfileOwnerFile(10).exists()).isFalse();
- assertThat(owners.getProfileOwnerFile(11).exists()).isFalse();
- assertThat(owners.getProfileOwnerFile(20).exists()).isFalse();
- assertThat(owners.getProfileOwnerFile(21).exists()).isFalse();
-
- assertThat(owners.hasDeviceOwner()).isTrue();
- assertThat(owners.getDeviceOwnerName()).isEqualTo(null);
- assertThat(owners.getDeviceOwnerPackageName()).isEqualTo("com.google.android.testdpc");
- assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM);
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_DEFAULT);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEmpty();
-
- assertThat(owners.getSystemUpdatePolicy()).isNull();
- assertThat(owners.getProfileOwnerKeys()).isEmpty();
-
- assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isTrue();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
- }
-
- // Then re-read and check.
- {
- final OwnersTestable owners = new OwnersTestable(getServices());
- owners.load();
-
- assertThat(owners.hasDeviceOwner()).isTrue();
- assertThat(owners.getDeviceOwnerName()).isEqualTo(null);
- assertThat(owners.getDeviceOwnerPackageName()).isEqualTo("com.google.android.testdpc");
- assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM);
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_DEFAULT);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEmpty();
-
- assertThat(owners.getSystemUpdatePolicy()).isNull();
- assertThat(owners.getProfileOwnerKeys()).isEmpty();
-
- assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isTrue();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
- }
- }
-
- @Test
- public void testUpgrade03() throws Exception {
- getServices().addUsers(10, 11, 20, 21);
-
- // First, migrate.
- {
- final OwnersTestable owners = new OwnersTestable(getServices());
-
- DpmTestUtils.writeToFile(owners.getLegacyConfigFile(),
- DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test03/input.xml"));
-
- owners.load();
-
- // The legacy file should be removed.
- assertThat(owners.getLegacyConfigFile().exists()).isFalse();
-
- assertThat(owners.getDeviceOwnerFile().exists()).isFalse();
-
- assertThat(owners.getProfileOwnerFile(10).exists()).isTrue();
- assertThat(owners.getProfileOwnerFile(11).exists()).isTrue();
- assertThat(owners.getProfileOwnerFile(20).exists()).isFalse();
- assertThat(owners.getProfileOwnerFile(21).exists()).isFalse();
-
- assertThat(owners.hasDeviceOwner()).isFalse();
- assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
- assertThat(owners.getSystemUpdatePolicy()).isNull();
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_DEFAULT);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEmpty();
-
- assertThat(owners.getProfileOwnerKeys()).hasSize(2);
- assertThat(owners.getProfileOwnerComponent(10))
- .isEqualTo(new ComponentName("com.google.android.testdpc",
- "com.google.android.testdpc.DeviceAdminReceiver0"));
- assertThat(owners.getProfileOwnerName(10)).isEqualTo("0");
- assertThat(owners.getProfileOwnerPackage(10)).isEqualTo("com.google.android.testdpc");
-
- assertThat(owners.getProfileOwnerComponent(11))
- .isEqualTo(new ComponentName("com.google.android.testdpc1", ""));
- assertThat(owners.getProfileOwnerName(11)).isEqualTo("1");
- assertThat(owners.getProfileOwnerPackage(11)).isEqualTo("com.google.android.testdpc1");
-
- assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isTrue();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isTrue();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
- }
-
- // Then re-read and check.
- {
- final OwnersTestable owners = new OwnersTestable(getServices());
- owners.load();
-
- assertThat(owners.hasDeviceOwner()).isFalse();
- assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
- assertThat(owners.getSystemUpdatePolicy()).isNull();
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_DEFAULT);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEmpty();
-
- assertThat(owners.getProfileOwnerKeys()).hasSize(2);
- assertThat(owners.getProfileOwnerComponent(10))
- .isEqualTo(new ComponentName("com.google.android.testdpc",
- "com.google.android.testdpc.DeviceAdminReceiver0"));
- assertThat(owners.getProfileOwnerName(10)).isEqualTo("0");
- assertThat(owners.getProfileOwnerPackage(10)).isEqualTo("com.google.android.testdpc");
-
- assertThat(owners.getProfileOwnerComponent(11))
- .isEqualTo(new ComponentName("com.google.android.testdpc1", ""));
- assertThat(owners.getProfileOwnerName(11)).isEqualTo("1");
- assertThat(owners.getProfileOwnerPackage(11)).isEqualTo("com.google.android.testdpc1");
-
- assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isTrue();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isTrue();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
- }
- }
-
- /**
- * Note this also tests {@link Owners#setDeviceOwnerUserRestrictionsMigrated()}
- * and {@link Owners#setProfileOwnerUserRestrictionsMigrated(int)}.
- */
- @Test
- public void testUpgrade04() throws Exception {
- getServices().addUsers(10, 11, 20, 21);
-
- // First, migrate.
- {
- final OwnersTestable owners = new OwnersTestable(getServices());
-
- DpmTestUtils.writeToFile(owners.getLegacyConfigFile(),
- DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test04/input.xml"));
-
- owners.load();
-
- // The legacy file should be removed.
- assertThat(owners.getLegacyConfigFile().exists()).isFalse();
-
- assertThat(owners.getDeviceOwnerFile().exists()).isTrue();
-
- assertThat(owners.getProfileOwnerFile(10).exists()).isTrue();
- assertThat(owners.getProfileOwnerFile(11).exists()).isTrue();
- assertThat(owners.getProfileOwnerFile(20).exists()).isFalse();
- assertThat(owners.getProfileOwnerFile(21).exists()).isFalse();
-
- assertThat(owners.hasDeviceOwner()).isTrue();
- assertThat(owners.getDeviceOwnerName()).isEqualTo(null);
- assertThat(owners.getDeviceOwnerPackageName()).isEqualTo("com.google.android.testdpc");
- assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM);
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_DEFAULT);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEmpty();
-
- assertThat(owners.getSystemUpdatePolicy()).isNotNull();
- assertThat(owners.getSystemUpdatePolicy().getPolicyType()).isEqualTo(5);
-
- assertThat(owners.getProfileOwnerKeys()).hasSize(2);
- assertThat(owners.getProfileOwnerComponent(10))
- .isEqualTo(new ComponentName("com.google.android.testdpc",
- "com.google.android.testdpc.DeviceAdminReceiver0"));
- assertThat(owners.getProfileOwnerName(10)).isEqualTo("0");
- assertThat(owners.getProfileOwnerPackage(10)).isEqualTo("com.google.android.testdpc");
-
- assertThat(owners.getProfileOwnerComponent(11))
- .isEqualTo(new ComponentName("com.google.android.testdpc1", ""));
- assertThat(owners.getProfileOwnerName(11)).isEqualTo("1");
- assertThat(owners.getProfileOwnerPackage(11)).isEqualTo("com.google.android.testdpc1");
-
- assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isTrue();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isTrue();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isTrue();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
- }
-
- // Then re-read and check.
- {
- final OwnersTestable owners = new OwnersTestable(getServices());
- owners.load();
-
- assertThat(owners.hasDeviceOwner()).isTrue();
- assertThat(owners.getDeviceOwnerName()).isEqualTo(null);
- assertThat(owners.getDeviceOwnerPackageName()).isEqualTo("com.google.android.testdpc");
- assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM);
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_DEFAULT);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEmpty();
-
- assertThat(owners.getSystemUpdatePolicy()).isNotNull();
- assertThat(owners.getSystemUpdatePolicy().getPolicyType()).isEqualTo(5);
-
- assertThat(owners.getProfileOwnerKeys()).hasSize(2);
- assertThat(owners.getProfileOwnerComponent(10))
- .isEqualTo(new ComponentName("com.google.android.testdpc",
- "com.google.android.testdpc.DeviceAdminReceiver0"));
- assertThat(owners.getProfileOwnerName(10)).isEqualTo("0");
- assertThat(owners.getProfileOwnerPackage(10)).isEqualTo("com.google.android.testdpc");
-
- assertThat(owners.getProfileOwnerComponent(11))
- .isEqualTo(new ComponentName("com.google.android.testdpc1", ""));
- assertThat(owners.getProfileOwnerName(11)).isEqualTo("1");
- assertThat(owners.getProfileOwnerPackage(11)).isEqualTo("com.google.android.testdpc1");
-
- assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isTrue();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isTrue();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isTrue();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
-
- owners.setDeviceOwnerUserRestrictionsMigrated();
-
- owners.setDeviceOwnerType(owners.getDeviceOwnerPackageName(),
- DEVICE_OWNER_TYPE_FINANCED, /* isAdminTestOnly= */ false);
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_FINANCED);
-
- owners.setDeviceOwnerProtectedPackages(
- owners.getDeviceOwnerPackageName(), DEVICE_OWNER_PROTECTED_PACKAGES);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEqualTo(DEVICE_OWNER_PROTECTED_PACKAGES);
- verify(getServices().packageManagerInternal)
- .setDeviceOwnerProtectedPackages(
- owners.getDeviceOwnerPackageName(), DEVICE_OWNER_PROTECTED_PACKAGES);
- }
-
- {
- final OwnersTestable owners = new OwnersTestable(getServices());
- owners.load();
-
- assertThat(owners.hasDeviceOwner()).isTrue();
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_FINANCED);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEqualTo(DEVICE_OWNER_PROTECTED_PACKAGES);
-
- assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isTrue();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isTrue();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
-
- owners.setProfileOwnerUserRestrictionsMigrated(11);
-
- owners.setDeviceOwnerType(owners.getDeviceOwnerPackageName(),
- DEVICE_OWNER_TYPE_DEFAULT, /* isAdminTestOnly= */ false);
- // The previous device owner type should persist.
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_FINANCED);
-
- owners.setDeviceOwnerProtectedPackages(
- owners.getDeviceOwnerPackageName(), new ArrayList<>());
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEmpty();
- verify(getServices().packageManagerInternal)
- .setDeviceOwnerProtectedPackages(
- owners.getDeviceOwnerPackageName(), new ArrayList<>());
- }
-
- {
- final OwnersTestable owners = new OwnersTestable(getServices());
- owners.load();
-
- assertThat(owners.hasDeviceOwner()).isTrue();
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_FINANCED);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEmpty();
-
- assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isTrue();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
-
- owners.setProfileOwnerUserRestrictionsMigrated(11);
- }
- }
-
- @Test
- public void testUpgrade05() throws Exception {
- getServices().addUsers(10, 11, 20, 21);
-
- // First, migrate.
- {
- final OwnersTestable owners = new OwnersTestable(getServices());
-
- DpmTestUtils.writeToFile(owners.getLegacyConfigFile(),
- DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test05/input.xml"));
-
- owners.load();
-
- // The legacy file should be removed.
- assertThat(owners.getLegacyConfigFile().exists()).isFalse();
-
- // Note device initializer is no longer supported. No need to write the DO file.
- assertThat(owners.getDeviceOwnerFile().exists()).isFalse();
-
- assertThat(owners.getProfileOwnerFile(10).exists()).isFalse();
- assertThat(owners.getProfileOwnerFile(11).exists()).isFalse();
- assertThat(owners.getProfileOwnerFile(20).exists()).isFalse();
-
- assertThat(owners.hasDeviceOwner()).isFalse();
- assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_DEFAULT);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEmpty();
-
-
- assertThat(owners.getSystemUpdatePolicy()).isNull();
- assertThat(owners.getProfileOwnerKeys()).isEmpty();
-
- assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
- }
-
- // Then re-read and check.
- {
- final OwnersTestable owners = new OwnersTestable(getServices());
- owners.load();
-
- assertThat(owners.hasDeviceOwner()).isFalse();
- assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_DEFAULT);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEmpty();
-
-
- assertThat(owners.getSystemUpdatePolicy()).isNull();
- assertThat(owners.getProfileOwnerKeys()).isEmpty();
-
- assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
- }
- }
-
- @Test
- public void testUpgrade06() throws Exception {
- getServices().addUsers(10, 11, 20, 21);
-
- // First, migrate.
- {
- final OwnersTestable owners = new OwnersTestable(getServices());
-
- DpmTestUtils.writeToFile(owners.getLegacyConfigFile(),
- DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test06/input.xml"));
-
- owners.load();
-
- // The legacy file should be removed.
- assertThat(owners.getLegacyConfigFile().exists()).isFalse();
-
- assertThat(owners.getDeviceOwnerFile().exists()).isTrue();
-
- assertThat(owners.getProfileOwnerFile(10).exists()).isFalse();
- assertThat(owners.getProfileOwnerFile(11).exists()).isFalse();
- assertThat(owners.getProfileOwnerFile(20).exists()).isFalse();
-
- assertThat(owners.hasDeviceOwner()).isFalse();
- assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_DEFAULT);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEmpty();
- assertThat(owners.getProfileOwnerKeys()).isEmpty();
-
- assertThat(owners.getSystemUpdatePolicy()).isNotNull();
- assertThat(owners.getSystemUpdatePolicy().getPolicyType()).isEqualTo(5);
-
- assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
- }
-
- // Then re-read and check.
- {
- final OwnersTestable owners = new OwnersTestable(getServices());
- owners.load();
-
- assertThat(owners.hasDeviceOwner()).isFalse();
- assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_DEFAULT);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEmpty();
- assertThat(owners.getProfileOwnerKeys()).isEmpty();
-
- assertThat(owners.getSystemUpdatePolicy()).isNotNull();
- assertThat(owners.getSystemUpdatePolicy().getPolicyType()).isEqualTo(5);
-
- assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
- assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
- }
- }
-
- @Test
- public void testRemoveExistingFiles() throws Exception {
- getServices().addUsers(10, 11, 20, 21);
+ public void loadProfileOwner() throws Exception {
+ getServices().addUsers(10);
final OwnersTestable owners = new OwnersTestable(getServices());
- // First, migrate to create new-style config files.
- DpmTestUtils.writeToFile(owners.getLegacyConfigFile(),
- DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/test04/input.xml"));
+ DpmTestUtils.writeToFile(owners.getProfileOwnerFile(10),
+ DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/profile_owner_1.xml"));
owners.load();
- assertThat(owners.getLegacyConfigFile().exists()).isFalse();
+ assertThat(owners.hasDeviceOwner()).isFalse();
+ assertThat(owners.getSystemUpdatePolicy()).isNull();
- assertThat(owners.getDeviceOwnerFile().exists()).isTrue();
- assertThat(owners.getDeviceOwnerType(owners.getDeviceOwnerPackageName())).isEqualTo(
- DEVICE_OWNER_TYPE_DEFAULT);
- assertThat(owners.getDeviceOwnerProtectedPackages(owners.getDeviceOwnerPackageName()))
- .isEmpty();
- assertThat(owners.getProfileOwnerFile(10).exists()).isTrue();
- assertThat(owners.getProfileOwnerFile(11).exists()).isTrue();
+ assertThat(owners.getProfileOwnerKeys()).hasSize(1);
+ assertThat(owners.getProfileOwnerComponent(10))
+ .isEqualTo(new ComponentName(TESTDPC_PACKAGE,
+ "com.afwsamples.testdpc.DeviceAdminReceiver"));
+ }
- String previousDeviceOwnerPackageName = owners.getDeviceOwnerPackageName();
- owners.setDeviceOwnerType(previousDeviceOwnerPackageName, DEVICE_OWNER_TYPE_FINANCED,
- /* isAdminTestOnly= */ false);
- assertThat(owners.getDeviceOwnerType(previousDeviceOwnerPackageName)).isEqualTo(
- DEVICE_OWNER_TYPE_FINANCED);
- owners.setDeviceOwnerProtectedPackages(
- previousDeviceOwnerPackageName, DEVICE_OWNER_PROTECTED_PACKAGES);
- assertThat(owners.getDeviceOwnerProtectedPackages(previousDeviceOwnerPackageName))
- .isEqualTo(DEVICE_OWNER_PROTECTED_PACKAGES);
- verify(getServices().packageManagerInternal)
- .setDeviceOwnerProtectedPackages(
- owners.getDeviceOwnerPackageName(), DEVICE_OWNER_PROTECTED_PACKAGES);
+ @Test
+ public void loadDeviceOwner() throws Exception {
+ final OwnersTestable owners = new OwnersTestable(getServices());
- // Then clear all information and save.
- owners.clearDeviceOwner();
- owners.clearSystemUpdatePolicy();
- owners.removeProfileOwner(10);
- owners.removeProfileOwner(11);
+ DpmTestUtils.writeToFile(owners.getDeviceOwnerFile(),
+ DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/device_owner_1.xml"));
- owners.writeDeviceOwner();
- owners.writeProfileOwner(10);
- owners.writeProfileOwner(11);
- owners.writeProfileOwner(20);
- owners.writeProfileOwner(21);
+ owners.load();
- // Now all files should be removed.
- assertThat(owners.getDeviceOwnerFile().exists()).isFalse();
- assertThat(owners.getProfileOwnerFile(10).exists()).isFalse();
- assertThat(owners.getProfileOwnerFile(11).exists()).isFalse();
+ assertThat(owners.hasDeviceOwner()).isTrue();
- assertThat(owners.getDeviceOwnerType(previousDeviceOwnerPackageName)).isEqualTo(
- DEVICE_OWNER_TYPE_DEFAULT);
- assertThat(owners.getDeviceOwnerProtectedPackages(previousDeviceOwnerPackageName))
- .isEmpty();
- verify(getServices().packageManagerInternal)
- .setDeviceOwnerProtectedPackages(
- previousDeviceOwnerPackageName, new ArrayList<>());
+ assertThat(owners.getProfileOwnerKeys()).hasSize(0);
+ assertThat(owners.getDeviceOwnerComponent())
+ .isEqualTo(new ComponentName(TESTDPC_PACKAGE,
+ "com.afwsamples.testdpc.DeviceAdminReceiver"));
+
+ assertThat(owners.getSystemUpdatePolicy().getPolicyType()).isEqualTo(TYPE_INSTALL_WINDOWED);
+ }
+
+ @Test
+ public void testDeviceOwnerType() throws Exception {
+ final OwnersTestable owners = new OwnersTestable(getServices());
+
+ DpmTestUtils.writeToFile(owners.getDeviceOwnerFile(),
+ DpmTestUtils.readAsset(mRealTestContext, "OwnersTest/device_owner_1.xml"));
+
+ owners.load();
+
+ assertThat(owners.getDeviceOwnerType(TESTDPC_PACKAGE))
+ .isEqualTo(DEVICE_OWNER_TYPE_DEFAULT);
+
+ // Should be able to set DO type to "financed".
+ owners.setDeviceOwnerType(
+ TESTDPC_PACKAGE, DEVICE_OWNER_TYPE_FINANCED, /* isAdminTestOnly= */ false);
+ assertThat(owners.getDeviceOwnerType(TESTDPC_PACKAGE))
+ .isEqualTo(DEVICE_OWNER_TYPE_FINANCED);
+
+ // Once set, DO type cannot be changed.
+ owners.setDeviceOwnerType(
+ TESTDPC_PACKAGE, DEVICE_OWNER_TYPE_DEFAULT, /* isAdminTestOnly= */ false);
+ assertThat(owners.getDeviceOwnerType(TESTDPC_PACKAGE))
+ .isEqualTo(DEVICE_OWNER_TYPE_FINANCED);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index a79a52c..e4ee4d06 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -538,6 +538,11 @@
}
@Override
+ ComponentName injectChooserActivity() {
+ return mInjectedChooserActivity;
+ }
+
+ @Override
void wtf(String message, Throwable th) {
// During tests, WTF is fatal.
fail(message + " exception: " + th + "\n" + Log.getStackTraceString(th));
@@ -678,6 +683,7 @@
protected int mInjectedCallingUid;
protected String mInjectedClientPackage;
+ protected ComponentName mInjectedChooserActivity;
protected Map<String, PackageInfo> mInjectedPackages;
@@ -723,6 +729,9 @@
protected static final String LAUNCHER_4 = "com.android.launcher.4";
protected static final int LAUNCHER_UID_4 = 10014;
+ protected static final String CHOOSER_ACTIVITY_PACKAGE = "com.android.intentresolver";
+ protected static final int CHOOSER_ACTIVITY_UID = 10015;
+
protected static final int USER_0 = UserHandle.USER_SYSTEM;
protected static final int USER_10 = 10;
protected static final int USER_11 = 11;
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index a350dfb..867890f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -6901,6 +6901,9 @@
}
public void testGetShareTargets_permission() {
+ addPackage(CHOOSER_ACTIVITY_PACKAGE, CHOOSER_ACTIVITY_UID, 10, "sig1");
+ mInjectedChooserActivity =
+ ComponentName.createRelative(CHOOSER_ACTIVITY_PACKAGE, ".ChooserActivity");
IntentFilter filter = new IntentFilter();
assertExpectException(SecurityException.class, "Missing permission", () ->
@@ -6909,6 +6912,11 @@
// Has permission, now it should pass.
mCallerPermissions.add(permission.MANAGE_APP_PREDICTIONS);
mManager.getShareTargets(filter);
+
+ runWithCaller(CHOOSER_ACTIVITY_PACKAGE, USER_0, () -> {
+ // Access is allowed when called from the configured system ChooserActivity
+ mManager.getShareTargets(filter);
+ });
}
public void testHasShareTargets_permission() {
diff --git a/services/tests/servicestests/src/com/android/server/policy/SideFpsEventHandlerTest.java b/services/tests/servicestests/src/com/android/server/policy/SideFpsEventHandlerTest.java
index 41c7e31..371861f 100644
--- a/services/tests/servicestests/src/com/android/server/policy/SideFpsEventHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/policy/SideFpsEventHandlerTest.java
@@ -26,9 +26,9 @@
import android.app.AlertDialog;
import android.content.pm.PackageManager;
+import android.hardware.biometrics.BiometricStateListener;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.hardware.fingerprint.FingerprintStateListener;
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
import android.os.Handler;
import android.os.PowerManager;
@@ -61,11 +61,11 @@
public class SideFpsEventHandlerTest {
private static final List<Integer> sAllStates = List.of(
- FingerprintStateListener.STATE_IDLE,
- FingerprintStateListener.STATE_ENROLLING,
- FingerprintStateListener.STATE_KEYGUARD_AUTH,
- FingerprintStateListener.STATE_BP_AUTH,
- FingerprintStateListener.STATE_AUTH_OTHER);
+ BiometricStateListener.STATE_IDLE,
+ BiometricStateListener.STATE_ENROLLING,
+ BiometricStateListener.STATE_KEYGUARD_AUTH,
+ BiometricStateListener.STATE_BP_AUTH,
+ BiometricStateListener.STATE_AUTH_OTHER);
@Rule
public TestableContext mContext =
@@ -83,7 +83,7 @@
private TestLooper mLooper = new TestLooper();
private SideFpsEventHandler mEventHandler;
- private FingerprintStateListener mFingerprintStateListener;
+ private BiometricStateListener mBiometricStateListener;
@Before
public void setup() {
@@ -116,7 +116,7 @@
setupWithSensor(false /* hasSfps */, true /* initialized */);
for (int state : sAllStates) {
- setFingerprintState(state);
+ setBiometricState(state);
assertThat(mEventHandler.onSinglePressDetected(200L)).isFalse();
mLooper.dispatchAll();
@@ -129,7 +129,7 @@
setupWithSensor(true /* hasSfps */, false /* initialized */);
for (int state : sAllStates) {
- setFingerprintState(state);
+ setBiometricState(state);
assertThat(mEventHandler.onSinglePressDetected(400L)).isFalse();
mLooper.dispatchAll();
@@ -141,10 +141,10 @@
public void ignoresWhenIdleOrUnknown() throws Exception {
setupWithSensor(true /* hasSfps */, true /* initialized */);
- setFingerprintState(FingerprintStateListener.STATE_IDLE);
+ setBiometricState(BiometricStateListener.STATE_IDLE);
assertThat(mEventHandler.onSinglePressDetected(80000L)).isFalse();
- setFingerprintState(FingerprintStateListener.STATE_AUTH_OTHER);
+ setBiometricState(BiometricStateListener.STATE_AUTH_OTHER);
assertThat(mEventHandler.onSinglePressDetected(90000L)).isFalse();
mLooper.dispatchAll();
@@ -155,7 +155,7 @@
public void ignoresOnKeyguard() throws Exception {
setupWithSensor(true /* hasSfps */, true /* initialized */);
- setFingerprintState(FingerprintStateListener.STATE_KEYGUARD_AUTH);
+ setBiometricState(BiometricStateListener.STATE_KEYGUARD_AUTH);
assertThat(mEventHandler.onSinglePressDetected(80000L)).isFalse();
mLooper.dispatchAll();
@@ -166,7 +166,7 @@
public void promptsWhenBPisActive() throws Exception {
setupWithSensor(true /* hasSfps */, true /* initialized */);
- setFingerprintState(FingerprintStateListener.STATE_BP_AUTH);
+ setBiometricState(BiometricStateListener.STATE_BP_AUTH);
assertThat(mEventHandler.onSinglePressDetected(80000L)).isTrue();
mLooper.dispatchAll();
@@ -177,16 +177,16 @@
public void promptsWhenEnrolling() throws Exception {
setupWithSensor(true /* hasSfps */, true /* initialized */);
- setFingerprintState(FingerprintStateListener.STATE_ENROLLING);
+ setBiometricState(BiometricStateListener.STATE_ENROLLING);
assertThat(mEventHandler.onSinglePressDetected(80000L)).isTrue();
mLooper.dispatchAll();
verify(mAlertDialog).show();
}
- private void setFingerprintState(@FingerprintStateListener.State int newState) {
- if (mFingerprintStateListener != null) {
- mFingerprintStateListener.onStateChanged(newState);
+ private void setBiometricState(@BiometricStateListener.State int newState) {
+ if (mBiometricStateListener != null) {
+ mBiometricStateListener.onStateChanged(newState);
mLooper.dispatchAll();
}
}
@@ -204,10 +204,10 @@
fpCallbackCaptor.getValue().onAllAuthenticatorsRegistered(
List.of(mock(FingerprintSensorPropertiesInternal.class)));
if (hasSfps) {
- ArgumentCaptor<FingerprintStateListener> captor = ArgumentCaptor.forClass(
- FingerprintStateListener.class);
- verify(mFingerprintManager).registerFingerprintStateListener(captor.capture());
- mFingerprintStateListener = captor.getValue();
+ ArgumentCaptor<BiometricStateListener> captor = ArgumentCaptor.forClass(
+ BiometricStateListener.class);
+ verify(mFingerprintManager).registerBiometricStateListener(captor.capture());
+ mBiometricStateListener = captor.getValue();
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/power/NotifierTest.java b/services/tests/servicestests/src/com/android/server/power/NotifierTest.java
index a3223d6d..8f5f0e6 100644
--- a/services/tests/servicestests/src/com/android/server/power/NotifierTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/NotifierTest.java
@@ -16,6 +16,8 @@
package com.android.server.power;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
@@ -56,6 +58,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.concurrent.Executor;
+
/**
* Tests for {@link com.android.server.power.Notifier}
*/
@@ -79,6 +83,7 @@
private Context mContextSpy;
private Resources mResourcesSpy;
private TestLooper mTestLooper = new TestLooper();
+ private FakeExecutor mTestExecutor = new FakeExecutor();
private Notifier mNotifier;
@Before
@@ -107,6 +112,7 @@
// WHEN wired charging starts
mNotifier.onWiredChargingStarted(USER_ID);
mTestLooper.dispatchAll();
+ mTestExecutor.simulateAsyncExecutionOfLastCommand();
// THEN the device vibrates once
verify(mVibrator, times(1)).vibrate(any(), any(VibrationAttributes.class));
@@ -122,6 +128,7 @@
// WHEN wired charging starts
mNotifier.onWiredChargingStarted(USER_ID);
mTestLooper.dispatchAll();
+ mTestExecutor.simulateAsyncExecutionOfLastCommand();
// THEN the device doesn't vibrate
verify(mVibrator, never()).vibrate(any(), any(VibrationAttributes.class));
@@ -137,6 +144,7 @@
// WHEN wireless charging starts
mNotifier.onWirelessChargingStarted(5, USER_ID);
mTestLooper.dispatchAll();
+ mTestExecutor.simulateAsyncExecutionOfLastCommand();
// THEN the device vibrates once
verify(mVibrator, times(1)).vibrate(any(), any(VibrationAttributes.class));
@@ -152,6 +160,7 @@
// WHEN wireless charging starts
mNotifier.onWirelessChargingStarted(5, USER_ID);
mTestLooper.dispatchAll();
+ mTestExecutor.simulateAsyncExecutionOfLastCommand();
// THEN the device doesn't vibrate
verify(mVibrator, never()).vibrate(any(), any(VibrationAttributes.class));
@@ -170,6 +179,7 @@
// WHEN wired charging starts
mNotifier.onWiredChargingStarted(USER_ID);
mTestLooper.dispatchAll();
+ mTestExecutor.simulateAsyncExecutionOfLastCommand();
// THEN the device doesn't vibrate
verify(mVibrator, never()).vibrate(any(), any(VibrationAttributes.class));
@@ -186,6 +196,7 @@
// WHEN wireless charging starts
mNotifier.onWirelessChargingStarted(5, USER_ID);
mTestLooper.dispatchAll();
+ mTestExecutor.simulateAsyncExecutionOfLastCommand();
// THEN the charging animation is triggered
verify(mStatusBarManagerInternal, times(1)).showChargingAnimation(5);
@@ -202,6 +213,7 @@
// WHEN wireless charging starts
mNotifier.onWirelessChargingStarted(5, USER_ID);
mTestLooper.dispatchAll();
+ mTestExecutor.simulateAsyncExecutionOfLastCommand();
// THEN the charging animation never gets called
verify(mStatusBarManagerInternal, never()).showChargingAnimation(anyInt());
@@ -211,7 +223,8 @@
@Override
Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
- FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector) {
+ FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector,
+ Executor backgroundExecutor) {
return mNotifierMock;
}
@@ -300,6 +313,32 @@
mInjector.createSuspendBlocker(mService, "testBlocker"),
null,
null,
- null);
+ null,
+ mTestExecutor);
}
+
+ private static class FakeExecutor implements Executor {
+ private Runnable mLastCommand;
+
+ @Override
+ public void execute(Runnable command) {
+ assertNull(mLastCommand);
+ assertNotNull(command);
+ mLastCommand = command;
+ }
+
+ public Runnable getAndResetLastCommand() {
+ Runnable toReturn = mLastCommand;
+ mLastCommand = null;
+ return toReturn;
+ }
+
+ public void simulateAsyncExecutionOfLastCommand() {
+ Runnable toRun = getAndResetLastCommand();
+ if (toRun != null) {
+ toRun.run();
+ }
+ }
+ }
+
}
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 c9721db..fbcad62 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -109,6 +109,7 @@
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicReference;
/**
@@ -220,7 +221,8 @@
@Override
Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
- FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector) {
+ FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector,
+ Executor executor) {
return mNotifierMock;
}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/FakeTimeZoneDetectorStrategy.java b/services/tests/servicestests/src/com/android/server/timezonedetector/FakeTimeZoneDetectorStrategy.java
index 2d0dca2..c9fc033 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/FakeTimeZoneDetectorStrategy.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/FakeTimeZoneDetectorStrategy.java
@@ -61,6 +61,16 @@
}
@Override
+ public boolean isTelephonyTimeZoneDetectionSupported() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isGeoTimeZoneDetectionSupported() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public void dump(IndentingPrintWriter pw, String[] args) {
mDumpCalled = true;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index 49cd343..82e5411 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -20,6 +20,8 @@
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.window.BackNavigationInfo.typeToString;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -81,8 +83,8 @@
@Test
public void backNavInfo_HomeWhenBackToLauncher() {
- Task task = createTopTaskWithActivity();
- IOnBackInvokedCallback callback = withSystemCallback(task);
+ IOnBackInvokedCallback callback =
+ withCallback(createTopTaskWithActivity(), OnBackInvokedDispatcher.PRIORITY_SYSTEM);
SurfaceControl.Transaction tx = mock(SurfaceControl.Transaction.class);
BackNavigationInfo backNavigationInfo = mBackNavigationController.startBackNavigation(mWm,
@@ -103,7 +105,7 @@
public void backTypeCrossTaskWhenBackToPreviousTask() {
Task taskA = createTask(mDefaultDisplay);
createActivityRecord(taskA);
- withSystemCallback(createTopTaskWithActivity());
+ withCallback(createTopTaskWithActivity(), OnBackInvokedDispatcher.PRIORITY_SYSTEM);
BackNavigationInfo backNavigationInfo = startBackNavigation();
assertWithMessage("BackNavigationInfo").that(backNavigationInfo).isNotNull();
assertThat(typeToString(backNavigationInfo.getType()))
@@ -155,7 +157,7 @@
@Test
public void preparesForBackToHome() {
Task task = createTopTaskWithActivity();
- withSystemCallback(task);
+ withCallback(task, OnBackInvokedDispatcher.PRIORITY_SYSTEM);
BackNavigationInfo backNavigationInfo = startBackNavigation();
assertThat(typeToString(backNavigationInfo.getType()))
@@ -165,7 +167,8 @@
@Test
public void backTypeCallback() {
Task task = createTopTaskWithActivity();
- IOnBackInvokedCallback appCallback = withAppCallback(task);
+ IOnBackInvokedCallback appCallback =
+ withCallback(task, OnBackInvokedDispatcher.PRIORITY_DEFAULT);
BackNavigationInfo backNavigationInfo = startBackNavigation();
assertThat(typeToString(backNavigationInfo.getType()))
@@ -226,18 +229,61 @@
1, appLatch.getCount());
}
- private IOnBackInvokedCallback withSystemCallback(Task task) {
+ @Test
+ public void returnsImeCallback_imeVisible() {
+ // Set up a top activity with a default priority callback.
+ IOnBackInvokedCallback appCallback =
+ withCallback(createTopTaskWithActivity(), OnBackInvokedDispatcher.PRIORITY_DEFAULT);
+ IOnBackInvokedCallback imeCallback = createOnBackInvokedCallback();
+
+ // Set up an IME window with also a default priority callback.
+ final DisplayArea.Tokens imeContainer = mDisplayContent.getImeContainer();
+ final WindowState imeWindow = createImeWindow();
+ imeWindow.setOnBackInvokedCallbackInfo(
+ new OnBackInvokedCallbackInfo(
+ imeCallback, OnBackInvokedDispatcher.PRIORITY_DEFAULT));
+ spyOn(imeContainer);
+ // Simulate IME becoming visible.
+ doReturn(true).when(imeContainer).isVisible();
+ doReturn(imeWindow).when(imeContainer).getWindow(any());
+ BackNavigationInfo backNavigationInfo = startBackNavigation();
+
+ // Expect the IME callback to be selected.
+ assertThat(backNavigationInfo.getOnBackInvokedCallback()).isEqualTo(imeCallback);
+ }
+
+ @Test
+ public void returnsAppOverlayCallback_imeVisible() {
+ // Set up a top activity with an overlay priority callback.
+ IOnBackInvokedCallback appCallback =
+ withCallback(createTopTaskWithActivity(), OnBackInvokedDispatcher.PRIORITY_OVERLAY);
+ IOnBackInvokedCallback imeCallback = createOnBackInvokedCallback();
+
+ // Set up an IME window with a default priority callback.
+ final DisplayArea.Tokens imeContainer = mDisplayContent.getImeContainer();
+ final WindowState imeWindow = createImeWindow();
+ imeWindow.setOnBackInvokedCallbackInfo(
+ new OnBackInvokedCallbackInfo(
+ imeCallback, OnBackInvokedDispatcher.PRIORITY_DEFAULT));
+ spyOn(imeContainer);
+ // Simulate IME becoming visible.
+ doReturn(true).when(imeContainer).isVisible();
+ doReturn(imeWindow).when(imeContainer).getWindow(any());
+ BackNavigationInfo backNavigationInfo = startBackNavigation();
+
+ // Expect the app callback to be selected.
+ assertThat(backNavigationInfo.getOnBackInvokedCallback()).isEqualTo(appCallback);
+ }
+
+ private IOnBackInvokedCallback withCallback(Task task, int priority) {
IOnBackInvokedCallback callback = createOnBackInvokedCallback();
task.getTopMostActivity().getTopChild().setOnBackInvokedCallbackInfo(
- new OnBackInvokedCallbackInfo(callback, OnBackInvokedDispatcher.PRIORITY_SYSTEM));
+ new OnBackInvokedCallbackInfo(callback, priority));
return callback;
}
- private IOnBackInvokedCallback withAppCallback(Task task) {
- IOnBackInvokedCallback callback = createOnBackInvokedCallback();
- task.getTopMostActivity().getTopChild().setOnBackInvokedCallbackInfo(
- new OnBackInvokedCallbackInfo(callback, OnBackInvokedDispatcher.PRIORITY_DEFAULT));
- return callback;
+ private WindowState createImeWindow() {
+ return createWindow(null, W_INPUT_METHOD, "mImeWindow", 12345 /* fake ime uide */);
}
@Nullable
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index 30c2413..54fa4e4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -209,7 +209,7 @@
}
@Test
- public void testEmbeddedTaskFragmentEnterPip_resetOrganizerOverrideConfig() {
+ public void testEmbeddedTaskFragmentEnterPip_singleActivity_resetOrganizerOverrideConfig() {
final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
.setOrganizer(mOrganizer)
.setFragmentToken(new Binder())
@@ -242,6 +242,38 @@
}
@Test
+ public void testEmbeddedTaskFragmentEnterPip_multiActivities_notifyOrganizer() {
+ final Task task = createTask(mDisplayContent);
+ final TaskFragment taskFragment0 = new TaskFragmentBuilder(mAtm)
+ .setParentTask(task)
+ .setOrganizer(mOrganizer)
+ .setFragmentToken(new Binder())
+ .createActivityCount(1)
+ .build();
+ final TaskFragment taskFragment1 = new TaskFragmentBuilder(mAtm)
+ .setParentTask(task)
+ .setOrganizer(mOrganizer)
+ .setFragmentToken(new Binder())
+ .createActivityCount(1)
+ .build();
+ final ActivityRecord activity0 = taskFragment0.getTopMostActivity();
+ spyOn(mAtm.mTaskFragmentOrganizerController);
+
+ // Move activity to pinned.
+ mRootWindowContainer.moveActivityToPinnedRootTask(activity0,
+ null /* launchIntoPipHostActivity */, "test");
+
+ // Ensure taskFragment requested config is reset.
+ assertTrue(taskFragment0.mClearedTaskFragmentForPip);
+ assertFalse(taskFragment1.mClearedTaskFragmentForPip);
+ final TaskFragmentInfo info = taskFragment0.getTaskFragmentInfo();
+ assertTrue(info.isTaskFragmentClearedForPip());
+ assertTrue(info.isEmpty());
+ verify(mAtm.mTaskFragmentOrganizerController)
+ .dispatchPendingInfoChangedEvent(taskFragment0);
+ }
+
+ @Test
public void testActivityHasOverlayOverUntrustedModeEmbedded() {
final Task rootTask = createTask(mDisplayContent, WINDOWING_MODE_MULTI_WINDOW,
ACTIVITY_TYPE_STANDARD);
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 07e18d5..37403a8 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -355,6 +355,11 @@
void setTestDefaultCallRedirectionApp(String packageName);
+ /**
+ * @see TelecomServiceImpl#requestLogMark
+ */
+ void requestLogMark(in String message);
+
void setTestPhoneAcctSuggestionComponent(String flattenedComponentName);
void setTestDefaultCallScreeningApp(String packageName);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index a6a7c84..9c886aa 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -832,6 +832,17 @@
"dial_string_replace_string_array";
/**
+ * Specifies a map from dialstrings to replacements for international roaming network service
+ * numbers which cannot be replaced on the carrier side.
+ * <p>
+ * Individual entries have the format:
+ * [dialstring to replace]:[replacement]
+ * @hide
+ */
+ public static final String KEY_INTERNATIONAL_ROAMING_DIAL_STRING_REPLACE_STRING_ARRAY =
+ "international_roaming_dial_string_replace_string_array";
+
+ /**
* Flag specifying whether WFC over IMS supports the "wifi only" option. If false, the wifi
* calling settings will not include an option for "wifi only". If true, the wifi calling
* settings will include an option for "wifi only"
@@ -8713,6 +8724,7 @@
sDefaults.putStringArray(KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY, null);
sDefaults.putStringArray(KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY, null);
sDefaults.putStringArray(KEY_DIAL_STRING_REPLACE_STRING_ARRAY, null);
+ sDefaults.putStringArray(KEY_INTERNATIONAL_ROAMING_DIAL_STRING_REPLACE_STRING_ARRAY, null);
sDefaults.putBoolean(KEY_FORCE_HOME_NETWORK_BOOL, false);
sDefaults.putInt(KEY_GSM_DTMF_TONE_DELAY_INT, 0);
sDefaults.putInt(KEY_IMS_DTMF_TONE_DELAY_INT, 0);
diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java
index d91134e..d978f57 100644
--- a/telephony/java/android/telephony/PhysicalChannelConfig.java
+++ b/telephony/java/android/telephony/PhysicalChannelConfig.java
@@ -23,16 +23,12 @@
import android.os.Parcelable;
import android.telephony.Annotation.NetworkType;
-import com.android.telephony.Rlog;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.Objects;
public final class PhysicalChannelConfig implements Parcelable {
- static final String TAG = "PhysicalChannelConfig";
-
// TODO(b/72993578) consolidate these enums in a central location.
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -571,21 +567,19 @@
public @NonNull Builder setNetworkType(@NetworkType int networkType) {
if (!TelephonyManager.isNetworkTypeValid(networkType)) {
- Rlog.e(TAG, "Builder.setNetworkType: Network type " + networkType + " is invalid.");
- } else {
- mNetworkType = networkType;
+ throw new IllegalArgumentException("Network type " + networkType + " is invalid.");
}
+ mNetworkType = networkType;
return this;
}
public @NonNull Builder setFrequencyRange(int frequencyRange) {
if (!ServiceState.isFrequencyRangeValid(frequencyRange)
&& frequencyRange != ServiceState.FREQUENCY_RANGE_UNKNOWN) {
- Rlog.e(TAG, "Builder.setFrequencyRange: Frequency range " + frequencyRange
+ throw new IllegalArgumentException("Frequency range " + frequencyRange
+ " is invalid.");
- } else {
- mFrequencyRange = frequencyRange;
}
+ mFrequencyRange = frequencyRange;
return this;
}
@@ -601,21 +595,19 @@
public @NonNull Builder setCellBandwidthDownlinkKhz(int cellBandwidthDownlinkKhz) {
if (cellBandwidthDownlinkKhz < CELL_BANDWIDTH_UNKNOWN) {
- Rlog.e(TAG, "Builder.setCellBandwidthDownlinkKhz: Cell downlink bandwidth(kHz) "
+ throw new IllegalArgumentException("Cell downlink bandwidth(kHz) "
+ cellBandwidthDownlinkKhz + " is invalid.");
- } else {
- mCellBandwidthDownlinkKhz = cellBandwidthDownlinkKhz;
}
+ mCellBandwidthDownlinkKhz = cellBandwidthDownlinkKhz;
return this;
}
public @NonNull Builder setCellBandwidthUplinkKhz(int cellBandwidthUplinkKhz) {
if (cellBandwidthUplinkKhz < CELL_BANDWIDTH_UNKNOWN) {
- Rlog.e(TAG, "Builder.setCellBandwidthUplinkKhz: Cell uplink bandwidth(kHz) "
+ throw new IllegalArgumentException("Cell uplink bandwidth(kHz) "
+ cellBandwidthUplinkKhz + " is invalid.");
- } else {
- mCellBandwidthUplinkKhz = cellBandwidthUplinkKhz;
}
+ mCellBandwidthUplinkKhz = cellBandwidthUplinkKhz;
return this;
}
@@ -632,20 +624,18 @@
public @NonNull Builder setPhysicalCellId(int physicalCellId) {
if (physicalCellId > PHYSICAL_CELL_ID_MAXIMUM_VALUE) {
- Rlog.e(TAG, "Builder.setPhysicalCellId: Physical cell ID " + physicalCellId
+ throw new IllegalArgumentException("Physical cell ID " + physicalCellId
+ " is over limit.");
- } else {
- mPhysicalCellId = physicalCellId;
}
+ mPhysicalCellId = physicalCellId;
return this;
}
public @NonNull Builder setBand(int band) {
if (band <= BAND_UNKNOWN) {
- Rlog.e(TAG, "Builder.setBand: Band " + band + " is invalid.");
- } else {
- mBand = band;
+ throw new IllegalArgumentException("Band " + band + " is invalid.");
}
+ mBand = band;
return this;
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
index 4cddd85..aaa2db7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
@@ -34,8 +34,6 @@
import com.android.server.wm.flicker.statusBarLayerRotatesScales
import com.android.server.wm.flicker.statusBarWindowIsVisible
import com.android.server.wm.flicker.replacesLayer
-import com.android.server.wm.flicker.rules.WMFlickerServiceRuleForTestSpec
-import org.junit.Rule
import org.junit.Test
/**
@@ -45,9 +43,6 @@
protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
protected open val testApp: StandardAppHelper = SimpleAppHelper(instrumentation)
- @get:Rule
- val flickerRule = WMFlickerServiceRuleForTestSpec(testSpec)
-
/**
* Specification of the test transition to execute
*/
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
index 04fdda4..2f546b5 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
@@ -63,8 +63,12 @@
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group4
class TaskTransitionTest(val testSpec: FlickerTestParameter) {
- val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val mTestApp: NewTasksAppHelper = NewTasksAppHelper(instrumentation)
+ private val mWallpaper by lazy {
+ getWallpaperPackage(InstrumentationRegistry.getInstrumentation())
+ ?: error("Unable to obtain wallpaper")
+ }
@FlickerBuilderProvider
fun buildFlicker(): FlickerBuilder {
@@ -97,7 +101,7 @@
@Test
fun wallpaperWindowIsNeverVisible() {
testSpec.assertWm {
- this.isNonAppWindowInvisible(WALLPAPER)
+ this.isNonAppWindowInvisible(mWallpaper)
}
}
@@ -109,7 +113,7 @@
@Test
fun wallpaperLayerIsNeverVisible() {
testSpec.assertLayers {
- this.isInvisible(WALLPAPER)
+ this.isInvisible(mWallpaper)
this.isInvisible(WALLPAPER_BBQ_WRAPPER)
}
}
@@ -229,15 +233,14 @@
fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
companion object {
- private val WALLPAPER = getWallpaperPackage(InstrumentationRegistry.getInstrumentation())
private val LAUNCH_NEW_TASK_ACTIVITY =
LAUNCH_NEW_TASK_ACTIVITY_COMPONENT_NAME.toFlickerComponent()
private val SIMPLE_ACTIVITY = SIMPLE_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME.toFlickerComponent()
- private fun getWallpaperPackage(instrumentation: Instrumentation): FlickerComponentName {
+ private fun getWallpaperPackage(instrumentation: Instrumentation): FlickerComponentName? {
val wallpaperManager = WallpaperManager.getInstance(instrumentation.targetContext)
- return wallpaperManager.wallpaperInfo.component.toFlickerComponent()
+ return wallpaperManager.wallpaperInfo?.component?.toFlickerComponent()
}
@Parameterized.Parameters(name = "{0}")
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index 8b851e5..f0d16f3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -25,13 +25,11 @@
import com.android.server.wm.flicker.annotation.Group3
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.SimpleAppHelper
-import com.android.server.wm.flicker.rules.WMFlickerServiceRuleForTestSpec
import com.android.server.wm.flicker.statusBarLayerIsVisible
import com.android.server.wm.flicker.statusBarLayerRotatesScales
import com.android.server.wm.flicker.statusBarWindowIsVisible
import com.android.server.wm.traces.common.FlickerComponentName
import org.junit.FixMethodOrder
-import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -80,9 +78,6 @@
class ChangeAppRotationTest(
testSpec: FlickerTestParameter
) : RotationTransition(testSpec) {
- @get:Rule
- val flickerRule = WMFlickerServiceRuleForTestSpec(testSpec)
-
override val testApp = SimpleAppHelper(instrumentation)
override val transition: FlickerBuilder.() -> Unit
get() = {
diff --git a/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java b/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java
index 525a784..c25ce71 100644
--- a/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java
+++ b/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java
@@ -21,7 +21,6 @@
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil;
import org.junit.Assert;
import org.junit.ClassRule;
@@ -369,7 +368,9 @@
device.executeShellCommand("disable-verity");
device.reboot();
}
- device.executeShellCommand("remount");
+ device.enableAdbRoot();
+ device.remountSystemWritable();
+ device.remountVendorWritable();
device.waitForDeviceAvailable();
}
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index bb98bc0..54b3c40 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -65,6 +65,7 @@
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.TelephonyNetworkSpecifier;
+import android.net.Uri;
import android.net.vcn.IVcnStatusCallback;
import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
import android.net.vcn.VcnConfig;
@@ -114,18 +115,24 @@
public class VcnManagementServiceTest {
private static final String TEST_PACKAGE_NAME =
VcnManagementServiceTest.class.getPackage().getName();
+ private static final String TEST_PACKAGE_NAME_2 = "TEST_PKG_2";
private static final String TEST_CB_PACKAGE_NAME =
VcnManagementServiceTest.class.getPackage().getName() + ".callback";
private static final ParcelUuid TEST_UUID_1 = new ParcelUuid(new UUID(0, 0));
private static final ParcelUuid TEST_UUID_2 = new ParcelUuid(new UUID(1, 1));
+ private static final ParcelUuid TEST_UUID_3 = new ParcelUuid(new UUID(2, 2));
private static final VcnConfig TEST_VCN_CONFIG;
+ private static final VcnConfig TEST_VCN_CONFIG_PKG_2;
private static final int TEST_UID = Process.FIRST_APPLICATION_UID;
static {
final Context mockConfigContext = mock(Context.class);
- doReturn(TEST_PACKAGE_NAME).when(mockConfigContext).getOpPackageName();
+ doReturn(TEST_PACKAGE_NAME).when(mockConfigContext).getOpPackageName();
TEST_VCN_CONFIG = VcnConfigTest.buildTestConfig(mockConfigContext);
+
+ doReturn(TEST_PACKAGE_NAME_2).when(mockConfigContext).getOpPackageName();
+ TEST_VCN_CONFIG_PKG_2 = VcnConfigTest.buildTestConfig(mockConfigContext);
}
private static final Map<ParcelUuid, VcnConfig> TEST_VCN_CONFIG_MAP =
@@ -246,18 +253,24 @@
eq(android.Manifest.permission.NETWORK_FACTORY), any());
}
+
private void setupMockedCarrierPrivilege(boolean isPrivileged) {
+ setupMockedCarrierPrivilege(isPrivileged, TEST_PACKAGE_NAME);
+ }
+
+ private void setupMockedCarrierPrivilege(boolean isPrivileged, String pkg) {
doReturn(Collections.singletonList(TEST_SUBSCRIPTION_INFO))
.when(mSubMgr)
.getSubscriptionsInGroup(any());
doReturn(mTelMgr)
.when(mTelMgr)
.createForSubscriptionId(eq(TEST_SUBSCRIPTION_INFO.getSubscriptionId()));
- doReturn(isPrivileged
- ? CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
- : CARRIER_PRIVILEGE_STATUS_NO_ACCESS)
+ doReturn(
+ isPrivileged
+ ? CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
+ : CARRIER_PRIVILEGE_STATUS_NO_ACCESS)
.when(mTelMgr)
- .checkCarrierPrivilegesForPackage(eq(TEST_PACKAGE_NAME));
+ .checkCarrierPrivilegesForPackage(eq(pkg));
}
@Test
@@ -414,7 +427,13 @@
private BroadcastReceiver getPackageChangeReceiver() {
final ArgumentCaptor<BroadcastReceiver> captor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
- verify(mMockContext).registerReceiver(captor.capture(), any(), any(), any());
+ verify(mMockContext).registerReceiver(captor.capture(), argThat(filter -> {
+ return filter.hasAction(Intent.ACTION_PACKAGE_ADDED)
+ && filter.hasAction(Intent.ACTION_PACKAGE_REPLACED)
+ && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED)
+ && filter.hasAction(Intent.ACTION_PACKAGE_DATA_CLEARED)
+ && filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
+ }), any(), any());
return captor.getValue();
}
@@ -539,6 +558,44 @@
}
@Test
+ public void testPackageChangeListener_packageDataCleared() throws Exception {
+ triggerSubscriptionTrackerCbAndGetSnapshot(TEST_UUID_1, Collections.singleton(TEST_UUID_1));
+ final Vcn vcn = mVcnMgmtSvc.getAllVcns().get(TEST_UUID_1);
+
+ final BroadcastReceiver receiver = getPackageChangeReceiver();
+ assertEquals(TEST_VCN_CONFIG_MAP, mVcnMgmtSvc.getConfigs());
+
+ final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED);
+ intent.setData(Uri.parse("package:" + TEST_PACKAGE_NAME));
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(TEST_UID));
+
+ receiver.onReceive(mMockContext, intent);
+ mTestLooper.dispatchAll();
+ verify(vcn).teardownAsynchronously();
+ assertTrue(mVcnMgmtSvc.getConfigs().isEmpty());
+ verify(mConfigReadWriteHelper).writeToDisk(any(PersistableBundle.class));
+ }
+
+ @Test
+ public void testPackageChangeListener_packageFullyRemoved() throws Exception {
+ triggerSubscriptionTrackerCbAndGetSnapshot(TEST_UUID_1, Collections.singleton(TEST_UUID_1));
+ final Vcn vcn = mVcnMgmtSvc.getAllVcns().get(TEST_UUID_1);
+
+ final BroadcastReceiver receiver = getPackageChangeReceiver();
+ assertEquals(TEST_VCN_CONFIG_MAP, mVcnMgmtSvc.getConfigs());
+
+ final Intent intent = new Intent(Intent.ACTION_PACKAGE_FULLY_REMOVED);
+ intent.setData(Uri.parse("package:" + TEST_PACKAGE_NAME));
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(TEST_UID));
+
+ receiver.onReceive(mMockContext, intent);
+ mTestLooper.dispatchAll();
+ verify(vcn).teardownAsynchronously();
+ assertTrue(mVcnMgmtSvc.getConfigs().isEmpty());
+ verify(mConfigReadWriteHelper).writeToDisk(any(PersistableBundle.class));
+ }
+
+ @Test
public void testSetVcnConfigRequiresNonSystemServer() throws Exception {
doReturn(Process.SYSTEM_UID).when(mMockDeps).getBinderCallingUid();
@@ -578,7 +635,7 @@
@Test
public void testSetVcnConfigMismatchedPackages() throws Exception {
try {
- mVcnMgmtSvc.setVcnConfig(TEST_UUID_1, TEST_VCN_CONFIG, "IncorrectPackage");
+ mVcnMgmtSvc.setVcnConfig(TEST_UUID_1, TEST_VCN_CONFIG, TEST_PACKAGE_NAME_2);
fail("Expected exception due to mismatched packages in config and method call");
} catch (IllegalArgumentException expected) {
verify(mMockPolicyListener, never()).onPolicyChanged();
@@ -678,11 +735,12 @@
}
@Test
- public void testClearVcnConfigRequiresCarrierPrivileges() throws Exception {
+ public void testClearVcnConfigRequiresCarrierPrivilegesOrProvisioningPackage()
+ throws Exception {
setupMockedCarrierPrivilege(false);
try {
- mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1, TEST_PACKAGE_NAME);
+ mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1, TEST_PACKAGE_NAME_2);
fail("Expected security exception for missing carrier privileges");
} catch (SecurityException expected) {
}
@@ -691,20 +749,32 @@
@Test
public void testClearVcnConfigMismatchedPackages() throws Exception {
try {
- mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1, "IncorrectPackage");
+ mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1, TEST_PACKAGE_NAME_2);
fail("Expected security exception due to mismatched packages");
} catch (SecurityException expected) {
}
}
@Test
- public void testClearVcnConfig() throws Exception {
+ public void testClearVcnConfig_callerIsProvisioningPackage() throws Exception {
+ // Lose carrier privileges to test that provisioning package is sufficient.
+ setupMockedCarrierPrivilege(false);
+
mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1, TEST_PACKAGE_NAME);
assertTrue(mVcnMgmtSvc.getConfigs().isEmpty());
verify(mConfigReadWriteHelper).writeToDisk(any(PersistableBundle.class));
}
@Test
+ public void testClearVcnConfig_callerIsCarrierPrivileged() throws Exception {
+ setupMockedCarrierPrivilege(true, TEST_PACKAGE_NAME_2);
+
+ mVcnMgmtSvc.clearVcnConfig(TEST_UUID_1, TEST_PACKAGE_NAME_2);
+ assertTrue(mVcnMgmtSvc.getConfigs().isEmpty());
+ verify(mConfigReadWriteHelper).writeToDisk(any(PersistableBundle.class));
+ }
+
+ @Test
public void testClearVcnConfigNotifiesStatusCallback() throws Exception {
setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_2, true /* isActive */);
mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_2, mMockStatusCallback, TEST_PACKAGE_NAME);
@@ -755,11 +825,12 @@
@Test
public void testGetConfiguredSubscriptionGroupsMismatchedPackages() throws Exception {
- final String badPackage = "IncorrectPackage";
- doThrow(new SecurityException()).when(mAppOpsMgr).checkPackage(TEST_UID, badPackage);
+ doThrow(new SecurityException())
+ .when(mAppOpsMgr)
+ .checkPackage(TEST_UID, TEST_PACKAGE_NAME_2);
try {
- mVcnMgmtSvc.getConfiguredSubscriptionGroups(badPackage);
+ mVcnMgmtSvc.getConfiguredSubscriptionGroups(TEST_PACKAGE_NAME_2);
fail("Expected security exception due to mismatched packages");
} catch (SecurityException expected) {
}
@@ -767,14 +838,16 @@
@Test
public void testGetConfiguredSubscriptionGroups() throws Exception {
+ setupMockedCarrierPrivilege(true, TEST_PACKAGE_NAME_2);
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
+ mVcnMgmtSvc.setVcnConfig(TEST_UUID_3, TEST_VCN_CONFIG_PKG_2, TEST_PACKAGE_NAME_2);
- // Assert that if both UUID 1 and 2 are provisioned, the caller only gets ones that they are
- // privileged for.
+ // Assert that if UUIDs 1, 2 and 3 are provisioned, the caller only gets ones that they are
+ // privileged for, or are the provisioning package of.
triggerSubscriptionTrackerCbAndGetSnapshot(TEST_UUID_1, Collections.singleton(TEST_UUID_1));
final List<ParcelUuid> subGrps =
mVcnMgmtSvc.getConfiguredSubscriptionGroups(TEST_PACKAGE_NAME);
- assertEquals(Collections.singletonList(TEST_UUID_1), subGrps);
+ assertEquals(Arrays.asList(new ParcelUuid[] {TEST_UUID_1, TEST_UUID_2}), subGrps);
}
@Test
diff --git a/tools/aapt/SdkConstants.h b/tools/aapt/SdkConstants.h
index f57c4ee..a146466 100644
--- a/tools/aapt/SdkConstants.h
+++ b/tools/aapt/SdkConstants.h
@@ -48,6 +48,7 @@
SDK_R = 30,
SDK_S = 31,
SDK_S_V2 = 32,
+ SDK_TIRAMISU = 33,
SDK_CUR_DEVELOPMENT = 10000,
};
diff --git a/tools/aapt2/SdkConstants.h b/tools/aapt2/SdkConstants.h
index f2aaaf5..0bd61c0 100644
--- a/tools/aapt2/SdkConstants.h
+++ b/tools/aapt2/SdkConstants.h
@@ -58,6 +58,7 @@
SDK_R = 30,
SDK_S = 31,
SDK_S_V2 = 32,
+ SDK_TIRAMISU = 33,
SDK_CUR_DEVELOPMENT = 10000,
};