diff options
365 files changed, 8512 insertions, 3812 deletions
diff --git a/Android.bp b/Android.bp index 8ac7de944fe7..df6fdaa5fdf6 100644 --- a/Android.bp +++ b/Android.bp @@ -65,7 +65,6 @@ filegroup { // Java/AIDL sources under frameworks/base ":framework-annotations", ":framework-blobstore-sources", - ":framework-connectivity-tiramisu-sources", ":framework-core-sources", ":framework-drm-sources", ":framework-graphics-nonupdatable-sources", diff --git a/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java b/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java new file mode 100644 index 000000000000..ea3d172b2e5f --- /dev/null +++ b/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.libcore; + +import android.perftests.utils.BenchmarkState; +import android.perftests.utils.PerfStatusReporter; +import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * What do various kinds of addition cost? + */ +@RunWith(AndroidJUnit4.class) +@LargeTest +public class AdditionPerfTest { + + @Rule + public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); + + @Test + public int timeAddConstantToLocalInt() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + int result = 0; + while (state.keepRunning()) { + result += 123; + } + return result; + } + @Test + public int timeAddTwoLocalInts() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + int result = 0; + int constant = 123; + while (state.keepRunning()) { + result += constant; + } + return result; + } + @Test + public long timeAddConstantToLocalLong() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + long result = 0; + while (state.keepRunning()) { + result += 123L; + } + return result; + } + @Test + public long timeAddTwoLocalLongs() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + long result = 0; + long constant = 123L; + while (state.keepRunning()) { + result += constant; + } + return result; + } + @Test + public float timeAddConstantToLocalFloat() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + float result = 0.0f; + while (state.keepRunning()) { + result += 123.0f; + } + return result; + } + @Test + public float timeAddTwoLocalFloats() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + float result = 0.0f; + float constant = 123.0f; + while (state.keepRunning()) { + result += constant; + } + return result; + } + @Test + public double timeAddConstantToLocalDouble() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + double result = 0.0; + while (state.keepRunning()) { + result += 123.0; + } + return result; + } + @Test + public double timeAddTwoLocalDoubles() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + double result = 0.0; + double constant = 123.0; + while (state.keepRunning()) { + result += constant; + } + return result; + } +} diff --git a/apct-tests/perftests/core/src/android/libcore/ArrayCopyPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ArrayCopyPerfTest.java new file mode 100644 index 000000000000..97ab6c7cd6b4 --- /dev/null +++ b/apct-tests/perftests/core/src/android/libcore/ArrayCopyPerfTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.libcore; + +import android.perftests.utils.BenchmarkState; +import android.perftests.utils.PerfStatusReporter; +import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Arrays; + +@RunWith(AndroidJUnit4.class) +@LargeTest +public class ArrayCopyPerfTest { + + @Rule + public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); + + @Test + public void timeManualArrayCopy() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + char[] src = new char[8192]; + while (state.keepRunning()) { + char[] dst = new char[8192]; + for (int i = 0; i < 8192; ++i) { + dst[i] = src[i]; + } + } + } + + @Test + public void time_System_arrayCopy() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + char[] src = new char[8192]; + while (state.keepRunning()) { + char[] dst = new char[8192]; + System.arraycopy(src, 0, dst, 0, 8192); + } + } + + @Test + public void time_Arrays_copyOf() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + char[] src = new char[8192]; + while (state.keepRunning()) { + char[] dst = Arrays.copyOf(src, 8192); + } + } + + @Test + public void time_Arrays_copyOfRange() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + char[] src = new char[8192]; + while (state.keepRunning()) { + char[] dst = Arrays.copyOfRange(src, 0, 8192); + } + } +} diff --git a/apct-tests/perftests/core/src/android/libcore/ArrayIterationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ArrayIterationPerfTest.java new file mode 100644 index 000000000000..bb452d394d47 --- /dev/null +++ b/apct-tests/perftests/core/src/android/libcore/ArrayIterationPerfTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.libcore; + +import android.perftests.utils.BenchmarkState; +import android.perftests.utils.PerfStatusReporter; +import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * How do various ways of iterating through an array compare? + */ +@RunWith(AndroidJUnit4.class) +@LargeTest +public class ArrayIterationPerfTest { + + public class Foo { + int mSplat; + } + + @Rule + public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); + + Foo[] mArray = new Foo[27]; + { + for (int i = 0; i < mArray.length; ++i) mArray[i] = new Foo(); + } + @Test + public void timeArrayIteration() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + while (state.keepRunning()) { + int sum = 0; + for (int i = 0; i < mArray.length; i++) { + sum += mArray[i].mSplat; + } + } + } + @Test + public void timeArrayIterationCached() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + while (state.keepRunning()) { + int sum = 0; + Foo[] localArray = mArray; + int len = localArray.length; + + for (int i = 0; i < len; i++) { + sum += localArray[i].mSplat; + } + } + } + @Test + public void timeArrayIterationForEach() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + while (state.keepRunning()) { + int sum = 0; + for (Foo a: mArray) { + sum += a.mSplat; + } + } + } +} diff --git a/apct-tests/perftests/core/src/android/libcore/ArrayListIterationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ArrayListIterationPerfTest.java new file mode 100644 index 000000000000..ff6d46f6db7f --- /dev/null +++ b/apct-tests/perftests/core/src/android/libcore/ArrayListIterationPerfTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.libcore; + +import android.perftests.utils.BenchmarkState; +import android.perftests.utils.PerfStatusReporter; +import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; + +/** + * Is a hand-coded counted loop through an ArrayList cheaper than enhanced for? + */ +@RunWith(AndroidJUnit4.class) +@LargeTest +public class ArrayListIterationPerfTest { + + public class Foo { + int mSplat; + } + @Rule + public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); + + ArrayList<Foo> mList = new ArrayList<Foo>(); + { + for (int i = 0; i < 27; ++i) mList.add(new Foo()); + } + @Test + public void timeArrayListIterationIndexed() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + while (state.keepRunning()) { + int sum = 0; + ArrayList<Foo> list = mList; + int len = list.size(); + for (int i = 0; i < len; ++i) { + sum += list.get(i).mSplat; + } + } + } + @Test + public void timeArrayListIterationForEach() { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + while (state.keepRunning()) { + int sum = 0; + for (Foo a : mList) { + sum += a.mSplat; + } + } + } +} diff --git a/apct-tests/perftests/core/src/android/libcore/OWNERS b/apct-tests/perftests/core/src/android/libcore/OWNERS new file mode 100644 index 000000000000..2d365747473a --- /dev/null +++ b/apct-tests/perftests/core/src/android/libcore/OWNERS @@ -0,0 +1,2 @@ +# Bug component: 24949 +include platform/libcore:/OWNERS diff --git a/apex/jobscheduler/framework/java/android/app/AlarmManager.java b/apex/jobscheduler/framework/java/android/app/AlarmManager.java index 61424ae0e158..1b9cf2648a3f 100644 --- a/apex/jobscheduler/framework/java/android/app/AlarmManager.java +++ b/apex/jobscheduler/framework/java/android/app/AlarmManager.java @@ -27,6 +27,7 @@ import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledAfter; import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; @@ -280,6 +281,18 @@ public class AlarmManager { @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU) public static final long ENABLE_USE_EXACT_ALARM = 218533173L; + /** + * For apps targeting {@link Build.VERSION_CODES#TIRAMISU} or above, the permission + * {@link Manifest.permission#SCHEDULE_EXACT_ALARM} will be denied, unless the user explicitly + * allows it from Settings. + * + * TODO (b/226439802): change to EnabledSince(T) after SDK finalization. + * @hide + */ + @ChangeId + @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S_V2) + public static final long SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = 226439802L; + @UnsupportedAppUsage private final IAlarmManager mService; private final Context mContext; 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 f67e8d2baa11..881453fe237d 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -66,6 +66,7 @@ import android.app.IAlarmListener; import android.app.IAlarmManager; import android.app.PendingIntent; import android.app.compat.CompatChanges; +import android.app.role.RoleManager; import android.app.usage.UsageStatsManager; import android.app.usage.UsageStatsManagerInternal; import android.content.BroadcastReceiver; @@ -164,6 +165,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Set; import java.util.TimeZone; @@ -224,6 +226,7 @@ public class AlarmManagerService extends SystemService { private ActivityManagerInternal mActivityManagerInternal; private final EconomyManagerInternal mEconomyManagerInternal; private PackageManagerInternal mPackageManagerInternal; + private RoleManager mRoleManager; private volatile PermissionManagerServiceInternal mLocalPermissionManager; final Object mLock = new Object(); @@ -562,6 +565,9 @@ public class AlarmManagerService extends SystemService { @VisibleForTesting static final String KEY_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED = "kill_on_schedule_exact_alarm_revoked"; + @VisibleForTesting + static final String KEY_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = + "schedule_exact_alarm_denied_by_default"; private static final long DEFAULT_MIN_FUTURITY = 5 * 1000; private static final long DEFAULT_MIN_INTERVAL = 60 * 1000; @@ -606,6 +612,9 @@ public class AlarmManagerService extends SystemService { 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; + // Minimum futurity of a new alarm public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY; @@ -693,6 +702,14 @@ public class AlarmManagerService extends SystemService { public boolean KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED = DEFAULT_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED; + /** + * When this is {@code true}, apps with the change + * {@link AlarmManager#SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT} enabled will not get + * {@link Manifest.permission#SCHEDULE_EXACT_ALARM} unless the user grants it to them. + */ + public volatile boolean SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = + DEFAULT_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT; + public boolean USE_TARE_POLICY = Settings.Global.DEFAULT_ENABLE_TARE == 1; private long mLastAllowWhileIdleWhitelistDuration = -1; @@ -876,6 +893,15 @@ public class AlarmManagerService extends SystemService { KEY_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED, DEFAULT_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED); break; + case KEY_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT: + final boolean oldValue = SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT; + + SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = properties.getBoolean( + KEY_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, + DEFAULT_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT); + handleScheduleExactAlarmDeniedByDefaultChange(oldValue, + SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT); + break; default: if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) { // The quotas need to be updated in order, so we can't just rely @@ -946,6 +972,15 @@ public class AlarmManagerService extends SystemService { } } + private void handleScheduleExactAlarmDeniedByDefaultChange(boolean oldValue, + boolean newValue) { + if (oldValue == newValue) { + return; + } + mHandler.obtainMessage(AlarmHandler.CHECK_EXACT_ALARM_PERMISSION_ON_FEATURE_TOGGLE, + newValue).sendToTarget(); + } + private void migrateAlarmsToNewStoreLocked() { final AlarmStore newStore = LAZY_BATCHING ? new LazyAlarmStore() : new BatchingAlarmStore(); @@ -1122,6 +1157,9 @@ public class AlarmManagerService extends SystemService { pw.print(KEY_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED, KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED); pw.println(); + pw.print(KEY_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, + SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT); + pw.println(); pw.print(Settings.Global.ENABLE_TARE, USE_TARE_POLICY); pw.println(); @@ -1892,11 +1930,10 @@ public class AlarmManagerService extends SystemService { if (hasUseExactAlarmInternal(packageName, uid)) { return; } - - final boolean requested = mExactAlarmCandidates.contains( - UserHandle.getAppId(uid)); - final boolean denyListed = - mConstants.EXACT_ALARM_DENY_LIST.contains(packageName); + if (!mExactAlarmCandidates.contains(UserHandle.getAppId(uid))) { + // Permission not requested, app op doesn't matter. + return; + } final int newMode = mAppOps.checkOpNoThrow( AppOpsManager.OP_SCHEDULE_EXACT_ALARM, uid, packageName); @@ -1913,11 +1950,24 @@ public class AlarmManagerService extends SystemService { mLastOpScheduleExactAlarm.setValueAt(index, newMode); } } - - final boolean hadPermission = getScheduleExactAlarmState(requested, - denyListed, oldMode); - final boolean hasPermission = getScheduleExactAlarmState(requested, - denyListed, newMode); + if (oldMode == newMode) { + return; + } + final boolean allowedByDefault = + isScheduleExactAlarmAllowedByDefault(packageName, uid); + + final boolean hadPermission; + if (oldMode != AppOpsManager.MODE_DEFAULT) { + hadPermission = (oldMode == AppOpsManager.MODE_ALLOWED); + } else { + hadPermission = allowedByDefault; + } + final boolean hasPermission; + if (newMode != AppOpsManager.MODE_DEFAULT) { + hasPermission = (newMode == AppOpsManager.MODE_ALLOWED); + } else { + hasPermission = allowedByDefault; + } if (hadPermission && !hasPermission) { mHandler.obtainMessage(AlarmHandler.REMOVE_EXACT_ALARMS, @@ -1939,6 +1989,8 @@ public class AlarmManagerService extends SystemService { LocalServices.getService(AppStandbyInternal.class); appStandbyInternal.addListener(new AppStandbyTracker()); + mRoleManager = getContext().getSystemService(RoleManager.class); + mMetricsHelper.registerPuller(() -> mAlarmStore); } } @@ -2525,19 +2577,6 @@ public class AlarmManagerService extends SystemService { } } - private static boolean getScheduleExactAlarmState(boolean requested, boolean denyListed, - int appOpMode) { - // This does not account for the state of the USE_EXACT_ALARM permission. - // The caller should do that separately. - if (!requested) { - return false; - } - if (appOpMode == AppOpsManager.MODE_DEFAULT) { - return !denyListed; - } - return appOpMode == AppOpsManager.MODE_ALLOWED; - } - boolean hasUseExactAlarmInternal(String packageName, int uid) { return isUseExactAlarmEnabled(packageName, UserHandle.getUserId(uid)) && (PermissionChecker.checkPermissionForPreflight(getContext(), @@ -2545,6 +2584,32 @@ public class AlarmManagerService extends SystemService { packageName) == PermissionChecker.PERMISSION_GRANTED); } + /** + * Returns whether SCHEDULE_EXACT_ALARM is allowed by default. + */ + boolean isScheduleExactAlarmAllowedByDefault(String packageName, int uid) { + if (isScheduleExactAlarmDeniedByDefault(packageName, UserHandle.getUserId(uid))) { + + // This is essentially like changing the protection level of the permission to + // (privileged|signature|role|appop), but have to implement this logic to maintain + // compatibility for older apps. + if (mPackageManagerInternal.isPlatformSigned(packageName) + || mPackageManagerInternal.isUidPrivileged(uid)) { + return true; + } + final long token = Binder.clearCallingIdentity(); + try { + final List<String> wellbeingHolders = (mRoleManager != null) + ? mRoleManager.getRoleHolders(RoleManager.ROLE_SYSTEM_WELLBEING) + : Collections.emptyList(); + return wellbeingHolders.contains(packageName); + } finally { + Binder.restoreCallingIdentity(token); + } + } + return !mConstants.EXACT_ALARM_DENY_LIST.contains(packageName); + } + boolean hasScheduleExactAlarmInternal(String packageName, int uid) { final long start = mStatLogger.getTime(); @@ -2560,7 +2625,7 @@ public class AlarmManagerService extends SystemService { final int mode = mAppOps.checkOpNoThrow(AppOpsManager.OP_SCHEDULE_EXACT_ALARM, uid, packageName); if (mode == AppOpsManager.MODE_DEFAULT) { - hasPermission = !mConstants.EXACT_ALARM_DENY_LIST.contains(packageName); + hasPermission = isScheduleExactAlarmAllowedByDefault(packageName, uid); } else { hasPermission = (mode == AppOpsManager.MODE_ALLOWED); } @@ -2860,6 +2925,13 @@ public class AlarmManagerService extends SystemService { packageName, UserHandle.of(userId)); } + private boolean isScheduleExactAlarmDeniedByDefault(String packageName, int userId) { + return mConstants.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT + && CompatChanges.isChangeEnabled( + AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, packageName, + UserHandle.of(userId)); + } + @NeverCompile // Avoid size overhead of debugging code. void dumpImpl(IndentingPrintWriter pw) { synchronized (mLock) { @@ -3769,26 +3841,27 @@ public class AlarmManagerService extends SystemService { if (!isExactAlarmChangeEnabled(changedPackage, userId)) { continue; } + if (isScheduleExactAlarmDeniedByDefault(changedPackage, userId)) { + continue; + } if (hasUseExactAlarmInternal(changedPackage, uid)) { continue; } + if (!mExactAlarmCandidates.contains(UserHandle.getAppId(uid))) { + // Permission isn't requested, deny list doesn't matter. + continue; + } final int appOpMode; synchronized (mLock) { appOpMode = mLastOpScheduleExactAlarm.get(uid, AppOpsManager.opToDefaultMode(AppOpsManager.OP_SCHEDULE_EXACT_ALARM)); } - final boolean requested = mExactAlarmCandidates.contains(UserHandle.getAppId(uid)); - - // added: true => package was added to the deny list - // added: false => package was removed from the deny list - final boolean hadPermission = getScheduleExactAlarmState(requested, !added, - appOpMode); - final boolean hasPermission = getScheduleExactAlarmState(requested, added, - appOpMode); - - if (hadPermission == hasPermission) { + if (appOpMode != AppOpsManager.MODE_DEFAULT) { + // Deny list doesn't matter. continue; } + // added: true => package was added to the deny list + // added: false => package was removed from the deny list if (added) { synchronized (mLock) { removeExactAlarmsOnPermissionRevokedLocked(uid, @@ -4634,6 +4707,7 @@ public class AlarmManagerService extends SystemService { public static final int REFRESH_EXACT_ALARM_CANDIDATES = 11; public static final int TARE_AFFORDABILITY_CHANGED = 12; public static final int CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE = 13; + public static final int CHECK_EXACT_ALARM_PERMISSION_ON_FEATURE_TOGGLE = 14; AlarmHandler() { super(Looper.myLooper()); @@ -4759,6 +4833,35 @@ public class AlarmManagerService extends SystemService { } } break; + case CHECK_EXACT_ALARM_PERMISSION_ON_FEATURE_TOGGLE: + final boolean defaultDenied = (Boolean) msg.obj; + + final int[] startedUserIds = mActivityManagerInternal.getStartedUserIds(); + for (int appId : mExactAlarmCandidates) { + for (int userId : startedUserIds) { + uid = UserHandle.getUid(userId, appId); + + final AndroidPackage packageForUid = + mPackageManagerInternal.getPackage(uid); + if (packageForUid == null) { + continue; + } + final String pkg = packageForUid.getPackageName(); + if (defaultDenied) { + if (!hasScheduleExactAlarmInternal(pkg, uid) + && !hasUseExactAlarmInternal(pkg, uid)) { + synchronized (mLock) { + removeExactAlarmsOnPermissionRevokedLocked(uid, pkg, + true); + } + } + } else if (hasScheduleExactAlarmInternal(pkg, uid)) { + sendScheduleExactAlarmPermissionStateChangedBroadcast(pkg, + UserHandle.getUserId(uid)); + } + } + } + break; default: // nope, just ignore it break; diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java index f26e051581f3..c6ba1eac56c0 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java @@ -307,7 +307,7 @@ public final class QuotaController extends StateController { private final SparseBooleanArray mTempAllowlistCache = new SparseBooleanArray(); /** - * Mapping of UIDs to the when their temp allowlist grace period ends (in the elapsed + * Mapping of UIDs to when their temp allowlist grace period ends (in the elapsed * realtime timebase). */ private final SparseLongArray mTempAllowlistGraceCache = new SparseLongArray(); @@ -815,6 +815,19 @@ public final class QuotaController extends StateController { jobStatus.getSourceUserId(), jobStatus.getSourcePackageName()); } + private boolean hasTempAllowlistExemptionLocked(int sourceUid, int standbyBucket, + long nowElapsed) { + if (standbyBucket == RESTRICTED_INDEX || standbyBucket == NEVER_INDEX) { + // Don't let RESTRICTED apps get free quota from the temp allowlist. + // TODO: consider granting the exemption to RESTRICTED apps if the temp allowlist allows + // them to start FGS + return false; + } + final long tempAllowlistGracePeriodEndElapsed = mTempAllowlistGraceCache.get(sourceUid); + return mTempAllowlistCache.get(sourceUid) + || nowElapsed < tempAllowlistGracePeriodEndElapsed; + } + /** @return true if the job is within expedited job quota. */ @GuardedBy("mLock") public boolean isWithinEJQuotaLocked(@NonNull final JobStatus jobStatus) { @@ -833,11 +846,8 @@ public final class QuotaController extends StateController { } final long nowElapsed = sElapsedRealtimeClock.millis(); - final long tempAllowlistGracePeriodEndElapsed = - mTempAllowlistGraceCache.get(jobStatus.getSourceUid()); - final boolean hasTempAllowlistExemption = mTempAllowlistCache.get(jobStatus.getSourceUid()) - || nowElapsed < tempAllowlistGracePeriodEndElapsed; - if (hasTempAllowlistExemption) { + if (hasTempAllowlistExemptionLocked(jobStatus.getSourceUid(), + jobStatus.getEffectiveStandbyBucket(), nowElapsed)) { return true; } @@ -2127,10 +2137,8 @@ public final class QuotaController extends StateController { final long nowElapsed = sElapsedRealtimeClock.millis(); final int standbyBucket = JobSchedulerService.standbyBucketForPackage(mPkg.packageName, mPkg.userId, nowElapsed); - final long tempAllowlistGracePeriodEndElapsed = mTempAllowlistGraceCache.get(mUid); final boolean hasTempAllowlistExemption = !mRegularJobTimer - && (mTempAllowlistCache.get(mUid) - || nowElapsed < tempAllowlistGracePeriodEndElapsed); + && hasTempAllowlistExemptionLocked(mUid, standbyBucket, nowElapsed); final long topAppGracePeriodEndElapsed = mTopAppGraceCache.get(mUid); final boolean hasTopAppExemption = !mRegularJobTimer && (mTopAppCache.get(mUid) || nowElapsed < topAppGracePeriodEndElapsed); diff --git a/apex/jobscheduler/service/java/com/android/server/tare/README.md b/apex/jobscheduler/service/java/com/android/server/tare/README.md index a4933a127f13..33eadffb8592 100644 --- a/apex/jobscheduler/service/java/com/android/server/tare/README.md +++ b/apex/jobscheduler/service/java/com/android/server/tare/README.md @@ -1,10 +1,12 @@ +# Overview + Welcome to The Android Resource Economy (TARE for short). If you're reading this, you may be wondering what all of this code is for and what it means. TARE is an attempt to apply economic principles to resource (principally battery) management. It acknowledges that battery is a limited resource on mobile devices and that the system must allocate and apportion those resources -accordingly. Every action (running a job, firing an alarm, using the network, using the CPU, -etc.) has a cost. Once that action has been performed and that bit of battery has been drained, it's -no longer available for someone else (another app) to use until the user charges the device again. +accordingly. Every action (running a job, firing an alarm, using the network, using the CPU, etc.) +has a cost. Once that action has been performed and that bit of battery has been drained, it's no +longer available for someone else (another app) to use until the user charges the device again. The key tenets of TARE are: @@ -13,10 +15,22 @@ The key tenets of TARE are: 1. Reward for good actions --- reward and encourage behavior that provides value to the user 1. Fine bad actions --- fine and discourage behavior that is bad for the user -# Details +In an ideal world, the system could be said to most efficiently allocate resources by maximizing its +profits — by maximizing the aggregate sum of the difference between an action's price (that +the app ends up paying) and the cost to produce by the system. This assumes that more important +actions have a higher price than less important actions. With this assumption, maximizing profits +implies that the system runs the most important work first and proceeds in decreasing order of +importance. Of course, that also means the system will not run anything where an app would pay less +for the action than the system's cost to produce that action. Some of this breaks down when we throw +TOP apps into the mix — TOP apps pay 0 for all actions, even though the CTP may be greater +than 0. This is to ensure ideal user experience for the app the user is actively interacting with. +Similar caveats exist for system-critical processes (such as the OS itself) and apps running +foreground services (since those could be critical to user experience, as is the case for media and +navigation apps). Excluding those caveats/special situations, maximizing profits of actions +performed by apps in the background should be the target. -To achieve the goal laid out by TARE, we introduce the concept of Android Resource Credits -(ARCs for short). +To achieve the goal laid out by TARE, we use Android Resource Credits (ARCs for short) as the +internal/representative currency of the system. ## How do ARCs work? @@ -36,6 +50,57 @@ all of its ARCs for jobs if it doesn't want to schedule any alarms. With the ARC system, we can limit the total number of ARCs in circulation, thus limiting how much total work can be done, regardless of how many apps the user has installed. +## EconomicPolicy + +An EconomicPolicy defines the actions and rewards a specific subsystem makes use of. Each subsystem +will likely have a unique set of actions that apps can perform, and may choose to reward apps for +certain behaviors. Generally, the app should be rewarded with ARCs for behaviors that indicate that +the app provided value to the user. The current set of behaviors that apps may be rewarded for +include 1) a user seeing a notification, 2) a user interacting with a notification, 3) the user +opening the app and/or staying in the app for some period of time, 4) the user interacting with a +widget, and 5) the user explicitly interacting with the app in some other way. These behaviors may +change as we determine better ways of identifying providing value to the user and/or user desire for +the app to perform the actions it's requesting. + +### Consumption Limit + +The consumption limit represents the maximum amount of resources available to be consumed. When the +battery is satiated (at 100%), then the amount of resources available to be consumed is equal to the +consumption limit. Each action has a cost to produce that action. When the action is performed, +those resources are consumed. Thus, when an action is performed, the action's CTP is deducted from +the remaining amount of resources available. In keeping with the tenet that resources are limited +and ARCs are a proxy for battery consumption, the amount of resources available to be consumed are +adjusted as the battery level changes. That is, the consumption limit is scaled based on the current +battery level, and if the amount currently available to be consumed is greater than the scaled +consumption limit, then the available resources are decreased to match the scaled limit. + +### Regulation + +Regulations are unique events invoked by the ~~government~~ system in order to get the whole economy +moving smoothly. + +# Previous Implementations + +## V0 + +The initial implementation/proposal combined the supply of resources with the allocation in a single +mechanism. It defined the maximum number of resources (ARCs) available at a time, and then divided +(allocated) that number among the installed apps, intending to have some left over that could be +allocated as part of the rewards. There were several problems with that mechanism: + +1. Not all apps used their credits, which meant that allocating credits to those packages + effectively permanently reduced the number of usable/re-allocatable ARCs. +1. Having a global maximum circulation spread across multiple apps meant that as more apps were + installed, the allocation to each app decreased. Eventually (with enough apps installed), no app + would be given enough credits to perform any actions. + +These problems effectively meant that misallocation was a big problem, demand wasn't well reflected, +and some apps may not have been able to perform work even though they otherwise should have been. + +Tare Improvement Proposal #1 (TIP1) separated allocation (to apps) from supply (by the system) and +allowed apps to accrue credits as appropriate while still limiting the total number of credits +consumed. + # Definitions * ARC: Android Resource Credits are the "currency" units used as an abstraction layer over the real diff --git a/cmds/locksettings/src/com/android/commands/locksettings/LockSettingsCmd.java b/cmds/locksettings/src/com/android/commands/locksettings/LockSettingsCmd.java index 6a4a4beaa763..7d9260a77158 100644 --- a/cmds/locksettings/src/com/android/commands/locksettings/LockSettingsCmd.java +++ b/cmds/locksettings/src/com/android/commands/locksettings/LockSettingsCmd.java @@ -28,43 +28,13 @@ import java.io.PrintStream; public final class LockSettingsCmd extends BaseCommand { - private static final String USAGE = - "usage: locksettings set-pattern [--old OLD_CREDENTIAL] NEW_PATTERN\n" + - " locksettings set-pin [--old OLD_CREDENTIAL] NEW_PIN\n" + - " locksettings set-password [--old OLD_CREDENTIAL] NEW_PASSWORD\n" + - " locksettings clear [--old OLD_CREDENTIAL]\n" + - " locksettings verify [--old OLD_CREDENTIAL]\n" + - " locksettings set-disabled DISABLED\n" + - " locksettings get-disabled\n" + - "\n" + - "flags: \n" + - " --user USER_ID: specify the user, default value is current user\n" + - "\n" + - "locksettings set-pattern: sets a pattern\n" + - " A pattern is specified by a non-separated list of numbers that index the cell\n" + - " on the pattern in a 1-based manner in left to right and top to bottom order,\n" + - " i.e. the top-left cell is indexed with 1, whereas the bottom-right cell\n" + - " is indexed with 9. Example: 1234\n" + - "\n" + - "locksettings set-pin: sets a PIN\n" + - "\n" + - "locksettings set-password: sets a password\n" + - "\n" + - "locksettings clear: clears the unlock credential\n" + - "\n" + - "locksettings verify: verifies the credential and unlocks the user\n" + - "\n" + - "locksettings set-disabled: sets whether the lock screen should be disabled\n" + - "\n" + - "locksettings get-disabled: retrieves whether the lock screen is disabled\n"; - public static void main(String[] args) { (new LockSettingsCmd()).run(args); } @Override public void onShowUsage(PrintStream out) { - out.println(USAGE); + main(new String[] { "help" }); } @Override diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 3b843a9c622a..852dd974ae42 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -536,6 +536,9 @@ public final class ActivityThread extends ClientTransactionHandler // A reusable token for other purposes, e.g. content capture, translation. It shouldn't be // used without security checks public IBinder shareableActivityToken; + // The token of the initial TaskFragment that embedded this activity. Do not rely on it + // after creation because the activity could be reparented. + @Nullable public IBinder mInitialTaskFragmentToken; int ident; @UnsupportedAppUsage Intent intent; @@ -618,7 +621,8 @@ public final class ActivityThread extends ClientTransactionHandler PersistableBundle persistentState, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, ActivityOptions activityOptions, boolean isForward, ProfilerInfo profilerInfo, ClientTransactionHandler client, - IBinder assistToken, IBinder shareableActivityToken, boolean launchedFromBubble) { + IBinder assistToken, IBinder shareableActivityToken, boolean launchedFromBubble, + IBinder initialTaskFragmentToken) { this.token = token; this.assistToken = assistToken; this.shareableActivityToken = shareableActivityToken; @@ -639,6 +643,7 @@ public final class ActivityThread extends ClientTransactionHandler compatInfo); mActivityOptions = activityOptions; mLaunchedFromBubble = launchedFromBubble; + mInitialTaskFragmentToken = initialTaskFragmentToken; init(); } diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index e9df50f1d987..961135f47143 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -1207,11 +1207,6 @@ public class Instrumentation { */ public void sendTrackballEventSync(MotionEvent event) { validateNotAppThread(); - if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { - throw new IllegalArgumentException( - "Cannot inject pointer events from sendTrackballEventSync()." - + " Use sendPointerSync() to inject pointer events."); - } if (!event.isFromSource(InputDevice.SOURCE_CLASS_TRACKBALL)) { event.setSource(InputDevice.SOURCE_TRACKBALL); } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 88ffdecfb537..d375a9e1ba26 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -1682,7 +1682,7 @@ public class DevicePolicyManager { public @interface ProvisioningConfiguration {} /** - * A String extra holding the provisioning trigger. It could be one of + * An int extra holding the provisioning trigger. It could be one of * {@link #PROVISIONING_TRIGGER_CLOUD_ENROLLMENT}, {@link #PROVISIONING_TRIGGER_QR_CODE}, * {@link #PROVISIONING_TRIGGER_MANAGED_ACCOUNT} or {@link * #PROVISIONING_TRIGGER_UNSPECIFIED}. @@ -3298,9 +3298,9 @@ public class DevicePolicyManager { * Activity action: Starts the device policy management role holder updater. * * <p>The activity must handle the device policy management role holder update and set the - * intent result to either {@link Activity#RESULT_OK} if the update was successful, {@link - * #RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR} if it encounters a - * problem that may be solved by relaunching it again, {@link + * intent result to either {@link Activity#RESULT_OK} if the update was successful or not + * necessary, {@link #RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_RECOVERABLE_ERROR} if + * it encounters a problem that may be solved by relaunching it again, {@link * #RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_PROVISIONING_DISABLED} if role holder * provisioning is disabled, or {@link * #RESULT_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER_UNRECOVERABLE_ERROR} if it encounters diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java index d7e09519bfb7..076dbef9ebc4 100644 --- a/core/java/android/app/servertransaction/LaunchActivityItem.java +++ b/core/java/android/app/servertransaction/LaunchActivityItem.java @@ -72,6 +72,7 @@ public class LaunchActivityItem extends ClientTransactionItem { private IBinder mAssistToken; private IBinder mShareableActivityToken; private boolean mLaunchedFromBubble; + private IBinder mTaskFragmentToken; /** * It is only non-null if the process is the first time to launch activity. It is only an * optimization for quick look up of the interface so the field is ignored for comparison. @@ -95,7 +96,8 @@ public class LaunchActivityItem extends ClientTransactionItem { ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState, mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo, - client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble); + client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble, + mTaskFragmentToken); client.handleLaunchActivity(r, pendingActions, null /* customIntent */); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); } @@ -119,7 +121,7 @@ public class LaunchActivityItem extends ClientTransactionItem { List<ReferrerIntent> pendingNewIntents, ActivityOptions activityOptions, boolean isForward, ProfilerInfo profilerInfo, IBinder assistToken, IActivityClientController activityClientController, IBinder shareableActivityToken, - boolean launchedFromBubble) { + boolean launchedFromBubble, IBinder taskFragmentToken) { LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class); if (instance == null) { instance = new LaunchActivityItem(); @@ -128,7 +130,7 @@ public class LaunchActivityItem extends ClientTransactionItem { voiceInteractor, procState, state, persistentState, pendingResults, pendingNewIntents, activityOptions, isForward, profilerInfo, assistToken, activityClientController, shareableActivityToken, - launchedFromBubble); + launchedFromBubble, taskFragmentToken); return instance; } @@ -136,7 +138,7 @@ public class LaunchActivityItem extends ClientTransactionItem { @Override public void recycle() { setValues(this, null, 0, null, null, null, null, null, null, 0, null, null, null, null, - null, false, null, null, null, null, false); + null, false, null, null, null, null, false, null); ObjectPool.recycle(this); } @@ -166,6 +168,7 @@ public class LaunchActivityItem extends ClientTransactionItem { dest.writeStrongInterface(mActivityClientController); dest.writeStrongBinder(mShareableActivityToken); dest.writeBoolean(mLaunchedFromBubble); + dest.writeStrongBinder(mTaskFragmentToken); } /** Read from Parcel. */ @@ -184,7 +187,8 @@ public class LaunchActivityItem extends ClientTransactionItem { in.readStrongBinder(), IActivityClientController.Stub.asInterface(in.readStrongBinder()), in.readStrongBinder(), - in.readBoolean()); + in.readBoolean(), + in.readStrongBinder()); } public static final @NonNull Creator<LaunchActivityItem> CREATOR = @@ -222,7 +226,8 @@ public class LaunchActivityItem extends ClientTransactionItem { && mIsForward == other.mIsForward && Objects.equals(mProfilerInfo, other.mProfilerInfo) && Objects.equals(mAssistToken, other.mAssistToken) - && Objects.equals(mShareableActivityToken, other.mShareableActivityToken); + && Objects.equals(mShareableActivityToken, other.mShareableActivityToken) + && Objects.equals(mTaskFragmentToken, other.mTaskFragmentToken); } @Override @@ -244,6 +249,7 @@ public class LaunchActivityItem extends ClientTransactionItem { result = 31 * result + Objects.hashCode(mProfilerInfo); result = 31 * result + Objects.hashCode(mAssistToken); result = 31 * result + Objects.hashCode(mShareableActivityToken); + result = 31 * result + Objects.hashCode(mTaskFragmentToken); return result; } @@ -291,7 +297,7 @@ public class LaunchActivityItem extends ClientTransactionItem { List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, ActivityOptions activityOptions, boolean isForward, ProfilerInfo profilerInfo, IBinder assistToken, IActivityClientController activityClientController, - IBinder shareableActivityToken, boolean launchedFromBubble) { + IBinder shareableActivityToken, boolean launchedFromBubble, IBinder taskFragmentToken) { instance.mIntent = intent; instance.mIdent = ident; instance.mInfo = info; @@ -312,5 +318,6 @@ public class LaunchActivityItem extends ClientTransactionItem { instance.mActivityClientController = activityClientController; instance.mShareableActivityToken = shareableActivityToken; instance.mLaunchedFromBubble = launchedFromBubble; + instance.mTaskFragmentToken = taskFragmentToken; } } diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index 5df64e3cca9e..d94ad3aa1732 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -623,6 +623,11 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> @Override public void writeToParcel(Parcel dest, int flags) { + if (!mPhysicalCameraSettings.containsKey(mLogicalCameraId)) { + throw new IllegalStateException("Physical camera settings map must contain a key for " + + "the logical camera id."); + } + int physicalCameraCount = mPhysicalCameraSettings.size(); dest.writeInt(physicalCameraCount); //Logical camera id and settings always come first. diff --git a/core/java/android/hardware/input/InputDeviceSensorManager.java b/core/java/android/hardware/input/InputDeviceSensorManager.java index 89db857b860b..8a40d00327f1 100644 --- a/core/java/android/hardware/input/InputDeviceSensorManager.java +++ b/core/java/android/hardware/input/InputDeviceSensorManager.java @@ -98,7 +98,7 @@ public class InputDeviceSensorManager implements InputManager.InputDeviceListene */ private void updateInputDeviceSensorInfoLocked(int deviceId) { final InputDevice inputDevice = InputDevice.getDevice(deviceId); - if (inputDevice.hasSensor()) { + if (inputDevice != null && inputDevice.hasSensor()) { final InputSensorInfo[] sensorInfos = mInputManager.getSensorList(deviceId); populateSensorsForInputDeviceLocked(deviceId, sensorInfos); diff --git a/core/java/android/inputmethodservice/NavigationBarController.java b/core/java/android/inputmethodservice/NavigationBarController.java index 03d11515c0a8..dc38db2134f4 100644 --- a/core/java/android/inputmethodservice/NavigationBarController.java +++ b/core/java/android/inputmethodservice/NavigationBarController.java @@ -151,6 +151,8 @@ final class NavigationBarController { private boolean mDrawLegacyNavigationBarBackground; + private final Rect mTempRect = new Rect(); + Impl(@NonNull InputMethodService inputMethodService) { mService = inputMethodService; } @@ -257,23 +259,22 @@ final class NavigationBarController { switch (originalInsets.touchableInsets) { case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME: if (inputFrame.getVisibility() == View.VISIBLE) { - touchableRegion = new Region(inputFrame.getLeft(), - inputFrame.getTop(), inputFrame.getRight(), - inputFrame.getBottom()); + inputFrame.getBoundsOnScreen(mTempRect); + touchableRegion = new Region(mTempRect); } break; case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: if (inputFrame.getVisibility() == View.VISIBLE) { - touchableRegion = new Region(inputFrame.getLeft(), - originalInsets.contentTopInsets, inputFrame.getRight(), - inputFrame.getBottom()); + inputFrame.getBoundsOnScreen(mTempRect); + mTempRect.top = originalInsets.contentTopInsets; + touchableRegion = new Region(mTempRect); } break; case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: if (inputFrame.getVisibility() == View.VISIBLE) { - touchableRegion = new Region(inputFrame.getLeft(), - originalInsets.visibleTopInsets, inputFrame.getRight(), - inputFrame.getBottom()); + inputFrame.getBoundsOnScreen(mTempRect); + mTempRect.top = originalInsets.visibleTopInsets; + touchableRegion = new Region(mTempRect); } break; case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: @@ -281,13 +282,13 @@ final class NavigationBarController { touchableRegion.set(originalInsets.touchableRegion); break; } - final Rect navBarRect = new Rect(decor.getLeft(), - decor.getBottom() - systemInsets.bottom, + // Hereafter "mTempRect" means a navigation bar rect. + mTempRect.set(decor.getLeft(), decor.getBottom() - systemInsets.bottom, decor.getRight(), decor.getBottom()); if (touchableRegion == null) { - touchableRegion = new Region(navBarRect); + touchableRegion = new Region(mTempRect); } else { - touchableRegion.union(navBarRect); + touchableRegion.union(mTempRect); } dest.touchableRegion.set(touchableRegion); diff --git a/core/java/android/net/Ikev2VpnProfile.java b/core/java/android/net/Ikev2VpnProfile.java index 3abe83bd3373..1b503b11816f 100644 --- a/core/java/android/net/Ikev2VpnProfile.java +++ b/core/java/android/net/Ikev2VpnProfile.java @@ -25,12 +25,6 @@ import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA384; import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA512; import static android.net.IpSecAlgorithm.CRYPT_AES_CBC; import static android.net.IpSecAlgorithm.CRYPT_AES_CTR; -import static android.net.eap.EapSessionConfig.EapMsChapV2Config; -import static android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig; -import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignLocalConfig; -import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig; -import static android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig; -import static android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig; import static com.android.internal.annotations.VisibleForTesting.Visibility; import static com.android.internal.util.Preconditions.checkStringNotEmpty; @@ -40,6 +34,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresFeature; import android.content.pm.PackageManager; +import android.net.ipsec.ike.IkeDerAsn1DnIdentification; import android.net.ipsec.ike.IkeFqdnIdentification; import android.net.ipsec.ike.IkeIdentification; import android.net.ipsec.ike.IkeIpv4AddrIdentification; @@ -119,8 +114,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { DEFAULT_ALGORITHMS = Collections.unmodifiableList(algorithms); } - @NonNull private final String mServerAddr; - @NonNull private final String mUserIdentity; + @Nullable private final String mServerAddr; + @Nullable private final String mUserIdentity; // PSK authentication @Nullable private final byte[] mPresharedKey; @@ -146,8 +141,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { private Ikev2VpnProfile( int type, - @NonNull String serverAddr, - @NonNull String userIdentity, + @Nullable String serverAddr, + @Nullable String userIdentity, @Nullable byte[] presharedKey, @Nullable X509Certificate serverRootCaCert, @Nullable String username, @@ -165,8 +160,6 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { @Nullable IkeTunnelConnectionParams ikeTunConnParams) { super(type, excludeLocalRoutes, requiresInternetValidation); - checkNotNull(serverAddr, MISSING_PARAM_MSG_TMPL, "Server address"); - checkNotNull(userIdentity, MISSING_PARAM_MSG_TMPL, "User Identity"); checkNotNull(allowedAlgorithms, MISSING_PARAM_MSG_TMPL, "Allowed Algorithms"); mServerAddr = serverAddr; @@ -191,18 +184,12 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { mIsMetered = isMetered; mMaxMtu = maxMtu; mIsRestrictedToTestNetworks = restrictToTestNetworks; - mIkeTunConnParams = ikeTunConnParams; validate(); } private void validate() { - // Server Address not validated except to check an address was provided. This allows for - // dual-stack servers and hostname based addresses. - checkStringNotEmpty(mServerAddr, MISSING_PARAM_MSG_TMPL, "Server Address"); - checkStringNotEmpty(mUserIdentity, MISSING_PARAM_MSG_TMPL, "User Identity"); - // IPv6 MTU is greater; since profiles may be started by the system on IPv4 and IPv6 // networks, the VPN must provide a link fulfilling the stricter of the two conditions // (at least that of the IPv6 MTU). @@ -210,6 +197,15 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { throw new IllegalArgumentException("Max MTU must be at least" + IPV6_MIN_MTU); } + // Skip validating the other fields if mIkeTunConnParams is set because the required + // information should all come from the mIkeTunConnParams. + if (mIkeTunConnParams != null) return; + + // Server Address not validated except to check an address was provided. This allows for + // dual-stack servers and hostname based addresses. + checkStringNotEmpty(mServerAddr, MISSING_PARAM_MSG_TMPL, "Server Address"); + checkStringNotEmpty(mUserIdentity, MISSING_PARAM_MSG_TMPL, "User Identity"); + switch (mType) { case TYPE_IKEV2_IPSEC_USER_PASS: checkNotNull(mUsername, MISSING_PARAM_MSG_TMPL, "Username"); @@ -286,22 +282,31 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { /** Retrieves the server address string. */ @NonNull public String getServerAddr() { - return mServerAddr; + if (mIkeTunConnParams == null) return mServerAddr; + + final IkeSessionParams ikeSessionParams = mIkeTunConnParams.getIkeSessionParams(); + return ikeSessionParams.getServerHostname(); } /** Retrieves the user identity. */ @NonNull public String getUserIdentity() { - return mUserIdentity; + if (mIkeTunConnParams == null) return mUserIdentity; + + final IkeSessionParams ikeSessionParams = mIkeTunConnParams.getIkeSessionParams(); + return getUserIdentityFromIkeSession(ikeSessionParams); } /** * Retrieves the pre-shared key. * - * <p>May be null if the profile is not using Pre-shared key authentication. + * <p>May be null if the profile is not using Pre-shared key authentication, or the profile is + * built from an {@link IkeTunnelConnectionParams}. */ @Nullable public byte[] getPresharedKey() { + if (mIkeTunConnParams != null) return null; + return mPresharedKey == null ? null : Arrays.copyOf(mPresharedKey, mPresharedKey.length); } @@ -309,46 +314,62 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { * Retrieves the certificate for the server's root CA. * * <p>May be null if the profile is not using RSA Digital Signature Authentication or - * Username/Password authentication + * Username/Password authentication, or the profile is built from an + * {@link IkeTunnelConnectionParams}. */ @Nullable public X509Certificate getServerRootCaCert() { + if (mIkeTunConnParams != null) return null; + return mServerRootCaCert; } - /** * Retrieves the username. * - * <p>May be null if the profile is not using Username/Password authentication + * <p>May be null if the profile is not using Username/Password authentication, or the profile + * is built from an {@link IkeTunnelConnectionParams}. */ @Nullable public String getUsername() { + if (mIkeTunConnParams != null) return null; + return mUsername; } /** * Retrieves the password. * - * <p>May be null if the profile is not using Username/Password authentication + * <p>May be null if the profile is not using Username/Password authentication, or the profile + * is built from an {@link IkeTunnelConnectionParams}. */ @Nullable public String getPassword() { + if (mIkeTunConnParams != null) return null; + return mPassword; } /** * Retrieves the RSA private key. * - * <p>May be null if the profile is not using RSA Digital Signature authentication + * <p>May be null if the profile is not using RSA Digital Signature authentication, or the + * profile is built from an {@link IkeTunnelConnectionParams}. */ @Nullable public PrivateKey getRsaPrivateKey() { + if (mIkeTunConnParams != null) return null; + return mRsaPrivateKey; } - /** Retrieves the user certificate, if any was set. */ + /** Retrieves the user certificate, if any was set. + * + * <p>May be null if the profile is built from an {@link IkeTunnelConnectionParams}. + */ @Nullable public X509Certificate getUserCert() { + if (mIkeTunConnParams != null) return null; + return mUserCert; } @@ -358,9 +379,14 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { return mProxyInfo; } - /** Returns all the algorithms allowed by this VPN profile. */ + /** Returns all the algorithms allowed by this VPN profile. + * + * <p>May be an empty list if the profile is built from an {@link IkeTunnelConnectionParams}. + */ @NonNull public List<String> getAllowedAlgorithms() { + if (mIkeTunConnParams != null) return new ArrayList<>(); + return mAllowedAlgorithms; } @@ -455,18 +481,25 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { @NonNull public VpnProfile toVpnProfile() throws IOException, GeneralSecurityException { final VpnProfile profile = new VpnProfile("" /* Key; value unused by IKEv2VpnProfile(s) */, - mIsRestrictedToTestNetworks, mExcludeLocalRoutes, mRequiresInternetValidation); - profile.type = mType; - profile.server = mServerAddr; - profile.ipsecIdentifier = mUserIdentity; + mIsRestrictedToTestNetworks, mExcludeLocalRoutes, mRequiresInternetValidation, + mIkeTunConnParams); + + profile.server = getServerAddr(); + profile.ipsecIdentifier = getUserIdentity(); profile.proxy = mProxyInfo; - profile.setAllowedAlgorithms(mAllowedAlgorithms); profile.isBypassable = mIsBypassable; profile.isMetered = mIsMetered; profile.maxMtu = mMaxMtu; profile.areAuthParamsInline = true; profile.saveLogin = true; + // The other fields should come from mIkeTunConnParams if it's available. + if (mIkeTunConnParams != null) { + profile.type = VpnProfile.TYPE_IKEV2_FROM_IKE_TUN_CONN_PARAMS; + return profile; + } + profile.type = mType; + profile.setAllowedAlgorithms(mAllowedAlgorithms); switch (mType) { case TYPE_IKEV2_IPSEC_USER_PASS: profile.username = mUsername; @@ -516,10 +549,47 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { @NonNull public static Ikev2VpnProfile fromVpnProfile(@NonNull VpnProfile profile) throws GeneralSecurityException { - // TODO: Build the VpnProfile from mIkeTunConnParams if it exists. - final Builder builder = new Builder(profile.server, profile.ipsecIdentifier); + final Builder builder; + if (profile.ikeTunConnParams == null) { + builder = new Builder(profile.server, profile.ipsecIdentifier); + builder.setAllowedAlgorithms(profile.getAllowedAlgorithms()); + + switch (profile.type) { + case TYPE_IKEV2_IPSEC_USER_PASS: + builder.setAuthUsernamePassword( + profile.username, + profile.password, + certificateFromPemString(profile.ipsecCaCert)); + break; + case TYPE_IKEV2_IPSEC_PSK: + builder.setAuthPsk(decodeFromIpsecSecret(profile.ipsecSecret)); + break; + case TYPE_IKEV2_IPSEC_RSA: + final PrivateKey key; + if (profile.ipsecSecret.startsWith(PREFIX_KEYSTORE_ALIAS)) { + final String alias = + profile.ipsecSecret.substring(PREFIX_KEYSTORE_ALIAS.length()); + key = getPrivateKeyFromAndroidKeystore(alias); + } else if (profile.ipsecSecret.startsWith(PREFIX_INLINE)) { + key = getPrivateKey(profile.ipsecSecret.substring(PREFIX_INLINE.length())); + } else { + throw new IllegalArgumentException("Invalid RSA private key prefix"); + } + + final X509Certificate userCert = + certificateFromPemString(profile.ipsecUserCert); + final X509Certificate serverRootCa = + certificateFromPemString(profile.ipsecCaCert); + builder.setAuthDigitalSignature(userCert, key, serverRootCa); + break; + default: + throw new IllegalArgumentException("Invalid auth method set"); + } + } else { + builder = new Builder(profile.ikeTunConnParams); + } + builder.setProxy(profile.proxy); - builder.setAllowedAlgorithms(profile.getAllowedAlgorithms()); builder.setBypassable(profile.isBypassable); builder.setMetered(profile.isMetered); builder.setMaxMtu(profile.maxMtu); @@ -527,36 +597,6 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { builder.restrictToTestNetworks(); } - switch (profile.type) { - case TYPE_IKEV2_IPSEC_USER_PASS: - builder.setAuthUsernamePassword( - profile.username, - profile.password, - certificateFromPemString(profile.ipsecCaCert)); - break; - case TYPE_IKEV2_IPSEC_PSK: - builder.setAuthPsk(decodeFromIpsecSecret(profile.ipsecSecret)); - break; - case TYPE_IKEV2_IPSEC_RSA: - final PrivateKey key; - if (profile.ipsecSecret.startsWith(PREFIX_KEYSTORE_ALIAS)) { - final String alias = - profile.ipsecSecret.substring(PREFIX_KEYSTORE_ALIAS.length()); - key = getPrivateKeyFromAndroidKeystore(alias); - } else if (profile.ipsecSecret.startsWith(PREFIX_INLINE)) { - key = getPrivateKey(profile.ipsecSecret.substring(PREFIX_INLINE.length())); - } else { - throw new IllegalArgumentException("Invalid RSA private key prefix"); - } - - final X509Certificate userCert = certificateFromPemString(profile.ipsecUserCert); - final X509Certificate serverRootCa = certificateFromPemString(profile.ipsecCaCert); - builder.setAuthDigitalSignature(userCert, key, serverRootCa); - break; - default: - throw new IllegalArgumentException("Invalid auth method set"); - } - if (profile.excludeLocalRoutes && !profile.isBypassable) { Log.w(TAG, "ExcludeLocalRoutes should only be set in the bypassable VPN"); } @@ -678,82 +718,13 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { } private static void checkBuilderSetter(boolean constructedFromIkeTunConParams, - @NonNull String message) { + @NonNull String field) { if (constructedFromIkeTunConParams) { - throw new IllegalArgumentException("Constructed using IkeTunnelConnectionParams " - + "should not set " + message); - } - } - - private static int getTypeFromIkeSession(@NonNull IkeSessionParams params) { - final IkeAuthConfig config = params.getLocalAuthConfig(); - if (config instanceof IkeAuthDigitalSignLocalConfig) { - return TYPE_IKEV2_IPSEC_RSA; - } else if (config instanceof IkeAuthEapConfig) { - return TYPE_IKEV2_IPSEC_USER_PASS; - } else if (config instanceof IkeAuthPskConfig) { - return TYPE_IKEV2_IPSEC_PSK; - } else { - throw new IllegalStateException("Invalid local IkeAuthConfig"); + throw new IllegalArgumentException( + field + " can't be set with IkeTunnelConnectionParams builder"); } } - @Nullable - private static String getPasswordFromIkeSession(@NonNull IkeSessionParams params) { - if (!(params.getLocalAuthConfig() instanceof IkeAuthEapConfig)) return null; - - final IkeAuthEapConfig ikeAuthEapConfig = (IkeAuthEapConfig) params.getLocalAuthConfig(); - final EapMsChapV2Config eapMsChapV2Config = - ikeAuthEapConfig.getEapConfig().getEapMsChapV2Config(); - return (eapMsChapV2Config != null) ? eapMsChapV2Config.getPassword() : null; - } - - @Nullable - private static String getUsernameFromIkeSession(@NonNull IkeSessionParams params) { - if (!(params.getLocalAuthConfig() instanceof IkeAuthEapConfig)) return null; - - final IkeAuthEapConfig ikeAuthEapConfig = (IkeAuthEapConfig) params.getLocalAuthConfig(); - final EapMsChapV2Config eapMsChapV2Config = - ikeAuthEapConfig.getEapConfig().getEapMsChapV2Config(); - return (eapMsChapV2Config != null) ? eapMsChapV2Config.getUsername() : null; - } - - @Nullable - private static X509Certificate getUserCertFromIkeSession(@NonNull IkeSessionParams params) { - if (!(params.getLocalAuthConfig() instanceof IkeAuthDigitalSignLocalConfig)) return null; - - final IkeAuthDigitalSignLocalConfig config = - (IkeAuthDigitalSignLocalConfig) params.getLocalAuthConfig(); - return config.getClientEndCertificate(); - } - - @Nullable - private static X509Certificate getServerRootCaCertFromIkeSession( - @NonNull IkeSessionParams params) { - if (!(params.getRemoteAuthConfig() instanceof IkeAuthDigitalSignRemoteConfig)) return null; - - final IkeAuthDigitalSignRemoteConfig config = - (IkeAuthDigitalSignRemoteConfig) params.getRemoteAuthConfig(); - return config.getRemoteCaCert(); - } - - @Nullable - private static PrivateKey getRsaPrivateKeyFromIkeSession(@NonNull IkeSessionParams params) { - if (!(params.getLocalAuthConfig() instanceof IkeAuthDigitalSignLocalConfig)) return null; - - final IkeAuthDigitalSignLocalConfig config = - (IkeAuthDigitalSignLocalConfig) params.getLocalAuthConfig(); - return config.getPrivateKey(); - } - - @Nullable - private static byte[] getPresharedKeyFromIkeSession(@NonNull IkeSessionParams params) { - if (!(params.getLocalAuthConfig() instanceof IkeAuthPskConfig)) return null; - - final IkeAuthPskConfig config = (IkeAuthPskConfig) params.getLocalAuthConfig(); - return config.getPsk(); - } - @NonNull private static String getUserIdentityFromIkeSession(@NonNull IkeSessionParams params) { final IkeIdentification ident = params.getLocalIdentification(); @@ -768,6 +739,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { return ((IkeIpv4AddrIdentification) ident).ipv4Address.getHostAddress(); } else if (ident instanceof IkeIpv6AddrIdentification) { return ((IkeIpv6AddrIdentification) ident).ipv6Address.getHostAddress(); + } else if (ident instanceof IkeDerAsn1DnIdentification) { + throw new IllegalArgumentException("Unspported ASN.1 encoded identities"); } else { throw new IllegalArgumentException("Unknown IkeIdentification to get user identity"); } @@ -776,8 +749,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { /** A incremental builder for IKEv2 VPN profiles */ public static final class Builder { private int mType = -1; - @NonNull private final String mServerAddr; - @NonNull private final String mUserIdentity; + @Nullable private final String mServerAddr; + @Nullable private final String mUserIdentity; // PSK authentication @Nullable private byte[] mPresharedKey; @@ -831,19 +804,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { checkNotNull(ikeTunConnParams, MISSING_PARAM_MSG_TMPL, "ikeTunConnParams"); mIkeTunConnParams = ikeTunConnParams; - - final IkeSessionParams ikeSessionParams = mIkeTunConnParams.getIkeSessionParams(); - mServerAddr = ikeSessionParams.getServerHostname(); - - mType = getTypeFromIkeSession(ikeSessionParams); - mUserCert = getUserCertFromIkeSession(ikeSessionParams); - mServerRootCaCert = getServerRootCaCertFromIkeSession(ikeSessionParams); - mRsaPrivateKey = getRsaPrivateKeyFromIkeSession(ikeSessionParams); - mServerRootCaCert = getServerRootCaCertFromIkeSession(ikeSessionParams); - mUsername = getUsernameFromIkeSession(ikeSessionParams); - mPassword = getPasswordFromIkeSession(ikeSessionParams); - mPresharedKey = getPresharedKeyFromIkeSession(ikeSessionParams); - mUserIdentity = getUserIdentityFromIkeSession(ikeSessionParams); + mServerAddr = null; + mUserIdentity = null; } private void resetAuthParams() { @@ -862,6 +824,10 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { * authentication method may be set. This method will overwrite any previously set * authentication method. * + * <p>It's not allowed to set this if this {@link Builder} is constructed from an + * {@link IkeTunnelConnectionParams}. This information should be retrieved from + * {@link IkeTunnelConnectionParams} + * * @param user the username to be used for EAP-MSCHAPv2 authentication * @param pass the password to be used for EAP-MSCHAPv2 authentication * @param serverRootCa the root certificate to be used for verifying the identity of the @@ -898,6 +864,10 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { * Only one authentication method may be set. This method will overwrite any previously set * authentication method. * + * <p>It's not allowed to set this if this {@link Builder} is constructed from an + * {@link IkeTunnelConnectionParams}. This information should be retrieved from + * {@link IkeTunnelConnectionParams} + * * @param userCert the username to be used for RSA Digital signiture authentication * @param key the PrivateKey instance associated with the user ceritificate, used for * constructing the signature @@ -936,6 +906,10 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { * authentication method may be set. This method will overwrite any previously set * authentication method. * + * <p>It's not allowed to set this if this {@link Builder} is constructed from an + * {@link IkeTunnelConnectionParams}. This information should be retrieved from + * {@link IkeTunnelConnectionParams} + * * @param psk the key to be used for Pre-Shared Key authentication * @return this {@link Builder} object to facilitate chaining of method calls */ @@ -1068,6 +1042,10 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { * Authentication, and one that provides Encryption. Authenticated Encryption with * Associated Data (AEAD) algorithms provide both Authentication and Encryption. * + * <p>It's not allowed to set this if this {@link Builder} is constructed from an + * {@link IkeTunnelConnectionParams}. This information should be retrieved from + * {@link IkeTunnelConnectionParams} + * * <p>By default, this profile will use any algorithm defined in {@link IpSecAlgorithm}, * with the exception of those considered insecure (as described above). * @@ -1079,6 +1057,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS) public Builder setAllowedAlgorithms(@NonNull List<String> algorithmNames) { checkNotNull(algorithmNames, MISSING_PARAM_MSG_TMPL, "algorithmNames"); + checkBuilderSetter(mIkeTunConnParams != null, "algorithmNames"); validateAllowedAlgorithms(algorithmNames); mAllowedAlgorithms = algorithmNames; diff --git a/core/java/android/net/TEST_MAPPING b/core/java/android/net/TEST_MAPPING index a379c33316f0..3df56162bd2c 100644 --- a/core/java/android/net/TEST_MAPPING +++ b/core/java/android/net/TEST_MAPPING @@ -17,7 +17,7 @@ "path": "frameworks/opt/net/wifi" } ], - "postsubmit": [ + "presubmit": [ { "name": "FrameworksCoreTests", "options": [ diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java index fe6ae78ccf2d..3be4c3edc10e 100644 --- a/core/java/android/util/FeatureFlagUtils.java +++ b/core/java/android/util/FeatureFlagUtils.java @@ -98,7 +98,7 @@ public class FeatureFlagUtils { DEFAULT_FLAGS.put("settings_search_always_expand", "true"); DEFAULT_FLAGS.put(SETTINGS_APP_LANGUAGE_SELECTION, "true"); DEFAULT_FLAGS.put(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS, "true"); - DEFAULT_FLAGS.put(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME, "false"); + DEFAULT_FLAGS.put(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME, "true"); DEFAULT_FLAGS.put(SETTINGS_HIDE_SECOND_LAYER_PAGE_NAVIGATE_UP_BUTTON_IN_TWO_PANE, "true"); } diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java index 01a037ae3495..4e7b3a51d758 100644 --- a/core/java/android/util/NtpTrustedTime.java +++ b/core/java/android/util/NtpTrustedTime.java @@ -193,6 +193,16 @@ public class NtpTrustedTime implements TrustedTime { } final Network network = connectivityManager.getActiveNetwork(); final NetworkInfo ni = connectivityManager.getNetworkInfo(network); + + // This connectivity check is to avoid performing a DNS lookup for the time server on a + // unconnected network. There are races to obtain time in Android when connectivity + // changes, which means that forceRefresh() can be called by various components before + // the network is actually available. This led in the past to DNS lookup failures being + // cached (~2 seconds) thereby preventing the device successfully making an NTP request + // when connectivity had actually been established. + // A side effect of check is that tests that run a fake NTP server on the device itself + // will only be able to use it if the active network is connected, even though loopback + // addresses are actually reachable. if (ni == null || !ni.isConnected()) { if (LOGD) Log.d(TAG, "forceRefresh: no connectivity"); return false; diff --git a/core/java/android/util/SparseSetArray.java b/core/java/android/util/SparseSetArray.java index f5025f7a9e99..f85280f0264b 100644 --- a/core/java/android/util/SparseSetArray.java +++ b/core/java/android/util/SparseSetArray.java @@ -15,15 +15,34 @@ */ package android.util; +import android.annotation.NonNull; + /** * A sparse array of ArraySets, which is suitable to hold userid->packages association. * * @hide */ public class SparseSetArray<T> { - private final SparseArray<ArraySet<T>> mData = new SparseArray<>(); + private final SparseArray<ArraySet<T>> mData; public SparseSetArray() { + mData = new SparseArray<>(); + } + + /** + * Copy constructor + */ + public SparseSetArray(@NonNull SparseSetArray<T> src) { + final int arraySize = src.size(); + mData = new SparseArray<>(arraySize); + for (int i = 0; i < arraySize; i++) { + final int key = src.keyAt(i); + final ArraySet<T> set = src.get(key); + final int setSize = set.size(); + for (int j = 0; j < setSize; j++) { + add(key, set.valueAt(j)); + } + } } /** diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 5f0098c25e55..0c4d9bf08583 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -1584,10 +1584,10 @@ public final class Display { return false; } final Configuration config = mResources.getConfiguration(); - // TODO(b/179308296) Temporarily - never report max bounds to only Launcher if the feature - // is disabled. + // TODO(b/179308296) Temporarily exclude Launcher from being given max bounds, by checking + // if the caller is the recents component. return config != null && !config.windowConfiguration.getMaxBounds().isEmpty() - && (mDisplayInfo.shouldConstrainMetricsForLauncher || !isRecentsComponent()); + && !isRecentsComponent(); } /** diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index 6917d664327f..9264d2ed42a3 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -306,13 +306,6 @@ public final class DisplayInfo implements Parcelable { public float brightnessDefault; /** - * @hide - * True if Display#getRealSize and getRealMetrics should be constrained for Launcher, false - * otherwise. - */ - public boolean shouldConstrainMetricsForLauncher = false; - - /** * The {@link RoundedCorners} if present, otherwise {@code null}. */ @Nullable @@ -395,7 +388,6 @@ public final class DisplayInfo implements Parcelable { && brightnessMaximum == other.brightnessMaximum && brightnessDefault == other.brightnessDefault && Objects.equals(roundedCorners, other.roundedCorners) - && shouldConstrainMetricsForLauncher == other.shouldConstrainMetricsForLauncher && installOrientation == other.installOrientation; } @@ -447,7 +439,6 @@ public final class DisplayInfo implements Parcelable { brightnessMaximum = other.brightnessMaximum; brightnessDefault = other.brightnessDefault; roundedCorners = other.roundedCorners; - shouldConstrainMetricsForLauncher = other.shouldConstrainMetricsForLauncher; installOrientation = other.installOrientation; } @@ -505,7 +496,6 @@ public final class DisplayInfo implements Parcelable { for (int i = 0; i < numUserDisabledFormats; i++) { userDisabledHdrTypes[i] = source.readInt(); } - shouldConstrainMetricsForLauncher = source.readBoolean(); installOrientation = source.readInt(); } @@ -561,7 +551,6 @@ public final class DisplayInfo implements Parcelable { for (int i = 0; i < userDisabledHdrTypes.length; i++) { dest.writeInt(userDisabledHdrTypes[i]); } - dest.writeBoolean(shouldConstrainMetricsForLauncher); dest.writeInt(installOrientation); } @@ -817,8 +806,6 @@ public final class DisplayInfo implements Parcelable { sb.append(brightnessMaximum); sb.append(", brightnessDefault "); sb.append(brightnessDefault); - sb.append(", shouldConstrainMetricsForLauncher "); - sb.append(shouldConstrainMetricsForLauncher); sb.append(", installOrientation "); sb.append(Surface.rotationToString(installOrientation)); sb.append("}"); diff --git a/core/java/android/view/RemoteAnimationTarget.java b/core/java/android/view/RemoteAnimationTarget.java index 2dac81c66d2a..e98d046e8c6c 100644 --- a/core/java/android/view/RemoteAnimationTarget.java +++ b/core/java/android/view/RemoteAnimationTarget.java @@ -33,6 +33,7 @@ import static android.view.RemoteAnimationTargetProto.TASK_ID; import static android.view.RemoteAnimationTargetProto.WINDOW_CONFIGURATION; import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE; +import android.annotation.ColorInt; import android.annotation.IntDef; import android.app.ActivityManager; import android.app.TaskInfo; @@ -221,6 +222,12 @@ public class RemoteAnimationTarget implements Parcelable { */ public boolean hasAnimatingParent; + /** + * The background color of animation in case the task info is not available if the transition + * is activity level. + */ + public @ColorInt int backgroundColor; + public RemoteAnimationTarget(int taskId, int mode, SurfaceControl leash, boolean isTranslucent, Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position, Rect localBounds, Rect screenSpaceBounds, @@ -279,6 +286,7 @@ public class RemoteAnimationTarget implements Parcelable { allowEnterPip = in.readBoolean(); windowType = in.readInt(); hasAnimatingParent = in.readBoolean(); + backgroundColor = in.readInt(); } @Override @@ -307,6 +315,7 @@ public class RemoteAnimationTarget implements Parcelable { dest.writeBoolean(allowEnterPip); dest.writeInt(windowType); dest.writeBoolean(hasAnimatingParent); + dest.writeInt(backgroundColor); } public void dump(PrintWriter pw, String prefix) { @@ -327,6 +336,7 @@ public class RemoteAnimationTarget implements Parcelable { pw.print(prefix); pw.print("allowEnterPip="); pw.println(allowEnterPip); pw.print(prefix); pw.print("windowType="); pw.print(windowType); pw.print(prefix); pw.print("hasAnimatingParent="); pw.print(hasAnimatingParent); + pw.print(prefix); pw.print("backgroundColor="); pw.print(backgroundColor); } public void dumpDebug(ProtoOutputStream proto, long fieldId) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index d7940e2de98c..8b9a86b9eec6 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -12033,7 +12033,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @Nullable public Rect getHandwritingArea() { final ListenerInfo info = mListenerInfo; - if (info != null) { + if (info != null && info.mHandwritingArea != null) { return new Rect(info.mHandwritingArea); } return null; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 7b3fed74a9be..c45a4c7f6e8d 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1742,7 +1742,7 @@ public final class ViewRootImpl implements ViewParent, mForceNextWindowRelayout = forceNextWindowRelayout; mPendingAlwaysConsumeSystemBars = args.argi2 != 0; - mSyncSeqId = args.argi4; + mSyncSeqId = args.argi4 > mSyncSeqId ? args.argi4 : mSyncSeqId; if (msg == MSG_RESIZED_REPORT) { reportNextDraw(); @@ -2767,17 +2767,16 @@ public final class ViewRootImpl implements ViewParent, dispatchApplyInsets(host); } + if (mFirst) { + // make sure touch mode code executes by setting cached value + // to opposite of the added touch mode. + mAttachInfo.mInTouchMode = !mAddedTouchMode; + ensureTouchModeLocally(mAddedTouchMode); + } + boolean layoutRequested = mLayoutRequested && (!mStopped || mReportNextDraw); if (layoutRequested) { - - final Resources res = mView.getContext().getResources(); - - if (mFirst) { - // make sure touch mode code executes by setting cached value - // to opposite of the added touch mode. - mAttachInfo.mInTouchMode = !mAddedTouchMode; - ensureTouchModeLocally(mAddedTouchMode); - } else { + if (!mFirst) { if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) { windowSizeMayChange = true; @@ -2797,7 +2796,7 @@ public final class ViewRootImpl implements ViewParent, } // Ask host how big it wants to be - windowSizeMayChange |= measureHierarchy(host, lp, res, + windowSizeMayChange |= measureHierarchy(host, lp, mView.getContext().getResources(), desiredWindowWidth, desiredWindowHeight); } @@ -6407,6 +6406,24 @@ public final class ViewRootImpl implements ViewParent, return FINISH_HANDLED; } + // If the new back dispatch is enabled, intercept KEYCODE_BACK before it reaches the + // view tree and invoke the appropriate {@link OnBackInvokedCallback}. + if (isBack(event) + && mContext != null + && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) { + OnBackInvokedCallback topCallback = + getOnBackInvokedDispatcher().getTopCallback(); + if (event.getAction() == KeyEvent.ACTION_UP) { + if (topCallback != null) { + topCallback.onBackInvoked(); + return FINISH_HANDLED; + } + } else { + // Drop other actions such as {@link KeyEvent.ACTION_DOWN}. + return FINISH_NOT_HANDLED; + } + } + // Deliver the key to the view hierarchy. if (mView.dispatchKeyEvent(event)) { return FINISH_HANDLED; @@ -6416,19 +6433,6 @@ public final class ViewRootImpl implements ViewParent, return FINISH_NOT_HANDLED; } - if (isBack(event) - && mContext != null - && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) { - // Invoke the appropriate {@link OnBackInvokedCallback} if the new back - // navigation should be used, and the key event is not handled by anything else. - OnBackInvokedCallback topCallback = - getOnBackInvokedDispatcher().getTopCallback(); - if (topCallback != null) { - topCallback.onBackInvoked(); - return FINISH_HANDLED; - } - } - // This dispatch is for windows that don't have a Window.Callback. Otherwise, // the Window.Callback usually will have already called this (see // DecorView.superDispatchKeyEvent) leaving this call a no-op. @@ -7986,7 +7990,10 @@ public final class ViewRootImpl implements ViewParent, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets, mTempControls, mRelayoutBundle); - mSyncSeqId = mRelayoutBundle.getInt("seqid"); + final int maybeSyncSeqId = mRelayoutBundle.getInt("seqid"); + if (maybeSyncSeqId > 0) { + mSyncSeqId = maybeSyncSeqId; + } if (mTranslator != null) { mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame); @@ -10763,11 +10770,7 @@ public final class ViewRootImpl implements ViewParent, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */, KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, InputDevice.SOURCE_KEYBOARD); - - ev.setDisplayId(mContext.getDisplay().getDisplayId()); - if (mView != null) { - mView.dispatchKeyEvent(ev); - } + enqueueInputEvent(ev); } private void registerCompatOnBackInvokedCallback() { diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index 29a9926aeb9f..aae930edb729 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -216,10 +216,14 @@ public final class WindowManagerGlobal { public String[] getViewRootNames() { synchronized (mLock) { final int numRoots = mRoots.size(); - String[] mViewRoots = new String[numRoots]; + final int windowlessRoots = mWindowlessRoots.size(); + String[] mViewRoots = new String[numRoots + windowlessRoots]; for (int i = 0; i < numRoots; ++i) { mViewRoots[i] = getWindowName(mRoots.get(i)); } + for (int i = 0; i < windowlessRoots; ++i) { + mViewRoots[i + numRoots] = getWindowName(mWindowlessRoots.get(i)); + } return mViewRoots; } } @@ -288,6 +292,10 @@ public final class WindowManagerGlobal { final ViewRootImpl root = mRoots.get(i); if (name.equals(getWindowName(root))) return root.getView(); } + for (int i = mWindowlessRoots.size() - 1; i >= 0; --i) { + final ViewRootImpl root = mWindowlessRoots.get(i); + if (name.equals(getWindowName(root))) return root.getView(); + } } return null; diff --git a/core/java/android/window/WindowContextController.java b/core/java/android/window/WindowContextController.java index 5007df574ec1..4b9a957f541d 100644 --- a/core/java/android/window/WindowContextController.java +++ b/core/java/android/window/WindowContextController.java @@ -41,14 +41,13 @@ import java.lang.annotation.Retention; * @hide */ public class WindowContextController { - // TODO(220049234): Disable attach debug logging before shipping. - private static final boolean DEBUG_ATTACH = true; + private static final boolean DEBUG_ATTACH = false; private static final String TAG = "WindowContextController"; /** - * {@link AttachStatus.STATUS_ATTACHED} to indicate that the {@code mToken} is associated with a + * {@link AttachStatus#STATUS_ATTACHED} to indicate that the {@code mToken} is associated with a * {@link com.android.server.wm.DisplayArea}. Note that {@code mToken} is able to attach a - * WindowToken after this flag sets to {@link AttachStatus.STATUS_ATTACHED}. + * WindowToken after this flag sets to {@link AttachStatus#STATUS_ATTACHED}. */ @VisibleForTesting public int mAttachedToDisplayArea = AttachStatus.STATUS_INITIALIZED; diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java index bea2c7885d57..cad8b9b64d0b 100644 --- a/core/java/android/window/WindowOnBackInvokedDispatcher.java +++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java @@ -51,9 +51,10 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { private IWindowSession mWindowSession; private IWindow mWindow; private static final String TAG = "WindowOnBackDispatcher"; - private static final String BACK_PREDICTABILITY_PROP = "persist.debug.back_predictability"; - private static final boolean IS_BACK_PREDICTABILITY_ENABLED = SystemProperties - .getInt(BACK_PREDICTABILITY_PROP, 1) > 0; + private static final boolean ENABLE_PREDICTIVE_BACK = SystemProperties + .getInt("persist.wm.debug.predictive_back", 1) != 0; + private static final boolean ALWAYS_ENFORCE_PREDICTIVE_BACK = SystemProperties + .getInt("persist.wm.debug.predictive_back_always_enforce", 0) != 0; /** Convenience hashmap to quickly decide if a callback has been added. */ private final HashMap<OnBackInvokedCallback, Integer> mAllCallbacks = new HashMap<>(); @@ -254,18 +255,18 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { public static boolean isOnBackInvokedCallbackEnabled(@Nullable Context context) { // new back is enabled if the feature flag is enabled AND the app does not explicitly // request legacy back. - boolean featureFlagEnabled = IS_BACK_PREDICTABILITY_ENABLED; + boolean featureFlagEnabled = ENABLE_PREDICTIVE_BACK; // If the context is null, we assume true and fallback on the two other conditions. boolean appRequestsPredictiveBack = context != null && context.getApplicationInfo().isOnBackInvokedCallbackEnabled(); if (DEBUG) { Log.d(TAG, TextUtils.formatSimple("App: %s featureFlagEnabled=%s " - + "appRequestsPredictiveBack=%s", + + "appRequestsPredictiveBack=%s alwaysEnforce=%s", context != null ? context.getApplicationInfo().packageName : "null context", - featureFlagEnabled, appRequestsPredictiveBack)); + featureFlagEnabled, appRequestsPredictiveBack, ALWAYS_ENFORCE_PREDICTIVE_BACK)); } - return featureFlagEnabled && appRequestsPredictiveBack; + return featureFlagEnabled && (appRequestsPredictiveBack || ALWAYS_ENFORCE_PREDICTIVE_BACK); } } diff --git a/core/java/com/android/internal/app/AppLocaleStore.java b/core/java/com/android/internal/app/AppLocaleStore.java index 76e58988eedf..f95838516927 100644 --- a/core/java/com/android/internal/app/AppLocaleStore.java +++ b/core/java/com/android/internal/app/AppLocaleStore.java @@ -16,6 +16,8 @@ package com.android.internal.app; +import static com.android.internal.app.AppLocaleStore.AppLocaleResult.LocaleStatus; + import android.app.LocaleConfig; import android.content.Context; import android.content.pm.PackageManager; @@ -25,41 +27,43 @@ import android.util.Log; import java.util.ArrayList; import java.util.Locale; -public class AppLocaleStore { +class AppLocaleStore { private static final String TAG = AppLocaleStore.class.getSimpleName(); - public static ArrayList<Locale> getAppSupportedLocales(Context context, String packageName) { + public static AppLocaleResult getAppSupportedLocales( + Context context, String packageName) { + LocaleConfig localeConfig = null; + AppLocaleResult.LocaleStatus localeStatus = LocaleStatus.UNKNOWN_FAILURE; ArrayList<Locale> appSupportedLocales = new ArrayList<>(); - LocaleList packageLocaleList = getPackageLocales(context, packageName); - if (packageLocaleList != null && packageLocaleList.size() > 0) { - for (int i = 0; i < packageLocaleList.size(); i++) { - appSupportedLocales.add(packageLocaleList.get(i)); - } - Log.d(TAG, "getAppSupportedLocales from LocaleConfig. Size: " - + appSupportedLocales.size()); - } else { - String[] languages = getAssetLocales(context, packageName); - for (String language : languages) { - appSupportedLocales.add(Locale.forLanguageTag(language)); - } - Log.d(TAG, "getAppSupportedLocales from asset. Size: " - + appSupportedLocales.size()); + try { + localeConfig = new LocaleConfig(context.createPackageContext(packageName, 0)); + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, "Can not found the package name : " + packageName + " / " + e); } - return appSupportedLocales; - } - private static LocaleList getPackageLocales(Context context, String packageName) { - try { - LocaleConfig localeConfig = - new LocaleConfig(context.createPackageContext(packageName, 0)); + if (localeConfig != null) { if (localeConfig.getStatus() == LocaleConfig.STATUS_SUCCESS) { - return localeConfig.getSupportedLocales(); + LocaleList packageLocaleList = localeConfig.getSupportedLocales(); + if (packageLocaleList.size() > 0) { + localeStatus = LocaleStatus.GET_SUPPORTED_LANGUAGE_FROM_LOCAL_CONFIG; + for (int i = 0; i < packageLocaleList.size(); i++) { + appSupportedLocales.add(packageLocaleList.get(i)); + } + } else { + localeStatus = LocaleStatus.NO_SUPPORTED_LANGUAGE; + } + } else if (localeConfig.getStatus() == LocaleConfig.STATUS_NOT_SPECIFIED) { + localeStatus = LocaleStatus.GET_SUPPORTED_LANGUAGE_FROM_ASSET; + String[] languages = getAssetLocales(context, packageName); + for (String language : languages) { + appSupportedLocales.add(Locale.forLanguageTag(language)); + } } - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, "Can not found the package name : " + packageName + " / " + e); } - return null; + Log.d(TAG, "getAppSupportedLocales(). status: " + localeStatus + + ", appSupportedLocales:" + appSupportedLocales.size()); + return new AppLocaleResult(localeStatus, appSupportedLocales); } private static String[] getAssetLocales(Context context, String packageName) { @@ -82,4 +86,20 @@ public class AppLocaleStore { return new String[0]; } + static class AppLocaleResult { + enum LocaleStatus { + UNKNOWN_FAILURE, + NO_SUPPORTED_LANGUAGE, + GET_SUPPORTED_LANGUAGE_FROM_LOCAL_CONFIG, + GET_SUPPORTED_LANGUAGE_FROM_ASSET, + } + + LocaleStatus mLocaleStatus; + ArrayList<Locale> mAppSupportedLocales; + + public AppLocaleResult(LocaleStatus localeStatus, ArrayList<Locale> appSupportedLocales) { + this.mLocaleStatus = localeStatus; + this.mAppSupportedLocales = appSupportedLocales; + } + } } diff --git a/core/java/com/android/internal/app/LocalePickerWithRegion.java b/core/java/com/android/internal/app/LocalePickerWithRegion.java index 52c74cf81508..213af26a436f 100644 --- a/core/java/com/android/internal/app/LocalePickerWithRegion.java +++ b/core/java/com/android/internal/app/LocalePickerWithRegion.java @@ -16,6 +16,8 @@ package com.android.internal.app; +import static com.android.internal.app.AppLocaleStore.AppLocaleResult.LocaleStatus; + import android.app.FragmentManager; import android.app.FragmentTransaction; import android.app.ListFragment; @@ -158,30 +160,39 @@ public class LocalePickerWithRegion extends ListFragment implements SearchView.O if (appCurrentLocale != null && !isForCountryMode) { mLocaleList.add(appCurrentLocale); } - filterTheLanguagesNotSupportedInApp(context, appPackageName); - if (!isForCountryMode) { - mLocaleList.add(LocaleStore.getSystemDefaultLocaleInfo()); + AppLocaleStore.AppLocaleResult result = + AppLocaleStore.getAppSupportedLocales(context, appPackageName); + boolean shouldShowList = + result.mLocaleStatus == LocaleStatus.GET_SUPPORTED_LANGUAGE_FROM_LOCAL_CONFIG + || result.mLocaleStatus == LocaleStatus.GET_SUPPORTED_LANGUAGE_FROM_ASSET; + + mLocaleList = filterTheLanguagesNotSupportedInApp( + shouldShowList, result.mAppSupportedLocales); + + // Add "system language" + if (!isForCountryMode && shouldShowList) { + mLocaleList.add(LocaleStore.getSystemDefaultLocaleInfo(appCurrentLocale == null)); } } return true; } - private void filterTheLanguagesNotSupportedInApp(Context context, String appPackageName) { - ArrayList<Locale> supportedLocales = - AppLocaleStore.getAppSupportedLocales(context, appPackageName); - + private Set<LocaleStore.LocaleInfo> filterTheLanguagesNotSupportedInApp( + boolean shouldShowList, ArrayList<Locale> supportedLocales) { Set<LocaleStore.LocaleInfo> filteredList = new HashSet<>(); - for(LocaleStore.LocaleInfo li: mLocaleList) { - for(Locale l: supportedLocales) { - if(LocaleList.matchesLanguageAndScript(li.getLocale(), l)) { - filteredList.add(li); + if (shouldShowList) { + for(LocaleStore.LocaleInfo li: mLocaleList) { + for(Locale l: supportedLocales) { + if(LocaleList.matchesLanguageAndScript(li.getLocale(), l)) { + filteredList.add(li); + } } } + Log.d(TAG, "mLocaleList after app-supported filter: " + filteredList.size()); } - Log.d(TAG, "mLocaleList after app-supported filter: " + filteredList.size()); - mLocaleList = filteredList; + return filteredList; } private void returnToParentFrame() { diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java index cea8eaa3ee7f..eb11b9b8b138 100644 --- a/core/java/com/android/internal/app/LocaleStore.java +++ b/core/java/com/android/internal/app/LocaleStore.java @@ -281,9 +281,12 @@ public class LocaleStore { * The "system default" is special case for per-app picker. Intentionally keep the locale * empty to let activity know "system default" been selected. */ - public static LocaleInfo getSystemDefaultLocaleInfo() { + public static LocaleInfo getSystemDefaultLocaleInfo(boolean hasAppLanguage) { LocaleInfo systemDefaultInfo = new LocaleInfo(""); systemDefaultInfo.mSuggestionFlags |= LocaleInfo.SUGGESTION_TYPE_SYSTEM_LANGUAGE; + if (hasAppLanguage) { + systemDefaultInfo.mSuggestionFlags |= LocaleInfo.SUGGESTION_TYPE_CURRENT; + } systemDefaultInfo.mIsTranslated = true; return systemDefaultInfo; } diff --git a/core/java/com/android/internal/app/SuggestedLocaleAdapter.java b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java index 2eb104ed215a..68b8968fe399 100644 --- a/core/java/com/android/internal/app/SuggestedLocaleAdapter.java +++ b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java @@ -27,6 +27,7 @@ import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Filter; import android.widget.Filterable; +import android.widget.FrameLayout; import android.widget.TextView; import com.android.internal.R; @@ -54,7 +55,11 @@ public class SuggestedLocaleAdapter extends BaseAdapter implements Filterable { private static final int TYPE_HEADER_ALL_OTHERS = 1; private static final int TYPE_LOCALE = 2; private static final int TYPE_SYSTEM_LANGUAGE_FOR_APP_LANGUAGE_PICKER = 3; + private static final int TYPE_CURRENT_LOCALE = 4; private static final int MIN_REGIONS_FOR_SUGGESTIONS = 6; + private static final int APP_LANGUAGE_PICKER_TYPE_COUNT = 5; + private static final int SYSTEM_LANGUAGE_TYPE_COUNT = 3; + private static final int SYSTEM_LANGUAGE_WITHOUT_HEADER_TYPE_COUNT = 1; private ArrayList<LocaleStore.LocaleInfo> mLocaleOptions; private ArrayList<LocaleStore.LocaleInfo> mOriginalLocaleOptions; @@ -93,7 +98,8 @@ public class SuggestedLocaleAdapter extends BaseAdapter implements Filterable { @Override public boolean isEnabled(int position) { return getItemViewType(position) == TYPE_LOCALE - || getItemViewType(position) == TYPE_SYSTEM_LANGUAGE_FOR_APP_LANGUAGE_PICKER; + || getItemViewType(position) == TYPE_SYSTEM_LANGUAGE_FOR_APP_LANGUAGE_PICKER + || getItemViewType(position) == TYPE_CURRENT_LOCALE; } @Override @@ -112,6 +118,9 @@ public class SuggestedLocaleAdapter extends BaseAdapter implements Filterable { if (item.isSystemLocale()) { return TYPE_SYSTEM_LANGUAGE_FOR_APP_LANGUAGE_PICKER; } + if (item.isAppCurrentLocale()) { + return TYPE_CURRENT_LOCALE; + } return TYPE_LOCALE; } } @@ -119,11 +128,13 @@ public class SuggestedLocaleAdapter extends BaseAdapter implements Filterable { @Override public int getViewTypeCount() { if (!TextUtils.isEmpty(mAppPackageName) && showHeaders()) { - return 4; // Two headers and 1 for "System language" + // Two headers, 1 "System language", 1 current locale + return APP_LANGUAGE_PICKER_TYPE_COUNT; } else if (showHeaders()) { - return 3; // Two headers in addition to the locales + // Two headers in addition to the locales + return SYSTEM_LANGUAGE_TYPE_COUNT; } else { - return 1; // Locales items only + return SYSTEM_LANGUAGE_WITHOUT_HEADER_TYPE_COUNT; // Locales items only } } @@ -204,11 +215,15 @@ public class SuggestedLocaleAdapter extends BaseAdapter implements Filterable { textView.setTextLocale( mDisplayLocale != null ? mDisplayLocale : Locale.getDefault()); break; - case TYPE_SYSTEM_LANGUAGE_FOR_APP_LANGUAGE_PICKER: if (!(convertView instanceof ViewGroup)) { - convertView = mInflater.inflate( - R.layout.app_language_picker_system_default, parent, false); + if (((LocaleStore.LocaleInfo)getItem(position)).isAppCurrentLocale()) { + convertView = mInflater.inflate( + R.layout.app_language_picker_system_current, parent, false); + } else { + convertView = mInflater.inflate( + R.layout.app_language_picker_system_default, parent, false); + } } Locale defaultLocale = Locale.getDefault(); @@ -219,25 +234,20 @@ public class SuggestedLocaleAdapter extends BaseAdapter implements Filterable { subtitle.setText(defaultLocale.getDisplayName()); subtitle.setTextLocale(defaultLocale); break; + case TYPE_CURRENT_LOCALE: + if (!(convertView instanceof ViewGroup)) { + convertView = mInflater.inflate( + R.layout.app_language_picker_current_locale_item, parent, false); + } + updateTextView( + convertView, convertView.findViewById(R.id.language_picker_item), position); + break; default: // Covers both null, and "reusing" a wrong kind of view if (!(convertView instanceof ViewGroup)) { convertView = mInflater.inflate(R.layout.language_picker_item, parent, false); } - - TextView text = (TextView) convertView.findViewById(R.id.locale); - LocaleStore.LocaleInfo item = (LocaleStore.LocaleInfo) getItem(position); - text.setText(item.getLabel(mCountryMode)); - text.setTextLocale(item.getLocale()); - text.setContentDescription(item.getContentDescription(mCountryMode)); - if (mCountryMode) { - int layoutDir = TextUtils.getLayoutDirectionFromLocale(item.getParent()); - //noinspection ResourceType - convertView.setLayoutDirection(layoutDir); - text.setTextDirection(layoutDir == View.LAYOUT_DIRECTION_RTL - ? View.TEXT_DIRECTION_RTL - : View.TEXT_DIRECTION_LTR); - } + updateTextView(convertView, convertView.findViewById(R.id.locale), position); } return convertView; } @@ -348,4 +358,19 @@ public class SuggestedLocaleAdapter extends BaseAdapter implements Filterable { public Filter getFilter() { return new FilterByNativeAndUiNames(); } + + private void updateTextView(View convertView, TextView text, int position) { + LocaleStore.LocaleInfo item = (LocaleStore.LocaleInfo) getItem(position); + text.setText(item.getLabel(mCountryMode)); + text.setTextLocale(item.getLocale()); + text.setContentDescription(item.getContentDescription(mCountryMode)); + if (mCountryMode) { + int layoutDir = TextUtils.getLayoutDirectionFromLocale(item.getParent()); + //noinspection ResourceType + convertView.setLayoutDirection(layoutDir); + text.setTextDirection(layoutDir == View.LAYOUT_DIRECTION_RTL + ? View.TEXT_DIRECTION_RTL + : View.TEXT_DIRECTION_LTR); + } + } } diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java index 576860d6a50f..b334e9172729 100644 --- a/core/java/com/android/internal/net/VpnProfile.java +++ b/core/java/com/android/internal/net/VpnProfile.java @@ -22,12 +22,17 @@ import android.net.Ikev2VpnProfile; import android.net.PlatformVpnProfile; import android.net.ProxyInfo; import android.net.Uri; +import android.net.ipsec.ike.IkeTunnelConnectionParams; +import android.net.vcn.persistablebundleutils.TunnelConnectionParamsUtils; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; +import android.os.PersistableBundle; import android.text.TextUtils; +import android.util.Log; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.HexDump; import com.android.net.module.util.ProxyUtils; import java.io.UnsupportedEncodingException; @@ -69,7 +74,8 @@ public final class VpnProfile implements Cloneable, Parcelable { public static final int TYPE_IKEV2_IPSEC_USER_PASS = 6; public static final int TYPE_IKEV2_IPSEC_PSK = 7; public static final int TYPE_IKEV2_IPSEC_RSA = 8; - public static final int TYPE_MAX = 8; + public static final int TYPE_IKEV2_FROM_IKE_TUN_CONN_PARAMS = 9; + public static final int TYPE_MAX = 9; // Match these constants with R.array.vpn_proxy_settings. public static final int PROXY_NONE = 0; @@ -145,25 +151,27 @@ public final class VpnProfile implements Cloneable, Parcelable { public final boolean excludeLocalRoutes; // 25 public final boolean requiresInternetValidation; // 26 + public final IkeTunnelConnectionParams ikeTunConnParams; // 27 // Helper fields. @UnsupportedAppUsage public transient boolean saveLogin = false; public VpnProfile(String key) { - this(key, false, false, false); + this(key, false, false, false, null); } public VpnProfile(String key, boolean isRestrictedToTestNetworks) { - this(key, isRestrictedToTestNetworks, false, false); + this(key, isRestrictedToTestNetworks, false, false, null); } public VpnProfile(String key, boolean isRestrictedToTestNetworks, boolean excludeLocalRoutes, - boolean requiresInternetValidation) { + boolean requiresInternetValidation, IkeTunnelConnectionParams ikeTunConnParams) { this.key = key; this.isRestrictedToTestNetworks = isRestrictedToTestNetworks; this.excludeLocalRoutes = excludeLocalRoutes; this.requiresInternetValidation = requiresInternetValidation; + this.ikeTunConnParams = ikeTunConnParams; } @UnsupportedAppUsage @@ -195,6 +203,10 @@ public final class VpnProfile implements Cloneable, Parcelable { isRestrictedToTestNetworks = in.readBoolean(); excludeLocalRoutes = in.readBoolean(); requiresInternetValidation = in.readBoolean(); + final PersistableBundle bundle = + in.readParcelable(PersistableBundle.class.getClassLoader()); + ikeTunConnParams = (bundle == null) ? null + : TunnelConnectionParamsUtils.fromPersistableBundle(bundle); } /** @@ -244,6 +256,8 @@ public final class VpnProfile implements Cloneable, Parcelable { out.writeBoolean(isRestrictedToTestNetworks); out.writeBoolean(excludeLocalRoutes); out.writeBoolean(requiresInternetValidation); + out.writeParcelable(ikeTunConnParams == null ? null + : TunnelConnectionParamsUtils.toPersistableBundle(ikeTunConnParams), flags); } /** @@ -259,15 +273,17 @@ public final class VpnProfile implements Cloneable, Parcelable { } String[] values = new String(value, StandardCharsets.UTF_8).split(VALUE_DELIMITER, -1); + // Acceptable numbers of values are: // 14-19: Standard profile, with option for serverCert, proxy // 24: Standard profile with serverCert, proxy and platform-VPN parameters // 25: Standard profile with platform-VPN parameters and isRestrictedToTestNetworks // 26: ...and excludeLocalRoutes - // (26 can only be found on dogfood devices) // 27: ...and requiresInternetValidation + // (26,27 can only be found on dogfood devices) + // 28: ...and ikeTunConnParams if ((values.length < 14 || (values.length > 19 && values.length < 24) - || values.length > 27)) { + || values.length > 28)) { return null; } @@ -292,8 +308,22 @@ public final class VpnProfile implements Cloneable, Parcelable { requiresInternetValidation = false; } + final IkeTunnelConnectionParams tempIkeTunConnParams; + // Assign null directly if the ikeTunConParams field is empty. + if (values.length >= 28 && values[27].length() != 0) { + final Parcel parcel = Parcel.obtain(); + final byte[] bytes = HexDump.hexStringToByteArray(values[27]); + parcel.unmarshall(bytes, 0, bytes.length); + parcel.setDataPosition(0); + final PersistableBundle bundle = (PersistableBundle) parcel.readValue( + PersistableBundle.class.getClassLoader()); + tempIkeTunConnParams = TunnelConnectionParamsUtils.fromPersistableBundle(bundle); + } else { + tempIkeTunConnParams = null; + } + VpnProfile profile = new VpnProfile(key, isRestrictedToTestNetworks, - excludeLocalRoutes, requiresInternetValidation); + excludeLocalRoutes, requiresInternetValidation, tempIkeTunConnParams); profile.name = values[0]; profile.type = Integer.parseInt(values[1]); if (profile.type < 0 || profile.type > TYPE_MAX) { @@ -345,6 +375,7 @@ public final class VpnProfile implements Cloneable, Parcelable { profile.saveLogin = !profile.username.isEmpty() || !profile.password.isEmpty(); return profile; } catch (Exception e) { + Log.d(TAG, "Got exception in decode.", e); // ignore } return null; @@ -406,6 +437,17 @@ public final class VpnProfile implements Cloneable, Parcelable { builder.append(VALUE_DELIMITER).append(excludeLocalRoutes); builder.append(VALUE_DELIMITER).append(requiresInternetValidation); + if (ikeTunConnParams != null) { + final PersistableBundle bundle = + TunnelConnectionParamsUtils.toPersistableBundle(ikeTunConnParams); + final Parcel parcel = Parcel.obtain(); + parcel.writeValue(bundle); + final byte[] bytes = parcel.marshall(); + builder.append(VALUE_DELIMITER).append(HexDump.toHexString(bytes)); + } else { + builder.append(VALUE_DELIMITER).append(""); + } + return builder.toString().getBytes(StandardCharsets.UTF_8); } @@ -486,7 +528,8 @@ public final class VpnProfile implements Cloneable, Parcelable { key, type, server, username, password, dnsServers, searchDomains, routes, mppe, l2tpSecret, ipsecIdentifier, ipsecSecret, ipsecUserCert, ipsecCaCert, ipsecServerCert, proxy, mAllowedAlgorithms, isBypassable, isMetered, maxMtu, areAuthParamsInline, - isRestrictedToTestNetworks, excludeLocalRoutes, requiresInternetValidation); + isRestrictedToTestNetworks, excludeLocalRoutes, requiresInternetValidation, + ikeTunConnParams); } /** Checks VPN profiles for interior equality. */ @@ -521,7 +564,8 @@ public final class VpnProfile implements Cloneable, Parcelable { && areAuthParamsInline == other.areAuthParamsInline && isRestrictedToTestNetworks == other.isRestrictedToTestNetworks && excludeLocalRoutes == other.excludeLocalRoutes - && requiresInternetValidation == other.requiresInternetValidation; + && requiresInternetValidation == other.requiresInternetValidation + && Objects.equals(ikeTunConnParams, other.ikeTunConnParams); } @NonNull diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java index 1feb5d415e16..06d12b5195ab 100644 --- a/core/java/com/android/server/SystemConfig.java +++ b/core/java/com/android/server/SystemConfig.java @@ -46,6 +46,7 @@ import android.util.Xml; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.XmlUtils; +import com.android.modules.utils.build.UnboundedSdkLevel; import libcore.io.IoUtils; import libcore.util.EmptyArray; @@ -58,7 +59,6 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -126,7 +126,7 @@ public class SystemConfig { * * <p>0 means not specified. */ - public final int onBootclasspathSince; + public final String onBootclasspathSince; /** * SDK version this library was removed from the BOOTCLASSPATH. @@ -138,7 +138,7 @@ public class SystemConfig { * * <p>0 means not specified. */ - public final int onBootclasspathBefore; + public final String onBootclasspathBefore; /** * Declares whether this library can be safely ignored from <uses-library> tags. @@ -155,19 +155,19 @@ public class SystemConfig { @VisibleForTesting public SharedLibraryEntry(String name, String filename, String[] dependencies, boolean isNative) { - this(name, filename, dependencies, 0 /* onBootclasspathSince */, - 0 /* onBootclasspathBefore */, isNative); + this(name, filename, dependencies, null /* onBootclasspathSince */, + null /* onBootclasspathBefore */, isNative); } @VisibleForTesting public SharedLibraryEntry(String name, String filename, String[] dependencies, - int onBootclasspathSince, int onBootclassPathBefore) { - this(name, filename, dependencies, onBootclasspathSince, onBootclassPathBefore, + String onBootclasspathSince, String onBootclasspathBefore) { + this(name, filename, dependencies, onBootclasspathSince, onBootclasspathBefore, false /* isNative */); } SharedLibraryEntry(String name, String filename, String[] dependencies, - int onBootclasspathSince, int onBootclasspathBefore, boolean isNative) { + String onBootclasspathSince, String onBootclasspathBefore, boolean isNative) { this.name = name; this.filename = filename; this.dependencies = dependencies; @@ -175,16 +175,14 @@ public class SystemConfig { this.onBootclasspathBefore = onBootclasspathBefore; this.isNative = isNative; - canBeSafelyIgnored = this.onBootclasspathSince != 0 - && isSdkAtLeast(this.onBootclasspathSince); - } - - private static boolean isSdkAtLeast(int level) { - if ("REL".equals(Build.VERSION.CODENAME)) { - return Build.VERSION.SDK_INT >= level; - } - return level == Build.VERSION_CODES.CUR_DEVELOPMENT - || Build.VERSION.SDK_INT >= level; + // this entry can be ignored if either: + // - onBootclasspathSince is set and we are at or past that SDK + // - onBootclasspathBefore is set and we are before that SDK + canBeSafelyIgnored = + (this.onBootclasspathSince != null + && UnboundedSdkLevel.isAtLeast(this.onBootclasspathSince)) + || (this.onBootclasspathBefore != null + && !UnboundedSdkLevel.isAtLeast(this.onBootclasspathBefore)); } } @@ -878,10 +876,8 @@ public class SystemConfig { String lname = parser.getAttributeValue(null, "name"); String lfile = parser.getAttributeValue(null, "file"); String ldependency = parser.getAttributeValue(null, "dependency"); - int minDeviceSdk = XmlUtils.readIntAttribute(parser, "min-device-sdk", - 0); - int maxDeviceSdk = XmlUtils.readIntAttribute(parser, "max-device-sdk", - 0); + String minDeviceSdk = parser.getAttributeValue(null, "min-device-sdk"); + String maxDeviceSdk = parser.getAttributeValue(null, "max-device-sdk"); if (lname == null) { Slog.w(TAG, "<" + name + "> without name in " + permFile + " at " + parser.getPositionDescription()); @@ -889,15 +885,18 @@ public class SystemConfig { Slog.w(TAG, "<" + name + "> without file in " + permFile + " at " + parser.getPositionDescription()); } else { - boolean allowedMinSdk = minDeviceSdk <= Build.VERSION.SDK_INT; + boolean allowedMinSdk = + minDeviceSdk == null || UnboundedSdkLevel.isAtLeast( + minDeviceSdk); boolean allowedMaxSdk = - maxDeviceSdk == 0 || maxDeviceSdk >= Build.VERSION.SDK_INT; + maxDeviceSdk == null || UnboundedSdkLevel.isAtMost( + maxDeviceSdk); final boolean exists = new File(lfile).exists(); if (allowedMinSdk && allowedMaxSdk && exists) { - int bcpSince = XmlUtils.readIntAttribute(parser, - "on-bootclasspath-since", 0); - int bcpBefore = XmlUtils.readIntAttribute(parser, - "on-bootclasspath-before", 0); + String bcpSince = parser.getAttributeValue(null, + "on-bootclasspath-since"); + String bcpBefore = parser.getAttributeValue(null, + "on-bootclasspath-before"); SharedLibraryEntry entry = new SharedLibraryEntry(lname, lfile, ldependency == null ? new String[0] : ldependency.split(":"), @@ -1487,7 +1486,7 @@ public class SystemConfig { addFeature(PackageManager.FEATURE_IPSEC_TUNNELS, 0); } - if (isFilesystemSupported("erofs")) { + if (isErofsSupported()) { if (isKernelVersionAtLeast(5, 10)) { addFeature(PackageManager.FEATURE_EROFS, 0); } else if (isKernelVersionAtLeast(4, 19)) { @@ -1865,11 +1864,10 @@ public class SystemConfig { return Process.myUid() == Process.SYSTEM_UID; } - private static boolean isFilesystemSupported(String fs) { + private static boolean isErofsSupported() { try { - final byte[] fsTableData = Files.readAllBytes(Paths.get("/proc/filesystems")); - final String fsTable = new String(fsTableData, StandardCharsets.UTF_8); - return fsTable.contains("\t" + fs + "\n"); + final Path path = Paths.get("/sys/fs/erofs"); + return Files.exists(path); } catch (Exception e) { return false; } diff --git a/core/proto/android/os/appbackgroundrestrictioninfo.proto b/core/proto/android/os/appbackgroundrestrictioninfo.proto new file mode 100644 index 000000000000..8445641694dc --- /dev/null +++ b/core/proto/android/os/appbackgroundrestrictioninfo.proto @@ -0,0 +1,199 @@ +/* + * 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. + */ + +syntax = "proto2"; +package android.os; + +option java_multiple_files = true; + +// This message is used for statsd logging and should be kept in sync with +// frameworks/proto_logging/stats/atoms.proto +/** + * Logs information about app background restrictions. + * + * Logged from: + * frameworks/base/services/core/java/com/android/server/am/AppRestrictionController.java + */ +message AppBackgroundRestrictionsInfo { + // the uid of the app. + optional int32 uid = 1; + + enum RestrictionLevel { + LEVEL_UNKNOWN = 0; + LEVEL_UNRESTRICTED = 1; + LEVEL_EXEMPTED = 2; + LEVEL_ADAPTIVE_BUCKET = 3; + LEVEL_RESTRICTED_BUCKET = 4; + LEVEL_BACKGROUND_RESTRICTED = 5; + LEVEL_HIBERNATION = 6; + } + // indicates the app background restriction level. + optional RestrictionLevel restriction_level = 2; + + enum Threshold { + THRESHOLD_UNKNOWN = 0; + THRESHOLD_RESTRICTED = 1; // app was background restricted by the system. + THRESHOLD_USER = 2; // app was background restricted by user action. + } + // indicates which threshold caused the app to be put into bg restriction. + optional Threshold threshold = 3; + + enum StateTracker { + UNKNOWN_TRACKER = 0; + BATTERY_TRACKER = 1; + BATTERY_EXEMPTION_TRACKER = 2; + FGS_TRACKER = 3; + MEDIA_SESSION_TRACKER = 4; + PERMISSION_TRACKER = 5; + BROADCAST_EVENTS_TRACKER = 6; + BIND_SERVICE_EVENTS_TRACKER = 7; + } + // indicates the reason/tracker which caused the app to hit the threshold. + optional StateTracker tracker = 4; + + message FgsTrackerInfo { + // indicates whether an fgs notification was visible for this app or not. + optional bool fgs_notification_visible = 1; + // total FGS duration for this app. + optional int64 fgs_duration = 2; + } + optional FgsTrackerInfo fgs_tracker_info = 5; + + message BatteryTrackerInfo { + // total battery usage within last 24h (percentage) + optional int32 battery_24h = 1; + // background battery usage (percentage) + optional int32 battery_usage_background = 2; + // FGS battery usage (percentage) + optional int32 battery_usage_fgs = 3; + } + optional BatteryTrackerInfo battery_tracker_info = 6; + + message BroadcastEventsTrackerInfo { + // the number of broadcasts sent by this app. + optional int32 broadcasts_sent = 1; + } + optional BroadcastEventsTrackerInfo broadcast_events_tracker_info = 7; + + message BindServiceEventsTrackerInfo { + // the number of bind service requests by this app. + optional int32 bind_service_requests = 1; + } + optional BindServiceEventsTrackerInfo bind_service_events_tracker_info = + 8; + + // The reasons listed below are defined in PowerExemptionManager.java + enum ExemptionReason { + // range 0-9 is reserved for default reasons + REASON_UNKNOWN = 0; + REASON_DENIED = 1; + REASON_OTHER = 2; + // range 10-49 is reserved for BG-FGS-launch allowed proc states + REASON_PROC_STATE_PERSISTENT = 10; + REASON_PROC_STATE_PERSISTENT_UI = 11; + REASON_PROC_STATE_TOP = 12; + REASON_PROC_STATE_BTOP = 13; + REASON_PROC_STATE_FGS = 14; + REASON_PROC_STATE_BFGS = 15; + // range 50-99 is reserved for BG-FGS-launch allowed reasons + REASON_UID_VISIBLE = 50; + REASON_SYSTEM_UID = 51; + REASON_ACTIVITY_STARTER = 52; + REASON_START_ACTIVITY_FLAG = 53; + REASON_FGS_BINDING = 54; + REASON_DEVICE_OWNER = 55; + REASON_PROFILE_OWNER = 56; + REASON_COMPANION_DEVICE_MANAGER = 57; + REASON_BACKGROUND_ACTIVITY_PERMISSION = 58; + REASON_BACKGROUND_FGS_PERMISSION = 59; + REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION = 60; + REASON_INSTR_BACKGROUND_FGS_PERMISSION = 61; + REASON_SYSTEM_ALERT_WINDOW_PERMISSION = 62; + REASON_DEVICE_DEMO_MODE = 63; + REASON_ALLOWLISTED_PACKAGE = 65; + REASON_APPOP = 66; + REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD = 67; + REASON_OP_ACTIVATE_VPN = 68; + REASON_OP_ACTIVATE_PLATFORM_VPN = 69; + REASON_TEMP_ALLOWED_WHILE_IN_USE = 70; + REASON_CURRENT_INPUT_METHOD = 71; + // range 100-199 is reserved for public reasons + REASON_GEOFENCING = 100; + REASON_PUSH_MESSAGING = 101; + REASON_PUSH_MESSAGING_OVER_QUOTA = 102; + REASON_ACTIVITY_RECOGNITION = 103; + REASON_ACCOUNT_TRANSFER = 104; + // range 200-299 is reserved for broadcast actions + REASON_BOOT_COMPLETED = 200; + REASON_PRE_BOOT_COMPLETED = 201; + REASON_LOCKED_BOOT_COMPLETED = 202; + REASON_BLUETOOTH_BROADCAST = 203; + REASON_TIMEZONE_CHANGED = 204; + REASON_TIME_CHANGED = 205; + REASON_LOCALE_CHANGED = 206; + REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED = 207; + REASON_REFRESH_SAFETY_SOURCES = 208; + // range 300-399 is reserved for other internal reasons + REASON_SYSTEM_ALLOW_LISTED = 300; + REASON_ALARM_MANAGER_ALARM_CLOCK = 301; + REASON_ALARM_MANAGER_WHILE_IDLE = 302; + REASON_SERVICE_LAUNCH = 303; + REASON_KEY_CHAIN = 304; + REASON_PACKAGE_VERIFIER = 305; + REASON_SYNC_MANAGER = 306; + REASON_DOMAIN_VERIFICATION_V1 = 307; + REASON_DOMAIN_VERIFICATION_V2 = 308; + REASON_VPN = 309; + REASON_NOTIFICATION_SERVICE = 310; + REASON_PACKAGE_REPLACED = 311; + REASON_LOCATION_PROVIDER = 312; + REASON_MEDIA_BUTTON = 313; + REASON_EVENT_SMS = 314; + REASON_EVENT_MMS = 315; + REASON_SHELL = 316; + REASON_MEDIA_SESSION_CALLBACK = 317; + REASON_ROLE_DIALER = 318; + REASON_ROLE_EMERGENCY = 319; + REASON_SYSTEM_MODULE = 320; + REASON_CARRIER_PRIVILEGED_APP = 321; + // app requested to be exempt + REASON_OPT_OUT_REQUESTED = 1000; + } + // indicates if the app is exempt from background restrictions and the reason if applicable. + optional ExemptionReason exemption_reason = 9; + + enum OptimizationLevel { + UNKNOWN = 0; + OPTIMIZED = 1; + BACKGROUND_RESTRICTED = 2; + NOT_OPTIMIZED = 3; + } + // the user choice for the optimization level of the app. + optional OptimizationLevel opt_level = 10; + + enum TargetSdk { + SDK_UNKNOWN = 0; + SDK_PRE_S = 1; + SDK_S = 2; + SDK_T = 3; + } + // indicates the target sdk level for this app. + optional TargetSdk target_sdk = 11; + + // indicates if the current device is a low ram device. + optional bool low_mem_device = 12; +} + diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 96fe7e1aa541..4075c5f4d8ae 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2086,7 +2086,7 @@ <!-- @SystemApi @hide Allows applications to register network factory or agent --> <permission android:name="android.permission.NETWORK_FACTORY" - android:protectionLevel="signature" /> + android:protectionLevel="signature|role" /> <!-- @SystemApi @hide Allows applications to access network stats provider --> <permission android:name="android.permission.NETWORK_STATS_PROVIDER" @@ -2275,13 +2275,13 @@ @hide --> <permission android:name="android.permission.BLUETOOTH_MAP" - android:protectionLevel="signature" /> + android:protectionLevel="signature|role" /> <!-- Allows bluetooth stack to access files @hide This should only be used by Bluetooth apk. --> <permission android:name="android.permission.BLUETOOTH_STACK" - android:protectionLevel="signature" /> + android:protectionLevel="signature|role" /> <!-- Allows uhid write access for creating virtual input devices @hide @@ -2552,7 +2552,7 @@ <!-- Allows access to configure network interfaces, configure/use IPSec, etc. @hide --> <permission android:name="android.permission.NET_ADMIN" - android:protectionLevel="signature" /> + android:protectionLevel="signature|role" /> <!-- Allows registration for remote audio playback. @hide --> <permission android:name="android.permission.REMOTE_AUDIO_PLAYBACK" @@ -2676,7 +2676,7 @@ <!-- Allows listen permission to always reported system signal strength. @hide Used internally. --> <permission android:name="android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH" - android:protectionLevel="signature" /> + android:protectionLevel="signature|role" /> <!-- @SystemApi Protects the ability to register any PhoneAccount with PhoneAccount#CAPABILITY_SIM_SUBSCRIPTION. This capability indicates that the PhoneAccount @@ -3911,7 +3911,7 @@ Not for use by third party apps. @hide --> <permission android:name="android.permission.MANAGE_APP_OPS_MODES" - android:protectionLevel="signature|installer|verifier" /> + android:protectionLevel="signature|installer|verifier|role" /> <!-- @SystemApi Allows an application to open windows that are for use by parts of the system user interface. @@ -4792,7 +4792,7 @@ <!-- Allows an application to manage the companion devices. @hide --> <permission android:name="android.permission.MANAGE_COMPANION_DEVICES" - android:protectionLevel="signature" /> + android:protectionLevel="signature|role" /> <!-- Allows an application to subscribe to notifications about the presence status change of their associated companion device @@ -5041,7 +5041,7 @@ <!-- @TestApi Allows an application to query audio related state. @hide --> <permission android:name="android.permission.QUERY_AUDIO_STATE" - android:protectionLevel="signature" /> + android:protectionLevel="signature|role" /> <!-- Allows an application to modify what effects are applied to all audio (matching certain criteria) from any application. @@ -5114,7 +5114,7 @@ @hide --> <permission android:name="android.permission.DEVICE_POWER" - android:protectionLevel="signature" /> + android:protectionLevel="signature|role" /> <!-- Allows toggling battery saver on the system. Superseded by DEVICE_POWER permission. @hide @SystemApi @@ -5140,7 +5140,7 @@ <!-- @hide Allows low-level access to tun tap driver --> <permission android:name="android.permission.NET_TUNNELING" - android:protectionLevel="signature" /> + android:protectionLevel="signature|role" /> <!-- Run as a manufacturer test application, running as the root user. Only available when the device is running in manufacturer test mode. diff --git a/core/res/res/drawable/ic_check_24dp.xml b/core/res/res/drawable/ic_check_24dp.xml new file mode 100644 index 000000000000..a0e21ff2826e --- /dev/null +++ b/core/res/res/drawable/ic_check_24dp.xml @@ -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. + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z" + android:fillColor="@android:color/white"/> +</vector> diff --git a/core/res/res/layout/app_language_picker_current_locale_item.xml b/core/res/res/layout/app_language_picker_current_locale_item.xml new file mode 100644 index 000000000000..bf6d9639791a --- /dev/null +++ b/core/res/res/layout/app_language_picker_current_locale_item.xml @@ -0,0 +1,44 @@ +<?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. + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <FrameLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight=".8"> + <include + android:id="@+id/language_picker_item" + layout="@layout/language_picker_item" /> + </FrameLayout> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight=".2" + android:gravity="center" + android:minHeight="?android:attr/listPreferredItemHeight"> + <ImageView + android:id="@+id/imageView" + android:layout_width="24dp" + android:layout_height="24dp" + android:src="@drawable/ic_check_24dp" + app:tint="#0F9D58"/> + </LinearLayout> +</LinearLayout> diff --git a/core/res/res/layout/app_language_picker_system_current.xml b/core/res/res/layout/app_language_picker_system_current.xml new file mode 100644 index 000000000000..341ee2528671 --- /dev/null +++ b/core/res/res/layout/app_language_picker_system_current.xml @@ -0,0 +1,45 @@ +<!-- + ~ 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. + --> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <FrameLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight=".8"> + <include + android:id="@+id/system_language_view" + layout="@layout/app_language_picker_system_default" /> + </FrameLayout> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight=".2" + android:gravity="center" + android:minHeight="?android:attr/listPreferredItemHeight"> + <ImageView + android:id="@+id/imageView" + android:layout_width="24dp" + android:layout_height="24dp" + android:src="@drawable/ic_check_24dp" + app:tint="#0F9D58"/> + </LinearLayout> +</LinearLayout> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 1b8e975135c3..5fa7457b2796 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Kon nie staaf nie"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gebruik skermslot"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Voer jou skermslot in om voort te gaan"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Druk ferm op die sensor"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Gedeeltelike vingerafdruk is bespeur"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kon nie vingerafdruk verwerk nie. Probeer asseblief weer."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Maak vingerafdruksensor skoon en probeer weer"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Maak sensor skoon en probeer weer"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Vingerafdruk word nie herken nie"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Vingerafdruk word nie herken nie"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Druk ferm op sensor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Vingerafdruk is gestaaf"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Gesig is gestaaf"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Gesig is gestaaf; druk asseblief bevestig"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AAN"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"AF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Gee <xliff:g id="SERVICE">%1$s</xliff:g> volle beheer oor jou toestel?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"As jy <xliff:g id="SERVICE">%1$s</xliff:g> aanskakel, sal jou toestel nie jou skermslot gebruik om data-enkripsie te verbeter nie."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Volle beheer is gepas vir programme wat jou help met toeganklikheidsbehoeftes, maar nie vir die meeste programme nie."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Bekyk en beheer skerm"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Dit kan alle inhoud op die skerm lees en inhoud bo-oor ander programme vertoon."</string> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Program is nie beskikbaar nie"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is nie op die oomblik beskikbaar nie."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> is nie beskikbaar nie"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Toestemming word benodig"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Jy kan nie nou toegang hiertoe op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie. Probeer eerder op jou Android TV-toestel."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Jy kan nie nou toegang hiertoe op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie. Probeer eerder op jou tablet."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Jy kan nie nou toegang hiertoe op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie. Probeer eerder op jou foon."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"MAAK TOG OOP"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Skadelike program is bespeur"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Gee <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> toegang tot alle toestelloglêers?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Gee eenmalige toegang"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Net hierdie keer"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Moenie toelaat nie"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Toestelloglêers teken aan wat op jou toestel gebeur. Programme kan hierdie loglêers gebruik om kwessies op te spoor en reg te stel.\n\nSommige loglêers bevat dalk sensitiewe inligting en daarom moet jy toegang tot alle toestelloglêers net gee aan programme wat jy vertrou. \n\nAs jy nie vir hierdie program toegang tot alle toestelloglêers gee nie, het dit steeds toegang tot sy eie loglêers. Jou toestelvervaardiger het dalk steeds toegang tot sommige loglêers of inligting op jou toestel. Kom meer te wete"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Moenie weer wys nie"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wil <xliff:g id="APP_2">%2$s</xliff:g>-skyfies wys"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Wysig"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Agtergrondaktiwiteit"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> werk tans op die agtergrond en gebruik batterykrag. Tik om na te gaan."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> werk al vir \'n lang tyd op die agtergrond. Tik om 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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Kan nie toegang tot die tablet se kamera op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Stelseltaal"</string> </resources> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index d4d762f5599d..4b4ceafaee89 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"ማረጋገጥ ላይ ስህተት"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"የማያ ገጽ መቆለፊን ይጠቀሙ"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ለመቀጠል የማያ ገጽ ቁልፍዎን ያስገቡ"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"ዳሳሹን በደንብ ይጫኑት"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"ከፊል የጣት አሻራ ተገኝቷል"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ጣት አሻራን መስራት አልተቻለም። እባክዎ እንደገና ይሞክሩ።"</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"የጣት አሻራ ዳሳሽን ያጽዱ እና እንደገና ይሞክሩ"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ዳሳሹን ያጽዱ እና እንደገና ይሞክሩ"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"የጣት አሻራ አልታወቀም"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"የጣት አሻራ አልታወቀም"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"ዳሳሹን ጠበቅ አድርገው ይጫኑት"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"የጣት አሻራ ትክክለኛነት ተረጋግጧል"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ፊት ተረጋግጧል"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ፊት ተረጋግጧል፣ እባክዎ አረጋግጥን ይጫኑ"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"<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> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"መተግበሪያ አይገኝም"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ይህ በዚህ ጊዜ በእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> ላይ ሊደረስበት አይችልም። በምትኩ በAndroid TV መሣሪያዎ ላይ ይሞክሩ።"</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ይህ በዚህ ጊዜ በእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> ላይ ሊደረስበት አይችልም። በምትኩ በጡባዊዎ ላይ ይሞክሩ።"</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ይህ በዚህ ጊዜ በእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> ላይ ሊደረስበት አይችልም። በምትኩ በስልክዎ ላይ ይሞክሩ።"</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ለማንኛውም ክፈት"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"ጎጂ መተግበሪያ ተገኝቷል"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ሁሉንም የመሣሪያ ምዝግብ ማስታወሻዎች እንዲደርስ ይፈቀድለት?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"የአንድ ጊዜ መዳረሻን ፍቀድ"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"አሁን ብቻ"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"አትፍቀድ"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"የመሣሪያ ምዝግብ ማስታወሻዎች በመሣሪያዎ ላይ ምን እንደሚከሰት ይመዘግባሉ። መተግበሪያዎች ችግሮችን ለማግኘት እና ለማስተካከል እነዚህን ምዝግብ ማስታወሻዎች መጠቀም ይችላሉ።\n\nአንዳንድ ምዝግብ ማስታወሻዎች ሚስጥራዊነት ያለው መረጃ ሊይዙ ይችላሉ፣ ስለዚህ የሚያምኗቸውን መተግበሪያዎች ብቻ ሁሉንም የመሣሪያ ምዝግብ ማስታወሻዎች እንዲደርሱ ይፍቀዱላቸው። \n\nይህ መተግበሪያ ሁሉንም የመሣሪያ ምዝግብ ማስታወሻዎች እንዲደርስ ካልፈቀዱለት አሁንም የራሱን ምዝግብ ማስታወሻዎች መድረስ ይችላል። የእርስዎ መሣሪያ አምራች አሁንም አንዳንድ ምዝግብ ማስታወሻዎችን ወይም መረጃን በመሣሪያዎ ላይ ሊደርስ ይችላል። የበለጠ ለመረዳት"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"ዳግም አታሳይ"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> የ<xliff:g id="APP_2">%2$s</xliff:g> ቁራጮችን ማሳየት ይፈልጋል"</string> <string name="screenshot_edit" msgid="7408934887203689207">"አርትዕ"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> የባትሪ ዕድሜ ላይ ተጽዕኖ ሊያሳድር ይችላል። ንቁ መተግበሪያዎችን ለመገምገም መታ ያድርጉ።"</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"የበስተጀርባ እንቅስቃሴ"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ከበስተጀርባ በማሄድ ላይ ነው እና ባትሪ እየጨረሰ ነው። ለመገምገም መታ ያድርጉ።"</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ጡባዊውን ካሜራ ከእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> መድረስ አይቻልም"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"የስርዓት ቋንቋ"</string> </resources> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 8c117d40203f..a1c80090f14c 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -429,9 +429,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="permdesc_bodySensors" product="default" msgid="7652650410295512140">"يتيح هذا الإذن للتطبيق بالوصول إلى بيانات أجهزة استشعار الجسم، مثل معدّل نبضات القلب ودرجة الحرارة ونسبة الأكسجين في الدم، وذلك عندما يكون التطبيق قيد الاستخدام."</string> - <string name="permlab_bodySensors_background" msgid="4912560779957760446">"الوصول في الخلفية إلى بيانات استشعار الجسم، مثل معدّل نبضات القلب"</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> @@ -589,8 +589,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"خطأ في المصادقة"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"استخدام قفل الشاشة"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"أدخِل قفل الشاشة للمتابعة"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"تم اكتشاف بصمة إصبع جزئية."</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"تعذرت معالجة بصمة الإصبع. يُرجى إعادة المحاولة."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"يُرجى تنظيف مستشعر بصمات الإصبع ثم إعادة المحاولة."</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"تنظيف المستشعر ثم إعادة المحاولة"</string> @@ -603,8 +602,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"لم يتمّ التعرّف على البصمة."</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"اضغط بقوة على المستشعر."</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"تم مصادقة بصمة الإصبع"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"تمّت مصادقة الوجه"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"تمّت مصادقة الوجه، يُرجى الضغط على \"تأكيد\"."</string> @@ -1685,6 +1683,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_enable_service_encryption_warning" msgid="8603532708618236909">"في حال تفعيل <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> @@ -1938,7 +1937,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"التطبيق غير متاح"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"لا يمكن الوصول إلى هذا التطبيق على <xliff:g id="DEVICE">%1$s</xliff:g> في الوقت الحالي. حاوِل الوصول إليه على جهاز Android TV بدلاً من ذلك."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"لا يمكن الوصول إلى هذا التطبيق على <xliff:g id="DEVICE">%1$s</xliff:g> في الوقت الحالي. حاوِل الوصول إليه على جهازك اللوحي بدلاً من ذلك."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"لا يمكن الوصول إلى هذا التطبيق على <xliff:g id="DEVICE">%1$s</xliff:g> في الوقت الحالي. حاوِل الوصول إليه على هاتفك بدلاً من ذلك."</string> @@ -2032,10 +2032,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"الفتح على أي حال"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"تم العثور على تطبيق ضار"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"هل تريد السماح لتطبيق <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> بالوصول إلى جميع سجلّات الجهاز؟"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"هذه المرَّة فقط"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"عدم السماح"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"ترصد سجلّات الجهاز ما يحدث على جهازك. يمكن أن تستخدم التطبيقات هذه السجلّات لتحديد المشاكل وحلها.\n\nقد تحتوي بعض السجلّات على معلومات حساسة، ولذلك يجب عدم السماح بالوصول إلى جميع سجلّات الجهاز إلا للتطبيقات التي تثق بها. \n\nإذا لم تسمح بوصول هذا التطبيق إلى جميع سجلّات الجهاز، يظل بإمكان التطبيق الوصول إلى سجلّاته. ويظل بإمكان الشركة المصنّعة لجهازك الوصول إلى بعض السجلّات أو المعلومات المتوفّرة على جهازك. مزيد من المعلومات"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"عدم الإظهار مرة أخرى"</string> <string name="slices_permission_request" msgid="3677129866636153406">"يريد تطبيق <xliff:g id="APP_0">%1$s</xliff:g> عرض شرائح تطبيق <xliff:g id="APP_2">%2$s</xliff:g>."</string> <string name="screenshot_edit" msgid="7408934887203689207">"تعديل"</string> @@ -2265,16 +2265,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"النشاط في الخلفية"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"يعمل تطبيق <xliff:g id="APP">%1$s</xliff:g> في الخلفية ويستنفد شحن البطارية. انقر لمراجعة الإعدادات."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"يعمل تطبيق <xliff:g id="APP">%1$s</xliff:g> في الخلفية لفترة طويلة. انقر لمراجعة الإعدادات."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"التحقّق من التطبيقات النشطة"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"يتعذّر الوصول إلى كاميرا الجهاز اللوحي من على جهاز <xliff:g id="DEVICE">%1$s</xliff:g>."</string> <string name="system_locale_title" msgid="3978041860457277638">"لغة النظام"</string> </resources> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 758d7a175277..5ae12f688463 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"আসোঁৱাহৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰি থকা হৈছে"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"স্ক্ৰীন ল\'ক ব্যৱহাৰ কৰক"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"অব্যাহত ৰাখিবলৈ আপোনাৰ স্ক্ৰীন লক দিয়ক"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"ছেন্সৰটোত ভালকৈ টিপক"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"আংশিক ফিংগাৰপ্ৰিণ্ট চিনাক্ত কৰা হৈছে"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ফিগাৰপ্ৰিণ্টৰ প্ৰক্ৰিয়া সম্পাদন কৰিবপৰা নগ\'ল। অনুগ্ৰহ কৰি আকৌ চেষ্টা কৰক৷"</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো মচি পুনৰ চেষ্টা কৰক"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ছেন্সৰটো মচি পুনৰ চেষ্টা কৰক"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ফিংগাৰপ্ৰিণ্ট চিনাক্ত কৰিব পৰা নাই"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"ফিংগাৰপ্ৰিণ্ট চিনাক্ত কৰিব পৰা নাই"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"ছেন্সৰটোত ভালকৈ টিপক"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ফিংগাৰপ্ৰিণ্টৰ সত্যাপন কৰা হ’ল"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল, অনুগ্ৰহ কৰি ‘নিশ্চিত কৰক’ বুটামটো টিপক"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"যদি আপুনি <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> @@ -2026,9 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"যিহ\'লেও খোলক"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"ক্ষতিকাৰক এপ্ চিনাক্ত কৰা হৈছে"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>ক আটাইবোৰ ডিভাইচৰ লগ এক্সেছ কৰাৰ অনুমতি প্ৰদান কৰিবনে?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"কেৱল এবাৰ এক্সেছ কৰাৰ অনুমতি দিয়ক"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"কেৱল এইবাৰৰ বাবে"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"অনুমতি নিদিব"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"আপোনাৰ ডিভাইচত কি কি ঘটে সেয়া ডিভাইচ লগে ৰেকৰ্ড কৰে। এপ্সমূহে সমস্যা বিচাৰিবলৈ আৰু সমাধান কৰিবলৈ এই লগসমূহ ব্যৱহাৰ কৰিব পাৰে।\n\nকিছুমান লগত সংবেদনশীল তথ্য থাকিব পাৰে, গতিকে কেৱল আপুনি বিশ্বাস কৰা এপকহে আটাইবোৰ ডিভাইচ লগ এক্সেছ কৰাৰ অনুমতি দিয়ক। \n\nআপুনি যদি এই এপ্টোক আটাইবোৰ ডিভাইচ লগ এক্সেছ কৰাৰ অনুমতি নিদিয়ে, তথাপিও ই নিজৰ লগসমূহ এক্সেছ কৰিব পাৰিব। আপোনাৰ ডিভাইচৰ নিৰ্মাতাই তথাপিও হয়তো আপোনাৰ ডিভাইচটোত থকা কিছু লগ অথবা তথ্য এক্সেছ কৰিব পাৰিব। অধিক জানক"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"পুনৰ নেদেখুৱাব"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>এ <xliff:g id="APP_2">%2$s</xliff:g>ৰ অংশ দেখুওৱাব খুজিছে"</string> <string name="screenshot_edit" msgid="7408934887203689207">"সম্পাদনা কৰক"</string> @@ -2258,12 +2260,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g>এ বেটাৰীৰ জীৱনকালৰ ওপৰত প্ৰভাৱ পেলাব পাৰে। সক্ৰিয় এপ্ পৰ্যালোচনা কৰিবলৈ টিপক।"</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"নেপথ্যত চলি থকা কাৰ্যকলাপ"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> নেপথ্যত চলি আছে আৰু অত্যধিক বেটাৰী খৰচ কৰিছে। পৰ্যালোচনা কৰিবলৈ টিপক।"</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ৰ পৰা টেবলেটটোৰ কেমেৰা এক্সেছ কৰিব নোৱাৰি"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"ছিষ্টেমৰ ভাষা"</string> </resources> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 7d28ab6108ec..d336d2e94a6b 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Doğrulama zamanı xəta baş verdi"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekran kilidindən istifadə edin"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Davam etmək üçün ekran kilidinizi daxil edin"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Sensora basıb saxlayın"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Barmaq izinin bir hissəsi aşkarlanıb"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Barmaq izi tanınmadı. Lütfən, yenidən cəhd edin."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Barmaq izi sensorunu silib yenidən cəhd edin"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Sensoru silib yenidən cəhd edin"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Barmaq izi tanınmır"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Barmaq izi tanınmır"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Sensora basıb saxlayın"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Barmaq izi doğrulandı"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Üz doğrulandı"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Üz təsdiq edildi, təsdiq düyməsinə basın"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AKTİV"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DEAKTİV"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> xidmətinin cihaza tam nəzarət etməsinə icazə verilsin?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g> aktiv olarsa, cihazınız data şifrələnməsini genişləndirmək üçün ekran kilidini istifadə etməyəcək."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Tam nəzarət icazəsi xüsusi imkanlara dair yardım edən tətbiqlərə lazımdır, digər tətbiqlərə lazım deyil."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Baxış və nəzarət ekranı"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Ekrandakı bütün kontenti oxuya və kontenti digər tətbiqlərin üzərində göstərə bilər."</string> @@ -2026,9 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"İSTƏNİLƏN HALDA AÇIN"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Zərərli tətbiq aşkarlandı"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> tətbiqinin bütün cihaz qeydlərinə girişinə icazə verilsin?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Birdəfəlik girişə icazə verin"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Yalnız bu dəfə"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"İcazə verməyin"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Cihaz qeydləri cihazınızda baş verənləri qeyd edir. Tətbiqlər problemləri tapmaq və həll etmək üçün bu qeydlərdən istifadə edə bilər.\n\nBəzi qeydlərdə həssas məlumatlar ola bilər, ona görə də yalnız etibar etdiyiniz tətbiqlərin bütün cihaz qeydlərinə giriş etməsinə icazə verin. \n\nBu tətbiqin bütün cihaz qeydlərinə girişinə icazə verməsəniz, o, hələ də öz qeydlərinə giriş edə bilər. Cihaz istehsalçınız hələ də cihazınızda bəzi qeydlərə və ya məlumatlara giriş edə bilər. Ətraflı məlumat"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Daha göstərməyin"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> <xliff:g id="APP_2">%2$s</xliff:g> tətbiqindən bölmələr göstərmək istəyir"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Redaktə edin"</string> @@ -2258,12 +2260,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Arxa Fonda Fəaliyyət"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> arxa fonda işləyir və enerjini tükədir. Nəzərdən keçirmək üçün toxunun."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> uzun müddət arxa fonda işləyir. 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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan planşetin kamerasına giriş etmək olmur"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Sistem dili"</string> </resources> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index d66e83bf4ee9..e6e83b384d68 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -218,7 +218,7 @@ <string name="turn_on_radio" msgid="2961717788170634233">"Uključi bežični signal"</string> <string name="turn_off_radio" msgid="7222573978109933360">"Isključi bežični signal"</string> <string name="screen_lock" msgid="2072642720826409809">"Zaključaj ekran"</string> - <string name="power_off" msgid="4111692782492232778">"Ugasi"</string> + <string name="power_off" msgid="4111692782492232778">"Isključi"</string> <string name="silent_mode_silent" msgid="5079789070221150912">"Zvono je isključeno"</string> <string name="silent_mode_vibrate" msgid="8821830448369552678">"Vibracija zvona"</string> <string name="silent_mode_ring" msgid="6039011004781526678">"Zvono je uključeno"</string> @@ -242,7 +242,7 @@ <string name="global_actions" product="tv" msgid="3871763739487450369">"Opcije Android TV-a"</string> <string name="global_actions" product="default" msgid="6410072189971495460">"Opcije telefona"</string> <string name="global_action_lock" msgid="6949357274257655383">"Zaključaj ekran"</string> - <string name="global_action_power_off" msgid="4404936470711393203">"Ugasi"</string> + <string name="global_action_power_off" msgid="4404936470711393203">"Isključi"</string> <string name="global_action_power_options" msgid="1185286119330160073">"Napajanje"</string> <string name="global_action_restart" msgid="4678451019561687074">"Restartuj"</string> <string name="global_action_emergency" msgid="1387617624177105088">"Hitan poziv"</string> @@ -586,7 +586,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Greška pri potvrdi identiteta"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Koristite zaključavanje ekrana"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Upotrebite zaključavanje ekrana da biste nastavili"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Jako pritisnite senzor"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Otkriven je delimičan otisak prsta"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nije uspela obrada otiska prsta. Probajte ponovo."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Obrišite senzor za otisak prsta i probajte ponovo"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Obrišite senzor i probajte ponovo"</string> @@ -599,7 +599,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Otisak prsta nije prepoznat"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Otisak prsta nije prepoznat"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Jako pritisnite senzor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisak prsta je potvrđen"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Lice je potvrđeno"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Lice je potvrđeno. Pritisnite Potvrdi"</string> @@ -1680,6 +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">"Želite li da dozvolite da usluga <xliff:g id="SERVICE">%1$s</xliff:g> ima potpunu kontrolu nad uređajem?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ako uključite uslugu <xliff:g id="SERVICE">%1$s</xliff:g>, uređaj neće koristiti zaključavanje ekrana da bi poboljšao šifrovanje podataka."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Potpuna kontrola je primerena za aplikacije koje vam pomažu kod usluga pristupačnosti, ali ne i za većinu aplikacija."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Pregledaj i kontroliši ekran"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Može da čita sav sadržaj na ekranu i prikazuje ga u drugim aplikacijama."</string> @@ -2027,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"IPAK OTVORI"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Otkrivena je štetna aplikacija"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Želite da dozvolite aplikaciji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> da pristupa svim evidencijama uređaja?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Dozvoli jednokratan pristup"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Samo ovaj put"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ne dozvoli"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Evidencije uređaja registruju šta se dešava na uređaju. Aplikacije mogu da koriste te evidencije da bi pronašle i rešile probleme.\n\nNeke evidencije mogu da sadrže osetljive informacije, pa pristup svim evidencijama uređaja treba da dozvoljavate samo aplikacijama u koje imate poverenja. \n\nAko ne dozvolite ovoj aplikaciji da pristupa svim evidencijama uređaja, ona i dalje može da pristupa sopstvenim evidencijama. Proizvođač uređaja će možda i dalje moći da pristupa nekim evidencijama ili informacijama na uređaju. Saznajte više"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne prikazuj ponovo"</string> <string name="slices_permission_request" msgid="3677129866636153406">"Aplikacija <xliff:g id="APP_0">%1$s</xliff:g> želi da prikazuje isečke iz aplikacije <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Izmeni"</string> @@ -2259,12 +2261,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Aktivnost u pozadini"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> troši bateriju u pozadini. Dodirnite da biste pregledali."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> je predugo pokrenuta u pozadini. Dodirnite da biste pregledali."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ne može da se pristupi kameri tableta sa <xliff:g id="DEVICE">%1$s</xliff:g> uređaja"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Jezik sistema"</string> </resources> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index f6af6c6a2a19..500a94acbb2c 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -587,8 +587,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Памылка аўтэнтыфікацыі"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ужываць блакіроўку экрана"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Каб працягнуць, скарыстайце свой сродак блакіроўкі экрана"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Адбітак пальца адсканіраваны не цалкам"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не атрымалася апрацаваць адбітак пальца. Паспрабуйце яшчэ раз."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Ачысціце сканер адбіткаў пальцаў і паўтарыце спробу"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Ачысціце сканер і паўтарыце спробу"</string> @@ -601,8 +600,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Адбітак пальца не распазнаны"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Моцна націсніце на сканер"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Адбітак пальца распазнаны"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Твар распазнаны"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Твар распазнаны. Націсніце, каб пацвердзіць"</string> @@ -1683,6 +1681,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_enable_service_encryption_warning" msgid="8603532708618236909">"Калі вы ўключыце сэрвіс \"<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> @@ -1936,7 +1935,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Праграма недаступная"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Не ўдаецца атрымаць доступ з вашай прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\". Паспрабуйце скарыстаць прыладу Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Не ўдаецца атрымаць доступ з вашай прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\". Паспрабуйце скарыстаць планшэт."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Не ўдаецца атрымаць доступ з вашай прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\". Паспрабуйце скарыстаць тэлефон."</string> @@ -2030,10 +2030,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"УСЁ РОЎНА АДКРЫЦЬ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Выяўлена шкодная праграма"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Дазволіць праграме \"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>\" мець доступ да ўсіх журналаў прылады?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Толькі ў гэты раз"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Не дазваляць"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Журналы прылад запісваюць усё, што адбываецца на вашай прыладзе. Праграмы выкарыстоўваюць гэтыя журналы для пошуку і выпраўлення памылак.\n\nУ некаторых журналах можа ўтрымлівацца канфідэнцыяльная інфармацыя, таму давайце доступ да ўсіх журналаў прылады толькі тым праграмам, якім вы давяраеце. \n\nКалі вы не дасце гэтай праграме доступу да ўсіх журналаў прылад, у яе ўсё роўна застанецца доступ да ўласных журналаў. Для вытворцы вашай прылады будуць даступнымі некаторыя журналы і інфармацыя на вашай прыладзе. Даведацца больш"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Больш не паказваць"</string> <string name="slices_permission_request" msgid="3677129866636153406">"Праграма <xliff:g id="APP_0">%1$s</xliff:g> запытвае дазвол на паказ зрэзаў праграмы <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Рэдагаваць"</string> @@ -2263,16 +2263,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Фонавая дзейнасць"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> працуе ў фонавым рэжыме і расходуе зарад акумулятара. Націсніце, каб праглядзець."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> працуе ў фонавым рэжыме працяглы час. Націсніце, каб праглядзець."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Праверце актыўныя праграмы"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не ўдалося атрымаць доступ да камеры планшэта з прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\""</string> <string name="system_locale_title" msgid="3978041860457277638">"Сістэмная мова"</string> </resources> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index b79ade53c546..eb1571263e36 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Грешка при удостоверяването"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ползване на заключв. на екрана"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Въведете опцията си за заключване на екрана, за да продължите"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Установен е частичен отпечатък"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Отпечатъкът не бе обработен. Моля, опитайте отново."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Почистете сензора за отпечатъци и опитайте отново"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Почистете сензора и опитайте отново"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Отпечатъкът не е разпознат"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Натиснете добре върху сензора"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечатъкът е удостоверен"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Лицето е удостоверено"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лицето е удостоверено. Моля, натиснете „Потвърждаване“"</string> @@ -1681,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"Ако включите <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> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Приложението не е достъпно"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Понастоящем не може да се осъществи достъп от устройството ви <xliff:g id="DEVICE">%1$s</xliff:g>. Вместо това опитайте от устройството си с Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Понастоящем не може да се осъществи достъп от устройството ви <xliff:g id="DEVICE">%1$s</xliff:g>. Вместо това опитайте от таблета си."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Понастоящем не може да се осъществи достъп от устройството ви <xliff:g id="DEVICE">%1$s</xliff:g>. Вместо това опитайте от телефона си."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ОТВАРЯНЕ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Открито е опасно приложение"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Да се разреши ли на <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> достъп до всички регистрационни файлове за устройството?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Само този път"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Забраняване"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"В регистрационните файлове за устройството се записва какво се извършва на него. Приложенията могат да използват тези регистрационни файлове, за да откриват и отстраняват проблеми.\n\nНякои регистрационни файлове за устройството може да съдържат поверителна информация, затова разрешавайте достъп до всички тях само на приложения, на които имате доверие. \n\nАко не разрешите на това приложение достъп до всички регистрационни файлове за устройството, то пак може да осъществява достъп до собствените си регистрационни файлове. Производителят на устройството пак може да има достъп до някои регистрационни файлове или информация на устройството ви. Научете повече"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Да не се показва пак"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> иска да показва части от <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Редактиране"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Активност на заден план"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> работи на заден план и изразходва батерия. Докоснете за преглед."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> работи на заден план от дълго време. Докоснете за преглед."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверете активните приложения"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Няма достъп до камерата на таблета от вашия <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="system_locale_title" msgid="3978041860457277638">"Системен език"</string> </resources> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index be8d5ffca090..981fbda23ae6 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -425,7 +425,7 @@ <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="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"এই অ্যাপ ব্যাকগ্রাউন্ডে চলার সময় বডি সেন্সর ডেটা অ্যাক্সেস করার অনুমতি দেওয়া হয়। এর মধ্যে হার্ট রেট, তাপমাত্রা এবং রক্তে অক্সিজেনের পরিমাণের শতাংশ সম্পর্কিত তথ্যও আছে।"</string> @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"যাচাইকরণে সমস্যা হয়েছে"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"স্ক্রিন লক ব্যবহার করুন"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"চালিয়ে যেতে আপনার স্ক্রিন লক ব্যবহার করুন"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"সেন্সর জোরে প্রেস করুন"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"আংশিক আঙ্গুলের ছাপ শনাক্ত করা হয়েছে"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"আঙ্গুলের ছাপ প্রক্রিয়া করা যায়নি৷ অনুগ্রহ করে আবার চেষ্টা করুন৷"</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"আঙ্গুলের ছাপের সেন্সর পরিষ্কার করে আবার চেষ্টা করুন"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"সেন্সর পরিষ্কার করে আবার চেষ্টা করুন"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"আঙ্গুলের ছাপ শনাক্ত করা যায়নি"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"আঙুলের ছাপ শনাক্ত করা যায়নি"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"সেন্সর জোরে প্রেস করুন"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"আঙ্গুলের ছাপ যাচাই করা হয়েছে"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ফেস যাচাই করা হয়েছে"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ফেস যাচাই করা হয়েছে, \'কনফার্ম করুন\' বোতাম প্রেস করুন"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"<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> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"অ্যাপ পাওয়া যাচ্ছে না"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"এই সময়ে আপনার <xliff:g id="DEVICE">%1$s</xliff:g>-এ এটি অ্যাক্সেস করা যাবে না। পরিবর্তে আপনার Android TV ডিভাইস ব্যবহার করে দেখুন।"</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"এই সময়ে আপনার <xliff:g id="DEVICE">%1$s</xliff:g>-এ এটি অ্যাক্সেস করা যাবে না। পরিবর্তে আপনার ট্যাবলেটে ব্যবহার করে দেখুন।"</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"এই সময়ে আপনার <xliff:g id="DEVICE">%1$s</xliff:g>-এ এটি অ্যাক্সেস করা যাবে না। পরিবর্তে আপনার ফোনে ব্যবহার করে দেখুন।"</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"যাই হোক, খুলতে চাই"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"ক্ষতিকর অ্যাপ শনাক্ত করা হয়েছে"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> অ্যাপকে ডিভাইসের সব লগ অ্যাক্সেসের অনুমতি দিতে চান?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"এককালীন অ্যাক্সেসের অনুমতি দিন"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"শুধুমাত্র এখন"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"অনুমতি দেবেন না"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"ডিভাইস লগে আপনার ডিভাইসে করা অ্যাক্টিভিটি রেকর্ড করা হয়। বিভিন্ন সমস্যা খুঁজে তা সমাধান করতে, অ্যাপ এইসব লগ ব্যবহার করতে পারে।\n\nকিছু লগে সংবেদনশীল তথ্য থাকতে পারে, তাই বিশ্বাস করেন শুধুমাত্র এমন অ্যাপকেই সব ডিভাইসের লগ অ্যাক্সেসের অনুমতি দিন। \n\nআপনি এই অ্যাপকে ডিভাইসের সব লগ অ্যাক্সেস করার অনুমতি না দিলেও, এটি নিজে লগ অ্যাক্সেস করতে পারবে। ডিভাইস প্রস্তুতকারকও আপনার ডিভাইসের কিছু লগ বা তথ্য হয়ত অ্যাক্সেস করতে পারবে। আরও জানুন"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"আর দেখতে চাই না"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> অ্যাপটি <xliff:g id="APP_2">%2$s</xliff:g> এর অংশ দেখাতে চায়"</string> <string name="screenshot_edit" msgid="7408934887203689207">"এডিট করুন"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ব্যাটারির আয়ুকে প্রভাবিত করতে পারে। চালু থাকা অ্যাপ পর্যালোচনা করতে ট্যাপ করুন।"</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"ব্যাকগ্রাউন্ড অ্যাক্টিভিটি"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ব্যাকগ্রাউন্ডে চলছে এবং এর ফলে ব্যাটারির চার্জ কমে যাচ্ছে। পর্যালোচনা করতে ট্যাপ করুন।"</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"আপনার <xliff:g id="DEVICE">%1$s</xliff:g> থেকে ট্যাবলেটের ক্যামেরা অ্যাক্সেস করা যাচ্ছে না"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"সিস্টেমের ভাষা"</string> </resources> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 5c6291d4222c..2114862b8c7d 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -586,7 +586,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Greška pri autentifikaciji"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Koristi zaključavanje ekrana"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Unesite zaključavanje ekrana da nastavite"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Čvrsto pritisnite senzor"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Otkriven je djelimični otisak prsta"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Obrada otiska prsta nije uspjela. Pokušajte ponovo."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Očistite senzor za otisak prsta i pokušajte ponovo"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Očistite senzor i pokušajte ponovo"</string> @@ -599,7 +599,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Otisak prsta nije prepoznat"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Otisak prsta nije prepoznat"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Čvrsto pritisnite senzor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisak prsta je potvrđen"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Lice je provjereno"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Lice je provjereno, pritisnite dugme za potvrdu"</string> @@ -1680,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"Ako uključite uslugu <xliff:g id="SERVICE">%1$s</xliff:g>, uređaj neće koristiti zaključavanje ekrana za poboljšanje šifriranja podataka."</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_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> @@ -1933,7 +1934,7 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string> <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> + <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Potrebno je dopuštenje"</string> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Trenutno ne možete pristupiti ovoj aplikaciji na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Umjesto toga pokušajte na uređaju Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Trenutno ne možete pristupiti ovoj aplikaciji na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Umjesto toga pokušajte na tabletu."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Trenutno ne možete pristupiti ovoj aplikaciji na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Umjesto toga pokušajte na telefonu."</string> @@ -2027,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"IPAK OTVORI"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Otkrivena je štetna aplikacija"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Dozvoliti aplikaciji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> da pristupa svim zapisnicima uređaja?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Omogući jednokratni pristup"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Samo ovaj put"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nemoj dozvoliti"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Zapisnici uređaja bilježe šta se dešava na uređaju. Aplikacije mogu koristiti te zapisnike da pronađu i isprave probleme.\n\nNeki zapisnici mogu sadržavati osjetljive podatke. Zato pristup svim zapisnicima uređaja dozvolite samo aplikacijama kojima vjerujete. \n\nAko ne dozvolite ovoj aplikaciji da pristupa svim zapisnicima uređaja, ona i dalje može pristupati svojim zapisnicima. Proizvođač uređaja će možda i dalje biti u stanju pristupiti nekim zapisnicima ili podacima na uređaju. Saznajte više"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne prikazuj ponovo"</string> <string name="slices_permission_request" msgid="3677129866636153406">"Aplikacija <xliff:g id="APP_0">%1$s</xliff:g> želi prikazati isječke aplikacije <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Uredi"</string> @@ -2259,12 +2261,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Aktivnost u pozadini"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> radi u pozadini i troši bateriju. Dodirnite da pregledate."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> dugo radi u pozadini. Dodirnite da pregledate."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nije moguće pristupiti kameri tableta s uređaja <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Jezik sistema"</string> </resources> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 625ed8edfac4..9722ef5cd9c6 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -390,7 +390,7 @@ <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Aquesta aplicació pot mostrar-se a sobre d\'altres aplicacions"</string> <string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"Aquesta aplicació pot mostrar-se a sobre d\'altres aplicacions o d\'altres parts de la pantalla. Això pot interferir en l\'ús normal de les aplicacions i alterar la manera en què es mostren."</string> <string name="permlab_runInBackground" msgid="541863968571682785">"Executar en segon pla"</string> - <string name="permdesc_runInBackground" msgid="4344539472115495141">"Aquesta aplicació es pot executar en segon pla. Això pot exhaurir la bateria més ràpidament."</string> + <string name="permdesc_runInBackground" msgid="4344539472115495141">"Aquesta aplicació es pot executar en segon pla. Això consumeix la bateria més ràpidament."</string> <string name="permlab_useDataInBackground" msgid="783415807623038947">"Utilitzar dades en segon pla"</string> <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Aquesta aplicació utilitza dades en segon pla. Això incrementa l\'ús de dades."</string> <string name="permlab_persistentActivity" msgid="464970041740567970">"fes que l\'aplicació s\'executi sempre"</string> @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Error en l\'autenticació"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utilitza el bloqueig de pantalla"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Introdueix el teu bloqueig de pantalla per continuar"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"S\'ha detectat una empremta digital parcial"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No s\'ha pogut processar l\'empremta digital. Torna-ho a provar."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Neteja el sensor d\'empremtes digitals i torna-ho a provar"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Neteja el sensor i torna-ho a provar"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"L\'empremta digital no s\'ha reconegut"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Prem el sensor de manera ferma"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"L\'empremta digital s\'ha autenticat"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Cara autenticada"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Cara autenticada; prem el botó per confirmar"</string> @@ -1681,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ACTIVAT"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DESACTIVAT"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vols permetre que <xliff:g id="SERVICE">%1$s</xliff:g> controli el teu dispositiu per complet?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Si actives <xliff:g id="SERVICE">%1$s</xliff:g>, el dispositiu no farà servir el bloqueig de pantalla per millorar l\'encriptació de dades."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"El control total és adequat per a les aplicacions que t\'ajuden amb l\'accessibilitat, però no per a la majoria de les aplicacions."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Veure i controlar la pantalla"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Pot llegir tot el contingut de la pantalla i mostrar contingut sobre altres aplicacions."</string> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"L\'aplicació no està disponible"</string> <string name="app_blocked_message" msgid="542972921087873023">"Ara mateix, <xliff:g id="APP_NAME">%1$s</xliff:g> no està disponible."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> no està disponible"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permís necessari"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"En aquests moments, no es pot accedir a aquesta aplicació al dispositiu <xliff:g id="DEVICE">%1$s</xliff:g>. Prova-ho al dispositiu Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"En aquests moments, no es pot accedir a aquesta aplicació al dispositiu <xliff:g id="DEVICE">%1$s</xliff:g>. Prova-ho a la tauleta."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"En aquests moments, no es pot accedir a aquesta aplicació al dispositiu <xliff:g id="DEVICE">%1$s</xliff:g>. Prova-ho al telèfon."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OBRE IGUALMENT"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"S\'ha detectat una aplicació perjudicial"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Vols permetre que <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> accedeixi a tots els registres del dispositiu?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Només aquesta vegada"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"No permetis"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Els registres del dispositiu inclouen informació sobre tot allò que passa al teu dispositiu. Les aplicacions poden utilitzar aquests registres per detectar i corregir problemes.\n\nÉs possible que alguns registres continguin informació sensible; per això només has de donar-hi accés a les aplicacions de confiança. \n\nEncara que no permetis que aquesta aplicació pugui accedir a tots els registres del dispositiu, podrà accedir als seus propis registres. És possible que el fabricant del dispositiu també tingui accés a alguns registres o a informació del teu dispositiu. Més informació"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"No tornis a mostrar"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> vol mostrar porcions de l\'aplicació <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Edita"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Activitat en segon pla"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> s\'està executant en segon pla i esgotant la bateria. Toca per revisar-ho."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Fa molta estona que <xliff:g id="APP">%1$s</xliff:g> s\'està executant en segon pla. Toca per revisar-ho."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Consulta les aplicacions actives"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No es pot accedir a la càmera de la tauleta des del teu <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="system_locale_title" msgid="3978041860457277638">"Idioma del sistema"</string> </resources> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 97f150e06977..8bcb834b3b26 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -587,8 +587,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Při ověřování došlo k chybě"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Použít zámek obrazovky"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Pokračujte zadáním zámku obrazovky"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Byla zjištěna jen část otisku prstu"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Zpracování otisku prstu se nezdařilo. Zkuste to znovu."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Vyčistěte snímač otisků prstů a zkuste to znovu"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Vyčistěte senzor a zkuste to znovu"</string> @@ -601,8 +600,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Otisk prstu nebyl rozpoznán"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Pevně zatlačte na senzor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisk byl ověřen"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Obličej byl ověřen"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Obličej byl ověřen, stiskněte tlačítko pro potvrzení"</string> @@ -1683,6 +1681,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ZAP"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"VYP"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Chcete službě <xliff:g id="SERVICE">%1$s</xliff:g> povolit plnou kontrolu nad vaším zařízením?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Pokud zapnete službu <xliff:g id="SERVICE">%1$s</xliff:g>, zařízení nebude používat zámek obrazovky k vylepšení šifrování dat."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Plná kontrola je vhodná u aplikací, které vám pomáhají s usnadněním přístupu. U většiny aplikací však vhodná není."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Zobrazení a ovládání obrazovky"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Služba může číst veškerý obsah obrazovky a zobrazovat ho přes ostatní aplikace."</string> @@ -1936,7 +1935,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikace není k dispozici"</string> <string name="app_blocked_message" msgid="542972921087873023">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> v tuto chvíli není k dispozici."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> není k dispozici"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Je vyžadováno oprávnění"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Tato položka na vašem zařízení <xliff:g id="DEVICE">%1$s</xliff:g> v tuto chvíli není k dispozici. Zkuste to na zařízení Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Tato položka na vašem zařízení <xliff:g id="DEVICE">%1$s</xliff:g> v tuto chvíli není k dispozici. Zkuste to na tabletu."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Tato položka na vašem zařízení <xliff:g id="DEVICE">%1$s</xliff:g> v tuto chvíli není k dispozici. Zkuste to na telefonu."</string> @@ -2030,10 +2030,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"PŘESTO OTEVŘÍT"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Byla zjištěna škodlivá aplikace"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Povolit aplikaci <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> přístup ke všem protokolům zařízení?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Pouze tentokrát"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nepovolovat"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Do protokolů zařízení se zaznamenává, co se na zařízení děje. Aplikace tyto protokoly mohou používat k vyhledání a odstranění problémů.\n\nNěkteré protokoly mohou zahrnovat citlivé údaje. Přístup k protokolům zařízení proto povolte pouze aplikacím, kterým důvěřujete. \n\nPokud této aplikaci nepovolíte přístup ke všem protokolům zařízení, bude mít stále přístup ke svým vlastním protokolům. Výrobce zařízení může mít stále přístup k některým protokolům nebo informacím na vašem zařízení. Další informace"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Příště nezobrazovat"</string> <string name="slices_permission_request" msgid="3677129866636153406">"Aplikace <xliff:g id="APP_0">%1$s</xliff:g> chce zobrazovat ukázky z aplikace <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Upravit"</string> @@ -2263,16 +2263,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Aktivita na pozadí"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikace <xliff:g id="APP">%1$s</xliff:g> je spuštěna na pozadí a vybíjí baterii. Klepnutím ji zkontrolujete."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikace <xliff:g id="APP">%1$s</xliff:g> je už dlouhou dobu spuštěna na pozadí. Klepnutím ji zkontrolujete."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Zkontrolujte aktivní aplikace"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ze zařízení <xliff:g id="DEVICE">%1$s</xliff:g> nelze získat přístup k fotoaparátu tabletu"</string> <string name="system_locale_title" msgid="3978041860457277638">"Jazyk systému"</string> </resources> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index c55b38e8eedb..5a2787d2d11b 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Der opstod fejl i forbindelse med godkendelse"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Brug skærmlås"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Angiv din skærmlås for at fortsætte"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Et delvist fingeraftryk blev registreret"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Fingeraftrykket kunne ikke behandles. Prøv igen."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Rengør fingeraftrykslæseren, og prøv igen"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Rengør læseren, og prøv igen"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Fingeraftrykket blev ikke genkendt"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Hold fingeren nede på læseren"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeraftrykket blev godkendt"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Ansigtet er godkendt"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ansigtet er godkendt. Tryk på Bekræft."</string> @@ -1681,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"TIL"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"FRA"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vil du give <xliff:g id="SERVICE">%1$s</xliff:g> fuld kontrol over din enhed?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Hvis du aktiverer <xliff:g id="SERVICE">%1$s</xliff:g>, vil enheden ikke benytte skærmlåsen til at forbedre datakrypteringen."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Fuld kontrol er velegnet til apps, der hjælper dig med hjælpefunktioner, men ikke de fleste apps."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Se og styre skærm"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Den kan læse alt indhold på skærmen og vise indhold oven på andre apps."</string> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Appen er ikke tilgængelig"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ikke tilgængelig lige nu."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> er ikke understøttet"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Der kræves tilladelse"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Du har ikke adgang til denne app på din <xliff:g id="DEVICE">%1$s</xliff:g> på nuværende tidspunkt. Prøv på din Android TV-enhed i stedet."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Du har ikke adgang til denne app på din <xliff:g id="DEVICE">%1$s</xliff:g> på nuværende tidspunkt. Prøv på din tablet i stedet."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Du har ikke adgang til denne app på din <xliff:g id="DEVICE">%1$s</xliff:g> på nuværende tidspunkt. Prøv på din telefon i stedet."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ÅBN ALLIGEVEL"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Der er registreret en skadelig app"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Vil du give <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> adgang til alle enhedslogs?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Kun denne gang"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Tillad ikke"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Enhedslogs registrerer, hvad der sker på din enhed. Apps kan bruge disse logs til at finde og løse problemer.\n\nNogle logs kan indeholde følsomme oplysninger, så giv kun apps, du har tillid til, adgang til alle enhedslogs. \n\nSelvom du ikke giver denne app adgang til alle enhedslogs, kan den stadig tilgå sine egne logs. Producenten af din enhed kan muligvis fortsat tilgå visse logs eller oplysninger på din enhed. Få flere oplysninger"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Vis ikke igen"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> anmoder om tilladelse til at vise eksempler fra <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Rediger"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Aktivitet i baggrunden"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> kører i baggrunden og dræner batteriet. Tryk for at gennemgå."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> har kørt i baggrunden i lang tid. Tryk for at gennemgå."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Tjek aktive apps"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Kameraet på din tablet kan ikke tilgås via din <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="system_locale_title" msgid="3978041860457277638">"Systemsprog"</string> </resources> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 824e1c4e3665..41f78e8e4a5b 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Fehler bei der Authentifizierung"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Displaysperre verwenden"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Displaysperre eingeben, um fortzufahren"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Fingerabdruck wurde nur teilweise erkannt"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Fingerabdruck konnte nicht verarbeitet werden. Bitte versuche es noch einmal."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Reinige den Fingerabdrucksensor und versuch es noch einmal"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Reinige den Sensor und versuche es noch einmal"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Fingerabdruck nicht erkannt"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Drücke fest auf den Sensor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerabdruck wurde authentifiziert"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Gesicht authentifiziert"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Gesicht authentifiziert, bitte bestätigen"</string> @@ -1681,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AN"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"AUS"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> die vollständige Kontrolle über dein Gerät geben?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Wenn du <xliff:g id="SERVICE">%1$s</xliff:g> aktivierst, verwendet dein Gerät nicht die Displaysperre, um die Datenverschlüsselung zu verbessern."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Die vollständige Kontrolle sollte nur für Apps aktiviert werden, die dir Zugang zu App-Funktionen erleichtern. Das ist in der Regel nur ein kleiner Teil der Apps."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Bildschirm aufrufen und steuern"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Die Funktion kann alle Inhalte auf dem Bildschirm lesen und diese Inhalte über andere Apps anzeigen."</string> @@ -1851,8 +1850,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Von deinem Administrator aktualisiert"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Von deinem Administrator gelöscht"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Der Energiesparmodus aktiviert das dunkle Design. Hintergrundaktivitäten, einige Funktionen und optische Effekte und manche Netzwerkverbindungen werden eingeschränkt oder deaktiviert."</string> - <string name="battery_saver_description" msgid="8518809702138617167">"Der Energiesparmodus aktiviert das dunkle Design. Hintergrundaktivitäten, einige Funktionen und optische Effekte und manche Netzwerkverbindungen werden eingeschränkt oder deaktiviert."</string> + <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Der Energiesparmodus aktiviert das dunkle Design und schränkt Hintergrundaktivitäten, einige Funktionen und optische Effekte sowie manche Netzwerkverbindungen ein oder deaktiviert sie."</string> + <string name="battery_saver_description" msgid="8518809702138617167">"Der Energiesparmodus aktiviert das dunkle Design und schränkt Hintergrundaktivitäten, einige Funktionen und optische Effekte und manche Netzwerkverbindungen ein oder deaktiviert sie."</string> <string name="data_saver_description" msgid="4995164271550590517">"Der Datensparmodus verhindert, dass manche Apps im Hintergrund Daten senden oder empfangen, sodass weniger Daten verbraucht werden. Auch werden die Datenzugriffe der gerade aktiven App eingeschränkt, was z. B. dazu führen kann, dass Bilder erst angetippt werden müssen, bevor sie sichtbar werden."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Datensparmodus aktivieren?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Aktivieren"</string> @@ -2028,10 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"TROTZDEM ÖFFNEN"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Schädliche App erkannt"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> den Zugriff auf alle Geräteprotokolle erlauben?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Nur dieses Mal"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nicht zulassen"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"In Geräteprotokollen wird aufgezeichnet, welche Aktionen auf deinem Gerät ausgeführt werden. Apps können sie verwenden, um Probleme zu finden und zu beheben.\n\nEinige Protokolle enthalten unter Umständen vertrauliche Informationen, daher solltest du nur vertrauenswürdigen Apps den Zugriff auf alle Geräteprotokolle erlauben. \n\nWenn du dieser App keinen Zugriff auf alle Geräteprotokolle gewährst, kann sie trotzdem auf ihre eigenen Protokolle zugreifen. Dein Gerätehersteller hat möglicherweise auch Zugriff auf einige Protokolle oder Informationen auf deinem Gerät. Weitere Informationen"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Nicht mehr anzeigen"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> möchte Teile von <xliff:g id="APP_2">%2$s</xliff:g> anzeigen"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Bearbeiten"</string> @@ -2261,16 +2260,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Hintergrundaktivität"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> wird im Hintergrund ausgeführt und belastet den Akku. Zum Prüfen tippen."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> wird schon längere Zeit im Hintergrund ausgeführt. Zum Prüfen tippen."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Aktive Apps prüfen"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Zugriff auf die Kamera des Tablets über dein Gerät (<xliff:g id="DEVICE">%1$s</xliff:g>) nicht möglich"</string> <string name="system_locale_title" msgid="3978041860457277638">"Systemsprache"</string> </resources> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 7776709e92c8..f4cb633ecec6 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Σφάλμα κατά τον έλεγχο ταυτότητας"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Χρήση κλειδώματος οθόνης"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Χρησιμοποιήστε το κλείδωμα οθόνης για να συνεχίσετε"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Πιέστε σταθερά τον αισθητήρα"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Εντοπίστηκε μέρους του δακτυλικού αποτυπώματος"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Δεν ήταν δυνατή η επεξεργασία του δακτυλικού αποτυπώματος. Δοκιμάστε ξανά."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Καθαρίστε τον αισθητήρα δακτυλικών αποτυπωμάτων και δοκιμάστε ξανά"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Καθαρίστε τον αισθητήρα και δοκιμάστε ξανά"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Δεν είναι δυνατή η αναγνώριση του δακτυλικού αποτυπώματος"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Δεν είναι δυνατή η αναγνώριση του δακτυλικού αποτυπώματος"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Πιέστε σταθερά τον αισθητήρα"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Η ταυτότητα του δακτυλικού αποτυπώματος ελέγχθηκε"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Έγινε έλεγχος ταυτότητας προσώπου"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Έγινε έλεγχος ταυτότητας προσώπου, πατήστε \"Επιβεβαίωση\""</string> @@ -1344,7 +1344,7 @@ <string name="no_permissions" msgid="5729199278862516390">"Δεν απαιτούνται άδειες"</string> <string name="perm_costs_money" msgid="749054595022779685">"ενδέχεται να χρεωθείτε"</string> <string name="dlg_ok" msgid="5103447663504839312">"ΟΚ"</string> - <string name="usb_charging_notification_title" msgid="1674124518282666955">"Φόρτιση μέσω USB"</string> + <string name="usb_charging_notification_title" msgid="1674124518282666955">"Φόρτιση αυτής της συσκευής μέσω USB"</string> <string name="usb_supplying_notification_title" msgid="5378546632408101811">"Φόρτιση συνδεδεμένης συσκευής μέσω USB"</string> <string name="usb_mtp_notification_title" msgid="1065989144124499810">"Η μεταφορά αρχείων μέσω USB ενεργοποιήθηκε"</string> <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Η λειτουργία PTP μέσω USB ενεργοποιήθηκε"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"Εάν ενεργοποιήσετε την υπηρεσία <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> @@ -1852,7 +1853,7 @@ <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_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> <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{Για 1 λ. (μέχρι τις {formattedTime})}other{Για # λ. (μέχρι τις {formattedTime})}}"</string> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Η εφαρμογή δεν είναι διαθέσιμη"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Δεν είναι δυνατή η πρόσβαση στη συγκεκριμένη εφαρμογή από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g> αυτήν τη στιγμή. Δοκιμάστε στη συσκευή Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Δεν είναι δυνατή η πρόσβαση στη συγκεκριμένη εφαρμογή από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g> αυτήν τη στιγμή. Δοκιμάστε στο tablet σας."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Δεν είναι δυνατή η πρόσβαση στη συγκεκριμένη εφαρμογή από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g> αυτήν τη στιγμή. Δοκιμάστε στο τηλέφωνό σας."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ΑΝΟΙΓΜΑ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Εντοπίστηκε επιβλαβής εφαρμογή"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Να επιτρέπεται στην εφαρμογή <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> η πρόσβαση σε όλα τα αρχεία καταγραφής συσκευής;"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Να επιτρέπεται η πρόσβαση για μία φορά"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Μόνο αυτήν τη φορά"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Να μην επιτραπεί"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Τα αρχεία καταγραφής συσκευής καταγράφουν ό,τι συμβαίνει στη συσκευή σας. Οι εφαρμογές μπορούν να χρησιμοποιούν αυτά τα αρχεία καταγραφής για να εντοπίζουν και να διορθώνουν ζητήματα.\n\nΟρισμένα αρχεία καταγραφής ενδέχεται να περιέχουν ευαίσθητες πληροφορίες. Ως εκ τούτου, επιτρέψτε την πρόσβαση σε όλα τα αρχεία καταγραφής συσκευής μόνο στις εφαρμογές που εμπιστεύεστε. \n\nΕάν δεν επιτρέψετε σε αυτήν την εφαρμογή την πρόσβαση σε όλα τα αρχεία καταγραφής συσκευής, η εφαρμογή εξακολουθεί να έχει πρόσβαση στα δικά της αρχεία καταγραφής. Ο κατασκευαστής της συσκευής σας ενδέχεται να εξακολουθεί να έχει πρόσβαση σε ορισμένα αρχεία καταγραφής ή ορισμένες πληροφορίες στη συσκευή σας. Μάθετε περισσότερα"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Να μην εμφανισ. ξανά"</string> <string name="slices_permission_request" msgid="3677129866636153406">"Η εφαρμογή <xliff:g id="APP_0">%1$s</xliff:g> θέλει να εμφανίζει τμήματα της εφαρμογής <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Επεξεργασία"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"Η εφαρμογή <xliff:g id="APP">%1$s</xliff:g> μπορεί να επηρεάσει τη διάρκεια ζωής μπαταρίας. Πατήστε για έλεγχο των ενεργών εφαρμογών."</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Δραστηριότητα στο παρασκήνιο"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Το <xliff:g id="APP">%1$s</xliff:g> εκτελείται στο παρασκήνιο και καταναλώνει μπαταρία. Έλεγχος."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Η εφαρμογή <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Δεν είναι δυνατή η πρόσβαση στην κάμερα του tablet από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Γλώσσα συστήματος"</string> </resources> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 21364cfc920c..cdb3dd7b42c7 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Enter your screen lock to continue"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Press firmly on the sensor"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Partial fingerprint detected"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Clean fingerprint sensor and try again"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Clean sensor and try again"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Fingerprint not recognised"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Fingerprint not recognised"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Press firmly on the sensor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Face authenticated"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated. Please press confirm"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ON"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"OFF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Allow <xliff:g id="SERVICE">%1$s</xliff:g> to have full control of your device?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"If you turn on <xliff:g id="SERVICE">%1$s</xliff:g>, your device won’t use your screen lock to enhance data encryption."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Full control is appropriate for apps that help you with accessibility needs, but not for most apps."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"View and control screen"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"It can read all content on the screen and display content over other apps."</string> @@ -2026,9 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OPEN ANYWAY"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Harmful app detected"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Allow one-time access"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Only this time"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Don’t allow"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device. Learn more"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Don’t show again"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wants to show <xliff:g id="APP_2">%2$s</xliff:g> slices"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string> @@ -2258,12 +2260,13 @@ <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_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_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_title_abusive_bg_apps" msgid="344582472797982073">"Background activity"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> is running in the background and draining battery. Tap to review."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"System language"</string> </resources> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 1d138e81a274..e816f162e0db 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Enter your screen lock to continue"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Press firmly on the sensor"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Partial fingerprint detected"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Clean fingerprint sensor and try again"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Clean sensor and try again"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Fingerprint not recognised"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Fingerprint not recognised"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Press firmly on the sensor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Face authenticated"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated. Please press confirm"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ON"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"OFF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Allow <xliff:g id="SERVICE">%1$s</xliff:g> to have full control of your device?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"If you turn on <xliff:g id="SERVICE">%1$s</xliff:g>, your device won’t use your screen lock to enhance data encryption."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Full control is appropriate for apps that help you with accessibility needs, but not for most apps."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"View and control screen"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"It can read all content on the screen and display content over other apps."</string> @@ -2026,9 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OPEN ANYWAY"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Harmful app detected"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Allow one-time access"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Only this time"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Don’t allow"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device. Learn more"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Don’t show again"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wants to show <xliff:g id="APP_2">%2$s</xliff:g> slices"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string> @@ -2258,12 +2260,13 @@ <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_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_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_title_abusive_bg_apps" msgid="344582472797982073">"Background activity"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> is running in the background and draining battery. Tap to review."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"System language"</string> </resources> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 9bff4c6401c0..63515c252154 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Enter your screen lock to continue"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Press firmly on the sensor"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Partial fingerprint detected"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Clean fingerprint sensor and try again"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Clean sensor and try again"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Fingerprint not recognised"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Fingerprint not recognised"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Press firmly on the sensor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Face authenticated"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated. Please press confirm"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ON"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"OFF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Allow <xliff:g id="SERVICE">%1$s</xliff:g> to have full control of your device?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"If you turn on <xliff:g id="SERVICE">%1$s</xliff:g>, your device won’t use your screen lock to enhance data encryption."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Full control is appropriate for apps that help you with accessibility needs, but not for most apps."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"View and control screen"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"It can read all content on the screen and display content over other apps."</string> @@ -2026,9 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OPEN ANYWAY"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Harmful app detected"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Allow one-time access"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Only this time"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Don’t allow"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device. Learn more"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Don’t show again"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wants to show <xliff:g id="APP_2">%2$s</xliff:g> slices"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string> @@ -2258,12 +2260,13 @@ <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_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_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_title_abusive_bg_apps" msgid="344582472797982073">"Background activity"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> is running in the background and draining battery. Tap to review."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"System language"</string> </resources> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index b8aabb04ecb5..e2f9440fac87 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Enter your screen lock to continue"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Press firmly on the sensor"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Partial fingerprint detected"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Clean fingerprint sensor and try again"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Clean sensor and try again"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Fingerprint not recognised"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Fingerprint not recognised"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Press firmly on the sensor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Face authenticated"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated. Please press confirm"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ON"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"OFF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Allow <xliff:g id="SERVICE">%1$s</xliff:g> to have full control of your device?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"If you turn on <xliff:g id="SERVICE">%1$s</xliff:g>, your device won’t use your screen lock to enhance data encryption."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Full control is appropriate for apps that help you with accessibility needs, but not for most apps."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"View and control screen"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"It can read all content on the screen and display content over other apps."</string> @@ -2026,9 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OPEN ANYWAY"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Harmful app detected"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Allow one-time access"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Only this time"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Don’t allow"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device. Learn more"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Don’t show again"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wants to show <xliff:g id="APP_2">%2$s</xliff:g> slices"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string> @@ -2258,12 +2260,13 @@ <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_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_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_title_abusive_bg_apps" msgid="344582472797982073">"Background activity"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> is running in the background and draining battery. Tap to review."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"System language"</string> </resources> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index ec32bd371c54..05545337303d 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Error authenticating"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Enter your screen lock to continue"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Press firmly on the sensor"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Partial fingerprint detected"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Clean fingerprint sensor and try again"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Clean sensor and try again"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Fingerprint not recognized"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Fingerprint not recognized"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Press firmly on the sensor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Face authenticated"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Face authenticated, please press confirm"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ON"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"OFF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Allow <xliff:g id="SERVICE">%1$s</xliff:g> to have full control of your device?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"If you turn on <xliff:g id="SERVICE">%1$s</xliff:g>, your device won’t use your screen lock to enhance data encryption."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Full control is appropriate for apps that help you with accessibility needs, but not for most apps."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"View and control screen"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"It can read all content on the screen and display content over other apps."</string> @@ -2026,9 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OPEN ANYWAY"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Harmful app detected"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Allow <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> to access all device logs?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Allow one-time access"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Only this time"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Don’t allow"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device. Learn more"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Don’t show again"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wants to show <xliff:g id="APP_2">%2$s</xliff:g> slices"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string> @@ -2258,12 +2260,13 @@ <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_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_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_title_abusive_bg_apps" msgid="344582472797982073">"Background Activity"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> is running in the background and draining battery. Tap to review."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Can’t access the tablet’s camera from your <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"System language"</string> </resources> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 72bb36329e32..db06ff278c69 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Error de autenticación"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueo de pantalla"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Ingresa tu bloqueo de pantalla para continuar"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Presiona con firmeza el sensor"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Detección parcial de una huella dactilar"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No se pudo procesar la huella dactilar. Vuelve a intentarlo."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpia el sensor de huellas dactilares y vuelve a intentarlo"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpia el sensor y vuelve a intentarlo"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"No se reconoció la huella dactilar"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"No se reconoció la huella dactilar"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Presiona con firmeza el sensor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Se autenticó la huella dactilar"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Se autenticó el rostro"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Se autenticó el rostro; presiona Confirmar"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"SÍ"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"NO"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"¿Deseas permitir que <xliff:g id="SERVICE">%1$s</xliff:g> tenga el control total del dispositivo?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Si activas <xliff:g id="SERVICE">%1$s</xliff:g>, el dispositivo no utilizará el bloqueo de pantalla para mejorar la encriptación de datos."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"El control total es apropiado para las apps que te ayudan con las necesidades de accesibilidad, pero no para la mayoría de las apps."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ver y controlar la pantalla"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Puede leer todo el contenido en la pantalla y mostrarlo sobre otras apps."</string> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"La app no está disponible"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> no está disponible en este momento."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> no disponible"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Se necesitan permisos"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Por el momento, no se puede acceder a esto en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Inténtalo en tu dispositivo Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Por el momento, no se puede acceder a esto en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Inténtalo en tu tablet."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Por el momento, no se puede acceder a esto en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Inténtalo en tu teléfono."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ABRIR DE TODOS MODOS"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Se detectó una app dañina"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"¿Quieres permitir que <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acceda a todos los registros del dispositivo?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Permitir acceso por única vez"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Solo esta vez"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"No permitir"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Los registros del dispositivo permiten documentar lo que sucede en él. Las apps pueden usarlos para encontrar y solucionar problemas.\n\nEs posible que algunos registros del dispositivo contengan información sensible, por lo que solo permitimos que accedan a todos ellos apps de tu confianza. \n\nSi no permites que esta app acceda a todos los registros del dispositivo, aún puede acceder a sus propios registros. Además, es posible que el fabricante del dispositivo acceda a algunos registros o información en tu dispositivo. Más información"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"No volver a mostrar"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> quiere mostrar fragmentos de <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Editar"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Actividad en segundo plano"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> se está ejecutando en segundo plano y está agotando la batería. Presiona para revisar."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Hace mucho tiempo que <xliff:g id="APP">%1$s</xliff:g> se está ejecutando en segundo plano. Presiona para revisar esta actividad."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No se puede acceder a la cámara de la tablet desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Idioma del sistema"</string> </resources> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 62add2327e3b..dbaf2819a8c0 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"No se ha podido autenticar"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueo de pantalla"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Introduce tu bloqueo de pantalla para continuar"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Huella digital parcial detectada"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No se ha podido procesar la huella digital. Vuelve a intentarlo."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpia el sensor de huellas digitales e inténtalo de nuevo"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpia el sensor e inténtalo de nuevo"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Huella digital no reconocida"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Mantén pulsado firmemente el sensor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Se ha autenticado la huella digital"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Cara autenticada"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Se ha autenticado la cara, pulsa para confirmar"</string> @@ -1681,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ACTIVADO"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"NO"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"¿Permitir que <xliff:g id="SERVICE">%1$s</xliff:g> pueda controlar totalmente tu dispositivo?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Si activas <xliff:g id="SERVICE">%1$s</xliff:g>, el dispositivo no utilizará el bloqueo de pantalla para mejorar el cifrado de datos."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"El control total es adecuado para las aplicaciones de accesibilidad, pero no para la mayoría de las aplicaciones."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ver y controlar la pantalla"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Puede leer todo el contenido de la pantalla y mostrar contenido encima de otras aplicaciones."</string> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"La aplicación no está disponible"</string> <string name="app_blocked_message" msgid="542972921087873023">"En estos momentos, <xliff:g id="APP_NAME">%1$s</xliff:g> no está disponible."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> no disponible"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Se necesita permiso"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"En estos momentos, no se puede acceder a este contenido en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Prueba en tu dispositivo Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"En estos momentos, no se puede acceder a este contenido en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Prueba en tu tablet."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"En estos momentos, no se puede acceder a este contenido en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Prueba en tu teléfono."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ABRIR IGUALMENTE"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Se ha detectado una aplicación dañina"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"¿Permitir que <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acceda a todos los registros del dispositivo?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Solo esta vez"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"No permitir"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Los registros del dispositivo documentan lo que sucede en tu dispositivo. Las aplicaciones pueden usar estos registros para encontrar y solucionar problemas.\n\nComo algunos registros pueden contener información sensible, es mejor que solo permitas que accedan a ellos las aplicaciones en las que confíes. \n\nAunque no permitas que esta aplicación acceda a todos los registros del dispositivo, aún podrá acceder a sus propios registros. Es posible que el fabricante del dispositivo pueda acceder a algunos registros o información de tu dispositivo. Más información"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"No volver a mostrar"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> quiere mostrar fragmentos de <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Editar"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Actividad en segundo plano"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> se está ejecutando en segundo plano y agotando batería. Toca para revisarlo."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> lleva mucho tiempo ejecutándose en segundo plano. Toca para revisarlo."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Consultar aplicaciones activas"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No se puede acceder a la cámara del tablet desde tu <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="system_locale_title" msgid="3978041860457277638">"Idioma del sistema"</string> </resources> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 7e0ddd49f1b2..8eea04870e08 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Viga autentimisel"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekraaniluku kasutamine"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Jätkamiseks sisestage oma ekraanilukk"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Tuvastati osaline sõrmejälg"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Sõrmejälge ei õnnestunud töödelda. Proovige uuesti."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Puhastage sõrmejäljeandur ja proovige uuesti"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Puhastage andur ja proovige uuesti"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Sõrmejälge ei tuvastatud"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Vajutage tugevalt andurile"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Sõrmejälg autenditi"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Nägu on autenditud"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Nägu on autenditud, vajutage käsku Kinnita"</string> @@ -1681,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"SEES"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"VÄLJAS"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Kas anda teenusele <xliff:g id="SERVICE">%1$s</xliff:g> teie seadme üle täielik kontroll?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Kui lülitate sisse teenuse <xliff:g id="SERVICE">%1$s</xliff:g>, ei kasuta seade andmete krüpteerimise täiustamiseks ekraanilukku."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Täielik haldusõigus sobib rakendustele, mis pakuvad juurdepääsufunktsioone. Enamiku rakenduste puhul seda ei soovitata."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ekraanikuva vaatamine ja haldamine"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"See saab lugeda kogu ekraanil kuvatud sisu ja kuvada sisu rakenduste peal."</string> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Rakendus ei ole saadaval"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei ole praegu saadaval."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ei ole saadaval"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Vaja on luba"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Sellele ei pääse praegu teie seadmega (<xliff:g id="DEVICE">%1$s</xliff:g>) juurde. Proovige juurde pääseda oma Android TV seadmega."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Sellele ei pääse praegu teie seadmega (<xliff:g id="DEVICE">%1$s</xliff:g>) juurde. Proovige juurde pääseda oma tahvelarvutiga."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Sellele ei pääse praegu teie seadmega (<xliff:g id="DEVICE">%1$s</xliff:g>) juurde. Proovige juurde pääseda oma telefoniga."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"AVA IKKA"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Tuvastati kahjulik rakendus"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Kas anda rakendusele <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> juurdepääs kõigile seadmelogidele?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Ainult see kord"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ära luba"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Seadmelogid jäädvustavad, mis teie seadmes toimub. Rakendused saavad neid logisid kasutada probleemide tuvastamiseks ja lahendamiseks.\n\nMõned logid võivad sisaldada tundlikku teavet, seega lubage juurdepääs kõigile seadmelogidele ainult rakendustele, mida usaldate. \n\nKui te ei luba sellel rakendusel kõigile seadmelogidele juurde pääseda, pääseb see siiski juurde oma logidele. Teie seadme tootja võib teie seadmes siiski teatud logidele või teabele juurde pääseda. Lisateave"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ära kuva uuesti"</string> <string name="slices_permission_request" msgid="3677129866636153406">"Rakendus <xliff:g id="APP_0">%1$s</xliff:g> soovib näidata rakenduse <xliff:g id="APP_2">%2$s</xliff:g> lõike"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Muuda"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Tegevus taustal"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> töötab taustal ja kulutab akut. Puudutage ülevaatamiseks."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> on taustal töötanud kaua aega. Puudutage ülevaatamiseks."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vaadake aktiivseid rakendusi"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Teie seadmest <xliff:g id="DEVICE">%1$s</xliff:g> ei pääse tahvelarvuti kaamerale juurde"</string> <string name="system_locale_title" msgid="3978041860457277638">"Süsteemi keel"</string> </resources> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index c48559397565..4d8baccb6d6c 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -427,7 +427,7 @@ <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Telefonoaren deien erregistroa aldatzeko baimena ematen die aplikazioei, sarrerako eta irteerako deiei buruzko datuak barne. Asmo txarreko aplikazioek deien erregistroa ezabatzeko edo aldatzeko erabil dezakete."</string> <string name="permlab_bodySensors" msgid="662918578601619569">"Atzitu gorputz-sentsoreen datuak (esaterako, bihotz-maiztasuna) aplikazioa erabili bitartean"</string> <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Aplikazioak erabiltzen diren bitartean, gorputz-sentsoreen datuak (besteak beste, bihotz-maiztasuna, tenperatura eta odolean dagoen oxigenoaren ehunekoa) atzitzeko baimena ematen die aplikazio horiei."</string> - <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Atzitu gorputz-sentsoreen datuak (adib., bihotz-maiztasunarenak) atzeko planoan"</string> + <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Atzitu gorputz-sentsoreen datuak (esaterako, bihotz-maiztasuna) aplikazioa atzeko planoan dagoen bitartean"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Aplikazioak atzeko planoan egon bitartean, gorputz-sentsoreen datuak (besteak beste, bihotz-maiztasuna, tenperatura eta odolean dagoen oxigenoaren ehunekoa) atzitzeko baimena ematen die aplikazio horiei."</string> <string name="permlab_readCalendar" msgid="6408654259475396200">"irakurri egutegiko gertaerak eta xehetasunak"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Aplikazioak tabletan gordetako egutegiko gertaerak irakur ditzake eta egutegiko datuak parteka eta gorde ditzake."</string> @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Errorea autentifikatzean"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Erabili pantailaren blokeoa"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Aurrera egiteko, desblokeatu pantailaren blokeoa"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Sakatu irmo sentsorea"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Hatz-marka ez da osorik hauteman"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Ezin izan da prozesatu hatz-marka. Saiatu berriro."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Garbitu hatz-marken sentsorea eta saiatu berriro"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Garbitu sentsorea eta saiatu berriro"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Ez da ezagutu hatz-marka"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Ez da ezagutu hatz-marka"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Sakatu irmo sentsorea"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Autentifikatu da hatz-marka"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Autentifikatu da aurpegia"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Autentifikatu da aurpegia; sakatu Berretsi"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AKTIBATUTA"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DESAKTIBATUTA"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Gailua guztiz kontrolatzeko baimena eman nahi diozu <xliff:g id="SERVICE">%1$s</xliff:g> zerbitzuari?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g> aktibatzen baduzu, gailuak ez du pantailaren blokeoa erabiliko datuen enkriptatzea hobetzeko."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Erabilerraztasun-beharrak asetzen dituzten aplikazioetan da egokia kontrol osoa, baina ez aplikazio gehienetan."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ikusi eta kontrolatu pantaila"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Pantailako eduki guztia irakur dezake, eta beste aplikazioen gainean edukia bistaratu."</string> @@ -1851,7 +1852,7 @@ <string name="confirm_battery_saver" msgid="5247976246208245754">"Ados"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Bateria-aurrezleak gai iluna aktibatzen du, eta murriztu edo desaktibatu egiten ditu atzeko planoko jarduerak, zenbait efektu bisual, eta eginbide jakin eta sareko konexio batzuk."</string> <string name="battery_saver_description" msgid="8518809702138617167">"Bateria-aurrezleak gai iluna aktibatzen du, eta atzeko planoko jarduerak, zenbait efektu bisual, eta eginbide jakin eta sareko konexio batzuk murrizten edo desaktibatzen ditu."</string> - <string name="data_saver_description" msgid="4995164271550590517">"Datu-erabilera murrizteko, atzeko planoan datuak bidaltzea eta jasotzea galarazten die datu-aurrezleak aplikazio batzuei. Erabiltzen ari zaren aplikazioek datuak atzitu ahalko dituzte, baina baliteke maiztasun txikiagoarekin atzitzea. Ondorioz, adibidez, baliteke irudiak ez erakustea haiek sakatu arte."</string> + <string name="data_saver_description" msgid="4995164271550590517">"Datu-erabilera murrizteko, atzeko planoan datuak bidaltzea eta jasotzea galarazten die datu-aurrezleak aplikazio batzuei. Une honetan erabiltzen ari zaren aplikazio batek datuak atzitu ahal izango ditu, baina baliteke maiztasun txikiagoarekin atzitzea. Horrela, adibidez, baliteke irudiak ez erakustea haiek sakatu arte."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Datu-aurrezlea aktibatu nahi duzu?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Aktibatu"</string> <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Minutu batez ({formattedTime} arte)}other{# minutuz ({formattedTime} arte)}}"</string> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikazioa ez dago erabilgarri"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ez dago erabilgarri une honetan."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ez dago erabilgarri"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Baimena behar da"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Une honetan, aplikazioa ezin da <xliff:g id="DEVICE">%1$s</xliff:g> erabilita atzitu. Gailu horren ordez, erabili Android TV gailua."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Une honetan, aplikazioa ezin da <xliff:g id="DEVICE">%1$s</xliff:g> erabilita atzitu. Gailu horren ordez, erabili tableta."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Une honetan, aplikazioa ezin da <xliff:g id="DEVICE">%1$s</xliff:g> erabilita atzitu. Gailu horren ordez, erabili telefonoa."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"IREKI, HALA ERE"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Aplikazio kaltegarri bat hauteman da"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Gailuko erregistro guztiak atzitzeko baimena eman nahi diozu <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> aplikazioari?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Eman behin erabiltzeko baimena"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Oraingoan soilik"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ez eman baimenik"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Gailuko erregistroetan gailuan gertatzen den guztia gordetzen da. Arazoak bilatu eta konpontzeko erabil ditzakete aplikazioek erregistro horiek.\n\nBaliteke erregistro batzuek kontuzko informazioa edukitzea. Beraz, eman gailuko erregistro guztiak atzitzeko baimena fidagarritzat jotzen dituzun aplikazioei bakarrik. \n\nNahiz eta gailuko erregistro guztiak atzitzeko baimena ez eman aplikazio honi, aplikazioak hari dagozkion erregistroak atzitu ahalko ditu. Gainera, baliteke gailuaren fabrikatzaileak gailuko erregistro edo datu batzuk atzitu ahal izatea. Lortu informazio gehiago"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ez erakutsi berriro"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> aplikazioak <xliff:g id="APP_2">%2$s</xliff:g> aplikazioaren zatiak erakutsi nahi ditu"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Editatu"</string> @@ -2258,12 +2261,14 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Atzeko planoko jarduerak"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g>, atzeko planoan exekutatzen, eta bateria xahutzen ari da. Sakatu berrikusteko."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> aplikazioak denbora asko darama atzeko planoan exekutatzen. Sakatu berrikusteko."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ezin da atzitu tabletaren kamera <xliff:g id="DEVICE">%1$s</xliff:g> gailutik"</string> - <string name="system_locale_title" msgid="3978041860457277638">"Sistemaren hizkuntza"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> + <!-- no translation found for system_locale_title (3978041860457277638) --> + <skip /> </resources> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 678e4b3612c1..5c435a93b7e0 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"خطا هنگام اصالتسنجی"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"از قفل صفحه استفاده کنید"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"برای ادامه، قفل صفحهتان را وارد کنید"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"محکم روی حسگر فشار دهید"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"بخشی از اثر انگشت شناسایی شد"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"اثرانگشت پردازش نشد. لطفاً دوباره امتحان کنید."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"حسگر اثر انگشت را تمیز و دوباره امتحان کنید"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"حسگر را تمیز و دوباره امتحان کنید"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"اثر انگشت تشخیص داده نشد"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"اثر انگشت تشخیص داده نشد"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"محکم روی حسگر فشار دهید"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"اثر انگشت اصالتسنجی شد"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"چهره اصالتسنجی شد"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"چهره اصالتسنجی شد، لطفاً تأیید را فشار دهید"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"اگر <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> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"برنامه در دسترس نیست"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"درحالحاضر نمیتوان در <xliff:g id="DEVICE">%1$s</xliff:g> شما به این برنامه دسترسی داشت. دسترسی به آن را در دستگاه Android TV امتحان کنید."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"درحالحاضر نمیتوان در <xliff:g id="DEVICE">%1$s</xliff:g> شما به این برنامه دسترسی داشت. دسترسی به آن را در رایانه لوحیتان امتحان کنید."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"درحالحاضر نمیتوان در <xliff:g id="DEVICE">%1$s</xliff:g> شما به این برنامه دسترسی داشت. دسترسی به آن را در تلفنتان امتحان کنید."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"درهرصورت باز شود"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"برنامه مضر شناسایی شد"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"به <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> اجازه میدهید به همه گزارشهای دستگاه دسترسی داشته باشد؟"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"مجاز کردن دسترسی یکباره"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"فقط این بار"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"مجاز نیست"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"گزارشهای دستگاه آنچه را در دستگاهتان رخ میدهد ثبت میکند. برنامهها میتوانند از این گزارشها برای پیدا کردن مشکلات و رفع آنها استفاده کنند.\n\nبرخیاز گزارشها ممکن است حاوی اطلاعات حساس باشند، بنابراین فقط به برنامههای مورداعتمادتان اجازه دسترسی به همه گزارشهای دستگاه را بدهید. \n\nاگر به این برنامه اجازه ندهید به همه گزارشهای دستگاه دسترسی داشته باشد، همچنان میتواند به گزارشهای خودش دسترسی داشته باشد. سازنده دستگاه نیز ممکن است همچنان بتواند به برخیاز گزارشها یا اطلاعات دستگاهتان دسترسی داشته باشد. بیشتر بدانید"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"دوباره نشان داده نشود"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> میخواهد تکههای <xliff:g id="APP_2">%2$s</xliff:g> را نشان دهد"</string> <string name="screenshot_edit" msgid="7408934887203689207">"ویرایش"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ممکن است بر عمر باتری تأثیر بگذارد. برای مرور برنامههای فعال، ضربه بزنید."</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"فعالیت در پسزمینه"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> در پسزمینه اجرا میشود و شارژ باتری را تخلیه میکند. برای مرور، ضربه بزنید."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"نمیتوان از <xliff:g id="DEVICE">%1$s</xliff:g> شما به دوربین رایانه لوحی دسترسی داشت"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"زبان سیستم"</string> </resources> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 4c1a03c1690c..4cb8c8c10208 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Virhe todennuksessa"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Käytä näytön lukitusta"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Jatka lisäämällä näytön lukituksen avaustapa"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Osittainen sormenjälki havaittu"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Sormenjäljen prosessointi epäonnistui. Yritä uudelleen."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Puhdista sormenjälkitunnistin ja yritä uudelleen"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Puhdista anturi ja yritä uudelleen"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Sormenjälkeä ei tunnistettu"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Paina anturia voimakkaasti"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Sormenjälki tunnistettu"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Kasvot tunnistettu"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Kasvot tunnistettu, valitse Vahvista"</string> @@ -1681,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"Jos <xliff:g id="SERVICE">%1$s</xliff:g> otetaan käyttöön, laitteesi ei käytä näytön lukitusta tiedon salauksen parantamiseen."</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_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> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Sovellus ei ole käytettävissä"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei ole nyt käytettävissä."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ei käytettävissä"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Edellyttää käyttöoikeutta"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"<xliff:g id="DEVICE">%1$s</xliff:g> ei tällä hetkellä saa pääsyä sovellukseen. Kokeile striimausta Android TV ‑laitteella."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"<xliff:g id="DEVICE">%1$s</xliff:g> ei tällä hetkellä saa pääsyä sovellukseen. Kokeile striimausta tabletilla."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"<xliff:g id="DEVICE">%1$s</xliff:g> ei tällä hetkellä saa pääsyä sovellukseen. Kokeile striimausta puhelimella."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"AVAA SILTI"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Haitallinen sovellus havaittu"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Saako <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> pääsyn kaikkiin laitelokeihin?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Vain tämän kerran"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Älä salli"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Laitteen tapahtumat tallentuvat laitelokeihin. Niiden avulla sovellukset voivat löytää ja korjata ongelmia.\n\nJotkin lokit voivat sisältää arkaluontoista tietoa, joten salli pääsy kaikkiin laitelokeihin vain sovelluksille, joihin luotat. \n\nJos et salli tälle sovellukselle pääsyä kaikkiin laitelokeihin, sillä on kuitenkin pääsy sen omiin lokeihin. Laitteen valmistajalla voi olla pääsy joihinkin lokeihin tai tietoihin laitteella. Lue lisää"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Älä näytä uudelleen"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> haluaa näyttää osia sovelluksesta <xliff:g id="APP_2">%2$s</xliff:g>."</string> <string name="screenshot_edit" msgid="7408934887203689207">"Muokkaa"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Taustatoiminta"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> on käynnissä taustalla ja kuluttaa akkua. Tarkista napauttamalla."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> on ollut käynnissä taustalla pitkän aikaa. Tarkista napauttamalla."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Tarkista aktiiviset sovellukset"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> ei pääse tabletin kameraan"</string> <string name="system_locale_title" msgid="3978041860457277638">"Järjestelmän kieli"</string> </resources> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 890a7ba318b3..32b0639eaa09 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Erreur d\'authentification"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utiliser le verrouillage de l\'écran"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Entrez votre verrouillage d\'écran pour continuer"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Empreinte digitale partielle détectée"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Impossible de reconnaître l\'empreinte digitale. Veuillez réessayer."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Nettoyez le capteur d\'empreintes digitales et réessayez"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Nettoyez le capteur et réessayez"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Empreinte digitale non reconnue"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Appuyez fermement sur le capteur"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Empreinte digitale authentifiée"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Visage authentifié"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Visage authentifié, veuillez appuyer sur le bouton Confirmer"</string> @@ -1681,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ACTIVÉ"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DÉSACTIVÉ"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Permettre à <xliff:g id="SERVICE">%1$s</xliff:g> de commander complètement votre appareil?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Si vous activez <xliff:g id="SERVICE">%1$s</xliff:g>, votre appareil n\'utilisera pas le verrouillage de l\'écran pour améliorer le chiffrement des données."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Le contrôle total convient aux applications qui répondent à vos besoins d\'accessibilité. Il ne convient pas à la plupart des applications."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Afficher et commander l\'écran"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Cette fonctionnalité peut lire tout le contenu à l\'écran et afficher du contenu par-dessus d\'autres applications."</string> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"L\'application n\'est pas accessible"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas accessible pour le moment."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> non accessible"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Autorisation nécessaire"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Impossible d\'accéder à ce contenu sur votre appareil <xliff:g id="DEVICE">%1$s</xliff:g> pour le moment. Essayez sur votre appareil Android TV à la place."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Impossible d\'accéder à ce contenu sur votre appareil <xliff:g id="DEVICE">%1$s</xliff:g> pour le moment. Essayez sur votre tablette à la place."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Impossible d\'accéder à ce contenu sur votre appareil <xliff:g id="DEVICE">%1$s</xliff:g> pour le moment. Essayez sur votre téléphone à la place."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OUVRIR QUAND MÊME"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Une application nuisible a été détectée"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Autoriser <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> à accéder à l\'ensemble des journaux de l\'appareil?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Seulement cette fois"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ne pas autoriser"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Les journaux de l\'appareil enregistrent ce qui se passe sur celui-ci. Les applications peuvent utiliser ces journaux pour trouver et résoudre des problèmes.\n\nCertains journaux peuvent contenir des renseignements confidentiels. N\'autorisez donc que les applications auxquelles vous faites confiance puisque celles-ci pourront accéder à l\'ensemble des journaux de l\'appareil. \n\nMême si vous n\'autorisez pas cette application à accéder à l\'ensemble des journaux de l\'appareil, elle aura toujours accès à ses propres journaux. Le fabricant de votre appareil pourrait toujours être en mesure d\'accéder à certains journaux ou renseignements sur votre appareil. En savoir plus"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne plus afficher"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> souhaite afficher <xliff:g id="APP_2">%2$s</xliff:g> tranches"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Modifier"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Activité en arrière-plan"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> s\'exécute en arrière-plan et décharge la pile. Touchez pour examiner."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> s\'exécute en arrière-plan depuis longtemps. Touchez pour examiner."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vérifier les applications actives"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossible d\'accéder à l\'appareil photo de la tablette à partir de votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="system_locale_title" msgid="3978041860457277638">"Langue du système"</string> </resources> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 045582887c7d..859ff1387dae 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -425,9 +425,9 @@ <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permet à l\'application de lire le journal d\'appels de votre tablette, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string> <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permet à l\'application de lire le journal d\'appels de votre appareil Android TV, y compris les données sur les appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string> <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permet à l\'application de lire le journal d\'appels de votre téléphone, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string> - <string name="permlab_bodySensors" msgid="662918578601619569">"Accéder aux données de capteurs corporels (comme le pouls) pendant l\'utilisation"</string> + <string name="permlab_bodySensors" msgid="662918578601619569">"Accéder aux données de capteurs corporels (comme fréquence cardiaque) pendant utilisation"</string> <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permet à l\'appli d\'accéder aux données des capteurs corporels (fréquence cardiaque, température, taux d\'oxygène dans le sang, etc.) quand l\'appli est en cours d\'utilisation."</string> - <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accéder aux données de capteurs corporels (comme le pouls) en arrière-plan"</string> + <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accéder aux données de capteurs corporels (comme fréquence cardiaque) quand en arrière-plan"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permet à l\'appli d\'accéder aux données des capteurs corporels (fréquence cardiaque, température, taux d\'oxygène dans le sang, etc.) quand l\'appli est en arrière-plan."</string> <string name="permlab_readCalendar" msgid="6408654259475396200">"Lire les événements d\'agenda et les détails associés"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Cette application peut lire tous les événements d\'agenda enregistrés sur votre tablette et partager ou enregistrer vos données d\'agenda."</string> @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Erreur d\'authentification"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utiliser verrouillage écran"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Utilisez le verrouillage de l\'écran pour continuer"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Empreinte partielle détectée"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Impossible de reconnaître l\'empreinte digitale. Veuillez réessayer."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Nettoyez le lecteur d\'empreinte digitale et réessayez"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Nettoyez le lecteur et réessayez"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Empreinte digitale non reconnue"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Appuyez bien sur le lecteur"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Empreinte digitale authentifiée"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Visage authentifié"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Visage authentifié, veuillez appuyer sur \"Confirmer\""</string> @@ -1681,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ACTIVÉE"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DÉSACTIVÉE"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Accorder le contrôle total de votre appareil à <xliff:g id="SERVICE">%1$s</xliff:g> ?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Si vous activez <xliff:g id="SERVICE">%1$s</xliff:g>, votre appareil n\'utilisera pas le verrouillage de l\'écran pour améliorer le chiffrement des données."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Le contrôle total convient aux applications qui répondent à vos besoins d\'accessibilité. Il ne convient pas à la plupart des autres applications."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Afficher et contrôler l\'écran"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Le service peut lire l\'intégralité du contenu à l\'écran et afficher du contenu par-dessus d\'autres applications."</string> @@ -1853,7 +1852,7 @@ <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"L\'économiseur de batterie active le thème sombre et limite ou désactive les activités en arrière-plan ainsi que certains effets visuels, fonctionnalités et connexions réseau."</string> <string name="battery_saver_description" msgid="8518809702138617167">"L\'économiseur de batterie active le thème sombre et limite ou désactive les activités en arrière-plan ainsi que certains effets visuels, fonctionnalités et connexions réseau."</string> - <string name="data_saver_description" msgid="4995164271550590517">"Pour réduire la consommation des données, l\'Économiseur de données empêche certaines applis d\'envoyer ou de recevoir des données en arrière-plan. Les applis que vous utiliserez pourront toujours accéder aux données, mais le feront moins fréquemment. Par exemple, les images pourront ne pas s\'afficher tant que vous n\'aurez pas appuyé dessus."</string> + <string name="data_saver_description" msgid="4995164271550590517">"Pour réduire la consommation des données, l\'Économiseur de données empêche certaines applis d\'envoyer ou de recevoir des données en arrière-plan. Les applis que vous utiliserez pourront toujours accéder aux données, mais le feront moins fréquemment. Par exemple, les images pourront ne pas s\'afficher tant que vous n\'aurez pas appuyé pas dessus."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Activer l\'Économiseur de données ?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Activer"</string> <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Pendant 1 minute (jusqu\'à {formattedTime})}one{Pendant # minute (jusqu\'à {formattedTime})}other{Pendant # minutes (jusqu\'à {formattedTime})}}"</string> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Application non disponible"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas disponible pour le moment."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponible"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Autorisation nécessaire"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Actuellement, vous ne pouvez pas accéder à cette application sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez plutôt d\'y accéder sur votre appareil Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Actuellement, vous ne pouvez pas accéder à cette application sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez plutôt d\'y accéder sur votre tablette."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Actuellement, vous ne pouvez pas accéder à cette application sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez plutôt d\'y accéder sur votre téléphone."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OUVRIR QUAND MÊME"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Application dangereuse détectée"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Autoriser <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> à accéder à tous les journaux de l\'appareil ?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Cette fois seulement"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ne pas autoriser"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Les journaux enregistrent ce qui se passe sur votre appareil. Les applis peuvent les utiliser pour rechercher et résoudre les problèmes.\n\nCertains journaux pouvant contenir des infos sensibles, autorisez uniquement les applis de confiance à accéder à tous les journaux de l\'appareil. \n\nSi vous refusez à cette appli l\'accès à tous les journaux de l\'appareil, elle a quand même accès aux siens. Le fabricant de l\'appareil peut accéder à certains journaux ou certaines infos sur votre appareil. En savoir plus"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne plus afficher"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> souhaite afficher des éléments de <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Modifier"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Activité en arrière-plan"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> s\'exécute en arrière-plan et décharge la batterie. Appuyez ici pour en savoir plus."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> s\'exécute en arrière-plan depuis longtemps. Appuyez ici pour en savoir plus."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vérifier les applis actives"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossible d\'accéder à l\'appareil photo de la tablette depuis votre <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="system_locale_title" msgid="3978041860457277638">"Langue du système"</string> </resources> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 0a0e36e752a4..cf0ebb6c46ff 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Produciuse un erro ao realizar a autenticación"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar credencial do dispositivo"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Desbloquea a pantalla para continuar"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Detectouse unha impresión dixital parcial"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Non se puido procesar a impresión dixital. Téntao de novo."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpa o sensor de impresión dixital e téntao de novo"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpa o sensor e téntao de novo"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Non se recoñeceu a impresión dixital"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Preme o sensor con firmeza"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Autenticouse a impresión dixital"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Autenticouse a cara"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Autenticouse a cara, preme Confirmar"</string> @@ -1358,10 +1356,10 @@ <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Detectouse un accesorio de audio analóxico"</string> <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"O dispositivo conectado non é compatible con este teléfono. Toca para obter máis información."</string> <string name="adb_active_notification_title" msgid="408390247354560331">"Depuración por USB conectada"</string> - <string name="adb_active_notification_message" msgid="5617264033476778211">"Toca e desactiva a depuración por USB"</string> + <string name="adb_active_notification_message" msgid="5617264033476778211">"Toca para desactivar a depuración por USB"</string> <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Selecciona a opción para desactivar a depuración por USB."</string> <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"A depuración sen fíos está conectada"</string> - <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Toca e desactiva a depuración sen fíos"</string> + <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Toca para desactivar a depuración sen fíos"</string> <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecciona para desactivar a depuración sen fíos."</string> <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Activouse o modo de axente de proba"</string> <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Restablece a configuración de fábrica para desactivar o modo de axente de proba."</string> @@ -1681,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ACTIVADO"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DESACTIVADO"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Queres permitir que <xliff:g id="SERVICE">%1$s</xliff:g> poida controlar totalmente o teu dispositivo?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Se activas <xliff:g id="SERVICE">%1$s</xliff:g>, o dispositivo non utilizará o teu bloqueo de pantalla para mellorar a encriptación de datos."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"O control total é adecuado para as aplicacións que che axudan coa accesibilidade, pero non para a maioría das aplicacións."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ver e controlar a pantalla"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Pode ler todo o contido da pantalla e mostralo sobre outras aplicacións."</string> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"A aplicación non está dispoñible"</string> <string name="app_blocked_message" msgid="542972921087873023">"A aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> non está dispoñible neste momento."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> non está dispoñible"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Necesítase permiso"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Nestes momentos, non podes acceder a este contido desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>). Proba a facelo desde o dispositivo con Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Nestes momentos, non podes acceder a este contido desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>). Proba a facelo desde a tableta."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Nestes momentos, non podes acceder a este contido desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>). Proba a facelo desde o teléfono."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ABRIR IGUALMENTE"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Detectouse unha aplicación daniña"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Queres permitir que a aplicación <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acceda a todos os rexistros do dispositivo?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Só esta vez"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Non permitir"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Os rexistros do dispositivo dan conta do que ocorre neste. As aplicacións poden usalos para buscar problemas e solucionalos.\n\nAlgúns poden conter información confidencial, polo que che recomendamos que só permitas que accedan a todos os rexistros do dispositivo as aplicacións nas que confíes. \n\nEsta aplicación pode acceder aos seus propios rexistros aínda que non lle permitas acceder a todos. É posible que o fabricante do dispositivo teña acceso a algúns rexistros ou á información do teu dispositivo. Máis información"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Non amosar outra vez"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> quere mostrar fragmentos de aplicación de <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Editar"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Actividade en segundo plano"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> está executándose en segundo plano e consumindo batería. Toca para revisalo."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> leva moito tempo executándose en segundo plano. Toca para revisalo."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Comprobar aplicacións activas"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Non se puido acceder á cámara da tableta desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>)"</string> <string name="system_locale_title" msgid="3978041860457277638">"Idioma do sistema"</string> </resources> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 464de112c95e..2e02dae4bc13 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -426,7 +426,7 @@ <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="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> @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"પ્રમાણિત કરવામાં ભૂલ આવી"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"સ્ક્રીન લૉકનો ઉપયોગ કરો"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"આગળ વધવા માટે તમારું સ્ક્રીન લૉક દાખલ કરો"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"આંશિક ફિંગરપ્રિન્ટ મળી"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ફિંગરપ્રિન્ટ પ્રક્રિયા કરી શકાઈ નથી. કૃપા કરીને ફરી પ્રયાસ કરો."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ફિંગરપ્રિન્ટ સેન્સર સાફ કરો અને ફરી પ્રયાસ કરો"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"સેન્સર સાફ કરો અને ફરી પ્રયાસ કરો"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ફિંગરપ્રિન્ટ ઓળખી શકાઈ નથી"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"સેન્સર પર જોરથી દબાવો"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ફિંગરપ્રિન્ટ પ્રમાણિત કરી"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ચહેરા પ્રમાણિત"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ચહેરા પ્રમાણિત, કૃપા કરીને કન્ફર્મ કરો"</string> @@ -1681,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"જો તમે <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> @@ -2028,10 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"કોઈપણ રીતે ખોલો"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"નુકસાનકારક ઍપ મળી આવી છે"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>ને ડિવાઇસનો બધો લૉગ ઍક્સેસ કરવાની મંજૂરી આપવી છે?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"માત્ર આ વખતે"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"મંજૂરી આપશો નહીં"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"તમારા ડિવાઇસ પર થતી કામગીરીને ડિવાઇસ લૉગ રેકોર્ડ કરે છે. ઍપ આ લૉગનો ઉપયોગ સમસ્યાઓ શોધી તેનું નિરાકરણ કરવા માટે કરી શકે છે.\n\nઅમુક લૉગમાં સંવેદનશીલ માહિતી હોઈ શકે, આથી ડિવાઇસનો બધો લૉગ ઍક્સેસ કરવાની મંજૂરી માત્ર તમારી વિશ્વાસપાત્ર ઍપને જ આપો. \n\nતમે આ ઍપને ડિવાઇસનો બધો લૉગ ઍક્સેસ કરવાની મંજૂરી નહીં આપી હોય, તો પણ તે તેના પોતાના લૉગ ઍક્સેસ કરી શકે છે. તમારા ડિવાઇસના નિર્માતા હજુ પણ કદાચ તમારા ડિવાઇસ પર અમુક લૉગ અથવા માહિતી ઍક્સેસ કરી શકે છે. વધુ જાણો"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"ફરીથી બતાવશો નહીં"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>એ <xliff:g id="APP_2">%2$s</xliff:g> સ્લાઇસ બતાવવા માગે છે"</string> <string name="screenshot_edit" msgid="7408934887203689207">"ફેરફાર કરો"</string> @@ -2261,16 +2260,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"બૅકગ્રાઉન્ડ પ્રવૃત્તિ"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ઍપ બૅકગ્રાઉન્ડમાં ચાલી રહી છે અને અતિશય બૅટરી વાપરી રહી છે. રિવ્યૂ કરવા માટે ટૅપ કરો."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> લાંબા સમયથી બૅકગ્રાઉન્ડમાં ચાલી રહી છે. રિવ્યૂ કરવા માટે ટૅપ કરો."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"સક્રિય ઍપ ચેક કરો"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"તમારા <xliff:g id="DEVICE">%1$s</xliff:g> પરથી ટૅબ્લેટના કૅમેરાનો ઍક્સેસ કરી શકતાં નથી"</string> <string name="system_locale_title" msgid="3978041860457277638">"સિસ્ટમની ભાષા"</string> </resources> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index e505e2364ef0..d44b55c8eba5 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -217,7 +217,7 @@ <string name="turn_on_radio" msgid="2961717788170634233">"वायरलेस चालू करें"</string> <string name="turn_off_radio" msgid="7222573978109933360">"वायरलेस बंद करें"</string> <string name="screen_lock" msgid="2072642720826409809">"स्क्रीन लॉक"</string> - <string name="power_off" msgid="4111692782492232778">"फ़ोन बंद करें"</string> + <string name="power_off" msgid="4111692782492232778">"पावर बंद करें"</string> <string name="silent_mode_silent" msgid="5079789070221150912">"रिंगर बंद"</string> <string name="silent_mode_vibrate" msgid="8821830448369552678">"रिंगर कंपन (वाइब्रेशन)"</string> <string name="silent_mode_ring" msgid="6039011004781526678">"रिंगर चालू"</string> @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"गड़बड़ी की पुष्टि की जा रही है"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"जारी रखने के लिए, अपने स्क्रीन लॉक की पुष्टि करें"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"सेंसर को उंगली से ज़ोर से दबाएं"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"पूरा फ़िंगरप्रिंट पहचाना नहीं जा सका"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"फ़िंगरप्रिंट प्रोसेस नहीं हो सका. कृपया दोबारा कोशिश करें."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"फ़िंगरप्रिंट सेंसर को साफ़ करके फिर से कोशिश करें"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"फ़िंगरप्रिंट सेंसर को साफ़ करके फिर से कोशिश करें"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"फ़िंगरप्रिंट की पहचान नहीं हो पाई"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"फ़िंगरप्रिंट की पहचान नहीं हो पाई"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"सेंसर को उंगली से ज़ोर से दबाएं"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"फ़िंगरप्रिंट की पुष्टि हो गई"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"चेहरे की पहचान की गई"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"चेहरे की पहचान की गई, कृपया पुष्टि बटन दबाएं"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"अगर आप <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> @@ -1851,7 +1852,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> @@ -2026,9 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"फिर भी खोलें"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"नुकसान पहुंचाने वाले ऐप का पता चला"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"क्या <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> को डिवाइस लॉग का ऐक्सेस देना है?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"एक बार ऐक्सेस करने की अनुमति दें"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"सिर्फ़ इस बार"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"अनुमति न दें"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"डिवाइस लॉग में आपके डिवाइस पर की गई कार्रवाइयां रिकॉर्ड होती हैं. ऐप्लिकेशन, इन लॉग का इस्तेमाल गड़बड़ियां ढूंढने और उन्हें सही करने के लिए करता है.\n\nकुछ लॉग में संवेदनशील जानकारी हो सकती है. इसलिए, सिर्फ़ भरोसेमंद ऐप्लिकेशन को डिवाइस लॉग का ऐक्सेस दें. \n\nअगर इस ऐप्लिकेशन को डिवाइस के सभी लॉग का ऐक्सेस नहीं दिया जाता है, तब भी यह डिवाइस पर अपने लॉग को ऐक्सेस कर सकता है. डिवाइस को बनाने वाली कंपनी अब भी डिवाइस के कुछ लॉग या जानकारी को ऐक्सेस कर सकती है. ज़्यादा जानें"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"फिर से न दिखाएं"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>, <xliff:g id="APP_2">%2$s</xliff:g> के हिस्से (स्लाइस) दिखाना चाहता है"</string> <string name="screenshot_edit" msgid="7408934887203689207">"बदलाव करें"</string> @@ -2258,12 +2260,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> से, आपके डिवाइस की बैटरी लाइफ़ पर असर पड़ सकता है. चालू ऐप्लिकेशन देखने के लिए टैप करें."</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"बैकग्राउंड में हो रही गतिविधि"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> बैकग्राउंड में चल रहा है और बैटरी खर्च कर रहा है. देखने के लिए टैप करें."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"आपके <xliff:g id="DEVICE">%1$s</xliff:g> से टैबलेट के कैमरे को ऐक्सेस नहीं किया जा सकता"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"सिस्टम की भाषा"</string> </resources> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 3723f1070429..07bc84ec3e24 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -586,7 +586,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Pogreška prilikom autentifikacije"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Upotreba zaključavanja zaslona"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Upotrijebite zaključavanje zaslona da biste nastavili"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Čvrsto pritisnite senzor"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Otkriven je djelomični otisak prsta"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Obrada otiska prsta nije uspjela. Pokušajte ponovo."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Očistite senzor otiska prsta i pokušajte ponovno"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Očistite senzor i pokušajte ponovno"</string> @@ -599,7 +599,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Otisak prsta nije prepoznat"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Otisak prsta nije prepoznat"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Čvrsto pritisnite senzor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Autentificirano otiskom prsta"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Lice je autentificirano"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Lice je autentificirano, pritisnite Potvrdi"</string> @@ -1680,6 +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">"Želite li usluzi <xliff:g id="SERVICE">%1$s</xliff:g> dopustiti potpunu kontrolu nad uređajem?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ako uključite <xliff:g id="SERVICE">%1$s</xliff:g>, vaš uređaj neće upotrebljavati zaključavanje zaslona za bolju enkripciju podataka."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Potpuna kontrola prikladna je za aplikacije koje vam pomažu s potrebama pristupačnosti, ali ne i za većinu aplikacija."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Pregled zaslona i upravljanje njime"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Može čitati sav sadržaj na zaslonu i prikazati sadržaj povrh drugih aplikacija."</string> @@ -1853,7 +1854,7 @@ <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Štednja baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizualne efekte, određene značajke i neke mrežne veze."</string> <string name="battery_saver_description" msgid="8518809702138617167">"Štednja baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizualne efekte, određene značajke i neke mrežne veze."</string> <string name="data_saver_description" msgid="4995164271550590517">"Da bi se smanjio podatkovni promet, značajka Štednja podatkovnog prometa onemogućuje nekim aplikacijama slanje ili primanje podataka u pozadini. Aplikacija koju trenutačno upotrebljavate može pristupiti podacima, no možda će to činiti rjeđe. To može značiti da se, na primjer, slike neće prikazivati dok ih ne dodirnete."</string> - <string name="data_saver_enable_title" msgid="7080620065745260137">"Uključiti štednju podatkovnog prometa?"</string> + <string name="data_saver_enable_title" msgid="7080620065745260137">"Uključiti Štednju podatkovnog prometa?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Uključi"</string> <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{1 min (do {formattedTime})}one{# min (do {formattedTime})}few{# min (do {formattedTime})}other{# min (do {formattedTime})}}"</string> <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{1 min (do {formattedTime})}one{# min (do {formattedTime})}few{# min (do {formattedTime})}other{# min (do {formattedTime})}}"</string> @@ -2027,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"IPAK OTVORI"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Otkrivena je štetna aplikacija"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Želite li dopustiti aplikaciji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> da pristupa svim zapisnicima uređaja?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Omogući jednokratni pristup"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Samo ovaj put"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nemoj dopustiti"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"U zapisnicima uređaja bilježi se što se događa na uređaju. Aplikacije mogu koristiti te zapisnike kako bi pronašle i riješile poteškoće.\n\nNeki zapisnici mogu sadržavati osjetljive podatke, pa pristup svim zapisnicima uređaja odobrite samo pouzdanim aplikacijama. \n\nAko ne dopustite ovoj aplikaciji da pristupa svim zapisnicima uređaja, ona i dalje može pristupati svojim zapisnicima. Proizvođač vašeg uređaja i dalje može pristupati nekim zapisnicima ili podacima na vašem uređaju. Saznajte više"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne prikazuj ponovo"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> želi prikazivati isječke aplikacije <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Uredi"</string> @@ -2259,12 +2261,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Aktivnost u pozadini"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> izvodi se u pozadini i prazni bateriju. Dodirnite za pregled."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> dugo se izvodi u pozadini. Dodirnite za pregled."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"S vašeg uređaja <xliff:g id="DEVICE">%1$s</xliff:g> nije moguće pristupiti fotoaparatu tableta"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Jezik sustava"</string> </resources> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 7cbb0ad90153..f47273487e7b 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Hiba történt a hitelesítés közben"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Képernyőzár használata"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"A folytatáshoz adja meg a képernyőzár hitelesítési adatait"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Nyomja meg határozottan az érzékelőt"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"A rendszer részleges ujjlenyomatot észlelt"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nem sikerült feldolgozni az ujjlenyomatot. Próbálkozzon újra."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Tisztítsa meg az ujjlenyomat-érzékelőt, majd próbálja újra"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Tisztítsa meg az érzékelőt, majd próbálja újra"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Az ujjlenyomat nem ismerhető fel"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Az ujjlenyomat nem ismerhető fel"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Nyomja meg határozottan az érzékelőt"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Ujjlenyomat hitelesítve"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Arc hitelesítve"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Arc hitelesítve; nyomja meg a Megerősítés lehetőséget"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"BE"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"KI"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Teljes körű vezérlést biztosít eszköze felett a(z) <xliff:g id="SERVICE">%1$s</xliff:g> szolgáltatás számára?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ha engedélyezi a(z) <xliff:g id="SERVICE">%1$s</xliff:g> szolgáltatást, az eszköz nem fogja használni a képernyőzárat az adattitkosítás növelése érdekében."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"A teljes vezérlés indokolt olyan alkalmazásoknál, amelyek kisegítő lehetőségeket nyújtanak, a legtöbb alkalmazásnál azonban nem."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Képernyő megtekintése és kezelése"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Elolvashatja a képernyő tartalmát, és tartalmakat jeleníthet meg más alkalmazások felett."</string> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Az alkalmazás nem hozzáférhető"</string> <string name="app_blocked_message" msgid="542972921087873023">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> jelenleg nem hozzáférhető."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"A(z) <xliff:g id="ACTIVITY">%1$s</xliff:g> nem áll rendelkezése"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Engedély szükséges"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Ehhez jelenleg nem lehet hozzáférni a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>. Próbálja újra Android TV-eszközén."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Ehhez jelenleg nem lehet hozzáférni a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>. Próbálja újra a táblagépén."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Ehhez jelenleg nem lehet hozzáférni a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>. Próbálja újra a telefonján."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"MEGNYITÁS MÉGIS"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"A rendszer kártékony alkalmazást észlelt"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Engedélyezi a(z) <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> számára, hogy hozzáférjen az összes eszköznaplóhoz?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Egyszeri hozzáférés engedélyezése"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Csak most"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Tiltás"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Az eszköznaplók rögzítik, hogy mi történik az eszközén. Az alkalmazások ezeket a naplókat használhatják a problémák megkeresésére és kijavítására.\n\nBizonyos naplók érzékeny adatokat is tartalmazhatnak, ezért csak olyan alkalmazások számára engedélyezze az összes eszköznaplóhoz való hozzáférést, amelyekben megbízik. \n\nHa nem engedélyezi ennek az alkalmazásnak, hogy hozzáférjen az összes eszköznaplójához, az app továbbra is hozzáférhet a saját naplóihoz. Előfordulhat, hogy az eszköz gyártója továbbra is hozzáfér az eszközön található bizonyos naplókhoz és adatokhoz. További információ."</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne jelenjen meg újra"</string> <string name="slices_permission_request" msgid="3677129866636153406">"A(z) <xliff:g id="APP_0">%1$s</xliff:g> alkalmazás részleteket szeretne megjeleníteni a(z) <xliff:g id="APP_2">%2$s</xliff:g> alkalmazásból"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Szerkesztés"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Háttértevékenység"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"A(z) <xliff:g id="APP">%1$s</xliff:g> fut a háttérben, és meríti az akkumulátort. Koppintson az áttekintéshez."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"A(z) <xliff:g id="APP">%1$s</xliff:g> alkalmazás már hosszú ideje fut a háttérben. Koppintson az áttekintéshez."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nem lehet hozzáférni a táblagép kamerájához a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Alapértelmezett nyelv"</string> </resources> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 075ea5afa220..88a8e14c17e2 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Չհաջողվեց նույնականացնել"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Էկրանի կողպում"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Շարունակելու համար ապակողպեք էկրանը"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Մատնահետքն ամբողջությամբ չի սկանավորվել"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Չհաջողվեց մշակել մատնահետքը: Նորից փորձեք:"</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Մաքրեք մատնահետքերի սկաները և նորից փորձեք"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Մաքրեք սկաները և նորից փորձեք"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Մատնահետքը չի ճանաչվել"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Մատը ուժեղ սեղմեք սկաների վրա"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Մատնահետքը նույնականացվեց"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Դեմքը ճանաչվեց"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Դեմքը ճանաչվեց: Սեղմեք «Հաստատել»:"</string> @@ -1681,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"Եթե միացնեք <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> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Հավելվածը հասանելի չէ"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Այս պահին հնարավոր չէ բացել հավելվածը <xliff:g id="DEVICE">%1$s</xliff:g> սարքում։ Փորձեք Android TV սարքում։"</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Այս պահին հնարավոր չէ բացել հավելվածը <xliff:g id="DEVICE">%1$s</xliff:g> սարքում։ Փորձեք ձեր պլանշետում։"</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Այս պահին հնարավոր չէ բացել հավելվածը <xliff:g id="DEVICE">%1$s</xliff:g> սարքում։ Փորձեք ձեր հեռախոսում։"</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ԲԱՑԵԼ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Հայտնաբերվել է վնասաբեր հավելված"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Հասանելի դարձնե՞լ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> հավելվածին սարքի բոլոր մատյանները"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Միայն այս անգամ"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Չթույլատրել"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Այն, ինչ տեղի է ունենում ձեր սարքում, գրանցվում է սարքի մատյաններում։ Հավելվածները կարող են դրանք օգտագործել անսարքությունները հայտնաբերելու և վերացնելու նպատակով։\n\nՔանի որ որոշ մատյաններ անձնական տեղեկություններ են պարունակում, խորհուրդ ենք տալիս հասանելի դարձնել ձեր սարքի բոլոր մատյանները միայն այն հավելվածներին, որոնց վստահում եք։ \n\nԵթե այս հավելվածին նման թույլտվություն չեք տվել, դրան նախկինի պես հասանելի կլինեն իր մատյանները։ Հնարավոր է՝ ձեր սարքի արտադրողին ևս հասանելի լինեն սարքի որոշ մատյաններ և տեղեկություններ։ Իմանալ ավելին"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Այլևս ցույց չտալ"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> հավելվածն ուզում է ցուցադրել հատվածներ <xliff:g id="APP_2">%2$s</xliff:g> հավելվածից"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Փոփոխել"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Ակտիվ հավելվածներ ֆոնային ռեժիմում"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g>-ն աշխատում է ֆոնային ռեժիմում և սպառում է մարտկոցը։ Հպեք՝ դիտելու համար։"</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> հավելվածը երկար ժամանակ աշխատում է ֆոնային ռեժիմում։ Հպեք՝ դիտելու համար։"</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Ստուգել ակտիվ հավելվածները"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Հնարավոր չէ օգտագործել պլանշետի տեսախցիկը ձեր <xliff:g id="DEVICE">%1$s</xliff:g> սարքից"</string> <string name="system_locale_title" msgid="3978041860457277638">"Համակարգի լեզու"</string> </resources> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 96d3809d0f93..fd9ff4de391b 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Error saat mengautentikasi"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gunakan kunci layar"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Masukkan kunci layar untuk melanjutkan"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Sebagian sidik jari terdeteksi"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Tidak dapat memproses sidik jari. Coba lagi."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Bersihkan sensor sidik jari lalu coba lagi"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Bersihkan sensor lalu coba lagi"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Sidik jari tidak dikenali"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Tekan sensor dengan kuat"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Sidik jari diautentikasi"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Wajah diautentikasi"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Wajah diautentikasi, silakan tekan konfirmasi"</string> @@ -1681,6 +1679,7 @@ <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_enable_service_encryption_warning" msgid="8603532708618236909">"Jika Anda mengaktifkan <xliff:g id="SERVICE">%1$s</xliff:g>, perangkat tidak akan menggunakan kunci layar untuk meningkatkan enkripsi data."</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_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> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikasi tidak tersedia"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak tersedia saat ini."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> tidak tersedia"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Perlu izin"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Aplikasi ini tidak dapat diakses di <xliff:g id="DEVICE">%1$s</xliff:g> untuk saat ini. Coba di perangkat Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Aplikasi ini tidak dapat diakses di <xliff:g id="DEVICE">%1$s</xliff:g> untuk saat ini. Coba di tablet."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Aplikasi ini tidak dapat diakses di <xliff:g id="DEVICE">%1$s</xliff:g> untuk saat ini. Coba di ponsel."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"TETAP BUKA"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Aplikasi berbahaya terdeteksi"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Izinkan <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> mengakses semua log perangkat?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Hanya kali ini"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Jangan izinkan"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Log perangkat merekam hal-hal yang terjadi di perangkat Anda. Aplikasi dapat menggunakan log ini untuk menemukan dan memperbaiki masalah.\n\nBeberapa log mungkin berisi info sensitif, jadi hanya izinkan aplikasi yang Anda percayai untuk mengakses semua log perangkat. \n\nJika Anda tidak mengizinkan aplikasi ini mengakses semua log perangkat, aplikasi masih dapat mengakses log-nya sendiri. Produsen perangkat masih dapat mengakses beberapa log atau info di perangkat Anda. Pelajari lebih lanjut"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Jangan tampilkan lagi"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ingin menampilkan potongan <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Aktivitas Latar Belakang"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> mengonsumsi banyak daya di latar belakang. Ketuk untuk meninjau."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> berjalan di latar belakang dalam waktu yang lama. Ketuk untuk meninjau."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Periksa aplikasi aktif"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Tidak dapat mengakses kamera tablet dari <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="system_locale_title" msgid="3978041860457277638">"Bahasa sistem"</string> </resources> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index c06c82233c6b..16af64fdc89f 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -324,7 +324,7 @@ <string name="permgrouplab_phone" msgid="570318944091926620">"Sími"</string> <string name="permgroupdesc_phone" msgid="270048070781478204">"hringja og stjórna símtölum"</string> <string name="permgrouplab_sensors" msgid="9134046949784064495">"Líkamsskynjarar"</string> - <string name="permgroupdesc_sensors" msgid="2610631290633747752">"aðgangur að skynjaragögnum um lífsmörk þín"</string> + <string name="permgroupdesc_sensors" msgid="2610631290633747752">"aðgangur að skynjaragögnum yfir lífsmörk þín"</string> <string name="permgrouplab_notifications" msgid="5472972361980668884">"Tilkynningar"</string> <string name="permgroupdesc_notifications" msgid="4608679556801506580">"sýna tilkynningar"</string> <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Sækja innihald glugga"</string> @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Villa við auðkenningu"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Nota skjálás"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Sláðu inn skjálásinn þinn til að halda áfram"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Hluti fingrafars greindist"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Ekki var hægt að vinna úr fingrafarinu. Reyndu aftur."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Hreinsaðu fingrafaralesarann og reyndu aftur"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Hreinsaðu lesarann og reyndu aftur"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Ekki þekkt fingrafar"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Ýttu ákveðið á lesarann"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingrafar staðfest"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Andlit staðfest"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Andlit staðfest, ýttu til að staðfesta"</string> @@ -1681,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"KVEIKT"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"SLÖKKT"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Viltu leyfa <xliff:g id="SERVICE">%1$s</xliff:g> að hafa fulla stjórn yfir tækinu þínu?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ef þú kveikir á <xliff:g id="SERVICE">%1$s</xliff:g> mun tækið ekki nota skjálásinn til að efla dulkóðun gagna."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Full stjórnun er viðeigandi fyrir forrit sem hjálpa þér ef þú hefur ekki aðgang, en ekki fyrir flest forrit."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Skoða og stjórna skjá"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Það getur lesið allt efni á skjánum og birt efni yfir öðrum forritum."</string> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Forrit er ekki tiltækt"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ekki tiltækt núna."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ekki í boði"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Heimildar krafist"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Aðgangur að þessu í <xliff:g id="DEVICE">%1$s</xliff:g> er ekki í boði eins og er. Prófaðu það í Android TV tækinu í staðinn."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Aðgangur að þessu í <xliff:g id="DEVICE">%1$s</xliff:g> er ekki í boði eins og er. Prófaðu það í spjaldtölvunni í staðinn."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Aðgangur að þessu í <xliff:g id="DEVICE">%1$s</xliff:g> er ekki í boði eins og er. Prófaðu það í símanum í staðinn."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OPNA SAMT"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Skaðlegt forrit fannst"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Veita <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> aðgang að öllum annálum í tækinu?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Aðeins í þetta skipti"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ekki leyfa"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Annálar tækisins skrá það sem gerist í tækinu. Forrit geta notað þessa annála til að finna og lagfæra vandamál.\n\nTilteknir annálar innihalda viðkvæmar upplýsingar og því skaltu einungis veita forritum sem þú treystir aðgang að öllum annálum tækisins. \n\nEf þú veitir þessu forriti ekki aðgang að öllum annálum tækisins hefur það áfram aðgang að eigin annálum. Framleiðandi tækisins getur þó hugsanlega opnað tiltekna annála eða upplýsingar í tækinu. Nánar"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ekki sýna aftur"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> vill sýna sneiðar úr <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Breyta"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Bakgrunnsvirkni"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> keyrir í bakgrunni og eyðir rafhlöðuorku. Ýttu til að skoða."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> hefur keyrt lengi í bakgrunni. Ýttu til að skoða."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Skoða virk forrit"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ekki er hægt að opna myndavél spjaldtölvunnar úr <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="system_locale_title" msgid="3978041860457277638">"Tungumál kerfis"</string> </resources> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 2635637bacd6..e21c2fd21949 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -426,9 +426,9 @@ <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Consente all\'app di modificare il registro chiamate del dispositivo Android TV, inclusi i dati relativi alle chiamate in arrivo e in uscita. Le app dannose potrebbero farne uso per cancellare o modificare il registro chiamate."</string> <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Consente all\'applicazione di modificare il registro chiamate del telefono, inclusi i dati sulle chiamate in arrivo e in uscita. Le applicazioni dannose potrebbero farne uso per cancellare o modificare il registro chiamate."</string> <string name="permlab_bodySensors" msgid="662918578601619569">"Accesso ai dati dei sensori del corpo, come il battito cardiaco, mentre è in uso"</string> - <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Autorizza l\'app ad accedere ai dati dei sensori del corpo, ad esempio battito cardiaco, temperatura e percentuale di ossigeno nel sangue, mentre l\'app è in uso."</string> + <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Autorizza l\'app ad accedere ai dati relativi ai sensori del corpo, ad esempio battito cardiaco, temperatura e percentuale di ossigeno nel sangue, mentre l\'app è in uso."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accesso ai dati dei sensori del corpo, come il battito cardiaco, in background"</string> - <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Autorizza l\'app ad accedere ai dati dei sensori del corpo, ad esempio battito cardiaco, temperatura e percentuale di ossigeno nel sangue, mentre l\'app è in background."</string> + <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Autorizza l\'app ad accedere ai dati relativi ai sensori del corpo, ad esempio battito cardiaco, temperatura e percentuale di ossigeno nel sangue, mentre l\'app è in background."</string> <string name="permlab_readCalendar" msgid="6408654259475396200">"lettura di eventi di calendario e dettagli"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Questa app può leggere tutti gli eventi di calendario memorizzati sul tablet e condividere o salvare i dati di calendario."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Questa app può leggere tutti gli eventi di calendario memorizzati sul dispositivo Android TV e condividere o salvare i dati di calendario."</string> @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Errore durante l\'autenticazione"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usa il blocco schermo"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Inserisci il blocco schermo per continuare"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Premi con decisione sul sensore"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Rilevata impronta parziale"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Impossibile elaborare l\'impronta. Riprova."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Pulisci il sensore di impronte digitali e riprova"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Pulisci il sensore e riprova"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Impronta non riconosciuta"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Impronta non riconosciuta"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Premi con decisione sul sensore"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Impronta autenticata"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Volto autenticato"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Volto autenticato, premi Conferma"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ON"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"OFF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vuoi consentire a <xliff:g id="SERVICE">%1$s</xliff:g> di avere il controllo totale del tuo dispositivo?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Se attivi <xliff:g id="SERVICE">%1$s</xliff:g>, il dispositivo non utilizzerà il blocco schermo per migliorare la crittografia dei dati."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Il controllo totale è appropriato per le app che rispondono alle tue esigenze di accessibilità, ma non per gran parte delle app."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Visualizzare e controllare lo schermo"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Può leggere i contenuti presenti sullo schermo e mostrare i contenuti su altre app."</string> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"L\'app non è disponibile"</string> <string name="app_blocked_message" msgid="542972921087873023">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> non è al momento disponibile."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> non disponibile"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"È necessaria l\'autorizzazione"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Al momento non è possibile accedere a questa app su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il dispositivo Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Al momento non è possibile accedere a questa app su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il tablet."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Al momento non è possibile accedere a questa app su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il telefono."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"APRI COMUNQUE"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"App dannosa rilevata"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Consentire all\'app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> di accedere a tutti i log del dispositivo?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Consenti accesso una tantum"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Solo questa volta"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Non consentire"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"I log del dispositivo registrano tutto ciò che succede sul tuo dispositivo. Le app possono usare questi log per individuare problemi e correggerli.\n\nAlcuni log potrebbero contenere informazioni sensibili, quindi concedi l\'accesso a tutti i log del dispositivo soltanto alle app attendibili. \n\nSe le neghi l\'accesso a tutti i log del dispositivo, questa app può comunque accedere ai propri log. Il produttore del tuo dispositivo potrebbe essere comunque in grado di accedere ad alcuni log o informazioni sul dispositivo. Scopri di più"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Non mostrare più"</string> <string name="slices_permission_request" msgid="3677129866636153406">"L\'app <xliff:g id="APP_0">%1$s</xliff:g> vuole mostrare porzioni dell\'app <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Modifica"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Attività in background"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> è in esecuzione in background e consuma batteria. Tocca per controllare."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> è in esecuzione in background da molto tempo. Tocca per controllare."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Impossibile accedere alla fotocamera del tablet dal tuo <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Lingua di sistema"</string> </resources> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 3b4866addb02..5a8206ae01c5 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -325,7 +325,7 @@ <string name="permgroupdesc_calllog" msgid="2026996642917801803">"קריאה וכתיבה של יומן השיחות של הטלפון"</string> <string name="permgrouplab_phone" msgid="570318944091926620">"טלפון"</string> <string name="permgroupdesc_phone" msgid="270048070781478204">"ביצוע וניהול של שיחות טלפון"</string> - <string name="permgrouplab_sensors" msgid="9134046949784064495">"חיישני גוף"</string> + <string name="permgrouplab_sensors" msgid="9134046949784064495">"חיישנים גופניים"</string> <string name="permgroupdesc_sensors" msgid="2610631290633747752">"גישה אל נתוני חיישנים של הסימנים החיוניים שלך"</string> <string name="permgrouplab_notifications" msgid="5472972361980668884">"התראות"</string> <string name="permgroupdesc_notifications" msgid="4608679556801506580">"הצגת התראות"</string> @@ -427,10 +427,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> @@ -587,7 +587,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"שגיאה באימות"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"שימוש בנעילת מסך"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"יש לבטל את נעילת המסך כדי להמשיך"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"צריך ללחוץ חזק על החיישן"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"זוהתה טביעת אצבע חלקית"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"לא ניתן היה לעבד את טביעת האצבע. אפשר לנסות שוב."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"עליך לנקות את חיישן טביעות האצבע ולנסות שוב"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"עליך לנקות את החיישן ולנסות שוב"</string> @@ -600,7 +600,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"טביעת האצבע לא זוהתה"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"טביעת האצבע לא זוהתה"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"צריך ללחוץ חזק על החיישן"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"טביעת האצבע אומתה"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"זיהוי הפנים בוצע"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"זיהוי הפנים בוצע. יש ללחוץ על אישור"</string> @@ -1681,6 +1681,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_enable_service_encryption_warning" msgid="8603532708618236909">"אם השירות <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> @@ -1934,7 +1935,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"האפליקציה לא זמינה"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"אי אפשר לגשת לאפליקציה הזו במכשיר <xliff:g id="DEVICE">%1$s</xliff:g> כרגע. במקום זאת, יש לנסות במכשיר Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"אי אפשר לגשת לאפליקציה הזו במכשיר <xliff:g id="DEVICE">%1$s</xliff:g> כרגע. במקום זאת, יש לנסות בטאבלט."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"אי אפשר לגשת לאפליקציה הזו במכשיר <xliff:g id="DEVICE">%1$s</xliff:g> כרגע. במקום זאת, יש לנסות בטלפון."</string> @@ -2028,9 +2030,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"לפתוח בכל זאת"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"אותרה אפליקציה מזיקה"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"לתת לאפליקציה <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> הרשאת גישה לכל יומני המכשיר?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"הרשאת גישה חד-פעמית"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"רק הפעם"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"אין אישור"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"ביומני המכשיר מתועדת הפעילות במכשיר. האפליקציות יכולות להשתמש ביומנים האלה כדי למצוא בעיות ולפתור אותן.\n\nהמידע בחלק מהיומנים יכול להיות רגיש, לכן יש לתת הרשאת גישה לכל יומני המכשיר רק לאפליקציות מהימנות. \n\nגם אם האפליקציה הזו לא תקבל הרשאת גישה לכל יומני המכשיר, היא תוכל לגשת ליומנים שלה. יכול להיות שליצרן המכשיר עדיין תהיה גישה לחלק מהיומנים או למידע במכשיר שלך. מידע נוסף"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"אין להציג שוב"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> רוצה להציג חלקים מ-<xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"עריכה"</string> @@ -2260,12 +2263,14 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"האפליקציה <xliff:g id="APP">%1$s</xliff:g> עלולה להשפיע על חיי הסוללה. אפשר להקיש כדי לבדוק את האפליקציות הפעילות."</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"פעילות ברקע"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"האפליקציה <xliff:g id="APP">%1$s</xliff:g> פועלת ברקע ומרוקנת את הסוללה. יש להקיש כדי לבדוק."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"האפליקציה <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"לא ניתן לגשת למצלמה של הטאבלט מה‑<xliff:g id="DEVICE">%1$s</xliff:g>"</string> - <string name="system_locale_title" msgid="3978041860457277638">"שפת המערכת"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> + <!-- no translation found for system_locale_title (3978041860457277638) --> + <skip /> </resources> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 139bdc0e33af..4b15f78687da 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"エラー認証"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"画面ロックの使用"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"続行するには画面ロックを入力してください"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"センサーにしっかりと押し当ててください"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"指紋の一部しか検出できません"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"指紋を処理できませんでした。もう一度お試しください。"</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"指紋認証センサーの汚れを取り除いて、もう一度お試しください"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"センサーの汚れを取り除いて、もう一度お試しください"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"指紋を認識できません"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"指紋を認識できません"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"センサーにしっかりと押し当ててください"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"指紋認証を完了しました"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"顔を認証しました"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"顔を認証しました。[確認] を押してください"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ON"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"OFF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> にデバイスのフル コントロールを許可しますか?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<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> @@ -1849,8 +1850,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">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"バッテリー セーバーを ON にすると、ダークモードが ON になります。また、バックグラウンド アクティビティ、一部の視覚効果、特定の機能、一部のネットワーク接続が制限されるか OFF になります。"</string> - <string name="battery_saver_description" msgid="8518809702138617167">"バッテリー セーバーを ON にすると、ダークモードが ON になります。また、バックグラウンド アクティビティ、一部の視覚効果、特定の機能、一部のネットワーク接続が制限されるか OFF になります。"</string> + <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"バッテリー セーバーを有効にすると、ダークモードが ON になり、バックグラウンド アクティビティ、一部の視覚効果、特定の機能、一部のネットワーク接続が制限されるか OFF になります。"</string> + <string name="battery_saver_description" msgid="8518809702138617167">"バッテリー セーバーを有効にすると、ダークモードが ON になり、バックグラウンド アクティビティ、一部の視覚効果、特定の機能、一部のネットワーク接続が制限されるか OFF になります。"</string> <string name="data_saver_description" msgid="4995164271550590517">"データセーバーは、一部のアプリによるバックグラウンドでのデータ送受信を停止することでデータ使用量を抑制します。使用中のアプリからデータを送受信することはできますが、その頻度は低くなる場合があります。この影響として、たとえば画像はタップしないと表示されないようになります。"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"データセーバーを ON にしますか?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ON にする"</string> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"アプリの利用不可"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"現在、<xliff:g id="DEVICE">%1$s</xliff:g> からアクセスできません。Android TV デバイスでのアクセスをお試しください。"</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"現在、<xliff:g id="DEVICE">%1$s</xliff:g> からアクセスできません。タブレットでのアクセスをお試しください。"</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"現在、<xliff:g id="DEVICE">%1$s</xliff:g> からアクセスできません。スマートフォンでのアクセスをお試しください。"</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"開く"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"有害なアプリが検出されました"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> にすべてのデバイスログへのアクセスを許可しますか?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"1 回限りのアクセスを許可"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"今回のみ"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"許可しない"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"デバイスのログに、このデバイスで発生したことが記録されます。アプリは問題を検出、修正するためにこれらのログを使用することができます。\n\nログによっては機密性の高い情報が含まれている可能性があるため、すべてのデバイスログへのアクセスは信頼できるアプリにのみ許可してください。\n\nすべてのデバイスログへのアクセスを許可しなかった場合も、このアプリはアプリ独自のログにアクセスできます。また、デバイスのメーカーもデバイスの一部のログや情報にアクセスできる可能性があります。詳細"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"次回から表示しない"</string> <string name="slices_permission_request" msgid="3677129866636153406">"「<xliff:g id="APP_0">%1$s</xliff:g>」が「<xliff:g id="APP_2">%2$s</xliff:g>」のスライスの表示をリクエストしています"</string> <string name="screenshot_edit" msgid="7408934887203689207">"編集"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> がバッテリー駆動時間に影響を与えている可能性があります。タップして、アクティブなアプリをご確認ください。"</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"バックグラウンド アクティビティ"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> がバックグラウンドでバッテリーを消費しています。タップして確認。"</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> からタブレットのカメラにアクセスできません"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"システムの言語"</string> </resources> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 27d1801a5c24..6e3bfebe4a90 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"შეცდომა ავთენტიკაციისას"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"გამოიყენეთ ეკრანის დაბლოკვა"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"გასაგრძელებლად შედით ეკრანის დაბლოკვაში"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"მაგრად დააჭირეთ სენსორს"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"ამოცნობილია ნაწილობრივი თითის ანაბეჭდი"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"თითის ანაბეჭდის დამუშავება ვერ მოხერხდა. გთხოვთ, ცადოთ ხელახლა."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"გაწმინდეთ თითის ანაბეჭდის სენსორი და ხელახლა ცადეთ"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"გაწმინდეთ სენსორი და ხელახლა ცადეთ"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"თითის ანაბეჭდის ამოცნობა ვერ მოხერხდა"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"თითის ანაბეჭდის ამოცნობა ვერ მოხერხდა"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"მაგრად დააჭირეთ სენსორს"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"თითის ანაბეჭდი ავტორიზებულია"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"სახე ავტორიზებულია"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"სახე ავტორიზებულია, დააჭირეთ დადასტურებას"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"<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> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"აპი მიუწვდომელია"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ამჟამად ამ აპზე თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან წვდომა შეუძლებელია. ცადეთ Android TV მოწყობილობიდან."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ამჟამად ამ აპზე თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან წვდომა შეუძლებელია. ცადეთ ტაბლეტიდან."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ამჟამად ამ აპზე თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან წვდომა შეუძლებელია. ცადეთ ტელეფონიდან."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"მაინც გახსნა"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"აღმოჩენილია საზიანო აპი"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"გსურთ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>-ს მიანიჭოთ მოწყობილობის ყველა ჟურნალზე წვდომა?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"ერთჯერადი წვდომის დაშვება"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"მხოლოდ ამ ერთხელ"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"არ დაიშვას"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"მოწყობილობის ჟურნალში იწერება, რა ხდება ამ მოწყობილობაზე. აპებს შეუძლია ამ ჟურნალების გამოყენება პრობლემების აღმოსაჩენად და მოსაგვარებლად.\n\nზოგი ჟურნალი შეიძლება სენსიტიური ინფორმაციის მატარებელი იყოს, ამიტომაც მოწყობილობის ყველა ჟურნალზე წვდომა მხოლოდ სანდო აპებს მიანიჭეთ. \n\nთუ ამ აპს მოწყობილობის ყველა ჟურნალზე წვდომას არ მიანიჭებთ, მას მაინც ექნება წვდომა თქვენს ჟურნალებზე. თქვენი მოწყობილობის მწარმოებელს მაინც შეეძლება თქვენი მოწყობილობის ზოგიერთ ჟურნალსა თუ ინფორმაციაზე წვდომა. შეიტყვეთ მეტი"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"აღარ გამოჩნდეს"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>-ს სურს, გაჩვენოთ <xliff:g id="APP_2">%2$s</xliff:g>-ის ფრაგმენტები"</string> <string name="screenshot_edit" msgid="7408934887203689207">"რედაქტირება"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> იმოქმედებს ბატარეის მუშაობის ხანგრძლივობაზე. შეეხეთ აქტიური აპების მიმოხილვისთვის."</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"აქტივობა ფონურ რეჟიმში"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> გაშვებულია ფონში და იყენებს ბატარეას. შეეხეთ გადასახედად."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ტაბლეტის კამერაზე წვდომა ვერ მოხერხდა თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"სისტემის ენა"</string> </resources> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index c7d314690661..6a2064d46f7e 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Аутентификациялауда қате шықты."</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Экран құлпын пайдалану"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Жалғастыру үшін экран құлпын енгізіңіз."</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Саусақ ізі жартылай анықталды."</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Саусақ ізін өңдеу мүмкін емес. Әрекетті қайталаңыз."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Саусақ ізін оқу сканерін тазалап, әрекетті қайталаңыз."</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Сканерді тазалап, әрекетті қайталаңыз."</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Саусақ ізі танылмады."</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Сканерге қатты басыңыз."</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Саусақ ізі аутентификацияланды"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Бет танылды"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Бет танылды, \"Растау\" түймесін басыңыз"</string> @@ -1681,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"<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> @@ -1851,8 +1850,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> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Қолданба қолжетімді емес"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Қазір бұған <xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан кіру мүмкін емес. Оның орнына Android TV құрылғысын пайдаланып көріңіз."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Қазір бұған <xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан кіру мүмкін емес. Оның орнына планшетті пайдаланып көріңіз."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Қазір бұған <xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан кіру мүмкін емес. Оның орнына телефонды пайдаланып көріңіз."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"БӘРІБІР АШУ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Зиянды қолданба анықталды"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> қолданбасына барлық құрылғының журналын пайдалануға рұқсат берілсін бе?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Тек осы жолы"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Рұқсат бермеу"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Журналдарға құрылғыда не болып жатқаны жазылады. Қолданбалар осы журналдарды қате тауып, түзету үшін пайдаланады.\n\nКейбір журналдарда құпия ақпарат болуы мүмкін. Сондықтан барлық құрылғының журналын пайдалану рұқсаты тек сенімді қолданбаларға берілуі керек. \n\nБұл қолданбаға барлық құрылғының журналын пайдалануға рұқсат бермесеңіз де, ол өзінің журналдарын пайдалана береді. Құрылғы өндірушісі де құрылғыдағы кейбір журналдарды немесе ақпаратты пайдалануы мүмкін. Толығырақ"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Қайта көрсетілмесін"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> қолданбасы <xliff:g id="APP_2">%2$s</xliff:g> қолданбасының үзінділерін көрсеткісі келеді"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Өзгерту"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Фондық режимдегі әрекет"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> қолданбасы фондық режимде жұмыс істеуде және батарея жұмсауда. Көру үшін түртіңіз."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> қолданбасы ұзақ уақыт бойы фондық режимде жұмыс істеуде. Көру үшін түртіңіз."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Белсенді қолданбаларды тексеру"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан планшет камерасын пайдалану мүмкін емес."</string> <string name="system_locale_title" msgid="3978041860457277638">"Жүйе тілі"</string> </resources> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 0bd230553de7..a8225c3d4e41 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"មានបញ្ហាក្នុងការផ្ទៀងផ្ទាត់"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ប្រើការចាក់សោអេក្រង់"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"បញ្ចូលការចាក់សោអេក្រង់របស់អ្នក ដើម្បីបន្ត"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"សង្កត់លើឧបករណ៍ចាប់សញ្ញាឱ្យណែន"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"បានសម្គាល់ស្នាមម្រាមដៃដោយផ្នែក"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"មិនអាចដំណើរការស្នាមម្រាមដៃបានទេ។ សូមព្យាយាមម្តងទៀត។"</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"សម្អាតឧបករណ៍ចាប់ស្នាមម្រាមដៃ រួចព្យាយាមម្ដងទៀត"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"សម្អាតឧបករណ៍ចាប់សញ្ញា រួចព្យាយាមម្ដងទៀត"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"មិនស្គាល់ស្នាមម្រាមដៃទេ"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"មិនស្គាល់ស្នាមម្រាមដៃទេ"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"សង្កត់លើឧបករណ៍ចាប់សញ្ញាឱ្យណែន"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"បានផ្ទៀងផ្ទាត់ស្នាមម្រាមដៃ"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"បានផ្ទៀងផ្ទាត់មុខ"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"បានផ្ទៀងផ្ទាត់មុខ សូមចុចបញ្ជាក់"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"បើអ្នកបើក <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> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"មិនអាចប្រើកម្មវិធីនេះបានទេ"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"មិនអាចប្រើកម្មវិធីនេះនៅលើ <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នកនៅពេលនេះបានទេ។ សូមសាកល្បងប្រើនៅលើឧបករណ៍ Android TV របស់អ្នកជំនួសវិញ។"</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"មិនអាចប្រើកម្មវិធីនេះនៅលើ <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នកនៅពេលនេះបានទេ។ សូមសាកល្បងប្រើនៅលើថេប្លេតរបស់អ្នកជំនួសវិញ។"</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"មិនអាចប្រើកម្មវិធីនេះនៅលើ <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នកនៅពេលនេះបានទេ។ សូមសាកល្បងប្រើនៅលើទូរសព្ទរបស់អ្នកជំនួសវិញ។"</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"មិនអីទេ បើកចុះ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"បានរកឃើញកម្មវិធីដែលបង្កគ្រោះថ្នាក់"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"អនុញ្ញាតឱ្យ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ចូលប្រើកំណត់ហេតុឧបករណ៍ទាំងអស់ឬ?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"អនុញ្ញាតការចូលប្រើតែម្ដង"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"តែពេលនេះប៉ុណ្ណោះ"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"មិនអនុញ្ញាត"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"កំណត់ហេតុឧបករណ៍កត់ត្រាអ្វីដែលកើតឡើងនៅលើឧបករណ៍របស់អ្នក។ កម្មវិធីអាចប្រើកំណត់ហេតុទាំងនេះដើម្បីស្វែងរក និងដោះស្រាយបញ្ហាបាន។\n\nកំណត់ហេតុមួយចំនួនអាចមានព័ត៌មានរសើប ដូច្នេះគួរអនុញ្ញាតឱ្យចូលប្រើកំណត់ហេតុឧបករណ៍ទាំងអស់សម្រាប់តែកម្មវិធីដែលអ្នកទុកចិត្តប៉ុណ្ណោះ។ \n\nប្រសិនបើអ្នកមិនអនុញ្ញាតឱ្យកម្មវិធីនេះចូលប្រើកំណត់ហេតុឧបករណ៍ទាំងអស់ទេ វានៅតែអាចចូលប្រើកំណត់ហេតុរបស់វាផ្ទាល់បាន។ ក្រុមហ៊ុនផលិតឧបករណ៍របស់អ្នកប្រហែលជានៅតែអាចចូលប្រើកំណត់ហេតុ ឬព័ត៌មានមួយចំនួននៅលើឧបករណ៍របស់អ្នកបានដដែល។ ស្វែងយល់បន្ថែម"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"កុំបង្ហាញម្ដងទៀត"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ចង់បង្ហាញស្ថិតិប្រើប្រាស់របស់ <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"កែសម្រួល"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> អាចប៉ះពាល់ដល់កម្រិតថាមពលថ្ម។ សូមចុច ដើម្បីពិនិត្យមើលកម្មវិធីដែលសកម្ម។"</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"សកម្មភាពនៅផ្ទៃខាងក្រោយ"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> កំពុងដំណើរការនៅផ្ទៃខាងក្រោយ និងធ្វើឱ្យអស់ថ្មលឿន។ សូមចុច ដើម្បីពិនិត្យមើល។"</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"មិនអាចចូលប្រើកាមេរ៉ាថេប្លេតពី <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នកបានទេ"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"ភាសាប្រព័ន្ធ"</string> </resources> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index c1e1ba4d7041..b9e17b60de67 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"ದೃಢೀಕರಿಸುವಾಗ ದೋಷ ಎದುರಾಗಿದೆ"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬಳಸಿ"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ಮುಂದುವರಿಯಲು ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ನಮೂದಿಸಿ"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"ಸೆನ್ಸರ್ ಮೇಲೆ ದೃಢವಾಗಿ ಒತ್ತಿರಿ"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"ಭಾಗಶಃ ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಪತ್ತೆಯಾಗಿದೆ"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಅನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ದಯವಿಟ್ಟು ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಸ್ವಚ್ಛಗೊಳಿಸಿ ಹಾಗೂ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ಸೆನ್ಸರ್ ಸ್ವಚ್ಛಗೊಳಿಸಿ ಹಾಗೂ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಅನ್ನು ಗುರುತಿಸಲಾಗಿಲ್ಲ"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಅನ್ನು ಗುರುತಿಸಲಾಗಿಲ್ಲ"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"ಸೆನ್ಸರ್ ಮೇಲೆ ದೃಢವಾಗಿ ಒತ್ತಿರಿ"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಅನ್ನು ಪ್ರಮಾಣೀಕರಣ ಮಾಡಲಾಗಿದೆ"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ, ದೃಢೀಕರಣವನ್ನು ಒತ್ತಿ"</string> @@ -1355,7 +1355,7 @@ <string name="usb_power_notification_message" msgid="7284765627437897702">"ಸಂಪರ್ಕಗೊಂಡಿರುವ ಸಾಧನವನ್ನು ಚಾರ್ಜ್ ಮಾಡಲಾಗುತ್ತಿದೆ. ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string> <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"ಅನ್ಲಾಗ್ ಆಡಿಯೋ ಪರಿಕರ ಪತ್ತೆಯಾಗಿದೆ"</string> <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ಲಗತ್ತಿಸಲಾದ ಸಾಧನವು ಈ ಫೋನಿನೊಂದಿಗೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> - <string name="adb_active_notification_title" msgid="408390247354560331">"USB ಡೀಬಗಿಂಗ್ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string> + <string name="adb_active_notification_title" msgid="408390247354560331">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string> <string name="adb_active_notification_message" msgid="5617264033476778211">"USB ಡೀಬಗಿಂಗ್ ಆಫ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಆಯ್ಕೆ ಮಾಡಿ."</string> <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"ವೈರ್ಲೆಸ್ ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"ನೀವು <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> @@ -2026,9 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ಹೇಗಿದ್ದರೂ ತೆರೆಯಿರಿ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"ಅಪಾಯಕಾರಿ ಅಪ್ಲಿಕೇಶನ್ ಕಂಡುಬಂದಿದೆ"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"ಎಲ್ಲಾ ಸಾಧನದ ಲಾಗ್ಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ಗೆ ಅನುಮತಿಸುವುದೇ?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"ಒಂದು ಬಾರಿಯ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸಿ"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"ಈ ಬಾರಿ ಮಾತ್ರ"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"ಅನುಮತಿಸಬೇಡಿ"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿನ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಸಾಧನದ ಲಾಗ್ಗಳು ರೆಕಾರ್ಡ್ ಮಾಡುತ್ತವೆ. ಸಮಸ್ಯೆಗಳನ್ನು ಪತ್ತೆಹಚ್ಚಲು ಮತ್ತು ಪರಿಹರಿಸಲು ಆ್ಯಪ್ಗಳು ಈ ಲಾಗ್ ಅನ್ನು ಬಳಸಬಹುದು.\n\nಕೆಲವು ಲಾಗ್ಗಳು ಸೂಕ್ಷ್ಮ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಿರಬಹುದು, ಆದ್ದರಿಂದ ನಿಮ್ಮ ವಿಶ್ವಾಸಾರ್ಹ ಆ್ಯಪ್ಗಳಿಗೆ ಮಾತ್ರ ಸಾಧನದ ಎಲ್ಲಾ ಲಾಗ್ಗಳಿಗೆ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸಿ. \n\nಎಲ್ಲಾ ಸಾಧನ ಲಾಗ್ಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ನೀವು ಈ ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸದಿದ್ದರೆ, ಅದು ಆಗಲೂ ತನ್ನದೇ ಆದ ಲಾಗ್ಗಳನ್ನು ಪ್ರವೇಶಿಸಬಹುದು. ನಿಮ್ಮ ಸಾಧನ ತಯಾರಕರಿಗೆ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿನ ಕೆಲವು ಲಾಗ್ಗಳು ಅಥವಾ ಮಾಹಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಲು ಈಗಲೂ ಸಾಧ್ಯವಾಗುತ್ತದೆ. ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"ಮತ್ತೊಮ್ಮೆ ತೋರಿಸಬೇಡಿ"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_2">%2$s</xliff:g> ಸ್ಲೈಸ್ಗಳನ್ನು <xliff:g id="APP_0">%1$s</xliff:g> ತೋರಿಸಲು ಬಯಸಿದೆ"</string> <string name="screenshot_edit" msgid="7408934887203689207">"ಎಡಿಟ್"</string> @@ -2258,12 +2260,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ಬ್ಯಾಟರಿ ಬಾಳಿಕೆಯ ಮೇಲೆ ಪ್ರಭಾವ ಬೀರಬಹುದು. ಸಕ್ರಿಯ ಆ್ಯಪ್ಗಳನ್ನು ಪರಿಶೀಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"ಹಿನ್ನೆಲೆ ಚಟುವಟಿಕೆ"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿದ್ದು ಬ್ಯಾಟರಿ ಖಾಲಿ ಮಾಡುತ್ತಿದೆ. ಪರಿಶೀಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ನಿಮ್ಮ <xliff:g id="DEVICE">%1$s</xliff:g> ಮೂಲಕ ಟ್ಯಾಬ್ಲೆಟ್ನ ಕ್ಯಾಮರಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"ಸಿಸ್ಟಂ ಭಾಷೆ"</string> </resources> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 960e30594687..1b657b661c9b 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -323,7 +323,7 @@ <string name="permgroupdesc_calllog" msgid="2026996642917801803">"통화 기록 읽고 쓰기"</string> <string name="permgrouplab_phone" msgid="570318944091926620">"전화"</string> <string name="permgroupdesc_phone" msgid="270048070781478204">"전화 걸기 및 관리"</string> - <string name="permgrouplab_sensors" msgid="9134046949784064495">"생체 신호 센서"</string> + <string name="permgrouplab_sensors" msgid="9134046949784064495">"신체 센서"</string> <string name="permgroupdesc_sensors" msgid="2610631290633747752">"생체 신호에 관한 센서 데이터에 액세스"</string> <string name="permgrouplab_notifications" msgid="5472972361980668884">"알림"</string> <string name="permgroupdesc_notifications" msgid="4608679556801506580">"알림 표시"</string> @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"인증 오류"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"화면 잠금 사용"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"계속하려면 화면 잠금용 사용자 인증 정보를 입력하세요"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"지문의 일부만 감지됨"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"지문을 인식할 수 없습니다. 다시 시도해 주세요."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"지문 센서를 닦은 후 다시 시도해 보세요."</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"센서를 닦은 후 다시 시도해 보세요."</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"지문이 인식되지 않습니다."</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"센서 위에 손가락을 좀 더 오래 올려놓으세요."</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"지문이 인증됨"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"얼굴이 인증되었습니다"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"얼굴이 인증되었습니다. 확인을 누르세요"</string> @@ -1681,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"<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> @@ -1851,8 +1850,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> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"앱을 사용할 수 없습니다"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"현재 <xliff:g id="DEVICE">%1$s</xliff:g>에서 액세스할 수 없습니다. 대신 Android TV 기기에서 시도해 보세요."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"현재 <xliff:g id="DEVICE">%1$s</xliff:g>에서 액세스할 수 없습니다. 대신 태블릿에서 시도해 보세요."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"현재 <xliff:g id="DEVICE">%1$s</xliff:g>에서 액세스할 수 없습니다. 대신 스마트폰에서 시도해 보세요."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"열기"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"유해한 앱 감지됨"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>에서 모든 기기에 액세스하도록 허용하시겠습니까?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"이번만 허용"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"허용 안함"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"기기 로그에 기기에서 발생한 상황이 기록됩니다. 앱은 문제를 찾고 해결하는 데 이 로그를 사용할 수 있습니다.\n\n일부 로그는 민감한 정보를 포함할 수 있으므로 신뢰할 수 있는 앱만 모든 기기 로그에 액세스하도록 허용하세요. \n\n앱에 전체 기기 로그에 대한 액세스 권한을 부여하지 않아도 앱이 자체 로그에는 액세스할 수 있습니다. 기기 제조업체에서 일부 로그 또는 기기 내 정보에 액세스할 수도 있습니다. 자세히 알아보기"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"다시 표시 안함"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>에서 <xliff:g id="APP_2">%2$s</xliff:g>의 슬라이스를 표시하려고 합니다"</string> <string name="screenshot_edit" msgid="7408934887203689207">"수정"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"백그라운드 활동"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> 앱이 백그라운드에서 실행 중이며 배터리를 소모하고 있습니다. 확인하려면 탭하세요."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> 앱이 백그라운드에서 오랫동안 실행 중입니다. 확인하려면 탭하세요."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"활성 상태의 앱 확인"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"사용자의 <xliff:g id="DEVICE">%1$s</xliff:g>에서 태블릿 카메라에 액세스할 수 없습니다."</string> <string name="system_locale_title" msgid="3978041860457277638">"시스템 언어"</string> </resources> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 79d275e14975..5983ddfb8cd2 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Аутентификация катасы"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Экран кулпусун колдонуу"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Улантуу үчүн экрандын кулпусун киргизиңиз"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Сенсорду катуу басыңыз"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Манжа изи жарым-жартылай аныкталды"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Манжа изи иштелбей койду. Кайталап көрүңүз."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Манжа изинин сенсорун тазалап, кайра аракет кылыңыз"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Сенсорду тазалап, кайра аракет кылыңыз"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Манжа изи таанылган жок"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Манжа изи таанылган жок"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Сенсорду катуу басыңыз"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Манжа изи текшерилди"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Жүздүн аныктыгы текшерилди"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Жүздүн аныктыгы текшерилди, эми \"Ырастоону\" басыңыз"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"Эгер <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> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Колдонмо учурда жеткиликсиз"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Учурда буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Android TV түзмөгүңүздөн аракет кылып көрүңүз."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Учурда буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Планшетиңизден кирип көрүңүз."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Учурда буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Анын ордуна телефондон кирип көрүңүз."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"БААРЫ БИР АЧЫЛСЫН"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Зыянкеч колдонмо аныкталды"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> колдонмосуна түзмөктөгү бардык таржымалдарды колдонууга уруксат бересизби?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Бир жолу кирүүгө уруксат берүү"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Ушул жолу гана"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Уруксат берилбесин"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Түзмөктө аткарылган бардык аракеттер түзмөктүн таржымалдарында сакталып калат. Колдонмолор бул таржымалдарды колдонуп, маселелерди оңдошот.\n\nАйрым таржымалдарда купуя маалымат болушу мүмкүн, андыктан түзмөктөгү бардык таржымалдарды ишенимдүү колдонмолорго гана пайдаланууга уруксат бериңиз. \n\nЭгер бул колдонмого түзмөктөгү айрым таржымалдарга кирүүгө тыюу салсаңыз, ал өзүнүн таржымалдарын пайдалана берет. Түзмөктү өндүрүүчү түзмөгүңүздөгү айрым таржымалдарды же маалыматты көрө берет. Кеңири маалымат"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Экинчи көрүнбөсүн"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> колдонмосу <xliff:g id="APP_2">%2$s</xliff:g> үлгүлөрүн көрсөткөнү жатат"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Түзөтүү"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> батареянын кубатынын мөөнөтүн азайтышы мүмкүн. Жигердүү колдонмолорду көрүү үчүн таптап коюңуз."</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Фондогу активдүүлүк"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> фондо иштеп, батареяны отургузуп жатат. Көрүү үчүн таптап коюңуз."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн планшетиңиздин камерасына мүмкүнчүлүк жок"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Тутумдун тили"</string> </resources> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 5f08cb74131b..6ed5f1c5625a 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"ເກີດຄວາມຜິດພາດໃນການພິສູດຢືນຢັນ"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ໃຊ້ການລັອກໜ້າຈໍ"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ໃສ່ການລັອກໜ້າຈໍຂອງທ່ານເພື່ອສືບຕໍ່"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"ກວດພົບລາຍນິ້ວມືບາງສ່ວນ"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ບໍ່ສາມາດດຳເນີນການລາຍນີ້ວມືໄດ້. ກະລຸນາລອງໃໝ່ອີກ."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ໃຫ້ອະນາໄມເຊັນເຊີລາຍນິ້ວມືແລ້ວລອງໃໝ່"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ໃຫ້ອະນາໄມເຊັນເຊີແລ້ວລອງໃໝ່"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ບໍ່ຮູ້ຈັກລາຍນິ້ວມື"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"ກົດຢູ່ເຊັນເຊີໃຫ້ແໜ້ນ"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ພິສູດຢືນຢັນລາຍນິ້ວມືແລ້ວ"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ພິສູດຢືນຢັນໃບໜ້າແລ້ວ"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ພິສູດຢືນຢັນໃບໜ້າແລ້ວ, ກະລຸນາກົດຢືນຢັນ"</string> @@ -1681,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"ຫາກທ່ານເປີດໃຊ້ <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> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"ແອັບບໍ່ສາມາດໃຊ້ໄດ້"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ບໍ່ສາມາດເຂົ້າເຖິງແອັບນີ້ໄດ້ຢູ່ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໃນຕອນນີ້. ກະລຸນາລອງໃຊ້ຢູ່ອຸປະກອນ Android TV ຂອງທ່ານແທນ."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ບໍ່ສາມາດເຂົ້າເຖິງແອັບນີ້ໄດ້ຢູ່ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໃນຕອນນີ້. ກະລຸນາລອງຢູ່ແທັບເລັດຂອງທ່ານແທນ."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ບໍ່ສາມາດເຂົ້າເຖິງແອັບນີ້ໄດ້ຢູ່ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໃນຕອນນີ້. ກະລຸນາລອງຢູ່ໂທລະສັບຂອງທ່ານແທນ."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ຢືນຢັນການເປີດ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"ກວດສອບແອັບທີ່ເປັນອັນຕະລາຍ"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"ອະນຸຍາດໃຫ້ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ເຂົ້າເຖິງບັນທຶກອຸປະກອນທັງໝົດບໍ?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"ສະເພາະເທື່ອນີ້"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"ບໍ່ອະນຸຍາດ"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"ບັນທຶກອຸປະກອນຈະບັນທຶກສິ່ງທີ່ເກີດຂຶ້ນຢູ່ອຸປະກອນຂອງທ່ານ. ແອັບສາມາດໃຊ້ບັນທຶກເຫຼົ່ານີ້ເພື່ອຊອກຫາ ແລະ ແກ້ໄຂບັນຫາໄດ້.\n\nບັນທຶກບາງຢ່າງອາດມີຂໍ້ມູນລະອຽດອ່ອນ, ດັ່ງນັ້ນໃຫ້ອະນຸຍາດສະເພາະແອັບທີ່ທ່ານເຊື່ອຖືໃຫ້ເຂົ້າເຖິງບັນທຶກອຸປະກອນທັງໝົດເທົ່ານັ້ນ. \n\nຫາກທ່ານບໍ່ອະນຸຍາດແອັບນີ້ໃຫ້ເຂົ້າເຖິງບັນທຶກອຸປະກອນທັງໝົດ, ມັນຈະຍັງຄົງສາມາດເຂົ້າເຖິງບັນທຶກຂອງຕົວມັນເອງໄດ້ຢູ່. ຜູ້ຜະລິດອຸປະກອນຂອງທ່ານອາດຍັງຄົງສາມາດເຂົ້າເຖິງບັນທຶກ ຫຼື ຂໍ້ມູນບາງຢ່າງຢູ່ອຸປະກອນຂອງທ່ານໄດ້. ສຶກສາເພີ່ມເຕີມ"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"ບໍ່ຕ້ອງສະແດງອີກ"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ຕ້ອງການສະແດງ <xliff:g id="APP_2">%2$s</xliff:g> ສະໄລ້"</string> <string name="screenshot_edit" msgid="7408934887203689207">"ແກ້ໄຂ"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"ການເຄື່ອນໄຫວໃນພື້ນຫຼັງ"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ກຳລັງເຮັດວຽກໃນພື້ນຫຼັງ ແລະ ໃຊ້ແບັດເຕີຣີຫຼາຍ. ແຕະເພື່ອກວດສອບ."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ກຳລັງເຮັດວຽກໃນພື້ນຫຼັງເປັນເວລາດົນແລ້ວ. ແຕະເພື່ອກວດສອບ."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ກວດສອບແອັບທີ່ເຄື່ອນໄຫວ"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ບໍ່ສາມາດເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຂອງແທັບເລັດຈາກ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໄດ້"</string> <string name="system_locale_title" msgid="3978041860457277638">"ພາສາລະບົບ"</string> </resources> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 57a607991fc6..00089d4fe126 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -587,7 +587,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Autentifikuojant įvyko klaida"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Naudoti ekrano užraktą"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Jei norite tęsti, įveskite ekrano užraktą"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Tvirtai paspauskite jutiklį"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Aptiktas dalinis kontrolinis kodas"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nepavyko apdoroti piršto antspaudo. Bandykite dar kartą."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Nuvalykite kontrolinio kodo jutiklį ir bandykite dar kartą"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Nuvalykite jutiklį ir bandykite dar kartą"</string> @@ -600,7 +600,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Kontrolinis kodas neatpažintas"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Kontrolinis kodas neatpažintas"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Tvirtai paspauskite jutiklį"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Piršto antspaudas autentifikuotas"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Veidas autentifikuotas"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Veidas autentifikuotas, paspauskite patvirtinimo mygtuką"</string> @@ -1681,6 +1681,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ĮJUNGTA"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"IŠJUNGTA"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Leisti „<xliff:g id="SERVICE">%1$s</xliff:g>“ valdyti visas įrenginio funkcijas?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Jei įjungsite „<xliff:g id="SERVICE">%1$s</xliff:g>“, įrenginyje nebus naudojamas ekrano užraktas siekiant patobulinti duomenų šifruotę."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Galimybę valdyti visas funkcijas patariama suteikti programoms, kurios padeda specialiųjų poreikių turintiems asmenims, bet ne daugumai programų."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ekrano peržiūra ir valdymas"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Naudojant šį ekrano valdiklį galima skaityti visą ekrane rodomą turinį ir rodyti turinį virš kitų programų."</string> @@ -1934,7 +1935,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Programa nepasiekiama."</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Šį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" product="tablet" msgid="4242053045964946062">"Šį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" product="default" msgid="6159168735030739398">"Šįkart nepavyksta pasiekti programos iš jūsų „<xliff:g id="DEVICE">%1$s</xliff:g>“. Pabandykite naudoti telefoną."</string> @@ -2028,9 +2030,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"VIS TIEK ATIDARYTI"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Aptikta žalinga programa"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Leisti „<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>“ pasiekti visus įrenginio žurnalus?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Leisti vienkartinę prieigą"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Tik šį kartą"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Neleisti"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Įrenginyje įrašoma, kas įvyksta jūsų įrenginyje. Programos gali naudoti šiuos žurnalus, kad surastų ir išspręstų problemas.\n\nKai kuriuose žurnaluose gali būti neskelbtinos informacijos, todėl visus įrenginio žurnalus leiskite pasiekti tik programoms, kuriomis pasitikite. \n\nJei neleisite šiai programai pasiekti visų įrenginio žurnalų, ji vis tiek galės pasiekti savo žurnalus. Įrenginio gamintojui vis tiek gali būti leidžiama pasiekti tam tikrus žurnalus ar informaciją jūsų įrenginyje. Sužinokite daugiau"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Daugiau neberodyti"</string> <string name="slices_permission_request" msgid="3677129866636153406">"„<xliff:g id="APP_0">%1$s</xliff:g>“ nori rodyti „<xliff:g id="APP_2">%2$s</xliff:g>“ fragmentus"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Redaguoti"</string> @@ -2260,12 +2263,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Veikla fone"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"„<xliff:g id="APP">%1$s</xliff:g>“ veikia fone ir eikvoja akumuliatoriaus energiją. Palieskite ir peržiūrėkite."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"„<xliff:g id="APP">%1$s</xliff:g>“ ilgą laiką veikia fone. Palieskite ir peržiūrėkite."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nepavyko pasiekti planšetinio kompiuterio fotoaparato iš „<xliff:g id="DEVICE">%1$s</xliff:g>“"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Sistemos kalba"</string> </resources> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 77580cbb32be..db66cea86007 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -586,8 +586,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Autentifikācijas kļūda"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekrāna bloķēšanas metodes izmantošana"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Lai turpinātu, ievadiet ekrāna bloķēšanas informāciju"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Tika konstatēts nepilnīgs pilna nospiedums"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nevarēja apstrādāt pirksta nospiedumu. Lūdzu, mēģiniet vēlreiz."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Notīriet pirkstu nospiedumu sensoru un mēģiniet vēlreiz"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Notīriet sensoru un mēģiniet vēlreiz"</string> @@ -600,8 +599,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Pirksta nospiedums netika atpazīts"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Stingri spiediet pirkstu pie sensora"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Pirksta nospiedums tika autentificēts."</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Seja autentificēta"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Seja ir autentificēta. Nospiediet pogu Apstiprināt."</string> @@ -1682,6 +1680,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"IESLĒGTA"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"IZSLĒGTA"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vai atļaut pakalpojumam <xliff:g id="SERVICE">%1$s</xliff:g> pilnībā kontrolēt jūsu ierīci?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ja ieslēgsiet pakalpojumu <xliff:g id="SERVICE">%1$s</xliff:g>, ierīce neizmantos ekrāna bloķēšanu datu šifrēšanas uzlabošanai."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Pilnīga kontrole ir piemērota lietotnēm, kas nepieciešamas lietotājiem ar īpašām vajadzībām, taču ne lielākajai daļai lietotņu."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Skatīt un pārvaldīt ekrānu"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Tā var nolasīt visu ekrānā esošo saturu un attēlot saturu citām lietotnēm."</string> @@ -1935,7 +1934,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Lietotne nav pieejama"</string> <string name="app_blocked_message" msgid="542972921087873023">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> pašlaik nav pieejama."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nav pieejams"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Nepieciešama atļauja"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Šajā ierīcē (<xliff:g id="DEVICE">%1$s</xliff:g>) pašlaik nevar piekļūt šai lietotnei. Mēģiniet tai piekļūt savā Android TV ierīcē."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Šajā ierīcē (<xliff:g id="DEVICE">%1$s</xliff:g>) pašlaik nevar piekļūt šai lietotnei. Mēģiniet tai piekļūt savā planšetdatorā."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Šajā ierīcē (<xliff:g id="DEVICE">%1$s</xliff:g>) pašlaik nevar piekļūt šai lietotnei. Mēģiniet tai piekļūt savā tālrunī."</string> @@ -2029,10 +2029,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"TIK UN TĀ ATVĒRT"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Konstatēta kaitīga lietotne"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Vai atļaujat lietotnei <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> piekļūt visiem ierīces žurnāliem?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Tikai šoreiz"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Neatļaut"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Ierīces žurnālos tiek reģistrēti ierīces procesi un notikumi. Lietotņu izstrādātāji var izmantot šos žurnālus, lai atrastu un novērstu problēmas savās lietotnēs.\n\nDažos žurnālos var būt ietverta sensitīva informācija, tāpēc atļaujiet tikai uzticamām lietotnēm piekļūt visiem ierīces žurnāliem. \n\nJa neatļausiet šai lietotnei piekļūt visiem ierīces žurnāliem, lietotnes izstrādātājs joprojām varēs piekļūt pašas lietotnes žurnāliem. Jūsu ierīces ražotājs, iespējams, joprojām varēs piekļūt noteiktiem žurnāliem vai informācijai jūsu ierīcē. Uzziniet vairāk."</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Vairs nerādīt"</string> <string name="slices_permission_request" msgid="3677129866636153406">"Lietotne <xliff:g id="APP_0">%1$s</xliff:g> vēlas rādīt lietotnes <xliff:g id="APP_2">%2$s</xliff:g> sadaļas"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Rediģēt"</string> @@ -2262,16 +2262,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Darbība fonā"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> darbojas fonā un patērē akumulatora enerģiju. Pieskarieties, lai to pārskatītu."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ilgi darbojas fonā. Pieskarieties, lai to pārskatītu."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Pārbaudiet aktīvās lietotnes"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nevar piekļūt planšetdatora kamerai no jūsu ierīces (<xliff:g id="DEVICE">%1$s</xliff:g>)."</string> <string name="system_locale_title" msgid="3978041860457277638">"Sistēmas valoda"</string> </resources> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index ddec737a0ba2..77532be1c1aa 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -426,7 +426,7 @@ <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="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> @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Грешка при проверката"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Користи заклучување екран"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Внесете го заклучувањето на екранот за да продолжите"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Откриен е делумен отпечаток"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Отпечатокот не може да се обработи. Обидете се повторно."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Исчистете го сензорот за отпечатоци и обидете се повторно"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Исчистете го сензорот и обидете се повторно"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Отпечатокот не е препознаен"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Цврсто притиснете на сензорот"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечатокот е проверен"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Лицето е проверено"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лицето е проверено, притиснете го копчето „Потврди“"</string> @@ -1681,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"Ако вклучите <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> @@ -2028,10 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"СЕПАК ОТВОРИ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Откриена е штетна апликација"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Да се дозволи <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> да пристапува до целата евиденција на уредот?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Само овој пат"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Не дозволувај"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Евиденцијата на уредот снима што се случува со вашиот уред. Апликациите можат да ја користат евиденцијата за да наоѓаат и поправаат проблеми.\n\nНекоја евиденција може да содржи чувствителни податоци, па затоа дозволувајте само апликации на кои им верувате да пристапуваат до целата евиденција на уредот. \n\nАко не ѝ дозволите на апликацијава да пристапува до сите евиденции на уредот, сепак ќе може да пристапува до сопствената евиденција. Производителот на вашиот уред можеби сепак ќе може да пристапува до некои евиденции или податоци на уредот. Дознајте повеќе"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Не прикажувај повторно"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> сака да прикажува делови од <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Измени"</string> @@ -2261,16 +2260,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Активност во заднина"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> работи во заднина и ја троши батеријата. Допрете за да прегледате."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> работи во заднина веќе долго време. Допрете за да прегледате."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверете ги активните апликации"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не може да се пристапи до камерата на вашиот таблет од <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="system_locale_title" msgid="3978041860457277638">"Јазик на системот"</string> </resources> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index e5da11b94dc9..ab701d387e34 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -323,7 +323,7 @@ <string name="permgroupdesc_calllog" msgid="2026996642917801803">"ഫോൺ കോൾ ലോഗ് വായിക്കുകയും എഴുതുകയും ചെയ്യുക"</string> <string name="permgrouplab_phone" msgid="570318944091926620">"ഫോണ്"</string> <string name="permgroupdesc_phone" msgid="270048070781478204">"ഫോൺ വിളിക്കുകയും നിയന്ത്രിക്കുകയും ചെയ്യുക"</string> - <string name="permgrouplab_sensors" msgid="9134046949784064495">"ബോഡി സെൻസറുകൾ"</string> + <string name="permgrouplab_sensors" msgid="9134046949784064495">"ബോഡി സെൻസർ"</string> <string name="permgroupdesc_sensors" msgid="2610631290633747752">"നിങ്ങളുടെ ജീവാധാര ലക്ഷണങ്ങളെ കുറിച്ചുള്ള സെൻസർ വിവരങ്ങൾ ആക്സസ് ചെയ്യുക"</string> <string name="permgrouplab_notifications" msgid="5472972361980668884">"അറിയിപ്പുകൾ"</string> <string name="permgroupdesc_notifications" msgid="4608679556801506580">"അറിയിപ്പുകൾ കാണിക്കുക"</string> @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"പിശക് പരിശോധിച്ചുറപ്പിക്കുന്നു"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"സ്ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"തുടരാൻ നിങ്ങളുടെ സ്ക്രീൻ ലോക്ക് നൽകുക"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"സെൻസറിന് മുകളിൽ ശക്തിയായി അമർത്തുക"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"ഫിംഗർപ്രിന്റ് ഭാഗികമായി തിരിച്ചറിഞ്ഞു"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ഫിംഗർപ്രിന്റ് പ്രോസസ് ചെയ്യാനായില്ല. വീണ്ടും ശ്രമിക്കുക."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ഫിംഗർപ്രിന്റ് സെൻസർ വൃത്തിയാക്കിയ ശേഷം വീണ്ടും ശ്രമിക്കുക"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"സെൻസർ വൃത്തിയാക്കിയ ശേഷം വീണ്ടും ശ്രമിക്കുക"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ഫിംഗർപ്രിന്റ് തിരിച്ചറിഞ്ഞില്ല"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"ഫിംഗർപ്രിന്റ് തിരിച്ചറിഞ്ഞില്ല"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"സെൻസറിന് മുകളിൽ ശക്തിയായി അമർത്തുക"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ഫിംഗർപ്രിന്റ് പരിശോധിച്ചുറപ്പിച്ചു"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"മുഖം പരിശോധിച്ചുറപ്പിച്ചു"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"മുഖം പരിശോധിച്ചുറപ്പിച്ചു, സ്ഥിരീകരിക്കുക അമർത്തുക"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"<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> @@ -2026,9 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"എന്തായാലും തുറക്കുക"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"ദോഷകരമായ ആപ്പ് കണ്ടെത്തി"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"എല്ലാ ഉപകരണ ലോഗുകളും ആക്സസ് ചെയ്യാൻ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> എന്നതിനെ അനുവദിക്കണോ?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"ഒറ്റത്തവണ ആക്സസ് അനുവദിക്കുക"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"ഇപ്രാവശ്യം മാത്രം"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"അനുവദിക്കരുത്"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"നിങ്ങളുടെ ഉപകരണത്തിൽ എന്തൊക്കെയാണ് സംഭവിക്കുന്നതെന്ന് ഉപകരണ ലോഗുകൾ റെക്കോർഡ് ചെയ്യുന്നു. പ്രശ്നങ്ങൾ കണ്ടെത്തി പരിഹരിക്കുന്നതിന് ആപ്പുകൾക്ക് ഈ ലോഗുകൾ ഉപയോഗിക്കാൻ കഴിയും.\n\nചില ലോഗുകളിൽ സൂക്ഷ്മമായി കൈകാര്യം ചെയ്യേണ്ട വിവരങ്ങൾ അടങ്ങിയിരിക്കാൻ സാധ്യതയുള്ളതിനാൽ, നിങ്ങൾക്ക് വിശ്വാസമുള്ള ആപ്പുകൾക്ക് മാത്രമേ എല്ലാ ഉപകരണ ലോഗുകളും ആക്സസ് ചെയ്യാൻ അനുമതി നൽകാവൂ. \n\nഎല്ലാ ഉപകരണ ലോഗുകളും ആക്സസ് ചെയ്യാൻ നിങ്ങൾ ഈ ആപ്പിനെ അനുവദിക്കുന്നില്ലെങ്കിൽ പോലും, ആപ്പിന് അതിന്റെ സ്വന്തം ലോഗുകൾ ആക്സസ് ചെയ്യാനാകും. നിങ്ങളുടെ ഉപകരണ നിർമ്മാതാവിനും നിങ്ങളുടെ ഉപകരണത്തിലെ ചില ലോഗുകളോ വിവരങ്ങളോ തുടർന്നും ആക്സസ് ചെയ്യാനായേക്കും. കൂടുതലറിയുക"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"വീണ്ടും കാണിക്കരുത്"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_2">%2$s</xliff:g> സ്ലൈസുകൾ കാണിക്കാൻ <xliff:g id="APP_0">%1$s</xliff:g> താൽപ്പര്യപ്പെടുന്നു"</string> <string name="screenshot_edit" msgid="7408934887203689207">"എഡിറ്റ് ചെയ്യുക"</string> @@ -2258,12 +2260,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ബാറ്ററി ലൈഫിനെ ബാധിച്ചേക്കാം. സജീവ ആപ്പുകൾ അവലോകനം ചെയ്യാൻ ടാപ്പ് ചെയ്യുക."</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"പശ്ചാത്തല ആക്റ്റിവിറ്റി"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ആപ്പ് പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുന്നു, ഇത് ബാറ്ററി ഉപയോഗിച്ചുതീർക്കുന്നു. അവലോകനം ചെയ്യാൻ ടാപ്പ് ചെയ്യുക."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"പശ്ചാത്തലത്തിൽ <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"നിങ്ങളുടെ <xliff:g id="DEVICE">%1$s</xliff:g> എന്നതിൽ നിന്ന് ടാബ്ലെറ്റിന്റെ ക്യാമറ ആക്സസ് ചെയ്യാനാകില്ല"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"സിസ്റ്റത്തിന്റെ ഭാഷ"</string> </resources> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index f78de73aa74c..4e382370df4e 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Баталгаажуулахад алдаа гарлаа"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Дэлгэцийн түгжээг ашиглах"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Үргэлжлүүлэхийн тулд дэлгэцийн түгжээгээ оруулна уу"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Мэдрэгч дээр чанга дарна уу"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Хэсэгчилсэн хурууны хээ илэрлээ"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Хурууны хээ боловсруулж чадахгүй байна. Дахин оролдоно уу."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Хурууны хээ мэдрэгчийг цэвэрлээд, дахин оролдоно уу"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Мэдрэгчийг цэвэрлээд, дахин оролдоно уу"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Хурууны хээг таньсангүй"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Хурууны хээг таньсангүй"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Мэдрэгч дээр чанга дарна уу"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Хурууны хээг нотолсон"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Царайг баталгаажууллаа"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Царайг баталгаажууллаа. Баталгаажуулах товчлуурыг дарна уу"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"Хэрэв та <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> @@ -1851,7 +1852,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> @@ -2026,9 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ЯМАР Ч ТОХИОЛДОЛД НЭЭХ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Аюултай апп олдсон"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>-д төхөөрөмжийн бүх логт хандахыг зөвшөөрөх үү?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Нэг удаагийн хандалтыг зөвшөөрнө үү"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Зөвхөн энэ удаа"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Бүү зөвшөөр"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Төхөөрөмжийн лог нь таны төхөөрөмж дээр юу болж байгааг бичдэг. Аппууд эдгээр логийг асуудлыг олох болон засахад ашиглах боломжтой.\n\nЗарим лог эмзэг мэдээлэл агуулж байж магадгүй тул та зөвхөн итгэдэг аппууддаа төхөөрөмжийн бүх логт хандахыг зөвшөөрнө үү. \n\nХэрэв та энэ аппад төхөөрөмжийн бүх логт хандахыг зөвшөөрөхгүй бол энэ нь өөрийн логт хандах боломжтой хэвээр байх болно. Tаны төхөөрөмж үйлдвэрлэгч таны төхөөрөмж дээрх зарим лог эсвэл мэдээлэлд хандах боломжтой хэвээр байж магадгүй. Нэмэлт мэдээлэл авах"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Дахиж бүү харуул"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> <xliff:g id="APP_2">%2$s</xliff:g>-н хэсгүүдийг (slices) харуулах хүсэлтэй байна"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Засах"</string> @@ -2258,12 +2260,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> батарейн ажиллах хугацаанд нөлөөлж болзошгүй. Идэвхтэй аппыг хянахын тулд товшино уу."</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Дэвсгэрийн үйл ажиллагаа"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> дэвсгэрт ажиллаж байгаа бөгөөд батарейг дуусгаж байна. Хянахын тулд товшино уу."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Таны <xliff:g id="DEVICE">%1$s</xliff:g>-с таблетын камерт хандах боломжгүй"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Системийн хэл"</string> </resources> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 1adb80f994ec..e0aa948bda16 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -426,7 +426,7 @@ <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="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> @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"एरर ऑथेंटिकेट करत आहे"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"स्क्रीन लॉक वापरा"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"पुढे सुरू ठेवण्यासाठी तुमचे स्क्रीन लॉक एंटर करा"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"सेन्सरवर जोरात दाबा"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"आंशिक फिंगरप्रिंट डिटेक्ट केली"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"फिंगरप्रिंटवर प्रक्रिया करणे शक्य झाले नाही. कृपया पुन्हा प्रयत्न करा."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"फिंगरप्रिंट सेन्सर स्वच्छ करा आणि पुन्हा प्रयत्न करा"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"सेन्सर स्वच्छ करा आणि पुन्हा प्रयत्न करा"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"फिंगरप्रिंट ओळखले नाही"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"फिंगरप्रिंट ओळखले नाही"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"सेन्सरवर जोरात दाबा"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"फिंगरप्रिंट ऑथेंटिकेट केली आहे"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"चेहरा ऑथेंटिकेशन केलेला आहे"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"चेहरा ऑथेंटिकेशन केलेला आहे, कृपया कंफर्म दाबा"</string> @@ -1474,7 +1474,7 @@ <string name="forward_intent_to_work" msgid="3620262405636021151">"तुम्ही हा अॅप आपल्या कार्य प्रोफाईलमध्ये वापरत आहात"</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="accessibility_binding_label" msgid="1974602776545801715">"प्रवेशयोग्यता"</string> <string name="wallpaper_binding_label" msgid="1197440498000786738">"वॉलपेपर"</string> <string name="chooser_wallpaper" msgid="3082405680079923708">"वॉलपेपर बदला"</string> <string name="notification_listener_binding_label" msgid="2702165274471499713">"सूचना ऐकणारा"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"तुम्ही <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> @@ -1851,7 +1852,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> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"ॲप उपलब्ध नाही"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"हे यावेळी तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वर अॅक्सेस करू शकत नाही. त्याऐवजी तुमच्या Android TV डिव्हाइसवर अॅक्सेस करून पहा."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"हे यावेळी तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वर अॅक्सेस करू शकत नाही. त्याऐवजी तुमच्या टॅबलेटवर अॅक्सेस करून पहा."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"हे यावेळी तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वर अॅक्सेस करू शकत नाही. त्याऐवजी तुमच्या फोनवर अॅक्सेस करून पहा."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"तरीही उघडा"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"हानिकारक अॅप आढळला"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ला सर्व डिव्हाइस लॉग अॅक्सेस करण्याची अनुमती द्यायची आहे का?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"एक-वेळ अॅक्सेसची अनुमती द्या"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"फक्त यावेळी"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"अनुमती देऊ नका"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"तुमच्या डिव्हाइसवर काय होते ते डिव्हाइस लॉग रेकॉर्ड करते. समस्या शोधण्यासाठी आणि त्यांचे निराकरण करण्याकरिता ॲप्स हे लॉग वापरू शकतात.\n\nकाही लॉगमध्ये संवेदनशील माहिती असू शकते, त्यामुळे फक्त तुमचा विश्वास असलेल्या ॲप्सना सर्व डिव्हाइस लॉग अॅक्सेस करण्याची अनुमती द्या. \n\nतुम्ही या ॲपला सर्व डिव्हाइस लॉग अॅक्सेस करण्याची अनुमती न दिल्यास, ते तरीही त्याचा स्वतःचा लॉग अॅक्सेस करू शकते. तुमच्या डिव्हाइसचा उत्पादक तरीही काही लॉग किंवा तुमच्या डिव्हाइसवरील माहिती अॅक्सेस करू शकतो. अधिक जाणून घ्या"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"पुन्हा दाखवू नका"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ला <xliff:g id="APP_2">%2$s</xliff:g> चे तुकडे दाखवायचे आहेत"</string> <string name="screenshot_edit" msgid="7408934887203689207">"संपादित करा"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> कदाचित बॅटरी लाइफवर परिणाम करेल. अॅक्टिव्ह अॅप्सचे पुनरावलोकन करण्यासाठी टॅप करा."</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"बॅकग्राउंड अॅक्टिव्हिटी"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> हे बॅकग्राउंडमध्ये रन होत आहे आणि बॅटरी संपवत आहे. पुनरावलोकनासाठी टॅप करा."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वरून टॅबलेटचा कॅमेरा अॅक्सेस करू शकत नाही"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"सिस्टीम भाषा"</string> </resources> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 4886b6897560..9c7d11d14c7c 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -427,7 +427,7 @@ <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Membenarkan apl untuk mengubah suai panggilan telefon anda, termasuk data tentang panggilan masuk dan keluar. Apl hasad boleh menggunakannya untuk memadam atau mengubah suai log panggilan anda."</string> <string name="permlab_bodySensors" msgid="662918578601619569">"Akses data penderia tubuh, seperti kadar denyut jantung, semasa digunakan"</string> <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Membenarkan apl mengakses data penderia tubuh, seperti kadar denyut jantung, suhu dan peratusan oksigen darah, semasa apl digunakan."</string> - <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Akses data penderia tubuh, seperti kadar denyut jantung, semasa di latar"</string> + <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Akses data penderia tubuh, seperti kadar denyut jantung, semasa berjalan di latar belakang"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Membenarkan apl mengakses data penderia tubuh, seperti kadar denyut jantung, suhu dan peratusan oksigen darah, semasa apl berjalan di latar belakang."</string> <string name="permlab_readCalendar" msgid="6408654259475396200">"Baca acara dan butiran kalendar"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Apl ini boleh membaca semua acara kalendar yang disimpan pada tablet anda dan berkongsi atau menyimpan data kalendar anda."</string> @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Ralat semasa membuat pengesahan"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gunakan kunci skrin"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Masukkan kunci skrin untuk teruskan"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Tekan dengan kuat pada penderia"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Cap jari separa dikesan"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Tidak dapat memproses cap jari. Sila cuba lagi."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Bersihkan penderia cap jari dan cuba lagi"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Bersihkan penderia dan cuba lagi"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Cap jari tidak dikenali"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Cap jari tidak dikenali"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Tekan dengan kuat pada penderia"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Cap jari disahkan"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Wajah disahkan"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Wajah disahkan, sila tekan sahkan"</string> @@ -1613,7 +1613,7 @@ <string name="wireless_display_route_description" msgid="8297563323032966831">"Paparan wayarles"</string> <string name="media_route_button_content_description" msgid="2299223698196869956">"Hantar"</string> <string name="media_route_chooser_title" msgid="6646594924991269208">"Sambung ke peranti"</string> - <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Hantar skrin kepada peranti"</string> + <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Hantar skrin ke peranti"</string> <string name="media_route_chooser_searching" msgid="6119673534251329535">"Mencari peranti..."</string> <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Tetapan"</string> <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Putuskan sambungan"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"HIDUP"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"MATI"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Benarkan <xliff:g id="SERVICE">%1$s</xliff:g> mempunyai kawalan penuh atas peranti anda?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Jika anda menghidupkan <xliff:g id="SERVICE">%1$s</xliff:g>, peranti anda tidak akan menggunakan kunci skrin anda untuk meningkatkan penyulitan data."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Kawalan penuh sesuai untuk apl yang membantu anda dengan keperluan kebolehaksesan tetapi bukan untuk kebanyakan apl."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Melihat dan mengawal skrin"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Ciri ini boleh membaca semua kandungan pada skrin dan memaparkan kandungan di atas apl lain."</string> @@ -2026,9 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"BUKA JUGA"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Apl berbahaya dikesan"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Benarkan <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> mengakses semua log peranti?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Benarkan akses sekali"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Kali ini sahaja"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Jangan benarkan"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Log peranti merekodkan perkara yang berlaku pada peranti anda. Apl dapat menggunakan log ini untuk menemukan dan membetulkan isu.\n\nSesetengah log mungkin mengandungi maklumat sensitif, jadi benarkan apl yang anda percaya sahaja untuk mengakses semua log peranti. \n\nJika anda tidak membenarkan apl ini mengakses semua log peranti, apl masih boleh mengakses log sendiri. Pengilang peranti anda mungkin masih boleh mengakses sesetengah log atau maklumat pada peranti anda. Ketahui lebih lanjut"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Jangan tunjuk lagi"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> mahu menunjukkan <xliff:g id="APP_2">%2$s</xliff:g> hirisan"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Edit"</string> @@ -2258,12 +2260,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Aktiviti Latar Belakang"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> dijalankan di latar belakang dan melemahkan bateri. Ketik untuk semak."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g>sedang berjalan di latar belakang untuk masa yang lama. Ketik untuk menyemak."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Tidak dapat mengakses kamera tablet daripada <xliff:g id="DEVICE">%1$s</xliff:g> anda"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Bahasa sistem"</string> </resources> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index d767b9b07a59..cd8b356538cd 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -323,7 +323,7 @@ <string name="permgroupdesc_calllog" msgid="2026996642917801803">"ဖုန်းခေါ်ဆိုထားသော မှတ်တမ်း ဖတ်ပြီး ရေးရန်"</string> <string name="permgrouplab_phone" msgid="570318944091926620">"ဖုန်း"</string> <string name="permgroupdesc_phone" msgid="270048070781478204">"ဖုန်းခေါ်ဆိုမှုများ ပြုလုပ်ရန်နှင့် စီမံရန်"</string> - <string name="permgrouplab_sensors" msgid="9134046949784064495">"ခန္ဓာကိုယ် အာရုံခံကိရိယာများ"</string> + <string name="permgrouplab_sensors" msgid="9134046949784064495">"စက်၏ အာရုံခံစနစ်များ"</string> <string name="permgroupdesc_sensors" msgid="2610631290633747752">"သင်၏အရေးပြီးသော ကျန်းမာရေးလက္ခဏာဆိုင်ရာ အာရုံခံကိရိယာဒေတာကို ရယူရန်"</string> <string name="permgrouplab_notifications" msgid="5472972361980668884">"အကြောင်းကြားချက်များ"</string> <string name="permgroupdesc_notifications" msgid="4608679556801506580">"အကြောင်းကြားချက်များ ပြနိုင်သည်"</string> @@ -425,7 +425,7 @@ <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="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"နောက်ခံတွင်အက်ပ်ဖွင့်စဉ် နှလုံးခုန်နှုန်း၊ အပူချိန်၊ သွေးတွင်း အောက်ဆီဂျင်ရာခိုင်နှုန်းကဲ့သို့ ခန္ဓာကိုယ်အာရုံခံစနစ် ဒေတာများသုံးရန် အက်ပ်ကိုခွင့်ပြုသည်။"</string> @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"အထောက်အထားစိစစ်ရာတွင် အမှားအယွင်းရှိနေသည်"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ရှေ့ဆက်ရန် သင်၏ဖန်သားပြင် လော့ခ်ချခြင်းကို ထည့်ပါ"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"အာရုံခံကိရိယာပေါ်တွင် သေချာဖိပါ"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"လက်ဗွေတစ်စိတ်တစ်ပိုင်းကို ရှာတွေ့သည်"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"လက်ဗွေယူ၍ မရပါ။ ထပ်စမ်းကြည့်ပါ။"</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"လက်ဗွေ အာရုံခံကိရိယာကို သန့်ရှင်းပြီး ထပ်စမ်းကြည့်ပါ"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"အာရုံခံကိရိယာကို သန့်ရှင်းပြီး ထပ်စမ်းကြည့်ပါ"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"လက်ဗွေကို မသိရှိပါ"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"လက်ဗွေကို မသိရှိပါ"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"အာရုံခံကိရိယာပေါ်တွင် သေချာဖိပါ"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"လက်ဗွေကို အထောက်အထား စိစစ်ပြီးပါပြီ"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"မျက်နှာ အထောက်အထားစိစစ်ပြီးပြီ"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"မျက်နှာ အထောက်အထားစိစစ်ပြီးပြီ၊ အတည်ပြုရန်ကို နှိပ်ပါ"</string> @@ -1168,7 +1168,7 @@ <string name="whichApplicationLabel" msgid="7852182961472531728">"လုပ်ဆောင်ချက်ကို အပြီးသတ်ပါ"</string> <string name="whichViewApplication" msgid="5733194231473132945">"...ဖြင့် ဖွင့်မည်"</string> <string name="whichViewApplicationNamed" msgid="415164730629690105">"%1$s ဖြင့် ဖွင့်မည်"</string> - <string name="whichViewApplicationLabel" msgid="7367556735684742409">"ဖွင့်ရန်"</string> + <string name="whichViewApplicationLabel" msgid="7367556735684742409">"ဖွင့်ပါ"</string> <string name="whichOpenHostLinksWith" msgid="7645631470199397485">"<xliff:g id="HOST">%1$s</xliff:g> လင့်ခ်များကို အောက်ပါဖြင့် ဖွင့်ရန်−"</string> <string name="whichOpenLinksWith" msgid="1120936181362907258">"လင့်ခ်များကို အောက်ပါဖြင့် ဖွင့်ရန်−"</string> <string name="whichOpenLinksWithApp" msgid="6917864367861910086">"လင့်ခ်ကို <xliff:g id="APPLICATION">%1$s</xliff:g> ဖြင့် ဖွင့်ရန်"</string> @@ -1613,7 +1613,7 @@ <string name="wireless_display_route_description" msgid="8297563323032966831">"ကြိုးမဲ့ပြသခြင်း"</string> <string name="media_route_button_content_description" msgid="2299223698196869956">"သရုပ်ဆောင်များ"</string> <string name="media_route_chooser_title" msgid="6646594924991269208">"စက်တစ်ခုကို ချိတ်ဆက်ရန်"</string> - <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"ဖန်သားပြင်ကို စက်သို့ ကာစ်လုပ်ခြင်း"</string> + <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"ဖန်သားပြင်ကို စက်ထံသို့ ပို့ပါ"</string> <string name="media_route_chooser_searching" msgid="6119673534251329535">"စက်များကို ရှာဖွေနေပါသည် ..."</string> <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"ဆက်တင်များ"</string> <string name="media_route_controller_disconnect" msgid="7362617572732576959">"ချိတ်ဆက်မှုဖြုတ်ရန်"</string> @@ -1624,7 +1624,7 @@ <string name="media_route_status_in_use" msgid="6684112905244944724">"အသုံးပြုနေစဉ်"</string> <string name="display_manager_built_in_display_name" msgid="1015775198829722440">"တခါတည်း ပါသော မြင်ကွင်း"</string> <string name="display_manager_hdmi_display_name" msgid="1022758026251534975">"HDMI မြင်ကွင်း"</string> - <string name="display_manager_overlay_display_name" msgid="5306088205181005861">"ထပ်ပိုးလွှာ #<xliff:g id="ID">%1$d</xliff:g>"</string> + <string name="display_manager_overlay_display_name" msgid="5306088205181005861">"အပေါ်မှ ထပ်သောအရာ #<xliff:g id="ID">%1$d</xliff:g>"</string> <string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string> <string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">", လုံခြုံသော"</string> <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"ပုံဖော်မှုအား မေ့လျော့ခြင်း"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"<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> @@ -1853,7 +1854,7 @@ <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> + <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> <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{1 မိနစ်ကြာ ({formattedTime} အထိ)}other{# မိနစ်ကြာ ({formattedTime} အထိ)}}"</string> <string name="zen_mode_duration_hours_summary" msgid="3866333100793277211">"{count,plural, =1{1 နာရီကြာ ({formattedTime} အထိ)}other{# နာရီကြာ ({formattedTime} အထိ)}}"</string> @@ -1928,11 +1929,12 @@ <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"အက်ပ်ကို ခဏမရပ်တော့ရန်"</string> <string name="work_mode_off_title" msgid="961171256005852058">"အလုပ်သုံးအက်ပ်များ ဖွင့်မလား။"</string> <string name="work_mode_off_message" msgid="7319580997683623309">"သင့်အလုပ်သုံးအက်ပ်နှင့် အကြောင်းကြားချက်များသုံးခွင့် ရယူပါ"</string> - <string name="work_mode_turn_on" msgid="3662561662475962285">"ဖွင့်ရန်"</string> + <string name="work_mode_turn_on" msgid="3662561662475962285">"ဖွင့်ပါ"</string> <string name="app_blocked_title" msgid="7353262160455028160">"အက်ပ်ကို မရနိုင်ပါ"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"၎င်းအား ယခု သင့် <xliff:g id="DEVICE">%1$s</xliff:g> တွင် ဝင်၍မရပါ။ ယင်းအစား Android TV စက်တွင် စမ်းကြည့်ပါ။"</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"၎င်းအား ယခု သင့် <xliff:g id="DEVICE">%1$s</xliff:g> တွင် ဝင်၍မရပါ။ ယင်းအစား တက်ဘလက်တွင် စမ်းကြည့်ပါ။"</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"၎င်းအား ယခု သင့် <xliff:g id="DEVICE">%1$s</xliff:g> တွင် ဝင်၍မရပါ။ ယင်းအစား ဖုန်းတွင် စမ်းကြည့်ပါ။"</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ဘာဖြစ်ဖြစ် ဖွင့်ရန်"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"အန္တရာယ်ရှိသော အက်ပ်ကို တွေ့ရှိထားသည်"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ကို စက်မှတ်တမ်းအားလုံး သုံးခွင့်ပြုမလား။"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"တစ်ခါသုံး ဝင်ခွင့်ပေးရန်"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"ဤတစ်ကြိမ်သာ"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"ခွင့်မပြုပါ"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"သင့်စက်ရှိ အဖြစ်အပျက်များကို စက်မှတ်တမ်းများက မှတ်တမ်းတင်သည်။ အက်ပ်များက ပြဿနာများ ရှာဖွေပြီးဖြေရှင်းရန် ဤမှတ်တမ်းများကို သုံးနိုင်သည်။\n\nအချို့မှတ်တမ်းများတွင် သတိထားရမည့်အချက်အလက်များ ပါဝင်နိုင်သဖြင့် စက်မှတ်တမ်းအားလုံးကို ယုံကြည်ရသည့် အက်ပ်များကိုသာ သုံးခွင့်ပြုပါ။ \n\nဤအက်ပ်ကို စက်မှတ်တမ်းအားလုံး သုံးခွင့်မပြုသော်လည်း ၎င်းက ၎င်း၏ကိုယ်ပိုင်မှတ်တမ်းကို သုံးနိုင်ဆဲဖြစ်သည်။ သင့်စက်ရှိ အချို့မှတ်တမ်းများ (သို့) အချက်အလက်များကို သင့်စက်ထုတ်လုပ်သူက သုံးနိုင်ပါသေးသည်။ ပိုမိုလေ့လာရန်"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"နောက်ထပ်မပြပါနှင့်"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> သည် <xliff:g id="APP_2">%2$s</xliff:g> ၏အချပ်များကို ပြသလိုသည်"</string> <string name="screenshot_edit" msgid="7408934887203689207">"တည်းဖြတ်ရန်"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> က ဘက်ထရီ သက်တမ်းကို ထိခိုက်နိုင်သည်။ ပွင့်နေသောအက်ပ်များ ပြန်ကြည့်ရန် တို့ပါ။"</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"နောက်ခံလုပ်ဆောင်ချက်"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> သည် နောက်ခံတွင်ပွင့်နေပြီး ဘက်ထရီအားကုန်စေသည်။ ပြန်ကြည့်ရန် တို့ပါ။"</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"သင်၏ <xliff:g id="DEVICE">%1$s</xliff:g> မှ တက်ဘလက်ကင်မရာကို သုံး၍မရပါ"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"စနစ်၏ ဘာသာစကား"</string> </resources> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 1b36b9d2fb9f..efca7cd756ee 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Feil under autentiseringen"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Bruk skjermlås"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Skriv inn skjermlåsen for å fortsette"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Et delvis fingeravtrykk er registrert"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kunne ikke registrere fingeravtrykket. Prøv på nytt."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Rengjør fingeravtrykkssensoren og prøv igjen"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Rengjør sensoren og prøv igjen"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Gjenkjenner ikke fingeravtrykket"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Trykk godt på sensoren"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeravtrykket er godkjent"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Ansiktet er autentisert"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ansiktet er autentisert. Trykk på Bekreft"</string> @@ -1681,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"PÅ"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"AV"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vil du gi <xliff:g id="SERVICE">%1$s</xliff:g> full kontroll over enheten din?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Hvis du slår på <xliff:g id="SERVICE">%1$s</xliff:g>, bruker ikke enheten skjermlåsen til å forbedre datakryptering."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Full kontroll er passende for apper som hjelper deg med tilgjengelighetsbehov, men ikke for de fleste apper."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Se og kontrollér skjermen"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Den kan lese alt innhold på skjermen og vise innhold over andre apper."</string> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Appen er ikke tilgjengelig"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ikke tilgjengelig for øyeblikket."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> er utilgjengelig"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Du må gi tillatelse"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Dette er ikke tilgjengelig på <xliff:g id="DEVICE">%1$s</xliff:g> for øyeblikket. Prøv på Android TV-enheten din i stedet."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Dette er ikke tilgjengelig på <xliff:g id="DEVICE">%1$s</xliff:g> for øyeblikket. Prøv på nettbrettet ditt i stedet."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Dette er ikke tilgjengelig på <xliff:g id="DEVICE">%1$s</xliff:g> for øyeblikket. Prøv på telefonen din i stedet."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ÅPNE LIKEVEL"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"En skadelig app ble oppdaget"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Vil du gi <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> tilgang til alle enhetslogger?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Bare denne gangen"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ikke tillat"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Enhetslogger registrerer det som skjer på enheten din. Apper kan bruke disse loggene til å finne og løse problemer.\n\nNoen logger kan inneholde sensitiv informasjon, så du bør bare gi tilgang til alle enhetslogger til apper du stoler på. \n\nHvis du ikke gir denne appen tilgang til alle enhetslogger, har den fremdeles tilgang til sine egne logger. Enhetsprodusenten kan fremdeles ha tilgang til noen logger eller noe informasjon på enheten din. Finn ut mer"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ikke vis igjen"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> vil vise <xliff:g id="APP_2">%2$s</xliff:g>-utsnitt"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Endre"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Aktivitet i bakgrunnen"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> kjører i bakgrunnen og bruker batteri. Trykk for å gjennomgå."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> kjører lenge i bakgrunnen. Trykk for å gjennomgå."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Sjekk aktive apper"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Det er ikke mulig å få tilgang til kameraet på nettbrettet fra <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="system_locale_title" msgid="3978041860457277638">"Systemspråk"</string> </resources> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index c3da04fb954a..368fa46e7515 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -323,7 +323,7 @@ <string name="permgroupdesc_calllog" msgid="2026996642917801803">"फोन कलको लग पढ्नुहोस् र लेख्नुहोस्"</string> <string name="permgrouplab_phone" msgid="570318944091926620">"फोन"</string> <string name="permgroupdesc_phone" msgid="270048070781478204">"फोन कलहरू गर्नुहोस् र व्यवस्थापन गर्नुहोस्"</string> - <string name="permgrouplab_sensors" msgid="9134046949784064495">"बडी सेन्सरहरू"</string> + <string name="permgrouplab_sensors" msgid="9134046949784064495">"शारीरिक सेन्सरहरू"</string> <string name="permgroupdesc_sensors" msgid="2610631290633747752">"तपाईंको महत्त्वपूर्ण संकेत बारे सेन्सर डेटा पहुँच गर्नुहोस्"</string> <string name="permgrouplab_notifications" msgid="5472972361980668884">"सूचनाहरू"</string> <string name="permgroupdesc_notifications" msgid="4608679556801506580">"सूचनाहरू देखाइयोस्"</string> @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"प्रमाणित गर्ने क्रममा त्रुटि भयो"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"स्क्रिन लक प्रयोग गर्नुहोस्"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"जारी राख्न आफ्नो स्क्रिन लक हाल्नुहोस्"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"फिंगरप्रिन्ट आंशिक रूपमा पत्ता लाग्यो"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"फिंगरप्रिन्ट प्रशोधन गर्न सकिएन। कृपया फेरि प्रयास गर्नुहोस्।"</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"फिंगरप्रिन्ट सेन्सर सफा गरेर फेरि प्रयास गर्नुहोस्"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"सेन्सर सफा गरेर फेरि प्रयास गर्नुहोस्"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"फिंगरप्रिन्ट पहिचान गर्न सकिएन"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"सेन्सरमा बेसरी थिच्नुहोस्"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"फिंगरप्रिन्ट प्रमाणीकरण गरियो"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"अनुहार प्रमाणीकरण गरियो"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"अनुहार प्रमाणीकरण गरियो, कृपया पुष्टि गर्नुहोस् थिच्नुहोस्"</string> @@ -1681,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"तपाईंले <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> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"एप उपलब्ध छैन"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"यस बखत तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मा यो एप स्ट्रिम गर्न मिल्दैन। बरु तपाईंको Android TV डिभाइसमा स्ट्रिम गरी हेर्नुहोस्।"</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"यस बखत तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मा यो एप स्ट्रिम गर्न मिल्दैन। बरु तपाईंको ट्याब्लेटमा स्ट्रिम गरी हेर्नुहोस्।"</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"यस बखत तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मा यो एप स्ट्रिम गर्न मिल्दैन। बरु तपाईंको फोनमा स्ट्रिम गरी हेर्नुहोस्।"</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"जे भए पनि खोल्नुहोस्"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"हानिकारक एप भेटियो"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> लाई डिभाइसका सबै लग हेर्ने अनुमति दिने हो?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"यस पटक मात्र"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"अनुमति नदिनुहोस्"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"डिभाइसका लगले तपाईंको डिभाइसमा भएका विभिन्न गतिविधिको अभिलेख राख्छ। एपहरू यी लगका आधारमा समस्या पत्ता लगाउन र तिनको समाधान गर्न सक्छन्।\n\nकेही लगहरूमा संवेदनशील जानकारी समावेश हुन सक्ने भएकाले आफूले भरोसा गर्ने एपलाई मात्र डिभाइसका सबै लग हेर्ने अनुमति दिनुहोस्। \n\nतपाईंले यो एपलाई डिभाइसका सबै लग हेर्ने अनुमति दिनुभएन भने पनि यसले आफ्नै लग भने हेर्न सक्छ। तपाईंको डिभाइसको उत्पादकले पनि तपाईंको डिभाइसमा भएका केही लग वा जानकारी हेर्न सक्ने सम्भावना हुन्छ। थप जान्नुहोस्"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"फेरि नदेखाइयोस्"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ले <xliff:g id="APP_2">%2$s</xliff:g> का स्लाइसहरू देखाउन चाहन्छ"</string> <string name="screenshot_edit" msgid="7408934887203689207">"सम्पादन गर्नुहोस्"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"ब्याकग्राउन्डमा गरिएको क्रियाकलाप"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ब्याकग्राउन्डमा चलिरहेको हुनाले ब्याट्री खपत भइरहेको छ। समीक्षा गर्न ट्याप गर्नुहोस्।"</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> लामो समयदेखि ब्याकग्राउन्डमा चलिरहेको छ। समीक्षा गर्न ट्याप गर्नुहोस्।"</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"कुन कुन एप सक्रिय छ भन्ने कुरा जाँच्नुहोस्"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मार्फत ट्याब्लेटको क्यामेरा प्रयोग गर्न मिल्दैन"</string> <string name="system_locale_title" msgid="3978041860457277638">"सिस्टमको भाषा"</string> </resources> diff --git a/core/res/res/values-night/colors.xml b/core/res/res/values-night/colors.xml index 783fabe20a6d..f5c82d5019ad 100644 --- a/core/res/res/values-night/colors.xml +++ b/core/res/res/values-night/colors.xml @@ -35,4 +35,9 @@ <color name="personal_apps_suspension_notification_color">#8AB4F8</color> <color name="overview_background">@color/overview_background_dark</color> + + <color name="user_icon_4">#fff439a0</color><!-- pink --> + <color name="user_icon_6">#ff4ecde6</color><!-- cyan --> + <color name="user_icon_7">#fffbbc04</color><!-- yellow --> + <color name="user_icon_8">#fffa903e</color><!-- orange --> </resources> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 3dffda0e4129..0b5dde11186e 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Fout bij verificatie"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Schermvergrendeling gebruiken"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Voer je schermvergrendeling in om door te gaan"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Druk stevig op de sensor"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Gedeeltelijke vingerafdruk gedetecteerd"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kan vingerafdruk niet verwerken. Probeer het opnieuw."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Reinig de vingerafdruksensor en probeer het opnieuw"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Reinig de sensor en probeer het opnieuw"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Vingerafdruk niet herkend"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Vingerafdruk niet herkend"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Druk stevig op de sensor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Vingerafdruk geverifieerd"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Gezicht geverifieerd"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Gezicht geverifieerd. Druk op Bevestigen."</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AAN"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"UIT"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Toestaan dat <xliff:g id="SERVICE">%1$s</xliff:g> volledige controle over je apparaat heeft?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Als je <xliff:g id="SERVICE">%1$s</xliff:g> aanzet, gebruikt je apparaat geen schermvergrendeling om de gegevensversleuteling te verbeteren."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Volledige controle is gepast voor apps die je helpen met toegankelijkheid, maar voor de meeste apps is het ongepast."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Scherm bekijken en bedienen"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"De functie kan alle content op het scherm lezen en content bovenop andere apps bekijken."</string> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"App is niet beschikbaar"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is momenteel niet beschikbaar."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> niet beschikbaar"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Rechten vereist"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Je hebt hier nu geen toegang toe op je <xliff:g id="DEVICE">%1$s</xliff:g>. Probeer het in plaats daarvan op je Android TV-apparaat."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Je hebt hier nu geen toegang toe op je <xliff:g id="DEVICE">%1$s</xliff:g>. Probeer het in plaats daarvan op je tablet."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Je hebt hier nu geen toegang toe op je <xliff:g id="DEVICE">%1$s</xliff:g>. Probeer het in plaats daarvan op je telefoon."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"TOCH OPENEN"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Schadelijke app gevonden"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> toegang geven tot alle apparaatlogboeken?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Eenmalige toegang toestaan"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Alleen deze keer"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Niet toestaan"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Apparaatlogboeken leggen vast wat er op je apparaat gebeurt. Apps kunnen deze logboeken gebruiken om problemen op te sporen en te verhelpen.\n\nSommige logboeken kunnen gevoelige informatie bevatten, dus geef alleen apps die je vertrouwt toegang tot alle apparaatlogboeken. \n\nAls je deze app geen toegang tot alle apparaatlogboeken geeft, heeft de app nog wel toegang tot de eigen logboeken. De fabrikant van je apparaat heeft misschien nog steeds toegang tot bepaalde logboeken of informatie op je apparaat. Meer informatie"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Niet opnieuw tonen"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> wil segmenten van <xliff:g id="APP_2">%2$s</xliff:g> tonen"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Bewerken"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Achtergrondactiviteit"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> wordt uitgevoerd op de achtergrond en verbruikt veel batterijlading. Tik om te bekijken."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> wordt al lange tijd uitgevoerd op de achtergrond. Tik om 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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Kan geen toegang tot de camera van de tablet krijgen vanaf je <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Systeemtaal"</string> </resources> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index 2c77638edaa3..adf6c8f4b469 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"ପ୍ରାମାଣିକରଣ କରିବା ସମୟରେ ତ୍ରୁଟି"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ସ୍କ୍ରିନ୍ ଲକ୍ ଏଣ୍ଟର୍ କରନ୍ତୁ"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"ଆଂଶିକ ଟିପଚିହ୍ନ ଚିହ୍ନଟ କରାଯାଇଛି"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ଟିପଚିହ୍ନ ପ୍ରୋସେସ୍ କରାଯାଇପାରିଲା ନାହିଁ। ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ଟିପଚିହ୍ନ ସେନ୍ସରକୁ ପରିଷ୍କାର କରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ସେନ୍ସରକୁ ପରିଷ୍କାର କରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ଟିପଚିହ୍ନ ଚିହ୍ନଟ ହେଲା ନାହିଁ"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"ସେନ୍ସର ଉପରେ ଦୃଢ଼ ଭାବେ ଦବାନ୍ତୁ"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ଟିପଚିହ୍ନ ପ୍ରମାଣିତ ହେଲା"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ମୁହଁ ଚିହ୍ନଟ ହୋଇଛି"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ମୁହଁ ଚିହ୍ନଟ ହୋଇଛି, ଦୟାକରି ସୁନିଶ୍ଚିତ ଦବାନ୍ତୁ"</string> @@ -1681,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"ଯଦି ଆପଣ <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> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"ଆପ୍ ଉପଲବ୍ଧ ନାହିଁ"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ବର୍ତ୍ତମାନ ଏହାକୁ ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରେ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ। ଏହା ପରିବର୍ତ୍ତେ ଆପଣଙ୍କ Android TV ଡିଭାଇସରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ବର୍ତ୍ତମାନ ଏହାକୁ ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରେ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ। ଏହା ପରିବର୍ତ୍ତେ ଆପଣଙ୍କ ଟାବଲେଟରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ବର୍ତ୍ତମାନ ଏହାକୁ ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରେ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ। ଏହା ପରିବର୍ତ୍ତେ ଆପଣଙ୍କ ଫୋନରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"କୌଣସିମତେ ଖୋଲନ୍ତୁ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"ହାନିକାରକ ଆପ୍ ଚିହ୍ନଟ ହୋଇଛି"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"କେବଳ ଏହି ଥର"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"ଅନୁମତି ଦିଅନ୍ତୁ ନାହିଁ"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଯାହା ହୁଏ ତାହା ଡିଭାଇସ ଲଗଗୁଡ଼ିକ ରେକର୍ଡ କରେ। ସମସ୍ୟାଗୁଡ଼ିକୁ ଖୋଜି ସମାଧାନ କରିବାକୁ ଆପ୍ସ ଏହି ଲଗଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିପାରିବ।\n\nକିଛି ଲଗରେ ସମ୍ବେଦନଶୀଳ ସୂଚନା ଥାଇପାରେ, ତେଣୁ ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପଣ ବିଶ୍ୱାସ କରୁଥିବା ଆପ୍ସକୁ ହିଁ ଅନୁମତି ଦିଅନ୍ତୁ। \n\nଯଦି ଆପଣ ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଅନ୍ତି ନାହିଁ, ତେବେ ବି ଏହା ନିଜର ଡିଭାଇସ ଲଗଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିପାରିବ। ଆପଣଙ୍କ ଡିଭାଇସର ନିର୍ମାତା ଏବେ ବି ଆପଣଙ୍କର ଡିଭାଇସରେ କିଛି ଲଗ କିମ୍ବା ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ସକ୍ଷମ ହୋଇପାରନ୍ତି। ଅଧିକ ଜାଣନ୍ତୁ"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"ପୁଣି ଦେଖାନ୍ତୁ ନାହିଁ"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>, <xliff:g id="APP_2">%2$s</xliff:g> ସ୍ଲାଇସ୍କୁ ଦେଖାଇବା ପାଇଁ ଚାହେଁ"</string> <string name="screenshot_edit" msgid="7408934887203689207">"ଏଡିଟ୍ କରନ୍ତୁ"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"ପୃଷ୍ଠପଟ କାର୍ଯ୍ୟକଳାପ"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g>ଟି ପୃଷ୍ଠପଟରେ ଚାଲୁଥିବା ଯୋଗୁଁ ବ୍ୟାଟେରୀର ଚାର୍ଜ ସରିଯାଉଛି। ସମୀକ୍ଷା କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ଦୀର୍ଘ ସମୟ ଧରି ପୃଷ୍ଠପଟରେ ଚାଲୁଛି। ସମୀକ୍ଷା କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ସକ୍ରିୟ ଆପଗୁଡ଼ିକୁ ଯାଞ୍ଚ କରନ୍ତୁ"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରୁ ଟାବଲେଟର କ୍ୟାମେରାକୁ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ"</string> <string name="system_locale_title" msgid="3978041860457277638">"ସିଷ୍ଟମ ଭାଷା"</string> </resources> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index ee15ab9fef2c..1b3cc29b14cd 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -244,7 +244,7 @@ <string name="global_action_power_off" msgid="4404936470711393203">"ਫ਼ੋਨ ਬੰਦ ਕਰੋ"</string> <string name="global_action_power_options" msgid="1185286119330160073">"ਪਾਵਰ"</string> <string name="global_action_restart" msgid="4678451019561687074">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string> - <string name="global_action_emergency" msgid="1387617624177105088">"ਐਮਰਜੈਂਸੀ"</string> + <string name="global_action_emergency" msgid="1387617624177105088">"ਸੰਕਟਕਾਲ"</string> <string name="global_action_bug_report" msgid="5127867163044170003">"ਬਗ ਰਿਪੋਰਟ"</string> <string name="global_action_logout" msgid="6093581310002476511">"ਸੈਸ਼ਨ ਸਮਾਪਤ ਕਰੋ"</string> <string name="global_action_screenshot" msgid="2610053466156478564">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਵੋ"</string> @@ -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> @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"ਗੜਬੜ ਨੂੰ ਪ੍ਰਮਾਣਿਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ਜਾਰੀ ਰੱਖਣ ਲਈ ਆਪਣਾ ਸਕ੍ਰੀਨ ਲਾਕ ਦਾਖਲ ਕਰੋ"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"ਸੈਂਸਰ ਨੂੰ ਜ਼ੋਰ ਨਾਲ ਦਬਾਓ"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"ਅੰਸ਼ਕ ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਾ ਪਤਾ ਲੱਗਿਆ"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ਫਿੰਗਰਪ੍ਰਿੰਟ \'ਤੇ ਪ੍ਰਕਿਰਿਆ ਨਹੀਂ ਹੋ ਸਕੀ। ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨੂੰ ਸਾਫ਼ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ਸੈਂਸਰ ਨੂੰ ਸਾਫ਼ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਪਛਾਣ ਨਹੀਂ ਹੋਈ"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਪਛਾਣ ਨਹੀਂ ਹੋਈ"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"ਸੈਂਸਰ ਨੂੰ ਜ਼ੋਰ ਨਾਲ ਦਬਾਓ"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਪ੍ਰਮਾਣਿਤ ਹੋਇਆ"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ਚਿਹਰਾ ਪੁਸ਼ਟੀਕਰਨ"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ਚਿਹਰਾ ਪੁਸ਼ਟੀਕਰਨ, ਕਿਰਪਾ ਕਰਕੇ \'ਪੁਸ਼ਟੀ ਕਰੋ\' ਦਬਾਓ"</string> @@ -912,7 +912,7 @@ <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਮੀਨੂ ਦਬਾਓ ਜਾਂ ਸੰਕਟਕਾਲੀਨ ਕਾਲ ਕਰੋ।"</string> <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਮੀਨੂ ਦਬਾਓ।"</string> <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਪੈਟਰਨ ਡ੍ਰਾ ਕਰੋ"</string> - <string name="lockscreen_emergency_call" msgid="7500692654885445299">"ਐਮਰਜੈਂਸੀ"</string> + <string name="lockscreen_emergency_call" msgid="7500692654885445299">"ਸੰਕਟਕਾਲ"</string> <string name="lockscreen_return_to_call" msgid="3156883574692006382">"ਕਾਲ ਤੇ ਵਾਪਸ ਜਾਓ"</string> <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"ਸਹੀ!"</string> <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string> @@ -934,7 +934,7 @@ <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"ਰੋਕੋ"</string> <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"ਰੀਵਾਈਂਡ ਕਰੋ"</string> <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"ਤੇਜ਼ੀ ਨਾਲ ਅੱਗੇ ਭੇਜੋ"</string> - <string name="emergency_calls_only" msgid="3057351206678279851">"ਸਿਰਫ਼ ਐਮਰਜੈਂਸੀ ਕਾਲਾਂ"</string> + <string name="emergency_calls_only" msgid="3057351206678279851">"ਸਿਰਫ਼ ਸੰਕਟਕਾਲੀਨ ਕਾਲਾਂ"</string> <string name="lockscreen_network_locked_message" msgid="2814046965899249635">"ਨੈੱਟਵਰਕ ਲਾਕ ਕੀਤਾ"</string> <string name="lockscreen_sim_puk_locked_message" msgid="6618356415831082174">"SIM ਕਾਰਡ PUK-ਲੌਕਡ ਹੈ।"</string> <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"ਵਰਤੋਂਕਾਰ ਗਾਈਡ ਦੇਖੋ ਜਾਂ ਗਾਹਕ ਸੇਵਾ ਨੂੰ ਫ਼ੋਨ ਕਰੋ।"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"ਜੇਕਰ ਤੁਸੀਂ <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> @@ -1851,7 +1852,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> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"ਐਪ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ਇਸ ਸਮੇਂ ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ Android TV ਡੀਵਾਈਸ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ਇਸ ਸਮੇਂ ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਟੈਬਲੈੱਟ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ਇਸ ਸਮੇਂ ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਫ਼ੋਨ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ਫਿਰ ਵੀ ਖੋਲ੍ਹੋ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"ਹਾਨੀਕਾਰਕ ਐਪ ਦਾ ਪਤਾ ਲੱਗਿਆ"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"ਕੀ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ਨੂੰ ਸਾਰੇ ਡੀਵਾਈਸ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"ਇੱਕ-ਵਾਰ ਲਈ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿਓ"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"ਸਿਰਫ਼ ਇਸ ਵਾਰ"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"ਆਗਿਆ ਨਾ ਦਿਓ"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"ਡੀਵਾਈਸ ਲੌਗਾਂ ਵਿੱਚ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੀਆਂ ਕਾਰਵਾਈਆਂ ਰਿਕਾਰਡ ਹੁੰਦੀਆਂ ਹਨ। ਐਪਾਂ ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਲੱਭਣ ਅਤੇ ਉਨ੍ਹਾਂ ਦਾ ਹੱਲ ਕਰਨ ਲਈ ਇਨ੍ਹਾਂ ਲੌਗਾਂ ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੀਆਂ ਹਨ।\n\nਕੁਝ ਲੌਗਾਂ ਵਿੱਚ ਸੰਵੇਦਨਸ਼ੀਲ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀ ਹੈ, ਇਸ ਲਈ ਸਿਰਫ਼ ਆਪਣੀਆਂ ਭਰੋਸੇਯੋਗ ਐਪਾਂ ਨੂੰ ਹੀ ਸਾਰੇ ਡੀਵਾਈਸ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ। \n\nਜੇ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ ਸਾਰੇ ਡੀਵਾਈਸ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਦਿੰਦੇ ਹੋ, ਤਾਂ ਇਹ ਹਾਲੇ ਵੀ ਆਪਣੇ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦੀ ਹੈ। ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਨਿਰਮਾਤਾ ਹਾਲੇ ਵੀ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਮੌਜੂਦ ਕੁਝ ਲੌਗਾਂ ਜਾਂ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦਾ ਹੈ। ਹੋਰ ਜਾਣੋ"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"ਦੁਬਾਰਾ ਨਾ ਦਿਖਾਓ"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ਦੀ <xliff:g id="APP_2">%2$s</xliff:g> ਦੇ ਹਿੱਸੇ ਦਿਖਾਉਣ ਦੀ ਇੱਛਾ ਹੈ"</string> <string name="screenshot_edit" msgid="7408934887203689207">"ਸੰਪਾਦਨ ਕਰੋ"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ਵੱਲੋਂ ਬੈਟਰੀ ਲਾਈਫ਼ ਨੂੰ ਪ੍ਰਭਾਵਿਤ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ। ਕਿਰਿਆਸ਼ੀਲ ਐਪਾਂ ਦੀ ਸਮੀਖਿਆ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"ਬੈਕਗ੍ਰਾਊਂਡ ਸਰਗਰਮੀ"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀ ਹੈ ਅਤੇ ਬੈਟਰੀ ਦੀ ਖਪਤ ਕਰ ਰਹੀ ਹੈ। ਸਮੀਖਿਆ ਲਈ ਟੈਪ ਕਰੋ।"</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> ਤੋਂ ਟੈਬਲੈੱਟ ਦੇ ਕੈਮਰੇ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"ਸਿਸਟਮ ਦੀ ਭਾਸ਼ਾ"</string> </resources> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 1523defe12b1..91f0c89c45c9 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -587,7 +587,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Podczas uwierzytelniania wystąpił błąd"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Używaj blokady ekranu"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Użyj blokady ekranu, aby kontynuować"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Mocno naciśnij czujnik"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Wykryto częściowy odcisk palca"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nie udało się przetworzyć odcisku palca. Spróbuj ponownie."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Wyczyść czytnik linii papilarnych i spróbuj ponownie"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Wyczyść czujnik i spróbuj ponownie"</string> @@ -600,7 +600,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Nie rozpoznano odcisku palca"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Nie rozpoznano odcisku palca"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Mocno naciśnij czujnik"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Uwierzytelniono odciskiem palca"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Twarz rozpoznana"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Twarz rozpoznana, kliknij Potwierdź"</string> @@ -1681,6 +1681,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"WŁ."</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"WYŁ."</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Pozwolić usłudze <xliff:g id="SERVICE">%1$s</xliff:g> na pełną kontrolę nad urządzeniem?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Jeśli włączysz usługę <xliff:g id="SERVICE">%1$s</xliff:g>, Twoje urządzenie nie będzie korzystać z blokady ekranu, by usprawnić szyfrowanie danych."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Pełna kontrola jest odpowiednia dla aplikacji, które pomagają Ci radzić sobie z niepełnosprawnością, ale nie należy jej przyznawać wszystkim aplikacjom."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Wyświetlaj i kontroluj ekran"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Może odczytywać całą zawartość ekranu i wyświetlać treść nad innymi aplikacjami."</string> @@ -1934,7 +1935,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacja jest niedostępna"</string> <string name="app_blocked_message" msgid="542972921087873023">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest obecnie niedostępna."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – brak dostępu"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Wymagane są uprawnienia"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"W tej chwili nie można z tego skorzystać na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>. Użyj urządzenia z Androidem TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"W tej chwili nie można z tego skorzystać na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>. Użyj tabletu."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"W tej chwili nie można z tego skorzystać na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>. Użyj telefonu."</string> @@ -2028,9 +2030,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OTWÓRZ MIMO TO"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Wykryto szkodliwą aplikację"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Zezwolić aplikacji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> na dostęp do wszystkich dzienników urządzenia?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Zezwól na jednorazowy dostęp"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Tylko tym razem"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nie zezwalaj"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Dzienniki urządzenia zapisują, co dzieje się na urządzeniu. Aplikacje mogą ich używać do wykrywania i rozwiązywania problemów.\n\nNiektóre dzienniki mogą zawierać poufne dane, dlatego na dostęp do wszystkich dzienników zezwalaj tylko aplikacjom, którym ufasz. \n\nNawet jeśli nie zezwolisz tej aplikacji na dostęp do wszystkich dzienników na urządzeniu, będzie miała dostęp do własnych. Producent urządzenia nadal będzie mógł korzystać z niektórych dzienników na urządzeniu. Więcej informacji"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Nie pokazuj ponownie"</string> <string name="slices_permission_request" msgid="3677129866636153406">"Aplikacja <xliff:g id="APP_0">%1$s</xliff:g> chce pokazywać wycinki z aplikacji <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Edytuj"</string> @@ -2260,12 +2263,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Aktywność w tle"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikacja <xliff:g id="APP">%1$s</xliff:g> działa w tle i zużywa baterię. Kliknij, aby sprawdzić."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacja <xliff:g id="APP">%1$s</xliff:g> długo działa w tle. Kliknij, aby sprawdzić."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nie można korzystać z aparatu tabletu na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Język systemu"</string> </resources> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 4882dcf4aab4..843f533f26fa 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Erro na autenticação"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueio de tela"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Insira seu bloqueio de tela para continuar"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Pressione o sensor com firmeza"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Impressão digital parcial detectada"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpe o sensor de impressão digital e tente novamente"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpe o sensor e tente novamente"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Impressão digital não reconhecida"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Impressão digital não reconhecida"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Pressione o sensor com firmeza"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Impressão digital autenticada"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Rosto autenticado"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado, pressione \"Confirmar\""</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ATIVADO"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DESATIVADO"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Permitir que o <xliff:g id="SERVICE">%1$s</xliff:g> tenha controle total do seu dispositivo?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Se o <xliff:g id="SERVICE">%1$s</xliff:g> for ativado, o dispositivo não usará o bloqueio de tela para melhorar a criptografia de dados."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"O controle total é adequado para apps que ajudam você com as necessidades de acessibilidade, mas não para a maioria dos apps."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ver e controlar tela"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Pode ler todo o conteúdo na tela e mostrar conteúdo sobreposto a outros apps."</string> @@ -1851,7 +1852,7 @@ <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"A Economia de bateria ativa o tema escuro e limita ou desativa atividades em segundo plano, alguns efeitos visuais, recursos específicos e algumas conexões de rede."</string> <string name="battery_saver_description" msgid="8518809702138617167">"A Economia de bateria ativa o tema escuro e limita ou desativa atividades em segundo plano, alguns efeitos visuais, recursos específicos e algumas conexões de rede."</string> - <string name="data_saver_description" msgid="4995164271550590517">"Para ajudar a reduzir o uso de dados, a Economia de dados impede que alguns apps enviem ou recebam dados em segundo plano. Um app que você está usando no momento pode acessar dados, mas com menos frequência. Isso pode fazer com que imagens não apareçam até você tocar nelas."</string> + <string name="data_saver_description" msgid="4995164271550590517">"Para ajudar a reduzir o uso de dados, a Economia de dados impede que alguns apps enviem ou recebam dados em segundo plano. Um app que você esteja usando no momento pode acessar dados, mas com menos frequência. Isso pode fazer com que imagens não sejam exibidas até que você toque nelas."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Ativar a Economia de dados?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Ativar"</string> <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Por um minuto (até {formattedTime})}one{Por # minuto (até {formattedTime})}other{Por # minutos (até {formattedTime})}}"</string> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"O app não está disponível"</string> <string name="app_blocked_message" msgid="542972921087873023">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível no momento."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponível"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permissão necessária"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo dispositivo Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo seu tablet."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo seu smartphone."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ABRIR MESMO ASSIM"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"App nocivo detectado"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Permitir que o app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acesse todos os registros do dispositivo?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Permitir o acesso único"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Apenas esta vez"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Não permitir"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então autorize apenas os apps em que você confia a acessar os registros. \n\nSe você não permitir que esse app acesse todos os registros do dispositivo, ele ainda vai poder acessar os próprios. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações. Saiba mais"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Não mostrar novamente"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> quer mostrar partes do app <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Editar"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Atividade em segundo plano"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> está sendo executado em segundo plano e drenando a energia da bateria. Toque para revisar."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> está sendo executado em segundo plano faz muito tempo. Toque para revisar."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível acessar a câmera do tablet pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Idioma do sistema"</string> </resources> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 4e25e6499adc..c0ac4fd9bdf0 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Erro ao autenticar."</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utilizar o bloqueio de ecrã"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Introduza o bloqueio de ecrã para continuar"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Prima firmemente o sensor"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Impressão digital parcial detetada"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpe o sensor de impressões digitais e tente novamente"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpe o sensor e tente novamente"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Impressão digital não reconhecida"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Impressão digital não reconhecida"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Prima firmemente o sensor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"A impressão digital foi autenticada."</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Rosto autenticado."</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado. Prima Confirmar."</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ATIVADO"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DESATIVADO"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Permitir que o serviço <xliff:g id="SERVICE">%1$s</xliff:g> tenha controlo total sobre o seu dispositivo?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Se ativar o serviço <xliff:g id="SERVICE">%1$s</xliff:g>, o dispositivo não utilizará o bloqueio de ecrã para otimizar a encriptação de dados."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"O controlo total é adequado para aplicações que ajudam nas necessidades de acessibilidade, mas não para a maioria das apps."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ver e controlar o ecrã"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Pode ler todo o conteúdo do ecrã e sobrepor conteúdo a outras aplicações."</string> @@ -1852,7 +1853,7 @@ <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"A Poupança de bateria ativa o tema escuro e limita ou desativa a atividade em segundo plano, alguns efeitos visuais, determinadas funcionalidades e algumas ligações de rede."</string> <string name="battery_saver_description" msgid="8518809702138617167">"A Poupança de bateria ativa o tema escuro e limita ou desativa a atividade em segundo plano, alguns efeitos visuais, determinadas funcionalidades e algumas ligações de rede."</string> <string name="data_saver_description" msgid="4995164271550590517">"Para ajudar a reduzir a utilização de dados, a Poupança de dados impede que algumas apps enviem ou recebam dados em segundo plano. Uma determinada app que esteja a utilizar atualmente pode aceder aos dados, mas é possível que o faça com menos frequência. Isto pode significar, por exemplo, que as imagens não são apresentadas até que toque nas mesmas."</string> - <string name="data_saver_enable_title" msgid="7080620065745260137">"Ativar a Poupança de dados?"</string> + <string name="data_saver_enable_title" msgid="7080620065745260137">"Pretende ativar a Poupança de dados?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Ativar"</string> <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Durante um minuto (até à[s] {formattedTime})}other{Durante # minutos (até à[s] {formattedTime})}}"</string> <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{Durante 1 min (até à[s] {formattedTime})}other{Durante # min (até à[s] {formattedTime})}}"</string> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"A app não está disponível"</string> <string name="app_blocked_message" msgid="542972921087873023">"De momento, a app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponível"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Autorização necessária"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"De momento, não é possível aceder a esta app no seu <xliff:g id="DEVICE">%1$s</xliff:g>. Em alternativa, experimente no dispositivo Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"De momento, não é possível aceder a esta app no seu <xliff:g id="DEVICE">%1$s</xliff:g>. Em alternativa, experimente no tablet."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"De momento, não é possível aceder a esta app no seu <xliff:g id="DEVICE">%1$s</xliff:g>. Em alternativa, experimente no telemóvel."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ABRIR MESMO ASSIM"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Aplicação prejudicial detetada"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Permitir que a app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> aceda a todos os registos do dispositivo?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Permitir acesso único"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Apenas desta vez"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Não permitir"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Os registos do dispositivo documentam o que ocorre no seu dispositivo. As apps podem usar esses registos para detetar e corrigir problemas.\n\nAlguns registos podem conter informações confidenciais, pelo que o acesso a todos os registos do dispositivo deve apenas ser permitido às apps nas quais confia. \n\nSe não permitir o acesso desta app a todos os registos do dispositivo, a mesma pode ainda assim aceder aos próprios registos. O fabricante do dispositivo pode continuar a aceder a alguns registos ou informações no seu dispositivo. Saiba mais"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Não mostrar de novo"</string> <string name="slices_permission_request" msgid="3677129866636153406">"A app <xliff:g id="APP_0">%1$s</xliff:g> pretende mostrar partes da app <xliff:g id="APP_2">%2$s</xliff:g>."</string> <string name="screenshot_edit" msgid="7408934887203689207">"Editar"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Atividade em segundo plano"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> está a ser executada em 2.º plano e a consumir muita bateria. Toque para analisar."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"A app <xliff:g id="APP">%1$s</xliff:g> está a ser executada em segundo plano há muito tempo. Toque para analisar."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível aceder à câmara do tablet a partir do dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Idioma do sistema"</string> </resources> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 4882dcf4aab4..843f533f26fa 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Erro na autenticação"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueio de tela"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Insira seu bloqueio de tela para continuar"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Pressione o sensor com firmeza"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Impressão digital parcial detectada"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpe o sensor de impressão digital e tente novamente"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpe o sensor e tente novamente"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Impressão digital não reconhecida"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Impressão digital não reconhecida"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Pressione o sensor com firmeza"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Impressão digital autenticada"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Rosto autenticado"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado, pressione \"Confirmar\""</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ATIVADO"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DESATIVADO"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Permitir que o <xliff:g id="SERVICE">%1$s</xliff:g> tenha controle total do seu dispositivo?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Se o <xliff:g id="SERVICE">%1$s</xliff:g> for ativado, o dispositivo não usará o bloqueio de tela para melhorar a criptografia de dados."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"O controle total é adequado para apps que ajudam você com as necessidades de acessibilidade, mas não para a maioria dos apps."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ver e controlar tela"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Pode ler todo o conteúdo na tela e mostrar conteúdo sobreposto a outros apps."</string> @@ -1851,7 +1852,7 @@ <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"A Economia de bateria ativa o tema escuro e limita ou desativa atividades em segundo plano, alguns efeitos visuais, recursos específicos e algumas conexões de rede."</string> <string name="battery_saver_description" msgid="8518809702138617167">"A Economia de bateria ativa o tema escuro e limita ou desativa atividades em segundo plano, alguns efeitos visuais, recursos específicos e algumas conexões de rede."</string> - <string name="data_saver_description" msgid="4995164271550590517">"Para ajudar a reduzir o uso de dados, a Economia de dados impede que alguns apps enviem ou recebam dados em segundo plano. Um app que você está usando no momento pode acessar dados, mas com menos frequência. Isso pode fazer com que imagens não apareçam até você tocar nelas."</string> + <string name="data_saver_description" msgid="4995164271550590517">"Para ajudar a reduzir o uso de dados, a Economia de dados impede que alguns apps enviem ou recebam dados em segundo plano. Um app que você esteja usando no momento pode acessar dados, mas com menos frequência. Isso pode fazer com que imagens não sejam exibidas até que você toque nelas."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Ativar a Economia de dados?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Ativar"</string> <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Por um minuto (até {formattedTime})}one{Por # minuto (até {formattedTime})}other{Por # minutos (até {formattedTime})}}"</string> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"O app não está disponível"</string> <string name="app_blocked_message" msgid="542972921087873023">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível no momento."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponível"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permissão necessária"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo dispositivo Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo seu tablet."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo seu smartphone."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ABRIR MESMO ASSIM"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"App nocivo detectado"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Permitir que o app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acesse todos os registros do dispositivo?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Permitir o acesso único"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Apenas esta vez"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Não permitir"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então autorize apenas os apps em que você confia a acessar os registros. \n\nSe você não permitir que esse app acesse todos os registros do dispositivo, ele ainda vai poder acessar os próprios. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações. Saiba mais"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Não mostrar novamente"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> quer mostrar partes do app <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Editar"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Atividade em segundo plano"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> está sendo executado em segundo plano e drenando a energia da bateria. Toque para revisar."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> está sendo executado em segundo plano faz muito tempo. Toque para revisar."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível acessar a câmera do tablet pelo <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Idioma do sistema"</string> </resources> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 16e097d56ee4..6d3f939a9c1c 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -586,7 +586,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Eroare la autentificare"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Folosiți blocarea ecranului"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Introduceți blocarea ecranului ca să continuați"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Apăsați ferm pe senzor"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"S-a detectat o amprentă parțială"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Amprenta nu a putut fi procesată. Încercați din nou."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Curățați senzorul de amprentă și încercați din nou"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Curățați senzorul și încercați din nou"</string> @@ -599,7 +599,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Amprenta nu a fost recunoscută"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Amprenta nu a fost recunoscută"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Apăsați ferm pe senzor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Amprentă autentificată"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Chip autentificat"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Chip autentificat, apăsați Confirmați"</string> @@ -1680,6 +1680,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ACTIVAT"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DEZACTIVAT"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Permiteți serviciului <xliff:g id="SERVICE">%1$s</xliff:g> să aibă control total asupra dispozitivului dvs.?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Dacă activați <xliff:g id="SERVICE">%1$s</xliff:g>, dispozitivul nu va folosi blocarea ecranului pentru a îmbunătăți criptarea datelor."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Controlul total este adecvat pentru aplicații care vă ajută cu accesibilitatea, însă nu pentru majoritatea aplicaților."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Vă vede și vă controlează ecranul"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Poate citi tot conținutul de pe ecran și poate afișa conținut peste alte aplicații."</string> @@ -2027,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"Deschideți oricum"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Aplicație dăunătoare detectată"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Permiteți ca <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> să acceseze toate jurnalele dispozitivului?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Permiteți accesul o dată"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Doar de data aceasta"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nu permiteți"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Jurnalele dispozitivului înregistrează activitatea de pe dispozitivul dvs. Aplicațiile pot folosi aceste jurnale pentru a identifica și a remedia probleme.\n\nUnele jurnale pot să conțină informații sensibile, prin urmare permiteți accesul la toate jurnalele dispozitivului doar aplicațiilor în care aveți încredere. \n\nDacă nu permiteți accesul aplicației la toate jurnalele dispozitivului, aceasta poate în continuare să acceseze propriile jurnale. Este posibil ca producătorul dispozitivului să acceseze în continuare unele jurnale sau informații de pe dispozitiv. Aflați mai multe"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Nu mai afișa"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> vrea să afișeze porțiuni din <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Editați"</string> @@ -2259,12 +2261,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Activitate de fundal"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> rulează în fundal și consumă bateria. Atingeți pentru a examina."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> rulează în fundal mult timp. Atingeți pentru a examina."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nu se poate accesa camera foto a tabletei de pe <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Limba sistemului"</string> </resources> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 5df213d67283..d1e40f56e66c 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -587,7 +587,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Ошибка аутентификации."</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Использовать блокировку экрана"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Чтобы продолжить, разблокируйте экран."</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Плотно прижмите палец к сканеру."</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Отсканирована только часть отпечатка."</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не удалось распознать отпечаток. Повторите попытку."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Очистите сканер отпечатков пальцев и повторите попытку."</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Очистите сканер и повторите попытку."</string> @@ -600,7 +600,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Отпечаток не распознан."</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Отпечаток не распознан."</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Плотно прижмите палец к сканеру."</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечаток пальца проверен"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Лицо распознано"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лицо распознано, нажмите кнопку \"Подтвердить\""</string> @@ -1681,6 +1681,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_enable_service_encryption_warning" msgid="8603532708618236909">"Если включить сервис \"<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> @@ -1934,7 +1935,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Приложение недоступно"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Эта функция пока недоступна на устройстве <xliff:g id="DEVICE">%1$s</xliff:g>. Используйте Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Эта функция пока недоступна на устройстве <xliff:g id="DEVICE">%1$s</xliff:g>. Используйте планшет."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Эта функция пока недоступна на устройстве <xliff:g id="DEVICE">%1$s</xliff:g>. Используйте телефон."</string> @@ -2028,9 +2030,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ОТКРЫТЬ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Обнаружено вредоносное приложение"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Разрешить приложению \"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>\" доступ ко всем журналам устройства?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Разрешить разовый доступ"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Только в этот раз"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Запретить"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"В журналы записывается информация о том, что происходит на устройстве. Приложения могут использовать их, чтобы находить и устранять неполадки.\n\nТак как некоторые журналы могут содержать конфиденциальную информацию, доступ ко всем журналам следует предоставлять только тем приложениям, которым вы доверяете. \n\nЕсли вы не предоставите такой доступ этому приложению, оно по-прежнему сможет просматривать свои журналы. Не исключено, что некоторые журналы или сведения на вашем устройстве будут по-прежнему доступны его производителю. Подробнее"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Больше не показывать"</string> <string name="slices_permission_request" msgid="3677129866636153406">"Приложение \"<xliff:g id="APP_0">%1$s</xliff:g>\" запрашивает разрешение на показ фрагментов приложения \"<xliff:g id="APP_2">%2$s</xliff:g>\"."</string> <string name="screenshot_edit" msgid="7408934887203689207">"Изменить"</string> @@ -2260,12 +2263,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"Приложение \"<xliff:g id="APP">%1$s</xliff:g>\" может влиять на время работы батареи. Нажмите, чтобы увидеть активные приложения."</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Работа в фоновом режиме"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Приложение \"<xliff:g id="APP">%1$s</xliff:g>\" работает в фоновом режиме и расходует заряд батареи. Нажмите, чтобы узнать подробности."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Приложение \"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"У устройства \"<xliff:g id="DEVICE">%1$s</xliff:g>\" нет доступа к камере планшета."</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Язык системы"</string> </resources> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 77b351fa3cb7..e97fbfc96382 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"සත්යාපනය කිරීමේ දෝෂයකි"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"තිර අගුල භාවිත කරන්න"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ඉදිරියට යාමට ඔබගේ තිර අගුල ඇතුළත් කරන්න"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"සංවේදකය මත තදින් ඔබන්න"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"අර්ධ ඇඟිලි සලකුණක් අනාවරණය කරන ලදි"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ඇඟිලි සලකුණ පිරිසැකසීමට නොහැකි විය. කරුණාකර නැවත උත්සාහ කරන්න."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ඇඟිලි සලකුණු සංවේදකය පිරිසිදු කර නැවත උත්සාහ කරන්න"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"සංවේදකය පිරිසිදු කර නැවත උත්සාහ කරන්න"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ඇඟිලි සලකුණ හඳුනා නොගන්නා ලදි"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"ඇඟිලි සලකුණ හඳුනා නොගන්නා ලදි"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"සංවේදකය මත තදින් ඔබන්න"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ඇඟිලි සලකුණ සත්යාපනය කරන ලදී"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"මුහුණ සත්යාපනය කරන ලදී"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"මුහුණ සත්යාපනය කරන ලදී, කරුණාකර තහවුරු කරන්න ඔබන්න"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"ඔබ <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> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"යෙදුම ලබා ගත නොහැකිය"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"මේ අවස්ථාවේදී මෙයට ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> හි ප්රවේශ විය නොහැකිය. ඒ වෙනුවට ඔබගේ Android TV උපාංගයෙහි උත්සාහ කරන්න."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"මේ අවස්ථාවේදී මෙයට ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> හි ප්රවේශ විය නොහැකිය. ඒ වෙනුවට ඔබගේ ටැබ්ලටයෙහි උත්සාහ කරන්න."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"මේ අවස්ථාවේදී මෙයට ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> හි ප්රවේශ විය නොහැකිය. ඒ වෙනුවට ඔබගේ දුරකථනයෙහි උත්සාහ කරන්න."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"කෙසේ වුවත් විවෘත කරන්න"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"හානිකර යෙදුමක් අනාවරණය කර ගන්නා ලදී"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> හට සියලු උපාංග ලොග ප්රවේශ වීමට ඉඩ දෙන්නද?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"එක් වරක් ප්රවේශය ඉඩ දෙන්න"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"මෙම වතාවේ පමණි"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"ඉඩ නොදෙන්න"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"උපාංග ලොග ඔබගේ උපාංගයේ සිදු වන දේ වාර්තා කරයි. ගැටලු සොයා ගැනීමට සහ විසඳීමට යෙදුම්වලට මෙම ලොග භාවිත කළ හැකිය.\n\nසමහර ලොගවල සංවේදී තොරතුරු අඩංගු විය හැකිය, එබැවින් ඔබ විශ්වාස කරන යෙදුම්වලට පමණක් සියලු උපාංග ලොග වෙත ප්රවේශ වීමට ඉඩ දෙන්න. \n\nඔබ මෙම යෙදුමට සියලු උපාංග ලොග වෙත ප්රවේශ වීමට ඉඩ නොදෙන්නේ නම්, එයට තවමත් එහිම ලොග වෙත ප්රවේශ විය හැකිය. ඔබගේ උපාංග නිෂ්පාදකයාට තවමත් ඔබගේ උපාංගයේ සමහර ලොග හෝ තොරතුරු වෙත ප්රවේශ විය හැකිය. තව දැන ගන්න"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"නැවත නොපෙන්වන්න"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> හට කොටස් <xliff:g id="APP_2">%2$s</xliff:g>ක් පෙන්වීමට අවශ්යයි"</string> <string name="screenshot_edit" msgid="7408934887203689207">"සංස්කරණය"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> බැටරි ආයු කාලය සඳහා බලපෑමට ඉඩ ඇත. සක්රිය යෙදුම් සමාලෝචනය කිරීමට තට්ටු කරන්න."</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"පසුබිම් ක්රියාකාරකම"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> පසුබිමේ ධාවනය වන අතර බැටරිය බැස යයි. සමාලෝචනය කිරීමට තට්ටු කරන්න."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> වෙතින් ටැබ්ලටයේ කැමරාවට ප්රවේශ විය නොහැකිය"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"පද්ධති භාෂාව"</string> </resources> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 2abf45921ab3..530f58c2c85f 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -587,7 +587,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Chyba overenia"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Použiť zámku obrazovky"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Pokračujte zadaním zámky obrazovky"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Pevne pridržte senzor"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Bol rozpoznaný čiastočný odtlačok prsta"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Odtlačok prsta sa nepodarilo spracovať. Skúste to znova."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Vyčistite senzor odtlačkov prstov a skúste to znova"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Vyčistite senzor a skúste to znova"</string> @@ -600,7 +600,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Odtlačok prsta nebol rozpoznaný"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Odtlačok prsta nebol rozpoznaný"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Pevne pridržte senzor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Odtlačok prsta bol overený"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Tvár bola overená"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Tvár bola overená, stlačte tlačidlo potvrdenia"</string> @@ -1681,6 +1681,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ZAP."</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"VYP."</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Chcete povoliť službe <xliff:g id="SERVICE">%1$s</xliff:g> úplnú kontrolu nad zariadením?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ak zapnete službu <xliff:g id="SERVICE">%1$s</xliff:g>, vaše zariadenie nezvýši úroveň šifrovania údajov zámkou obrazovky."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Úplná kontrola je vhodná pre aplikácie, ktoré vám pomáhajú s dostupnosťou, ale nie pre väčšinu aplikácií."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Zobrazenie a ovládanie obrazovky"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Môže čítať všetok obsah na obrazovke a zobrazovať obsah cez ďalšie aplikácie."</string> @@ -1934,7 +1935,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikácia nie je dostupná"</string> <string name="app_blocked_message" msgid="542972921087873023">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> nie je teraz dostupná."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nie je k dispozícii"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Vyžaduje sa povolenie"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> momentálne nemáte k tomuto obsahu prístup. Skúste namiesto toho použiť zariadenie Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> momentálne nemáte k tomuto obsahu prístup. Skúste namiesto toho použiť tablet."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> momentálne nemáte k tomuto obsahu prístup. Skúste namiesto toho použiť telefón."</string> @@ -2028,9 +2030,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OTVORIŤ AJ TAK"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Bola zistená škodlivá aplikácia"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Chcete povoliť aplikácii <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> prístup k všetkým denníkom zariadenia?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Povoliť jednorazový prístup"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Iba tentokrát"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nepovoliť"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Denníky zariadenia zaznamenávajú, čo sa deje vo vašom zariadení. Aplikácie môžu pomocou týchto denníkov vyhľadávať a riešiť problémy.\n\nNiektoré denníky môžu obsahovať citlivé údaje, preto povoľte prístup k všetkým denníkom zariadenia iba dôveryhodným aplikáciám. \n\nAk tejto aplikácii nepovolíte prístup k všetkým denníkom zariadenia, stále bude mať prístup k vlastným denníkom. Výrobca vášho zariadenia bude mať naďalej prístup k niektorým denníkom alebo informáciám vo vašom zariadení. Ďalšie informácie"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Už nezobrazovať"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> chce zobrazovať rezy z aplikácie <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Upraviť"</string> @@ -2260,12 +2263,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Aktivita na pozadí"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikácie <xliff:g id="APP">%1$s</xliff:g> je spustená na pozadí a vybíja batériu. Skontrolujte to klepnutím."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikácia <xliff:g id="APP">%1$s</xliff:g> je dlhodobo spustená na pozadí. Skontrolujte to klepnutím."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> nemáte prístup ku kamere tabletu"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Jazyk systému"</string> </resources> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 1b2b38314168..b724c89ee495 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -587,7 +587,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Napaka pri preverjanju pristnosti"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Uporaba odklepanja s poverilnico"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Odklenite zaslon, če želite nadaljevati."</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Prst dobro pridržite na tipalu."</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Zaznan je delni prstni odtis."</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Prstnega odtisa ni bilo mogoče obdelati. Poskusite znova."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Očistite tipalo prstnih odtisov in poskusite znova."</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Očistite tipalo in poskusite znova."</string> @@ -600,7 +600,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Prstni odtis ni prepoznan."</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Prstni odtis ni prepoznan."</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Prst dobro pridržite na tipalu."</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Pristnost prstnega odtisa je preverjena"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Pristnost obraza je potrjena"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Pristnost obraza je preverjena. Pritisnite gumb »Potrdi«."</string> @@ -1681,6 +1681,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"VKLOPLJENO"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"IZKLOPLJ."</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Ali storitvi <xliff:g id="SERVICE">%1$s</xliff:g> dovolite popoln nadzor nad svojo napravo?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Če vklopite storitev <xliff:g id="SERVICE">%1$s</xliff:g>, vaša naprava ne bo uporabljala zaklepanja zaslona za izboljšanje šifriranja podatkov."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Popoln nadzor je ustrezen za aplikacije, ki vam pomagajo pri funkcijah za ljudi s posebnimi potrebami, vendar ne za večino aplikacij."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ogledovanje in upravljanje zaslona"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Bere lahko vso vsebino na zaslonu ter prikaže vsebino prek drugih aplikacij."</string> @@ -1934,7 +1935,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija ni na voljo"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"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" product="tablet" msgid="4242053045964946062">"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" product="default" msgid="6159168735030739398">"V napravi <xliff:g id="DEVICE">%1$s</xliff:g> trenutno ni mogoče dostopati do te vsebine. Poskusite s telefonom."</string> @@ -2028,9 +2030,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"VSEENO ODPRI"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Zaznana je bila škodljiva aplikacija"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Ali aplikaciji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> dovolite dostop do vseh dnevnikov naprave?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Dovoli enkratni dostop"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Samo tokrat"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ne dovoli"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"V dnevnikih naprave se beleži dogajanje v napravi. Aplikacije lahko te dnevnike uporabijo za iskanje in odpravljanje težav.\n\nNekateri dnevniki morda vsebujejo občutljive podatke, zato dostop do vseh dnevnikov naprave omogočite le aplikacijam, ki jim zaupate. \n\nČe tej aplikaciji ne dovolite dostopa do vseh dnevnikov naprave, bo aplikacija kljub temu lahko dostopala do svojih dnevnikov. Proizvajalec naprave bo morda lahko kljub temu dostopal do nekaterih dnevnikov ali podatkov v napravi. Več o tem"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne prikaži več"</string> <string name="slices_permission_request" msgid="3677129866636153406">"Aplikacija <xliff:g id="APP_0">%1$s</xliff:g> želi prikazati izreze aplikacije <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Uredi"</string> @@ -2260,12 +2263,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Dejavnost v ozadju"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> se izvaja v ozadju in porablja energijo baterije. Dotaknite se za pregled."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> se dolgo časa izvaja v ozadju. Dotaknite se za pregled."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ni mogoče dostopati do fotoaparata tabličnega računalnika prek naprave <xliff:g id="DEVICE">%1$s</xliff:g>."</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Sistemski jezik"</string> </resources> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 693087a84031..ac155e8462f4 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Gabim gjatë vërtetimit"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Përdor kyçjen e ekranit"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Fut kyçjen e ekranit për të vazhduar"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"U zbulua gjurmë gishti e pjesshme"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Gjurma e gishtit nuk mund të përpunohej. Provo përsëri."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Pastro sensorin e gjurmës së gishtit dhe provo sërish"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Pastro sensorin dhe provo sërish"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Gjurma e gishtit nuk u njoh"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Shtyp fort te sensori"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Gjurma e gishtit u vërtetua"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Fytyra u vërtetua"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Fytyra u vërtetua, shtyp \"Konfirmo\""</string> @@ -1681,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AKTIV"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"JOAKTIV"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Do të lejosh që <xliff:g id="SERVICE">%1$s</xliff:g> të ketë kontroll të plotë të pajisjes sate?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Nëse aktivizon <xliff:g id="SERVICE">%1$s</xliff:g>, pajisja nuk do të përdorë kyçjen e ekranit për të përmirësuar enkriptimin e të dhënave."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Kontrolli i plotë është i përshtatshëm për aplikacionet që të ndihmojnë me nevojat e qasshmërisë, por jo për shumicën e aplikacioneve."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Shiko dhe kontrollo ekranin"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Ai mund të lexojë të gjithë përmbajtjen në ekran dhe të shfaqë përmbajtjen mbi aplikacione të tjera."</string> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacioni nuk ofrohet"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk ofrohet për momentin."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nuk ofrohet"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Kërkohet leje"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Qasja është e pamundur në <xliff:g id="DEVICE">%1$s</xliff:g> për momentin. Provoje në pajisjen Android TV më mirë."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Qasja është e pamundur në <xliff:g id="DEVICE">%1$s</xliff:g> për momentin. Provoje në tablet më mirë."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Qasja është e pamundur në <xliff:g id="DEVICE">%1$s</xliff:g> për momentin. Provoje në telefon më mirë."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"HAPE GJITHSESI"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"U gjet aplikacion i dëmshëm"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Të lejohet që <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> të ketë qasje te të gjitha evidencat e pajisjes?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Vetëm këtë herë"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Mos lejo"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Evidencat e pajisjes regjistrojnë çfarë ndodh në pajisjen tënde. Aplikacionet mund t\'i përdorin këto evidenca për të gjetur dhe rregulluar problemet.\n\nDisa evidenca mund të përmbajnë informacione delikate, ndaj lejo vetëm aplikacionet që u beson të kenë qasje te të gjitha evidencat e pajisjes. \n\nNëse nuk e lejon këtë aplikacion që të ketë qasje tek të gjitha evidencat e pajisjes, ai mund të vazhdojë të ketë qasje tek evidencat e tij. Prodhuesi i pajisjes sate mund të jetë ende në gjendje që të ketë qasje te disa evidenca ose informacione në pajisjen tënde. Mëso më shumë"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Mos e shfaq më"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> dëshiron të shfaqë pjesë të <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Modifiko"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Aktiviteti në sfond"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> po ekzekutohet në sfond dhe po shkarkon baterinë. Trokit për ta shqyrtuar."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> po ekzekutohet në sfond për një kohe të gjatë. Trokit për ta shqyrtuar."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Kontrollo aplikacionet aktive"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Nuk mund të qasesh në kamerën e tabletit tënd nga <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="system_locale_title" msgid="3978041860457277638">"Gjuha e sistemit"</string> </resources> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index c5f3ec7e0602..afe01d73b6bd 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -218,7 +218,7 @@ <string name="turn_on_radio" msgid="2961717788170634233">"Укључи бежични сигнал"</string> <string name="turn_off_radio" msgid="7222573978109933360">"Искључи бежични сигнал"</string> <string name="screen_lock" msgid="2072642720826409809">"Закључај екран"</string> - <string name="power_off" msgid="4111692782492232778">"Угаси"</string> + <string name="power_off" msgid="4111692782492232778">"Искључи"</string> <string name="silent_mode_silent" msgid="5079789070221150912">"Звоно је искључено"</string> <string name="silent_mode_vibrate" msgid="8821830448369552678">"Вибрација звона"</string> <string name="silent_mode_ring" msgid="6039011004781526678">"Звоно је укључено"</string> @@ -242,7 +242,7 @@ <string name="global_actions" product="tv" msgid="3871763739487450369">"Опције Android TV-а"</string> <string name="global_actions" product="default" msgid="6410072189971495460">"Опције телефона"</string> <string name="global_action_lock" msgid="6949357274257655383">"Закључај екран"</string> - <string name="global_action_power_off" msgid="4404936470711393203">"Угаси"</string> + <string name="global_action_power_off" msgid="4404936470711393203">"Искључи"</string> <string name="global_action_power_options" msgid="1185286119330160073">"Напајање"</string> <string name="global_action_restart" msgid="4678451019561687074">"Рестартуј"</string> <string name="global_action_emergency" msgid="1387617624177105088">"Хитан позив"</string> @@ -586,7 +586,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Грешка при потврди идентитета"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Користите закључавање екрана"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Употребите закључавање екрана да бисте наставили"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Јако притисните сензор"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Откривен је делимичан отисак прста"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Није успела обрада отиска прста. Пробајте поново."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Обришите сензор за отисак прста и пробајте поново"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Обришите сензор и пробајте поново"</string> @@ -599,7 +599,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Отисак прста није препознат"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Отисак прста није препознат"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Јако притисните сензор"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отисак прста је потврђен"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Лице је потврђено"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лице је потврђено. Притисните Потврди"</string> @@ -1680,6 +1680,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_enable_service_encryption_warning" msgid="8603532708618236909">"Ако укључите услугу <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> @@ -2027,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ИПАК ОТВОРИ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Откривена је штетна апликација"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Желите да дозволите апликацији <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> да приступа свим евиденцијама уређаја?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Дозволи једнократан приступ"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Само овај пут"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Не дозволи"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Евиденције уређаја региструју шта се дешава на уређају. Апликације могу да користе те евиденције да би пронашле и решиле проблеме.\n\nНеке евиденције могу да садрже осетљиве информације, па приступ свим евиденцијама уређаја треба да дозвољавате само апликацијама у које имате поверења. \n\nАко не дозволите овој апликацији да приступа свим евиденцијама уређаја, она и даље може да приступа сопственим евиденцијама. Произвођач уређаја ће можда и даље моћи да приступа неким евиденцијама или информацијама на уређају. Сазнајте више"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Не приказуј поново"</string> <string name="slices_permission_request" msgid="3677129866636153406">"Апликација <xliff:g id="APP_0">%1$s</xliff:g> жели да приказује исечке из апликације <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Измени"</string> @@ -2259,12 +2261,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> може да утиче на трајање батерије. Додирните да бисте прегледали активне апликације."</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Активност у позадини"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Апликација <xliff:g id="APP">%1$s</xliff:g> троши батерију у позадини. Додирните да бисте прегледали."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Апликација <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не може да се приступи камери таблета са <xliff:g id="DEVICE">%1$s</xliff:g> уређаја"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Језик система"</string> </resources> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 674d9e0ca0f5..888fdd937b64 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Ett fel uppstod vid autentiseringen"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Använd skärmlåset"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Fortsätt med hjälp av ditt skärmlås"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Ofullständigt fingeravtryck upptäcktes"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Det gick inte att bearbeta fingeravtrycket. Försök igen."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Rengör fingeravtryckssensorn och försök igen"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Rengör sensorn och försök igen"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Fingeravtrycket känns inte igen"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Tryck på sensorn med ett stadigt tryck"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeravtrycket har autentiserats"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Ansiktet har autentiserats"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ansiktet har autentiserats. Tryck på Bekräfta"</string> @@ -1681,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"PÅ"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"AV"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vill du tillåta att <xliff:g id="SERVICE">%1$s</xliff:g> får fullständig kontroll över enheten?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Om du aktiverar <xliff:g id="SERVICE">%1$s</xliff:g> används inte skärmlåset för att förbättra datakryptering på enheten."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Fullständig kontroll lämpar sig för appar med tillgänglighetsfunktioner, men är inte lämplig för de flesta appar."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Visa och styra skärmen"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Den kan läsa allt innehåll på skärmen och visa innehåll över andra appar."</string> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Appen är inte tillgänglig"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> är inte tillgängligt just nu."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> är inte tillgänglig"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Behörighet krävs"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Det går inte att streama detta till <xliff:g id="DEVICE">%1$s</xliff:g> för närvarande. Testa med Android TV-enheten i stället."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Det går inte att streama detta till <xliff:g id="DEVICE">%1$s</xliff:g> för närvarande. Testa med surfplattan i stället."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Det går inte att streama detta till <xliff:g id="DEVICE">%1$s</xliff:g> för närvarande. Testa med telefonen i stället."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ÖPPNA ÄNDÅ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"En skadlig app har upptäckts"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Vill du tillåta att <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> får åtkomst till alla enhetsloggar?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Bara den här gången"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Tillåt inte"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"I enhetsloggar registreras vad som händer på enheten. Appar kan använda dessa loggar för att hitta och åtgärda problem.\n\nVissa loggar kan innehålla känsliga uppgifter, så du ska bara bevilja appar du litar på åtkomst till alla enhetsloggar. \n\nEn app har åtkomst till sina egna loggar även om du inte ger den åtkomst till alla enhetsloggar. Enhetens tillverkare kan fortfarande ha åtkomst till vissa loggar eller viss information på enheten. Läs mer"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Visa inte igen"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> vill kunna visa bitar av <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Redigera"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Bakgrundsaktivitet"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> körs i bakgrunden så att batteriet tar slut fortare. Tryck för att granska."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> har körts i bakgrunden under lång tid. Tryck för att granska."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Kontrollera aktiva appar"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Surfplattans kamera kan inte användas från <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="system_locale_title" msgid="3978041860457277638">"Systemets språkinställning"</string> </resources> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index d9677588ca68..cca9d09bf902 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Hitilafu imetokea wakati wa uthibitishaji"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Tumia mbinu ya kufunga skrini"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Weka mbinu yako ya kufunga skrini ili uendelee"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Kimetambua sehemu ya alama ya kidole"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Imeshindwa kuchakata alama ya kidole. Tafadhali jaribu tena."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Safisha kitambua alama ya kidole kisha ujaribu tena"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Safisha kitambuzi kisha ujaribu tena"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Alama ya kidole haijatambuliwa"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Bonyeza kwa nguvu kwenye kitambuzi"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Imethibitisha alama ya kidole"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Uso umethibitishwa"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Uso umethibitishwa, tafadhali bonyeza thibitisha"</string> @@ -1681,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"IMEWASHWA"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"IMEZIMWA"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Ungependa kuruhusu <xliff:g id="SERVICE">%1$s</xliff:g> idhibiti kifaa chako kikamilifu?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Ukiwasha <xliff:g id="SERVICE">%1$s</xliff:g>, kifaa chako hakitatumia kipengele cha kufunga skrini yako ili kuboresha usimbaji wa data kwa njia fiche."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Udhibiti kamili unafaa kwa programu zinazokusaidia kwa mahitaji ya ufikivu, ila si kwa programu nyingi."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Kuangalia na kudhibiti skrini"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Kinaweza kusoma maudhui yote kwenye skrini na kuonyesha maudhui kwenye programu zingine."</string> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Programu haipatikani"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> haipatikani hivi sasa."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> haipatikani"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Ruhusa inahitajika"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Programu hii haiwezi kufikiwa kwenye <xliff:g id="DEVICE">%1$s</xliff:g> kwa muda huu. Badala yake jaribu kwenye kifaa chako cha Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Programu hii haiwezi kufikiwa kwenye <xliff:g id="DEVICE">%1$s</xliff:g> kwa muda huu. Badala yake jaribu kwenye kompyuta kibao yako."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Programu hii haiwezi kufikiwa kwenye <xliff:g id="DEVICE">%1$s</xliff:g> kwa muda huu. Badala yake jaribu kwenye simu yako."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"FUNGUA TU"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Imetambua programu hatari"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Ungependa kuruhusu <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ifikie kumbukumbu zote za kifaa?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Mara hii pekee"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Usiruhusu"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Kumbukumbu za kifaa hurekodi kinachofanyika kwenye kifaa chako. Programu zinaweza kutumia kumbukumbu hizi ili kutambua na kurekebisha hitilafu.\n\nBaadhi ya kumbukumbu huenda zikawa na taarifa nyeti, hivyo ruhusu tu programu unazoziamini kufikia kumbukumbu zote za kifaa. \n\nIwapo hutaruhusu programu hii ifikie kumbukumbu zote za kifaa, bado inaweza kufikia kumbukumbu zake yenyewe. Mtengenezaji wa kifaa chako bado anaweza kufikia baadhi ya kumbukumbu au taarifa zilizopo kwenye kifaa chako. Pata maelezo zaidi"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Usionyeshe tena"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> inataka kuonyesha vipengee <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Badilisha"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Shughuli za Chinichini"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> inatumika chinichini na kumaliza nishati ya betri. Gusa ili ukague."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> inatumika chinichini kwa muda mrefu. Gusa ili ukague."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Angalia programu zinazotumika"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Haiwezi kufikia kamera ya kompyuta kibao kutoka kwenye <xliff:g id="DEVICE">%1$s</xliff:g> yako"</string> <string name="system_locale_title" msgid="3978041860457277638">"Lugha ya mfumo"</string> </resources> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 0c0484e1d5d8..14ded62c26d5 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"அங்கீகரிப்பதில் பிழை"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"திரைப் பூட்டைப் பயன்படுத்து"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"தொடர்வதற்கு உங்கள் திரைப் பூட்டை உள்ளிடுங்கள்"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"சென்சாரின் மீது நன்றாக அழுத்தவும்"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"பகுதியளவு கைரேகை கண்டறியப்பட்டது"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"கைரேகையைச் செயலாக்க முடியவில்லை. மீண்டும் முயலவும்."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"கைரேகை சென்சாரைச் சுத்தம் செய்துவிட்டு மீண்டும் முயலவும்"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"சென்சாரைச் சுத்தம் செய்துவிட்டு மீண்டும் முயலவும்"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"கைரேகை அங்கீகரிக்கப்படவில்லை"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"கைரேகை அங்கீகரிக்கப்படவில்லை"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"சென்சாரின் மீது நன்றாக அழுத்தவும்"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"கைரேகை அங்கீகரிக்கப்பட்டது"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"முகம் அங்கீகரிக்கப்பட்டது"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"முகம் அங்கீகரிக்கப்பட்டது. ’உறுதிப்படுத்துக’ என்பதை அழுத்துக"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"<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> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"இந்த ஆப்ஸ் இப்போது கிடைப்பதில்லை"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"தற்போது உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்தில் இதை அணுக முடியாது. அதற்குப் பதிலாக Android TV சாதனத்தில் பயன்படுத்திப் பாருங்கள்."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"தற்போது உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்தில் இதை அணுக முடியாது. அதற்குப் பதிலாக உங்கள் டேப்லெட்டில் பயன்படுத்திப் பாருங்கள்."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"தற்போது உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்தில் இதை அணுக முடியாது. அதற்குப் பதிலாக உங்கள் மொபைலில் பயன்படுத்திப் பாருங்கள்."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"பரவாயில்லை, திற"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"தீங்கிழைக்கும் ஆப்ஸ் உள்ளது"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"சாதனப் பதிவுகள் அனைத்தையும் <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> அணுக அனுமதிக்கவா?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"ஒருமுறை அணுகலை அனுமதி"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"இப்போது மட்டும்"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"அனுமதிக்க வேண்டாம்"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"உங்கள் சாதனத்தில் நடப்பவற்றைச் சாதனப் பதிவுகள் ரெக்கார்டு செய்யும். சிக்கல்களைக் கண்டறிந்து சரிசெய்ய ஆப்ஸ் இந்தப் பதிவுகளைப் பயன்படுத்தலாம்.\n\nபாதுகாக்கப்பட வேண்டிய தகவல்கள் சில பதிவுகளில் இருக்கக்கூடும் என்பதால் சாதனப் பதிவுகள் அனைத்தையும் அணுக நீங்கள் நம்பும் ஆப்ஸை மட்டும் அனுமதிக்கவும். \n\nசாதனப் பதிவுகள் அனைத்தையும் அணுக இந்த ஆப்ஸை அனுமதிக்கவில்லை என்றாலும் அதற்குச் சொந்தமான பதிவுகளை அதனால் அணுக முடியும். சாதன உற்பத்தியாளர் உங்கள் சாதனத்திலுள்ள சில பதிவுகளையோ தகவல்களையோ தொடர்ந்து அணுகக்கூடும். மேலும் அறிக"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"மீண்டும் காட்டாதே"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_2">%2$s</xliff:g> ஆப்ஸின் விழிப்பூட்டல்களைக் காண்பிக்க, <xliff:g id="APP_0">%1$s</xliff:g> அனுமதி கேட்கிறது"</string> <string name="screenshot_edit" msgid="7408934887203689207">"திருத்து"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> பேட்டரியின் ஆயுளைப் பாதிக்கலாம். செயலிலுள்ள ஆப்ஸைப் பார்க்க தட்டவும்."</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"பின்னணிச் செயல்பாடு"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ஆப்ஸ் பின்னணியில் இயங்குவதுடன் பேட்டரியை அதிகமாகப் பயன்படுத்துகிறது. பார்க்க தட்டவும்."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்திலிருந்து டேப்லெட்டின் கேமராவை அணுக முடியாது"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"சிஸ்டம் மொழி"</string> </resources> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 1a4f904a1d27..0fa7a9ff2209 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -217,7 +217,7 @@ <string name="turn_on_radio" msgid="2961717788170634233">"వైర్లెస్ను ప్రారంభించండి"</string> <string name="turn_off_radio" msgid="7222573978109933360">"వైర్లెస్ను ఆపివేయండి"</string> <string name="screen_lock" msgid="2072642720826409809">"స్క్రీన్ లాక్"</string> - <string name="power_off" msgid="4111692782492232778">"పవర్ ఆఫ్ చేయండి"</string> + <string name="power_off" msgid="4111692782492232778">"పవర్ ఆఫ్ చేయి"</string> <string name="silent_mode_silent" msgid="5079789070221150912">"రింగర్ ఆఫ్లో ఉంది"</string> <string name="silent_mode_vibrate" msgid="8821830448369552678">"రింగర్ వైబ్రేట్లో ఉంది"</string> <string name="silent_mode_ring" msgid="6039011004781526678">"రింగర్ ఆన్లో ఉంది"</string> @@ -241,9 +241,9 @@ <string name="global_actions" product="tv" msgid="3871763739487450369">"Android TV ఎంపికలు"</string> <string name="global_actions" product="default" msgid="6410072189971495460">"ఫోన్ ఎంపికలు"</string> <string name="global_action_lock" msgid="6949357274257655383">"స్క్రీన్ లాక్"</string> - <string name="global_action_power_off" msgid="4404936470711393203">"పవర్ ఆఫ్ చేయండి"</string> + <string name="global_action_power_off" msgid="4404936470711393203">"పవర్ ఆఫ్ చేయి"</string> <string name="global_action_power_options" msgid="1185286119330160073">"పవర్"</string> - <string name="global_action_restart" msgid="4678451019561687074">"రీస్టార్ట్ చేయండి"</string> + <string name="global_action_restart" msgid="4678451019561687074">"రీస్టార్ట్ చేయి"</string> <string name="global_action_emergency" msgid="1387617624177105088">"ఎమర్జెన్సీ"</string> <string name="global_action_bug_report" msgid="5127867163044170003">"బగ్ రిపోర్ట్"</string> <string name="global_action_logout" msgid="6093581310002476511">"సెషన్ను ముగించు"</string> @@ -251,7 +251,7 @@ <string name="bugreport_title" msgid="8549990811777373050">"బగ్ రిపోర్ట్"</string> <string name="bugreport_message" msgid="5212529146119624326">"ఇది ఈమెయిల్ మెసేజ్ రూపంలో పంపడానికి మీ ప్రస్తుత పరికర స్థితి గురించి సమాచారాన్ని సేకరిస్తుంది. బగ్ రిపోర్ట్ను ప్రారంభించడం మొదలుకొని పంపడానికి సిద్ధం చేసే వరకు ఇందుకు కొంత సమయం పడుతుంది; దయచేసి ఓపిక పట్టండి."</string> <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"ప్రభావశీల రిపోర్ట్"</string> - <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"చాలా సందర్భాల్లో దీన్ని ఉపయోగించండి. ఇది రిపోర్ట్ ప్రోగ్రెస్ను ట్రాక్ చేయడానికి, సమస్య గురించి మరిన్ని వివరాలను నమోదు చేయడానికి మరియు స్క్రీన్షాట్లు తీయడానికి మిమ్మల్ని అనుమతిస్తుంది. ఇది రిపోర్ట్ చేయడానికి ఎక్కువ సమయం పట్టే తక్కువ వినియోగ విభాగాలను విడిచిపెట్టవచ్చు."</string> + <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"చాలా సందర్భాల్లో దీన్ని ఉపయోగించండి. ఇది రిపోర్ట్ ప్రోగ్రెస్ను ట్రాక్ చేయడానికి, సమస్య గురించి మరిన్ని వివరాలను నమోదు చేయడానికి మరియు స్క్రీన్షాట్లు తీయడానికి మిమ్మల్ని అనుమతిస్తుంది. ఇది నివేదించడానికి ఎక్కువ సమయం పట్టే తక్కువ వినియోగ విభాగాలను విడిచిపెట్టవచ్చు."</string> <string name="bugreport_option_full_title" msgid="7681035745950045690">"పూర్తి రిపోర్ట్"</string> <string name="bugreport_option_full_summary" msgid="1975130009258435885">"మీ పరికరం ప్రతిస్పందనరహితంగా ఉన్నప్పుడు లేదా చాలా నెమ్మదిగా ఉన్నప్పుడు లేదా మీకు అన్ని రిపోర్ట్ విభాగాలు అవసరమైనప్పుడు సిస్టమ్కి అంతరాయ స్థాయి కనిష్టంగా ఉండేలా చేయడానికి ఈ ఎంపిక ఉపయోగించండి. ఇది మరిన్ని వివరాలను నమోదు చేయడానికి లేదా అదనపు స్క్రీన్షాట్లు తీయడానికి మిమ్మల్ని అనుమతించదు."</string> <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{# సెకనులో బగ్ రిపోర్ట్ కోసం స్క్రీన్ షాట్ తీయడం.}other{# సెకన్లలో బగ్ రిపోర్ట్ కోసం స్క్రీన్ షాట్ తీయడం.}}"</string> @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"ప్రామాణీకరిస్తున్నప్పుడు ఎర్రర్ ఏర్పడింది"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"స్క్రీన్ లాక్ను ఉపయోగించండి"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"కొనసాగించడానికి మీ స్క్రీన్ లాక్ను ఎంటర్ చేయండి"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"సెన్సార్ మీద గట్టిగా నొక్కండి"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"పాక్షిక వేలిముద్ర గుర్తించబడింది"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"వేలిముద్రను ప్రాసెస్ చేయడం సాధ్యపడలేదు. దయచేసి మళ్లీ ప్రయత్నించండి."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"వేలిముద్ర సెన్సార్ను క్లీన్ చేసి, మళ్లీ ట్రై చేయండి"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"సెన్సార్ను క్లీన్ చేసి, మళ్లీ ట్రై చేయండి"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"వేలిముద్ర గుర్తించబడలేదు"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"వేలిముద్ర గుర్తించబడలేదు"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"సెన్సార్ మీద గట్టిగా నొక్కండి"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"వేలిముద్ర ప్రమాణీకరించబడింది"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ముఖం ప్రమాణీకరించబడింది"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ముఖం ప్రమాణీకరించబడింది, దయచేసి ధృవీకరించును నొక్కండి"</string> @@ -1130,7 +1130,7 @@ <string name="copy" msgid="5472512047143665218">"కాపీ చేయి"</string> <string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"క్లిప్బోర్డ్కు కాపీ చేయడంలో విఫలమైంది"</string> <string name="paste" msgid="461843306215520225">"అతికించు"</string> - <string name="paste_as_plain_text" msgid="7664800665823182587">"సాదా వచనం లాగా అతికించు"</string> + <string name="paste_as_plain_text" msgid="7664800665823182587">"సాదా వచనం వలె అతికించు"</string> <string name="replace" msgid="7842675434546657444">"భర్తీ చేయండి..."</string> <string name="delete" msgid="1514113991712129054">"తొలగించు"</string> <string name="copyUrl" msgid="6229645005987260230">"URLని కాపీ చేయి"</string> @@ -1211,7 +1211,7 @@ <string name="anr_application_process" msgid="4978772139461676184">"<xliff:g id="APPLICATION">%1$s</xliff:g> ప్రతిస్పందించడం లేదు"</string> <string name="anr_process" msgid="1664277165911816067">"ప్రాసెస్ <xliff:g id="PROCESS">%1$s</xliff:g> ప్రతిస్పందించడం లేదు"</string> <string name="force_close" msgid="9035203496368973803">"సరే"</string> - <string name="report" msgid="2149194372340349521">"రిపోర్ట్ చేయండి"</string> + <string name="report" msgid="2149194372340349521">"నివేదించు"</string> <string name="wait" msgid="7765985809494033348">"వేచి ఉండు"</string> <string name="webpage_unresponsive" msgid="7850879412195273433">"పేజీ ప్రతిస్పందించడం లేదు.\n\nమీరు దీన్ని మూసివేయాలనుకుంటున్నారా?"</string> <string name="launch_warning_title" msgid="6725456009564953595">"యాప్ దారి మళ్లించబడింది"</string> @@ -1328,7 +1328,7 @@ <string name="sim_done_button" msgid="6464250841528410598">"పూర్తయింది"</string> <string name="sim_added_title" msgid="7930779986759414595">"సిమ్ కార్డు జోడించబడింది"</string> <string name="sim_added_message" msgid="6602906609509958680">"మొబైల్ నెట్వర్క్ను యాక్సెస్ చేయడానికి మీ పరికరాన్ని పునఃప్రారంభించండి."</string> - <string name="sim_restart_button" msgid="8481803851341190038">"రీస్టార్ట్ చేయండి"</string> + <string name="sim_restart_button" msgid="8481803851341190038">"రీస్టార్ట్ చేయి"</string> <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"మొబైల్ సేవను సక్రియం చేయండి"</string> <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"మీ కొత్త SIMని సక్రియం చేయడానికి క్యారియర్ యాప్ను డౌన్లోడ్ చేయండి"</string> <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"మీ కొత్త SIMని సక్రియం చేయడం కోసం <xliff:g id="APP_NAME">%1$s</xliff:g> యాప్ని డౌన్లోడ్ చేయండి"</string> @@ -1525,7 +1525,7 @@ <string name="number_picker_increment_button" msgid="7621013714795186298">"పెంచు"</string> <string name="number_picker_decrement_button" msgid="5116948444762708204">"తగ్గించు"</string> <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> తాకి & అలాగే పట్టుకోండి."</string> - <string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"పెంచడానికి పైకి మరియు తగ్గించడానికి క్రిందికి స్లయిడ్ చేయండి."</string> + <string name="number_picker_increment_scroll_action" msgid="8310191318914268271">"పెంచడానికి పైకి మరియు తగ్గించడానికి క్రిందికి స్లైడ్ చేయండి."</string> <string name="time_picker_increment_minute_button" msgid="7195870222945784300">"నిమిషాన్ని పెంచు"</string> <string name="time_picker_decrement_minute_button" msgid="230925389943411490">"నిమిషాన్ని తగ్గించు"</string> <string name="time_picker_increment_hour_button" msgid="3063572723197178242">"గంటను పెంచు"</string> @@ -1564,7 +1564,7 @@ <string name="storage_usb_drive" msgid="448030813201444573">"USB డ్రైవ్"</string> <string name="storage_usb_drive_label" msgid="6631740655876540521">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB డ్రైవ్"</string> <string name="storage_usb" msgid="2391213347883616886">"USB నిల్వ"</string> - <string name="extract_edit_menu_button" msgid="63954536535863040">"ఎడిట్ చేయండి"</string> + <string name="extract_edit_menu_button" msgid="63954536535863040">"సవరించు"</string> <string name="data_usage_warning_title" msgid="9034893717078325845">"డేటా హెచ్చరిక"</string> <string name="data_usage_warning_body" msgid="1669325367188029454">"మీరు డేటాలో <xliff:g id="APP">%s</xliff:g> ఉపయోగించారు"</string> <string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"మొబైల్ డేటా పరిమితిని చేరుకున్నారు"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"మీరు <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> @@ -2026,9 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"ఏదేమైనా తెరువు"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"హానికరమైన యాప్ గుర్తించబడింది"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"అన్ని పరికర లాగ్లను యాక్సెస్ చేయడానికి <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>ను అనుమతించాలా?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"వన్-టైమ్ యాక్సెస్ను అనుమతించండి"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"ఈ ఒక్కసారి మాత్రమే"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"అనుమతించవద్దు"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"మీ పరికరంలో జరిగే దాన్ని పరికర లాగ్లు రికార్డ్ చేస్తాయి. సమస్యలను కనుగొని, పరిష్కరించడానికి యాప్లు ఈ లాగ్లను ఉపయోగిస్తాయి.\n\nకొన్ని లాగ్లలో గోప్యమైన సమాచారం ఉండవచ్చు, కాబట్టి మీరు విశ్వసించే యాప్లను మాత్రమే అన్ని పరికర లాగ్లను యాక్సెస్ చేయడానికి అనుమతించండి. \n\nఅన్ని పరికర లాగ్లను యాక్సెస్ చేయడానికి మీరు ఈ యాప్ను అనుమతించకపోతే, అది తన స్వంత లాగ్లను ఇప్పటికి యాక్సెస్ చేయగలదు. మీ పరికర తయారీదారు ఇప్పటికీ మీ పరికరంలో కొన్ని లాగ్లు లేదా సమాచారాన్ని యాక్సెస్ చేయగలరు. మరింత తెలుసుకోండి"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"మళ్లీ చూపవద్దు"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> <xliff:g id="APP_2">%2$s</xliff:g> స్లైస్లను చూపించాలనుకుంటోంది"</string> <string name="screenshot_edit" msgid="7408934887203689207">"ఎడిట్ చేయండి"</string> @@ -2258,12 +2260,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> బ్యాటరీ జీవితకాలాన్ని ప్రభావితం చేయవచ్చు. యాక్టివ్ యాప్లను రివ్యూ చేయడానికి ట్యాప్ చేయండి."</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"బ్యాక్గ్రౌండ్ యాక్టివిటీ"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> బ్యాక్గ్రౌండ్లో రన్ అవుతోంది, బ్యాటరీని ఎక్కువగా వాడుతోంది. రివ్యూ చేయడానికి ట్యాప్ చేయండి."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"మీ <xliff:g id="DEVICE">%1$s</xliff:g> నుండి టాబ్లెట్ కెమెరాను యాక్సెస్ చేయడం సాధ్యపడదు"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"సిస్టమ్ భాష"</string> </resources> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 845d218d1f12..5ab27266700a 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"การตรวจสอบข้อผิดพลาด"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ใช้การล็อกหน้าจอ"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ป้อนข้อมูลการล็อกหน้าจอเพื่อดำเนินการต่อ"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"ตรวจพบลายนิ้วมือบางส่วน"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ประมวลผลลายนิ้วมือไม่ได้ โปรดลองอีกครั้ง"</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ทำความสะอาดเซ็นเซอร์ลายนิ้วมือแล้วลองอีกครั้ง"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ทำความสะอาดเซ็นเซอร์แล้วลองอีกครั้ง"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ไม่รู้จักลายนิ้วมือ"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"กดเซ็นเซอร์ให้แน่น"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ตรวจสอบสิทธิ์ลายนิ้วมือแล้ว"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ตรวจสอบสิทธิ์ใบหน้าแล้ว"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ตรวจสอบสิทธิ์ใบหน้าแล้ว โปรดกดยืนยัน"</string> @@ -1681,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"หากคุณเปิด <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> @@ -2028,10 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"เปิดต่อไป"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"ตรวจพบแอปที่เป็นอันตราย"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"อนุญาตให้ <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> เข้าถึงบันทึกทั้งหมดของอุปกรณ์ใช่ไหม"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"เฉพาะครั้งนี้"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"ไม่อนุญาต"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"บันทึกของอุปกรณ์เก็บข้อมูลสิ่งที่เกิดขึ้นในอุปกรณ์ แอปสามารถใช้บันทึกเหล่านี้เพื่อค้นหาและแก้ไขปัญหา\n\nบันทึกบางรายการอาจมีข้อมูลที่ละเอียดอ่อน คุณจึงควรอนุญาตเฉพาะแอปที่เชื่อถือได้ให้เข้าถึงบันทึกทั้งหมดของอุปกรณ์ \n\nหากคุณไม่อนุญาตให้แอปนี้เข้าถึงบันทึกทั้งหมดของอุปกรณ์ แอปจะยังเข้าถึงบันทึกของตัวเองได้อยู่ ผู้ผลิตอุปกรณ์อาจยังเข้าถึงบันทึกหรือข้อมูลบางรายการในอุปกรณ์ของคุณได้ ดูข้อมูลเพิ่มเติม"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"ไม่ต้องแสดงอีก"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ต้องการแสดงส่วนต่างๆ ของ <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"แก้ไข"</string> @@ -2261,16 +2260,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"กิจกรรมในเบื้องหลัง"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> กำลังทำงานอยู่ในเบื้องหลังและทำให้เปลืองแบตเตอรี่ แตะเพื่อตรวจสอบ"</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ทำงานอยู่ในเบื้องหลังเป็นเวลานาน แตะเพื่อตรวจสอบ"</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ตรวจสอบแอปที่ใช้งานอยู่"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"เข้าถึงกล้องของแท็บเล็ตจาก <xliff:g id="DEVICE">%1$s</xliff:g> ไม่ได้"</string> <string name="system_locale_title" msgid="3978041860457277638">"ภาษาของระบบ"</string> </resources> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 27b2804d2500..aee994b0bef0 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Nagkaroon ng error sa pag-authenticate"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gumamit ng lock ng screen"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Ilagay ang iyong lock ng screen para magpatuloy"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Pumindot nang madiin sa sensor"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Hindi buo ang natukoy na fingerprint"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Hindi maproseso ang fingerprint. Pakisubukan ulit."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Linisin ang sensor para sa fingerprint at subukan ulit"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Linisin ang sensor at subukan ulit"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Hindi nakilala ang fingerprint"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Hindi nakilala ang fingerprint"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Pumindot nang madiin sa sensor"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Na-authenticate ang fingerprint"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Na-authenticate ang mukha"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Na-authenticate ang mukha, pakipindot ang kumpirmahin"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"NAKA-ON"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"NAKA-OFF"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Bigyan ang <xliff:g id="SERVICE">%1$s</xliff:g> ng ganap na kontrol sa iyong device?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Kung io-on mo ang <xliff:g id="SERVICE">%1$s</xliff:g>, hindi gagamitin ng iyong device ang lock ng screen mo para pahusayin ang pag-encrypt ng data."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Naaangkop ang ganap na kontrol sa mga app na tumutulong sa mga pangangailangan mo sa accessibility, pero hindi sa karamihan ng mga app."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Tingnan at kontrolin ang screen"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Mababasa nito ang lahat ng content na nasa screen at makakapagpakita ito ng content sa iba pang app."</string> @@ -2026,9 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"BUKSAN PA RIN"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"May na-detect na mapaminsalang app"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Payagan ang <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> na i-access ang lahat ng log ng device?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Payagan ang isang beses na pag-access"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Ngayon lang"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Huwag payagan"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Nire-record ng mga log ng device kung ano ang nangyayari sa iyong device. Magagamit ng mga app ang mga log na ito para maghanap at mag-ayos ng mga isyu.\n\nPosibleng maglaman ang ilang log ng sensitibong impormasyon, kaya ang mga app lang na pinagkakatiwalaan mo ang payagang maka-access sa lahat ng log ng device. \n\nKung hindi mo papayagan ang app na ito na i-access ang lahat ng log ng device, maa-access pa rin nito ang mga sarili nitong log. Posible pa ring ma-access ng manufacturer ng iyong device ang ilang log o impormasyon sa device mo. Matuto pa"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Huwag ipakita ulit"</string> <string name="slices_permission_request" msgid="3677129866636153406">"Gustong ipakita ng <xliff:g id="APP_0">%1$s</xliff:g> ang mga slice ng <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"I-edit"</string> @@ -2258,12 +2260,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Aktibidad sa Background"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Gumagana ang <xliff:g id="APP">%1$s</xliff:g> sa background at gumagamit ito ng baterya I-tap para suriin."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Napakatagal nang gumagana ang <xliff:g id="APP">%1$s</xliff:g> sa background. I-tap para suriin."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Hindi ma-access ang camera ng tablet mula sa iyong <xliff:g id="DEVICE">%1$s</xliff:g>"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Wika ng system"</string> </resources> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 990aad0b3655..b3624f37329d 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Kimlik doğrulama sırasında hata oluştu"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekran kilidi kullan"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Devam etmek için ekran kilidinizi girin"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Parmak izinin tümü algılanamadı"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Parmak izi işlenemedi. Lütfen tekrar deneyin."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Parmak izi sensörünü temizleyip tekrar deneyin"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Sensörü temizleyip tekrar deneyin"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Parmak izi tanınmadı"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Sensöre sıkıca bastırın"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Parmak izi kimlik doğrulaması yapıldı"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Yüz kimliği doğrulandı"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Yüz kimliği doğrulandı, lütfen onayla\'ya basın"</string> @@ -1681,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AÇIK"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"KAPALI"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> hizmetinin cihazınızı tamamen kontrol etmesine izin veriyor musunuz?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g> hizmetini açarsanız cihazınız veri şifrelemeyi geliştirmek için ekran kilidinizi kullanmaz."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Erişebilirlik ihtiyaçlarınıza yardımcı olan uygulamalara tam kontrol verilmesi uygundur ancak diğer pek çok uygulama için uygun değildir."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ekranı görüntüleme ve kontrol etme"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Ekrandaki tüm içeriği okuyabilir ve içeriği diğer uygulamaların üzerinde gösterebilir."</string> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Uygulama kullanılamıyor"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması şu anda kullanılamıyor."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> kullanılamıyor"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"İzin gerekli"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Bu uygulamaya şu anda <xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan erişilemiyor. Bunun yerine Android TV cihazınızı kullanmayı deneyin."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Bu uygulamaya şu anda <xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan erişilemiyor. Bunun yerine tabletinizi kullanmayı deneyin."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Bu uygulamaya şu anda <xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan erişilemiyor. Bunun yerine telefonunuzu kullanmayı deneyin."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"YİNE DE AÇ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Zararlı uygulama tespit edildi"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> uygulamasının tüm cihaz günlüklerine erişmesine izin verilsin mi?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Yalnız bu sefer"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"İzin verme"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Cihaz günlükleri, cihazınızda olanları kaydeder. Uygulamalar, sorunları bulup düzeltmek için bu günlükleri kullanabilir.\n\nBazı günlükler hassas bilgiler içerebileceği için yalnızca güvendiğiniz uygulamaların tüm cihaz günlüklerine erişmesine izin verin. \n\nBu uygulamanın tüm cihaz günlüklerine erişmesine izin vermeseniz de kendi günlüklerine erişmeye devam edebilir. Ayrıca, cihaz üreticiniz de cihazınızdaki bazı günlüklere veya bilgilere erişmeye devam edebilir. Daha fazla bilgi"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Bir daha gösterme"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> uygulaması, <xliff:g id="APP_2">%2$s</xliff:g> dilimlerini göstermek istiyor"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Düzenle"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Arka Plan Etkinliği"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> arka planda çalışıyor ve pil tüketiyor. İncelemek için dokunun."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> uzun süredir arka planda çalışıyor. İncelemek için dokunun."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Etkin uygulamaları kontrol edin"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan tabletin kamerasına erişilemiyor"</string> <string name="system_locale_title" msgid="3978041860457277638">"Sistem dili"</string> </resources> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 2ce474a72e93..56a53ea202f5 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -587,8 +587,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Помилка автентифікації"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Доступ розблокуванням екрана"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Щоб продовжити, введіть дані для розблокування екрана"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Виявлено частковий відбиток пальця"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не вдалось обробити відбиток пальця. Повторіть спробу."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Очистьте сканер відбитків пальців і повторіть спробу"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Очистьте сканер і повторіть спробу"</string> @@ -601,8 +600,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Відбиток пальця не розпізнано"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Міцно притисніть палець до сканера"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Відбиток пальця автентифіковано"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Обличчя автентифіковано"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Обличчя автентифіковано. Натисніть \"Підтвердити\""</string> @@ -1359,7 +1357,7 @@ <string name="usb_power_notification_message" msgid="7284765627437897702">"Під’єднаний пристрій заряджається. Торкніться, щоб побачити більше опцій."</string> <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Виявлено аналоговий аксесуар для аудіо"</string> <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Під’єднаний пристрій несумісний із цим телефоном. Торкніться, щоб дізнатися більше."</string> - <string name="adb_active_notification_title" msgid="408390247354560331">"Налагодження через USB активне"</string> + <string name="adb_active_notification_title" msgid="408390247354560331">"Налагодження USB підключено"</string> <string name="adb_active_notification_message" msgid="5617264033476778211">"Торкніться, щоб вимкнути його"</string> <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Виберіть, щоб вимкнути налагодження за USB"</string> <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Активне налагодження через Wi-Fi"</string> @@ -1683,6 +1681,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_enable_service_encryption_warning" msgid="8603532708618236909">"Якщо ви ввімкнете сервіс <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> @@ -1936,7 +1935,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Додаток недоступний"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Цей додаток зараз недоступний на вашому <xliff:g id="DEVICE">%1$s</xliff:g>. Спробуйте натомість скористатися пристроєм Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Цей додаток зараз недоступний на вашому <xliff:g id="DEVICE">%1$s</xliff:g>. Спробуйте натомість скористатися планшетом."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Цей додаток зараз недоступний на вашому <xliff:g id="DEVICE">%1$s</xliff:g>. Спробуйте натомість скористатися телефоном."</string> @@ -2030,10 +2030,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"УСЕ ОДНО ВІДКРИТИ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Виявлено шкідливий додаток"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Надати додатку <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> доступ до всіх журналів пристрою?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Лише цього разу"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Не дозволяти"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"У журналах пристрою реєструється все, що відбувається на ньому. За допомогою цих журналів додатки можуть виявляти й усувати проблеми.\n\nДеякі журнали можуть містити конфіденційні дані, тому надавати доступ до всіх журналів пристрою слід лише надійним додаткам. \n\nЯкщо додаток не має доступу до всіх журналів пристрою, він усе одно може використовувати власні журнали. Виробник вашого пристрою все одно може використовувати деякі журнали чи інформацію на ньому. Докладніше"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Більше не показувати"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> хоче показати фрагменти додатка <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Редагувати"</string> @@ -2263,16 +2263,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Робота у фоновому режимі"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Додаток <xliff:g id="APP">%1$s</xliff:g> працює у фоновому режимі та розряджає акумулятор. Натисніть, щоб переглянути."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Додаток <xliff:g id="APP">%1$s</xliff:g> довго працює у фоновому режимі. Натисніть, щоб переглянути."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Перевірте активні додатки"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Не вдається отримати доступ до камери планшета з пристрою <xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="system_locale_title" msgid="3978041860457277638">"Мова системи"</string> </resources> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 0cd35c57f9f3..a9f21f0bf1df 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"خرابی کی توثیق ہو رہی ہے"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"اسکرین لاک استعمال کریں"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"جاری رکھنے کے لیے اپنا اسکرین لاک درج کریں"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"جزوی فنگر پرنٹ کا پتہ چلا"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"فنگر پرنٹ پر کارروائی نہیں کی جا سکی۔ براہ کرم دوبارہ کوشش کریں۔"</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"فنگر پرنٹ سینسر صاف کریں اور دوبارہ کوشش کریں"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"سینسر صاف کریں اور دوبارہ کوشش کریں"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"فنگر پرنٹ کی شناخت نہیں ہو سکی"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"سینسر پر اچھی طرح دبائیں"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"فنگر پرنٹ کی تصدیق ہو گئی"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"چہرے کی تصدیق ہو گئی"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"چہرے کی تصدیق ہو گئی، براہ کرم \'تصدیق کریں\' کو دبائيں"</string> @@ -1681,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"اگر آپ <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> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"ایپ دستیاب نہیں ہے"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"اس وقت آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> پر اس تک رسائی نہیں مل سکتی۔ اس کے بجائے اپنے Android TV آلے پر کوشش کریں۔"</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"اس وقت آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> پر اس تک رسائی نہیں مل سکتی۔ اس کے بجائے اپنے ٹیبلیٹ پر کوشش کریں۔"</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"اس وقت آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> پر اس تک رسائی نہیں مل سکتی۔ اس کے بجائے اپنے فون پر کوشش کریں۔"</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"بہر صورت کھولیں"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"ضرر رساں ایپ کا پتہ چلا"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> کو آلے کے تمام لاگز تک رسائی کی اجازت دیں؟"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"صرف اس وقت"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"اجازت نہ دیں"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"آپ کے آلے پر جو ہوتا ہے آلے کے لاگز اسے ریکارڈ کر لیتے ہیں۔ ایپس ان لاگز کا استعمال مسائل کو تلاش کرنے اور ان کو حل کرنے کے لیے کر سکتی ہیں۔\n\nکچھ لاگز میں حساس معلومات شامل ہو سکتی ہیں، اس لیے صرف اپنے بھروسے مند ایپس کو ہی آلے کے تمام لاگز تک رسائی کی اجازت دیں۔ \n\nاگر آپ اس ایپ کو آلے کے تمام لاگز تک رسائی کی اجازت نہیں دیتے ہیں تب بھی یہ اپنے لاگز تک رسائی حاصل کر سکتی ہے۔ آپ کے آلے کا مینوفیکچرر اب بھی آپ کے آلے پر کچھ لاگز یا معلومات تک رسائی حاصل کر سکتا ہے۔ مزید جانیں"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"دوبارہ نہ دکھائیں"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> <xliff:g id="APP_2">%2$s</xliff:g> کے سلائسز دکھانا چاہتی ہے"</string> <string name="screenshot_edit" msgid="7408934887203689207">"ترمیم کریں"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"پس منظر کی سرگرمی"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> پس منظر میں چل رہی ہے اور بیٹری ختم ہو رہی ہے۔ جائزے کے لیے تھپتھپائیں۔"</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> کافی وقت سے پس منظر میں چل رہی ہے۔ جائزے کے لیے تھپتھپائیں۔"</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"فعال ایپس چیک کریں"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> سے ٹیبلیٹ کے کیمرا تک رسائی حاصل نہیں کی جا سکتی"</string> <string name="system_locale_title" msgid="3978041860457277638">"سسٹم کی زبان"</string> </resources> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index 5c06b51308a7..929d9d35c22b 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -323,7 +323,7 @@ <string name="permgroupdesc_calllog" msgid="2026996642917801803">"telefon chaqiruvlari jurnalini o‘qish va unga yozish"</string> <string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string> <string name="permgroupdesc_phone" msgid="270048070781478204">"telefon qo‘ng‘iroqlarini amalga oshirish va boshqarish"</string> - <string name="permgrouplab_sensors" msgid="9134046949784064495">"Tana sensorlari"</string> + <string name="permgrouplab_sensors" msgid="9134046949784064495">"Tana sezgichlari"</string> <string name="permgroupdesc_sensors" msgid="2610631290633747752">"organizm holati haqidagi sezgich ma’lumotlariga kirish"</string> <string name="permgrouplab_notifications" msgid="5472972361980668884">"Bildirishnomalar"</string> <string name="permgroupdesc_notifications" msgid="4608679556801506580">"bildirishnomalarni chiqarish"</string> @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Autentifikatsiya amalga oshmadi"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekran qulfi"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Ekran qulfini kiritish bilan davom eting"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Sensorni mahkam bosing"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Barmoq izi qismi aniqlandi"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Barmoq izi aniqlanmadi. Qaytadan urining."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Barmoq izi skanerini tozalang va qayta urining"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Sensorni tozalang va qayta urining"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Barmoq izi aniqlanmadi"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Barmoq izi aniqlanmadi"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Sensorni mahkam bosing"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Barmoq izi tekshirildi"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Yuzingiz aniqlandi"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Yuzingiz aniqlandi, tasdiqlash uchun bosing"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"YONIQ"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"YOQILMAGAN"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> xizmatiga qurilmangizni boshqarish uchun toʻliq ruxsat berilsinmi?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Agar <xliff:g id="SERVICE">%1$s</xliff:g> xizmatini yoqsangiz, qurilmangiz maʼlumotlarni shifrlashni kuchaytirish uchun ekran qulfidan foydalanmaydi."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Toʻliq nazorat maxsus imkoniyatlar bilan ishlovchi ilovalar uchun mos, lekin barcha ilovalar uchun emas."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ekranni ochish va boshqarish"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Ekrandagi barcha kontentni oʻqishi va kontentni boshqa ilovalar ustida ochishi mumkin."</string> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Ilova ishlamayapti"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"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" product="tablet" msgid="4242053045964946062">"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" product="default" msgid="6159168735030739398">"Ayni vaqtda bu translatsiya <xliff:g id="DEVICE">%1$s</xliff:g> qurilmangizda ishlamaydi. Telefon orqali urininb koʻring."</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"BARIBIR OCHILSIN"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Zararli ilova aniqlandi"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ilovasiga qurilmadagi barcha jurnal qaydlariga ruxsat berilsinmi?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Bir matalik foydalanishga ruxsat berish"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Faqat shu safar"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Rad etish"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Qurilma jurnaliga qurilma bilan yuz bergan hodisalar qaydlari yoziladi. Ilovalar bu jurnal qaydlari yordamida muammolarni topishi va bartaraf qilishi mumkin.\n\nAyrim jurnal qaydlarida maxfiy axborotlar yozilishi mumkin, shu sababli qurilmadagi barcha jurnal qaydlariga ruxsatni faqat ishonchli ilovalarga bering. \n\nBu ilovaga qurilmadagi barcha jurnal qaydlariga ruxsat berilmasa ham, u oʻzining jurnalini ocha oladi. Qurilma ishlab chiqaruvchisi ham ayrim jurnallar yoki qurilma haqidagi axborotlarni ocha oladi. Batafsil"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Boshqa chiqmasin"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> ilovasi <xliff:g id="APP_2">%2$s</xliff:g> ilovasidan fragmentlar ko‘rsatish uchun ruxsat so‘ramoqda"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Tahrirlash"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Fondagi harakatlar"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> fonda ishlamoqda va batareyani tugatmoqda. Tekshirish uchun bosing."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> uzoq vaqt orqa fonda ishlamoqda. Tekshirish 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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"<xliff:g id="DEVICE">%1$s</xliff:g> qurilmasidan planshetning kamerasiga kirish imkonsiz"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Tizim tili"</string> </resources> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index f0019cf54fb3..e22126d6b851 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -425,7 +425,7 @@ <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Cho phép ứng dụng sửa đổi nhật ký cuộc gọi trên máy tính bảng của bạn, bao gồm dữ liệu về các cuộc gọi đến và gọi đi. Các ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi nhật ký cuộc gọi của bạn."</string> <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Cho phép ứng dụng sửa đổi nhật ký cuộc gọi trên thiết bị Android TV, bao gồm cả dữ liệu về cuộc gọi đến và cuộc gọi đi. Các ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi nhật ký cuộc gọi của bạn."</string> <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Cho phép ứng dụng sửa đổi nhật ký cuộc gọi trên điện thoại của bạn, bao gồm dữ liệu về các cuộc gọi đến và gọi đi. Các ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi nhật ký cuộc gọi của bạn."</string> - <string name="permlab_bodySensors" msgid="662918578601619569">"Truy cập vào dữ liệu cảm biến cơ thể khi đang được sử dụng, chẳng hạn như nhịp tim"</string> + <string name="permlab_bodySensors" msgid="662918578601619569">"Truy cập vào dữ liệu cảm biến cơ thể khi đang dùng, chẳng hạn như nhịp tim"</string> <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Cho phép ứng dụng truy cập vào dữ liệu cảm biến cơ thể khi đang dùng, chẳng hạn như nhịp tim, thân nhiệt và tỷ lệ phần trăm oxy trong máu."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Truy cập vào dữ liệu cảm biến cơ thể khi ở chế độ nền, chẳng hạn như nhịp tim"</string> <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Cho phép ứng dụng truy cập vào dữ liệu cảm biến cơ thể khi ở chế độ nền, chẳng hạn như nhịp tim, thân nhiệt và tỷ lệ phần trăm oxy trong máu."</string> @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Lỗi khi xác thực"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Dùng phương thức khóa màn hình"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Hãy nhập phương thức khóa màn hình của bạn để tiếp tục"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Phát hiện thấy một phần vân tay"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Không thể xử lý vân tay. Vui lòng thử lại."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Hãy vệ sinh cảm biến vân tay rồi thử lại"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Vệ sinh cảm biến rồi thử lại"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Không nhận dạng được vân tay"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Nhấn chắc trên cảm biến"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Đã xác thực vân tay"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Đã xác thực khuôn mặt"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Đã xác thực khuôn mặt, vui lòng nhấn để xác nhận"</string> @@ -1616,7 +1614,7 @@ <string name="media_route_button_content_description" msgid="2299223698196869956">"Truyền"</string> <string name="media_route_chooser_title" msgid="6646594924991269208">"Kết nối với thiết bị"</string> <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"Truyền màn hình tới thiết bị"</string> - <string name="media_route_chooser_searching" msgid="6119673534251329535">"Đang tìm thiết bị…"</string> + <string name="media_route_chooser_searching" msgid="6119673534251329535">"Đang tìm kiếm thiết bị…"</string> <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"Cài đặt"</string> <string name="media_route_controller_disconnect" msgid="7362617572732576959">"Ngắt kết nối"</string> <string name="media_route_status_scanning" msgid="8045156315309594482">"Đang quét..."</string> @@ -1681,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ĐANG BẬT"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ĐANG TẮT"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Cho phép <xliff:g id="SERVICE">%1$s</xliff:g> toàn quyền kiểm soát thiết bị của bạn?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Nếu bạn bật <xliff:g id="SERVICE">%1$s</xliff:g>, thiết bị của bạn sẽ không dùng phương thức khóa màn hình để tăng cường mã hóa dữ liệu."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Bạn chỉ nên cấp toàn quyền kiểm soát cho những ứng dụng trợ giúp mình khi cần hỗ trợ tiếp cận, chứ không nên cấp cho hầu hết các ứng dụng."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Xem và điều khiển màn hình"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Dịch vụ này có thể đọc toàn bộ nội dung trên màn hình và hiển thị nội dung trên các ứng dụng khác."</string> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"Ứng dụng này không dùng được"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> hiện không dùng được."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"Không hỗ trợ <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string> - <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Cần có quyền"</string> + <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Hiện tại, bạn không thể truy cập vào ứng dụng này trên <xliff:g id="DEVICE">%1$s</xliff:g>. Hãy thử trên thiết bị Android TV."</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Hiện tại, bạn không thể truy cập vào ứng dụng này trên <xliff:g id="DEVICE">%1$s</xliff:g>. Hãy thử trên máy tính bảng."</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Hiện tại, bạn không thể truy cập vào ứng dụng này trên <xliff:g id="DEVICE">%1$s</xliff:g>. Hãy thử trên điện thoại."</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"VẪN MỞ"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Đã phát hiện ứng dụng độc hại"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Cho phép <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> truy cập vào tất cả các nhật ký thiết bị?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Chỉ lần này"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Không cho phép"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Nhật ký thiết bị ghi lại những hoạt động diễn ra trên thiết bị. Các ứng dụng có thể dùng nhật ký này để tìm và khắc phục sự cố.\n\nMột số nhật ký có thể chứa thông tin nhạy cảm, vì vậy, bạn chỉ nên cấp quyền truy cập vào mọi nhật ký trên thiết bị cho những ứng dụng mà mình tin cậy. \n\nNếu bạn không cho phép ứng dụng này truy cập vào mọi nhật ký trên thiết bị, thì ứng dụng vẫn có thể truy cập vào nhật ký của chính nó. Nhà sản xuất thiết bị vẫn có thể truy cập vào một số nhật ký hoặc thông tin trên thiết bị của bạn. Tìm hiểu thêm"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Không hiện lại"</string> <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> muốn hiển thị các lát của <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Chỉnh sửa"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Hoạt động trong nền"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> đang chạy trong nền và làm tiêu hao pin. Nhấn để xem."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> đang chạy trong nền trong thời gian dài. Nhấn để xem lại."</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Xem các ứng dụng đang hoạt động"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Không truy cập được vào máy ảnh trên máy tính bảng từ <xliff:g id="DEVICE">%1$s</xliff:g> của bạn"</string> <string name="system_locale_title" msgid="3978041860457277638">"Ngôn ngữ hệ thống"</string> </resources> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 2cc8daaea8c6..9053195d09c0 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/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="permdesc_bodySensors" product="default" msgid="7652650410295512140">"允许应用在使用期间访问身体传感器数据,如心率、体温和血氧浓度。"</string> - <string name="permlab_bodySensors_background" msgid="4912560779957760446">"在后台运行时可访问身体传感器数据,如心率"</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> @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"进行身份验证时出错"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用屏幕锁定凭据"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"输入您的屏幕锁定凭据才能继续"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"请用力按住传感器"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"检测到局部指纹"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"无法处理指纹,请重试。"</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"请清洁指纹传感器,然后重试"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"请清洁传感器,然后重试"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"未能识别指纹"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"未能识别指纹"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"请用力按住传感器"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"已验证指纹"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"面孔已验证"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"面孔已验证,请按确认按钮"</string> @@ -1679,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"如果您开启<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> @@ -1932,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"应用无法使用"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"目前无法在您的<xliff:g id="DEVICE">%1$s</xliff:g>上访问此内容。您可以尝试在 Android TV 设备上访问。"</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"目前无法在您的<xliff:g id="DEVICE">%1$s</xliff:g>上访问此内容。您可以尝试在平板电脑上访问。"</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"目前无法在您的<xliff:g id="DEVICE">%1$s</xliff:g>上访问此内容。您可以尝试在手机上访问。"</string> @@ -2026,9 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"仍然打开"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"检测到有害应用"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"允许“<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>”访问所有设备日志吗?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"允许访问一次"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"仅限这一次"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"不允许"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"设备日志会记录设备上发生的活动。应用可以使用这些日志查找和修复问题。\n\n部分日志可能包含敏感信息,因此请仅允许您信任的应用访问所有设备日志。\n\n如果您不授予此应用访问所有设备日志的权限,它仍然可以访问自己的日志。您的设备制造商可能仍然能够访问您设备上的部分日志或信息。了解详情"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"不再显示"</string> <string name="slices_permission_request" msgid="3677129866636153406">"“<xliff:g id="APP_0">%1$s</xliff:g>”想要显示“<xliff:g id="APP_2">%2$s</xliff:g>”图块"</string> <string name="screenshot_edit" msgid="7408934887203689207">"编辑"</string> @@ -2258,12 +2261,13 @@ <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> - <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> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"“<xliff:g id="APP">%1$s</xliff:g>”可能会影响电池续航时间。点按即可查看使用中的应用。"</string> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"后台活动"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"“<xliff:g id="APP">%1$s</xliff:g>”正在后台运行,并且消耗了大量电池电量。点按即可查看。"</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"“<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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"无法从<xliff:g id="DEVICE">%1$s</xliff:g>上访问平板电脑的摄像头"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"系统语言"</string> </resources> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index aeba31270405..90811367d387 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"驗證時發生錯誤"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用螢幕鎖定"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"如要繼續操作,請輸入螢幕鎖定解鎖憑證"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"只偵測到部分指紋"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"無法處理指紋。請再試一次。"</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"請清潔指紋感應器,然後再試一次"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"請清潔感應器,然後再試一次"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"無法辨識指紋"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"請用力按住感應器"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"驗證咗指紋"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"面孔已經驗證"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"面孔已經驗證,請㩒一下 [確認]"</string> @@ -1681,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"如果您開啟 <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> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"無法使用應用程式"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用 Android TV 裝置存取。"</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用平板電腦存取。"</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用手機存取。"</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"仍要開啟"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"偵測到有害的應用程式"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"要允許「<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>」存取所有裝置記錄嗎?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"僅限這次"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"不允許"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"裝置記錄會記下裝置上的活動。應用程式可透過這些記錄找出並修正問題。\n\n部分記錄可能包含敏感資料,因此請只允許信任的應用程式存取所有裝置記錄。\n\n如果不允許此應用程式存取所有裝置記錄,此應用程式仍能存取自己的記錄,且裝置製造商可能仍可存取裝置上的部分記錄或資料。瞭解詳情"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"不要再顯示"</string> <string name="slices_permission_request" msgid="3677129866636153406">"「<xliff:g id="APP_0">%1$s</xliff:g>」想顯示「<xliff:g id="APP_2">%2$s</xliff:g>」的快訊"</string> <string name="screenshot_edit" msgid="7408934887203689207">"編輯"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"背景活動"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> 正在背景執行並大量耗電。輕按即可查看。"</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> 已長時間在背景執行。輕按即可查看。"</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"查看使用中的應用程式"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取平板電腦的相機"</string> <string name="system_locale_title" msgid="3978041860457277638">"系統語言"</string> </resources> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index a0e6485ec415..b257d16c47ac 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -585,8 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"驗證時發生錯誤"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用螢幕鎖定功能"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"如要繼續操作,請輸入螢幕鎖定憑證"</string> - <!-- no translation found for fingerprint_acquired_partial (4323789264604479684) --> - <skip /> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"僅偵測到局部指紋"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"無法處理指紋,請再試一次。"</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"請清潔指紋感應器,然後再試一次"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"清潔感應器,然後再試一次"</string> @@ -599,8 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"指紋辨識失敗"</string> - <!-- no translation found for fingerprint_udfps_error_not_match (8236930793223158856) --> - <skip /> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"請確實按住感應器"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"指紋驗證成功"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"臉孔驗證成功"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"臉孔驗證成功,請按下 [確認] 按鈕"</string> @@ -1681,6 +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_enable_service_encryption_warning" msgid="8603532708618236909">"如果你開啟「<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> @@ -1934,7 +1933,8 @@ <string name="app_blocked_title" msgid="7353262160455028160">"應用程式無法使用"</string> <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_permission_dialog (4483161748582966785) --> + <skip /> <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用 Android TV 裝置。"</string> <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用平板電腦。"</string> <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用手機。"</string> @@ -2028,10 +2028,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"仍要開啟"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"偵測到有害應用程式"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"要允許「<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>」存取所有裝置記錄嗎?"</string> - <!-- no translation found for log_access_confirmation_allow (5302517782599389507) --> - <skip /> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"僅允許這一次"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"不允許"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"系統會透過裝置記錄記下裝置上的活動。應用程式可以根據這些記錄找出問題並進行修正。\n\n某些記錄可能含有機密資訊,因此請勿讓不信任的應用程式存取所有裝置記錄。\n\n即使你不允許這個應用程式存取所有裝置記錄,這個應用程式仍能存取自己的記錄,而且裝置製造商或許仍可存取裝置的某些記錄或資訊。瞭解詳情"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"不要再顯示"</string> <string name="slices_permission_request" msgid="3677129866636153406">"「<xliff:g id="APP_0">%1$s</xliff:g>」想要顯示「<xliff:g id="APP_2">%2$s</xliff:g>」的區塊"</string> <string name="screenshot_edit" msgid="7408934887203689207">"編輯"</string> @@ -2261,16 +2261,13 @@ <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> - <!-- no translation found for notification_title_abusive_bg_apps (3258460527676573815) --> - <skip /> - <!-- no translation found for notification_title_long_running_fgs (8170284286477131587) --> - <skip /> - <!-- no translation found for notification_content_abusive_bg_apps (9180610713603474720) --> + <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"背景活動"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"「<xliff:g id="APP">%1$s</xliff:g>」正在背景運作且耗用大量電力。輕觸即可查看。"</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"「<xliff:g id="APP">%1$s</xliff:g>」已長時間在背景運作。輕觸即可查看。"</string> + <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"查看使用中的應用程式"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> <skip /> - <!-- no translation found for notification_content_long_running_fgs (8258193410039977101) --> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> <skip /> - <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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"無法從 <xliff:g id="DEVICE">%1$s</xliff:g> 存取平板電腦的相機"</string> <string name="system_locale_title" msgid="3978041860457277638">"系統語言"</string> </resources> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 37b4fee0489d..17bf7a4cc1e5 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -585,7 +585,7 @@ <string name="biometric_error_generic" msgid="6784371929985434439">"Iphutha lokufakazela ubuqiniso"</string> <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Sebenzisa isikhiya sesikrini"</string> <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Faka ukukhiya isikrini kwakho ukuze uqhubeke"</string> - <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Cindezela ngokuqinile kunzwa"</string> + <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Kutholwe ingxenye yesigxivizo somunwe"</string> <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Ayikwazanga ukucubungula izigxivizo zeminwe. Sicela uzame futhi."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Hlanza inzwa yesigxivizo somunwe bese uzame futhi"</string> <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Hlanza inzwa bese uzame futhi"</string> @@ -598,7 +598,7 @@ <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Isigxivizo somunwe asaziwa"</string> - <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Isigxivizo somunwe asaziwa"</string> + <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Cindezela ngokuqinile kunzwa"</string> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Izigxivizo zeminwe zigunyaziwe"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Ubuso bufakazelwe ubuqiniso"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ukuqinisekiswa kobuso, sicela ucindezele okuthi qinisekisa"</string> @@ -1679,6 +1679,7 @@ <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"VULA"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"VALA"</string> <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vumela i-<xliff:g id="SERVICE">%1$s</xliff:g> ukuthola ukulawula okuphelele kwedivayisi yakho?"</string> + <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"Uma uvula i-<xliff:g id="SERVICE">%1$s</xliff:g>, idivayisi yakho ngeke isebenzise ukukhiya kwakho kwesikrini sakho ukuthuthukisa ukubethelwa kwedatha."</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Ukulawula okugcwele kulungele izinhlelo zokusebenza ezikusiza ngezidingo zokufinyelela, kodwa hhayi izinhlelo zokusebenza eziningi."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Buka futhi ulawule isikrini"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Singafunda konke okuqukethwe esikrinini futhi sibonise okuqukethwe kwezinye izinhlelo zokusebenza."</string> @@ -2026,9 +2027,10 @@ <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"VULA NOMA KUNJALO"</string> <string name="harmful_app_warning_title" msgid="8794823880881113856">"Uhlelo lokusebenza oluyingozi lutholakele"</string> <string name="log_access_confirmation_title" msgid="2343578467290592708">"Vumela i-<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ukuba ifinyelele wonke amalogu edivayisi?"</string> - <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Vumela ukufinyelela kwesikhathi esisodwa"</string> + <string name="log_access_confirmation_allow" msgid="143157286283302512">"Kulokhu kuphela"</string> <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Ungavumeli"</string> - <string name="log_access_confirmation_body" msgid="6581985716241928135">"Amalogu edivayisi arekhoda okwenzekayo kudivayisi yakho. Ama-app angasebenzisa lawa malogu ukuze athole futhi alungise izinkinga.\n\nAmanye amalogu angase aqukathe ulwazi olubucayi, ngakho vumela ama-app owathembayo kuphela ukuthi afinyelele wonke amalogu edivayisi. \n\nUma ungayivumeli le app ukuthi ifinyelele wonke amalogu wedivayisi, isengakwazi ukufinyelela amalogu wayo. Umkhiqizi wedivayisi yakho usengakwazi ukufinyelela amanye amalogu noma ulwazi kudivayisi yakho. Funda kabanzi"</string> + <!-- no translation found for log_access_confirmation_body (6581985716241928135) --> + <skip /> <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ungabonisi futhi"</string> <string name="slices_permission_request" msgid="3677129866636153406">"I-<xliff:g id="APP_0">%1$s</xliff:g> ifuna ukubonisa izingcezu ze-<xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7408934887203689207">"Hlela"</string> @@ -2258,12 +2260,13 @@ <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> - <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> - <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_title_abusive_bg_apps" msgid="344582472797982073">"Umsebenzi Wangemuva"</string> + <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"I-<xliff:g id="APP">%1$s</xliff:g> isebenza ngemuva futhi idla ibhethri. Thepha ukuze ubuyekeze."</string> + <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"I-<xliff:g id="APP">%1$s</xliff:g> isebenza ngemuva isikhathi eside. Thepha ukuze ubuyekeze."</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> - <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Ayikwazi ukufinyelela ikhamera yethebulethi kusuka ku-<xliff:g id="DEVICE">%1$s</xliff:g> yakho"</string> + <!-- no translation found for vdm_camera_access_denied (6102378580971542473) --> + <skip /> + <!-- no translation found for vdm_camera_access_denied (6895968310395249076) --> + <skip /> <string name="system_locale_title" msgid="3978041860457277638">"Ulimi lwesistimu"</string> </resources> diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml index 54325e590347..71c98d002984 100644 --- a/core/res/res/values/colors.xml +++ b/core/res/res/values/colors.xml @@ -174,14 +174,14 @@ <color name="system_notification_accent_color">#00000000</color> <!-- Default user icon colors --> - <color name="user_icon_1">#ff00bcd4</color><!-- cyan 500 --> - <color name="user_icon_2">#ff3f51b5</color><!-- indigo 500 --> - <color name="user_icon_3">#ff4285f4</color><!-- blue 500 --> - <color name="user_icon_4">#ffe91e63</color><!-- pink 500 --> - <color name="user_icon_5">#ff0f9d58</color><!-- green 500 --> - <color name="user_icon_6">#ff8bc34a</color><!-- light green 500 --> - <color name="user_icon_7">#ffff9800</color><!-- orange 500 --> - <color name="user_icon_8">#ffff5722</color><!-- deep orange 500 --> + <color name="user_icon_1">#ffe46962</color><!-- red --> + <color name="user_icon_2">#ffaf5cf7</color><!-- purple --> + <color name="user_icon_3">#ff4c8df6</color><!-- blue --> + <color name="user_icon_4">#fff439a0</color><!-- pink --> + <color name="user_icon_5">#ff1ea446</color><!-- green --> + <color name="user_icon_6">#ff129eaf</color><!-- cyan --> + <color name="user_icon_7">#ffb26c00</color><!-- yellow --> + <color name="user_icon_8">#ffe8710a</color><!-- orange --> <color name="user_icon_default_gray">#ff9e9e9e</color><!-- gray 500 --> <color name="user_icon_default_white">#ffffffff</color><!-- white --> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 60d875c2ca39..42f789bb59fc 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2918,6 +2918,11 @@ com.android.settings.intelligence </string> + <!-- System bluetooth stack package name --> + <string name="config_systemBluetoothStack" translatable="false"> + com.android.bluetooth.services + </string> + <!-- Flag indicating that the media framework should not allow changes or mute on any stream or global volumes. --> <bool name="config_useFixedVolume">false</bool> diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml index 870f54989674..86bad7f12258 100644 --- a/core/res/res/values/public-staging.xml +++ b/core/res/res/values/public-staging.xml @@ -184,6 +184,8 @@ <public name="safety_protection_display_text" /> <!-- @hide @SystemApi --> <public name="config_systemSettingsIntelligence" /> + <!-- @hide --> + <public name="config_systemBluetoothStack" /> </staging-public-group> <staging-public-group type="dimen" first-id="0x01db0000"> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 7069e716087d..776d3dafe8c0 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2303,6 +2303,7 @@ <java-symbol type="drawable" name="scrubber_control_disabled_holo" /> <java-symbol type="drawable" name="scrubber_control_selector_holo" /> <java-symbol type="drawable" name="scrubber_progress_horizontal_holo_dark" /> + <java-symbol type="drawable" name="progress_small_material" /> <java-symbol type="string" name="chooseUsbActivity" /> <java-symbol type="string" name="ext_media_badremoval_notification_message" /> <java-symbol type="string" name="ext_media_badremoval_notification_title" /> @@ -4753,7 +4754,11 @@ <java-symbol type="drawable" name="ic_swap_horiz" /> <java-symbol type="bool" name="config_notificationForceUserSetOnUpgrade" /> + <!-- For app language picker --> <java-symbol type="string" name="system_locale_title" /> <java-symbol type="layout" name="app_language_picker_system_default" /> + <java-symbol type="layout" name="app_language_picker_system_current" /> + <java-symbol type="layout" name="app_language_picker_current_locale_item" /> <java-symbol type="id" name="system_locale_subtitle" /> + <java-symbol type="id" name="language_picker_item" /> </resources> diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java index 3e261a7113ac..50639be57f22 100644 --- a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java +++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java @@ -157,7 +157,7 @@ public class ObjectPoolTests { .setPendingResults(resultInfoList()).setPendingNewIntents(referrerIntentList()) .setIsForward(true).setAssistToken(assistToken) .setShareableActivityToken(shareableActivityToken) - .build(); + .setTaskFragmentToken(new Binder()).build(); LaunchActivityItem emptyItem = new LaunchActivityItemBuilder().build(); LaunchActivityItem item = itemSupplier.get(); diff --git a/core/tests/coretests/src/android/app/servertransaction/TestUtils.java b/core/tests/coretests/src/android/app/servertransaction/TestUtils.java index 1467fed898c4..26d9628ba55b 100644 --- a/core/tests/coretests/src/android/app/servertransaction/TestUtils.java +++ b/core/tests/coretests/src/android/app/servertransaction/TestUtils.java @@ -110,6 +110,7 @@ class TestUtils { private IBinder mAssistToken; private IBinder mShareableActivityToken; private boolean mLaunchedFromBubble; + private IBinder mTaskFragmentToken; LaunchActivityItemBuilder setIntent(Intent intent) { mIntent = intent; @@ -206,13 +207,18 @@ class TestUtils { return this; } + LaunchActivityItemBuilder setTaskFragmentToken(IBinder taskFragmentToken) { + mTaskFragmentToken = taskFragmentToken; + return this; + } + LaunchActivityItem build() { return LaunchActivityItem.obtain(mIntent, mIdent, mInfo, mCurConfig, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mProcState, mState, mPersistentState, mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo, mAssistToken, null /* activityClientController */, mShareableActivityToken, - mLaunchedFromBubble); + mLaunchedFromBubble, mTaskFragmentToken); } } } diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java index beadc4464516..8276d10be4cd 100644 --- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java +++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java @@ -203,6 +203,7 @@ public class TransactionParcelTests { .setPendingResults(resultInfoList()).setActivityOptions(ActivityOptions.makeBasic()) .setPendingNewIntents(referrerIntentList()).setIsForward(true) .setAssistToken(new Binder()).setShareableActivityToken(new Binder()) + .setTaskFragmentToken(new Binder()) .build(); writeAndPrepareForReading(item); diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java index b006a1681a99..8d3751e6ad6c 100644 --- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java +++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java @@ -345,7 +345,7 @@ public class ActivityThreadClientTest { null /* pendingResults */, null /* pendingNewIntents */, null /* activityOptions */, true /* isForward */, null /* profilerInfo */, mThread /* client */, null /* asssitToken */, null /* shareableActivityToken */, - false /* launchedFromBubble */); + false /* launchedFromBubble */, null /* taskfragmentToken */); } @Override diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 58a2073981bf..04ead1bf1e9c 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -33,6 +33,30 @@ applications that come with the platform <permission name="android.permission.WRITE_SECURE_SETTINGS"/> </privapp-permissions> + <privapp-permissions package="com.android.bluetooth.services"> + <permission name="android.permission.DUMP"/> + <permission name="android.permission.MODIFY_AUDIO_ROUTING"/> + <permission name="android.permission.WRITE_SECURE_SETTINGS"/> + <permission name="android.permission.TETHER_PRIVILEGED"/> + <permission name="android.permission.CALL_PRIVILEGED"/> + <permission name="android.permission.MODIFY_PHONE_STATE"/> + <permission name="android.permission.INTERACT_ACROSS_USERS"/> + <permission name="android.permission.INTERACT_ACROSS_USERS_FULL"/> + <permission name="android.permission.CONTROL_INCALL_EXPERIENCE"/> + <permission name="android.permission.UPDATE_DEVICE_STATS"/> + <permission name="android.permission.PACKAGE_USAGE_STATS"/> + <permission name="android.permission.NFC_HANDOVER_STATUS"/> + <permission name="android.permission.CONNECTIVITY_INTERNAL"/> + <permission name="android.permission.BLUETOOTH_PRIVILEGED"/> + <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> + <permission name="android.permission.MEDIA_CONTENT_CONTROL"/> + <permission name="android.permission.REAL_GET_TASKS"/> + <permission name="android.permission.MANAGE_USERS"/> + <permission name="android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND"/> + <permission name="android.permission.WRITE_APN_SETTINGS"/> + <permission name="android.permission.UPDATE_APP_OPS_STATS"/> + </privapp-permissions> + <privapp-permissions package="com.android.backupconfirm"> <permission name="android.permission.BACKUP"/> <permission name="android.permission.CRYPT_KEEPER"/> 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 c76fa9658c67..01f5feb9b13e 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -615,14 +615,22 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen return null; } + private void updateCallbackIfNecessary() { + updateCallbackIfNecessary(true /* deferCallbackUntilAllActivitiesCreated */); + } + /** * Notifies listeners about changes to split states if necessary. + * + * @param deferCallbackUntilAllActivitiesCreated boolean to indicate whether the split info + * callback should be deferred until all the + * organized activities have been created. */ - private void updateCallbackIfNecessary() { + private void updateCallbackIfNecessary(boolean deferCallbackUntilAllActivitiesCreated) { if (mEmbeddingCallback == null) { return; } - if (!allActivitiesCreated()) { + if (deferCallbackUntilAllActivitiesCreated && !allActivitiesCreated()) { return; } List<SplitInfo> currentSplitStates = getActiveSplitStates(); @@ -838,6 +846,36 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen private final class LifecycleCallbacks extends EmptyLifecycleCallbacksAdapter { @Override + public void onActivityPreCreated(Activity activity, Bundle savedInstanceState) { + final IBinder activityToken = activity.getActivityToken(); + final IBinder initialTaskFragmentToken = ActivityThread.currentActivityThread() + .getActivityClient(activityToken).mInitialTaskFragmentToken; + // If the activity is not embedded, then it will not have an initial task fragment token + // so no further action is needed. + if (initialTaskFragmentToken == null) { + return; + } + for (int i = mTaskContainers.size() - 1; i >= 0; i--) { + final List<TaskFragmentContainer> containers = mTaskContainers.valueAt(i) + .mContainers; + for (int j = containers.size() - 1; j >= 0; j--) { + final TaskFragmentContainer container = containers.get(j); + if (!container.hasActivity(activityToken) + && container.getTaskFragmentToken().equals(initialTaskFragmentToken)) { + // The onTaskFragmentInfoChanged callback containing this activity has not + // reached the client yet, so add the activity to the pending appeared + // activities and send a split info callback to the client before + // {@link Activity#onCreate} is called. + container.addPendingAppearedActivity(activity); + updateCallbackIfNecessary( + false /* deferCallbackUntilAllActivitiesCreated */); + return; + } + } + } + } + + @Override public void onActivityPostCreated(Activity activity, Bundle savedInstanceState) { // Calling after Activity#onCreate is complete to allow the app launch something // first. In case of a configured placeholder activity we want to make sure diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java index e49af41d4eac..9a12669f078a 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java @@ -120,7 +120,7 @@ class TaskFragmentContainer { } ActivityStack toActivityStack() { - return new ActivityStack(collectActivities(), mInfo.getRunningActivityCount() == 0); + return new ActivityStack(collectActivities(), isEmpty()); } void addPendingAppearedActivity(@NonNull Activity pendingAppearedActivity) { diff --git a/libs/WindowManager/Jetpack/tests/OWNERS b/libs/WindowManager/Jetpack/tests/OWNERS index f2c3388023be..ac522b2dde10 100644 --- a/libs/WindowManager/Jetpack/tests/OWNERS +++ b/libs/WindowManager/Jetpack/tests/OWNERS @@ -1,4 +1,4 @@ -# Bug component: 909476 +# Bug component: 1157642 # includes OWNERS from parent directories charlesccchen@google.com diegovela@google.com diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java index e528df8c89b4..3f0b01bef0ce 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java @@ -131,7 +131,7 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou mDisplayController.getDisplayContext(mRootTaskInfo.displayId), mRootTaskInfo.configuration, this /* layoutChangeListener */, mParentContainerCallbacks, mDisplayImeController, mController.getTaskOrganizer(), - true /* applyDismissingParallax */); + SplitLayout.PARALLAX_DISMISSING); mDisplayInsetsController.addInsetsChangedListener(mRootTaskInfo.displayId, mSplitLayout); final WindowContainerToken token1 = task1.token; @@ -327,13 +327,15 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou @Override public void onLayoutPositionChanging(SplitLayout layout) { mSyncQueue.runInSync(t -> - layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2)); + layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2, + true /* applyResizingOffset */)); } @Override public void onLayoutSizeChanging(SplitLayout layout) { mSyncQueue.runInSync(t -> - layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2)); + layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2, + true /* applyResizingOffset */)); } @Override @@ -342,7 +344,8 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou layout.applyTaskChanges(wct, mTaskInfo1, mTaskInfo2); mSyncQueue.queue(wct); mSyncQueue.runInSync(t -> - layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2)); + layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2, + false /* applyResizingOffset */)); } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java index 577ced53f992..42ac19509693 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java @@ -48,18 +48,16 @@ import com.android.wm.shell.common.annotations.ShellMainThread; * Controls the window animation run when a user initiates a back gesture. */ public class BackAnimationController implements RemoteCallable<BackAnimationController> { - - private static final String BACK_PREDICTABILITY_PROGRESS_THRESHOLD_PROP = - "persist.debug.back_predictability_progress_threshold"; - // By default, enable new back dispatching without any animations. - private static final int BACK_PREDICTABILITY_PROP = - SystemProperties.getInt("persist.debug.back_predictability", 1); - public static final boolean IS_ENABLED = BACK_PREDICTABILITY_PROP > 0; - private static final int PROGRESS_THRESHOLD = SystemProperties - .getInt(BACK_PREDICTABILITY_PROGRESS_THRESHOLD_PROP, -1); private static final String TAG = "BackAnimationController"; + private static final String PREDICTIVE_BACK_PROGRESS_THRESHOLD_PROP = + "persist.wm.debug.predictive_back_progress_threshold"; + public static final boolean IS_ENABLED = + SystemProperties.getInt("persist.wm.debug.predictive_back", 1) != 0; + private static final int PROGRESS_THRESHOLD = SystemProperties + .getInt(PREDICTIVE_BACK_PROGRESS_THRESHOLD_PROP, -1); @VisibleForTesting - boolean mEnableAnimations = (BACK_PREDICTABILITY_PROP & (1 << 1)) != 0; + boolean mEnableAnimations = SystemProperties.getInt( + "persist.wm.debug.predictive_back_anim", 0) != 0; /** * Location of the initial touch event of the back gesture. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index 116d3524e711..ec81d230fae7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -72,6 +72,10 @@ import java.io.PrintWriter; */ public final class SplitLayout implements DisplayInsetsController.OnInsetsChangedListener { + public static final int PARALLAX_NONE = 0; + public static final int PARALLAX_DISMISSING = 1; + public static final int PARALLAX_ALIGN_CENTER = 2; + private final int mDividerWindowWidth; private final int mDividerInsets; private final int mDividerSize; @@ -87,7 +91,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange private final SplitWindowManager mSplitWindowManager; private final DisplayImeController mDisplayImeController; private final ImePositionProcessor mImePositionProcessor; - private final DismissingEffectPolicy mDismissingEffectPolicy; + private final ResizingEffectPolicy mSurfaceEffectPolicy; private final ShellTaskOrganizer mTaskOrganizer; private final InsetsState mInsetsState = new InsetsState(); @@ -105,7 +109,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange SplitLayoutHandler splitLayoutHandler, SplitWindowManager.ParentContainerCallbacks parentContainerCallbacks, DisplayImeController displayImeController, ShellTaskOrganizer taskOrganizer, - boolean applyDismissingParallax) { + int parallaxType) { mContext = context.createConfigurationContext(configuration); mOrientation = configuration.orientation; mRotation = configuration.windowConfiguration.getRotation(); @@ -115,7 +119,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange parentContainerCallbacks); mTaskOrganizer = taskOrganizer; mImePositionProcessor = new ImePositionProcessor(mContext.getDisplayId()); - mDismissingEffectPolicy = new DismissingEffectPolicy(applyDismissingParallax); + mSurfaceEffectPolicy = new ResizingEffectPolicy(parallaxType); final Resources resources = context.getResources(); mDividerSize = resources.getDimensionPixelSize(R.dimen.split_divider_bar_width); @@ -281,7 +285,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange } DockedDividerUtils.sanitizeStackBounds(mBounds1, true /** topLeft */); DockedDividerUtils.sanitizeStackBounds(mBounds2, false /** topLeft */); - mDismissingEffectPolicy.applyDividerPosition(position, isLandscape); + mSurfaceEffectPolicy.applyDividerPosition(position, isLandscape); } /** Inflates {@link DividerView} on the root surface. */ @@ -486,7 +490,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange /** Apply recorded surface layout to the {@link SurfaceControl.Transaction}. */ public void applySurfaceChanges(SurfaceControl.Transaction t, SurfaceControl leash1, - SurfaceControl leash2, SurfaceControl dimLayer1, SurfaceControl dimLayer2) { + SurfaceControl leash2, SurfaceControl dimLayer1, SurfaceControl dimLayer2, + boolean applyResizingOffset) { final SurfaceControl dividerLeash = getDividerLeash(); if (dividerLeash != null) { mTempRect.set(getRefDividerBounds()); @@ -506,7 +511,10 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange return; } - mDismissingEffectPolicy.adjustDismissingSurface(t, leash1, leash2, dimLayer1, dimLayer2); + mSurfaceEffectPolicy.adjustDimSurface(t, dimLayer1, dimLayer2); + if (applyResizingOffset) { + mSurfaceEffectPolicy.adjustRootSurface(t, leash1, leash2); + } } /** Apply recorded task layout to the {@link WindowContainerTransaction}. */ @@ -590,7 +598,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange * Calls when resizing the split bounds. * * @see #applySurfaceChanges(SurfaceControl.Transaction, SurfaceControl, SurfaceControl, - * SurfaceControl, SurfaceControl) + * SurfaceControl, SurfaceControl, boolean) */ void onLayoutSizeChanging(SplitLayout layout); @@ -600,7 +608,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange * @see #applyTaskChanges(WindowContainerTransaction, ActivityManager.RunningTaskInfo, * ActivityManager.RunningTaskInfo) * @see #applySurfaceChanges(SurfaceControl.Transaction, SurfaceControl, SurfaceControl, - * SurfaceControl, SurfaceControl) + * SurfaceControl, SurfaceControl, boolean) */ void onLayoutSizeChanged(SplitLayout layout); @@ -609,7 +617,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange * panel. * * @see #applySurfaceChanges(SurfaceControl.Transaction, SurfaceControl, SurfaceControl, - * SurfaceControl, SurfaceControl) + * SurfaceControl, SurfaceControl, boolean) */ void onLayoutPositionChanging(SplitLayout layout); @@ -637,21 +645,25 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange * Calculates and applies proper dismissing parallax offset and dimming value to hint users * dismissing gesture. */ - private class DismissingEffectPolicy { + private class ResizingEffectPolicy { /** Indicates whether to offset splitting bounds to hint dismissing progress or not. */ - private final boolean mApplyParallax; + private final int mParallaxType; + + int mShrinkSide = DOCKED_INVALID; // The current dismissing side. int mDismissingSide = DOCKED_INVALID; // The parallax offset to hint the dismissing side and progress. - final Point mDismissingParallaxOffset = new Point(); + final Point mParallaxOffset = new Point(); // The dimming value to hint the dismissing side and progress. float mDismissingDimValue = 0.0f; + final Rect mContentBounds = new Rect(); + final Rect mSurfaceBounds = new Rect(); - DismissingEffectPolicy(boolean applyDismissingParallax) { - mApplyParallax = applyDismissingParallax; + ResizingEffectPolicy(int parallaxType) { + mParallaxType = parallaxType; } /** @@ -662,7 +674,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange */ void applyDividerPosition(int position, boolean isLandscape) { mDismissingSide = DOCKED_INVALID; - mDismissingParallaxOffset.set(0, 0); + mParallaxOffset.set(0, 0); mDismissingDimValue = 0; int totalDismissingDistance = 0; @@ -676,15 +688,39 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange - mDividerSnapAlgorithm.getDismissEndTarget().position; } + final boolean topLeftShrink = isLandscape + ? position < mWinBounds1.right : position < mWinBounds1.bottom; + if (topLeftShrink) { + mShrinkSide = isLandscape ? DOCKED_LEFT : DOCKED_TOP; + mContentBounds.set(mWinBounds1); + mSurfaceBounds.set(mBounds1); + } else { + mShrinkSide = isLandscape ? DOCKED_RIGHT : DOCKED_BOTTOM; + mContentBounds.set(mWinBounds2); + mSurfaceBounds.set(mBounds2); + } + if (mDismissingSide != DOCKED_INVALID) { float fraction = Math.max(0, Math.min(mDividerSnapAlgorithm.calculateDismissingFraction(position), 1f)); mDismissingDimValue = DIM_INTERPOLATOR.getInterpolation(fraction); - fraction = calculateParallaxDismissingFraction(fraction, mDismissingSide); + if (mParallaxType == PARALLAX_DISMISSING) { + fraction = calculateParallaxDismissingFraction(fraction, mDismissingSide); + if (isLandscape) { + mParallaxOffset.x = (int) (fraction * totalDismissingDistance); + } else { + mParallaxOffset.y = (int) (fraction * totalDismissingDistance); + } + } + } + + if (mParallaxType == PARALLAX_ALIGN_CENTER) { if (isLandscape) { - mDismissingParallaxOffset.x = (int) (fraction * totalDismissingDistance); + mParallaxOffset.x = + (mSurfaceBounds.width() - mContentBounds.width()) / 2; } else { - mDismissingParallaxOffset.y = (int) (fraction * totalDismissingDistance); + mParallaxOffset.y = + (mSurfaceBounds.height() - mContentBounds.height()) / 2; } } } @@ -704,41 +740,66 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange } /** Applies parallax offset and dimming value to the root surface at the dismissing side. */ - boolean adjustDismissingSurface(SurfaceControl.Transaction t, - SurfaceControl leash1, SurfaceControl leash2, + void adjustRootSurface(SurfaceControl.Transaction t, + SurfaceControl leash1, SurfaceControl leash2) { + SurfaceControl targetLeash = null; + + if (mParallaxType == PARALLAX_DISMISSING) { + switch (mDismissingSide) { + case DOCKED_TOP: + case DOCKED_LEFT: + targetLeash = leash1; + mTempRect.set(mBounds1); + break; + case DOCKED_BOTTOM: + case DOCKED_RIGHT: + targetLeash = leash2; + mTempRect.set(mBounds2); + break; + } + } else if (mParallaxType == PARALLAX_ALIGN_CENTER) { + switch (mShrinkSide) { + case DOCKED_TOP: + case DOCKED_LEFT: + targetLeash = leash1; + mTempRect.set(mBounds1); + break; + case DOCKED_BOTTOM: + case DOCKED_RIGHT: + targetLeash = leash2; + mTempRect.set(mBounds2); + break; + } + } + if (mParallaxType != PARALLAX_NONE && targetLeash != null) { + t.setPosition(targetLeash, + mTempRect.left + mParallaxOffset.x, mTempRect.top + mParallaxOffset.y); + // Transform the screen-based split bounds to surface-based crop bounds. + mTempRect.offsetTo(-mParallaxOffset.x, -mParallaxOffset.y); + t.setWindowCrop(targetLeash, mTempRect); + } + } + + void adjustDimSurface(SurfaceControl.Transaction t, SurfaceControl dimLayer1, SurfaceControl dimLayer2) { - SurfaceControl targetLeash, targetDimLayer; + SurfaceControl targetDimLayer; switch (mDismissingSide) { case DOCKED_TOP: case DOCKED_LEFT: - targetLeash = leash1; targetDimLayer = dimLayer1; - mTempRect.set(mBounds1); break; case DOCKED_BOTTOM: case DOCKED_RIGHT: - targetLeash = leash2; targetDimLayer = dimLayer2; - mTempRect.set(mBounds2); break; case DOCKED_INVALID: default: t.setAlpha(dimLayer1, 0).hide(dimLayer1); t.setAlpha(dimLayer2, 0).hide(dimLayer2); - return false; - } - - if (mApplyParallax) { - t.setPosition(targetLeash, - mTempRect.left + mDismissingParallaxOffset.x, - mTempRect.top + mDismissingParallaxOffset.y); - // Transform the screen-based split bounds to surface-based crop bounds. - mTempRect.offsetTo(-mDismissingParallaxOffset.x, -mDismissingParallaxOffset.y); - t.setWindowCrop(targetLeash, mTempRect); + return; } t.setAlpha(targetDimLayer, mDismissingDimValue) .setVisibility(targetDimLayer, mDismissingDimValue > 0.001f); - return true; } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index 73f393140cbc..7f9ecca20b48 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -63,6 +63,7 @@ import com.android.wm.shell.pip.PipUiEventLogger; import com.android.wm.shell.pip.phone.PhonePipMenuController; import com.android.wm.shell.pip.phone.PipAppOpsListener; import com.android.wm.shell.pip.phone.PipController; +import com.android.wm.shell.pip.phone.PipKeepClearAlgorithm; import com.android.wm.shell.pip.phone.PipMotionHelper; import com.android.wm.shell.pip.phone.PipTouchHandler; import com.android.wm.shell.recents.RecentTasksController; @@ -207,7 +208,8 @@ public class WMShellModule { @Provides static Optional<Pip> providePip(Context context, DisplayController displayController, PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm, - PipBoundsState pipBoundsState, PipMediaController pipMediaController, + PipKeepClearAlgorithm pipKeepClearAlgorithm, PipBoundsState pipBoundsState, + PipMotionHelper pipMotionHelper, PipMediaController pipMediaController, PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer, PipTouchHandler pipTouchHandler, PipTransitionController pipTransitionController, WindowManagerShellWrapper windowManagerShellWrapper, @@ -215,9 +217,11 @@ public class WMShellModule { Optional<OneHandedController> oneHandedController, @ShellMainThread ShellExecutor mainExecutor) { return Optional.ofNullable(PipController.create(context, displayController, - pipAppOpsListener, pipBoundsAlgorithm, pipBoundsState, pipMediaController, - phonePipMenuController, pipTaskOrganizer, pipTouchHandler, pipTransitionController, - windowManagerShellWrapper, taskStackListener, oneHandedController, mainExecutor)); + pipAppOpsListener, pipBoundsAlgorithm, pipKeepClearAlgorithm, pipBoundsState, + pipMotionHelper, + pipMediaController, phonePipMenuController, pipTaskOrganizer, pipTouchHandler, + pipTransitionController, windowManagerShellWrapper, taskStackListener, + oneHandedController, mainExecutor)); } @WMSingleton @@ -234,6 +238,12 @@ public class WMShellModule { @WMSingleton @Provides + static PipKeepClearAlgorithm providePipKeepClearAlgorithm() { + return new PipKeepClearAlgorithm(); + } + + @WMSingleton + @Provides static PipBoundsAlgorithm providesPipBoundsAlgorithm(Context context, PipBoundsState pipBoundsState, PipSnapAlgorithm pipSnapAlgorithm) { return new PipBoundsAlgorithm(context, pipBoundsState, pipSnapAlgorithm); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/BackgroundWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/BackgroundWindowManager.java index c20b7d9b2747..b310ee2095bf 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/BackgroundWindowManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/BackgroundWindowManager.java @@ -142,12 +142,7 @@ public final class BackgroundWindowManager extends WindowlessWindowManager { * @param displayLayout The latest {@link DisplayLayout} for display bounds. */ public void onDisplayChanged(DisplayLayout displayLayout) { - // One-handed mode is only available on portrait. - if (displayLayout.height() > displayLayout.width()) { - mDisplayBounds = new Rect(0, 0, displayLayout.width(), displayLayout.height()); - } else { - mDisplayBounds = new Rect(0, 0, displayLayout.height(), displayLayout.width()); - } + mDisplayBounds = new Rect(0, 0, displayLayout.width(), displayLayout.height()); } private void updateThemeOnly() { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java index 48acfc1c76e7..179b725ab210 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java @@ -37,7 +37,6 @@ import android.os.ServiceManager; import android.os.SystemProperties; import android.provider.Settings; import android.util.Slog; -import android.view.Surface; import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; import android.window.WindowContainerTransaction; @@ -349,8 +348,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, return; } - final int currentRotation = mDisplayAreaOrganizer.getDisplayLayout().rotation(); - if (currentRotation != Surface.ROTATION_0 && currentRotation != Surface.ROTATION_180) { + if (mDisplayAreaOrganizer.getDisplayLayout().isLandscape()) { Slog.w(TAG, "One handed mode only support portrait mode"); return; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java index 04e8cf9d2c44..fe997b93616b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java @@ -149,12 +149,7 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, * @param displayLayout The latest {@link DisplayLayout} representing current displayId */ public void onDisplayChanged(DisplayLayout displayLayout) { - // Ensure the mDisplayBounds is portrait, due to OHM only support on portrait - if (displayLayout.height() > displayLayout.width()) { - mDisplayBounds = new Rect(0, 0, displayLayout.width(), displayLayout.height()); - } else { - mDisplayBounds = new Rect(0, 0, displayLayout.height(), displayLayout.width()); - } + mDisplayBounds = new Rect(0, 0, displayLayout.width(), displayLayout.height()); mTutorialAreaHeight = Math.round(mDisplayBounds.height() * mTutorialHeightRatio); mAlphaTransitionStart = mTutorialAreaHeight * START_TRANSITION_FRACTION; mBackgroundWindowManager.onDisplayChanged(displayLayout); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 623ef05ec7e2..175a2445f28d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -107,7 +107,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb private PipAppOpsListener mAppOpsListener; private PipMediaController mMediaController; private PipBoundsAlgorithm mPipBoundsAlgorithm; + private PipKeepClearAlgorithm mPipKeepClearAlgorithm; private PipBoundsState mPipBoundsState; + private PipMotionHelper mPipMotionHelper; private PipTouchHandler mTouchHandler; private PipTransitionController mPipTransitionController; private TaskStackListenerImpl mTaskStackListener; @@ -241,6 +243,10 @@ public class PipController implements PipTransitionController.PipTransitionCallb Set<Rect> unrestricted) { if (mPipBoundsState.getDisplayId() == displayId) { mPipBoundsState.setKeepClearAreas(restricted, unrestricted); + mPipMotionHelper.moveToBounds(mPipKeepClearAlgorithm.adjust( + mPipBoundsState.getBounds(), + mPipBoundsState.getRestrictedKeepClearAreas(), + mPipBoundsState.getUnrestrictedKeepClearAreas())); } } }; @@ -293,7 +299,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb @Nullable public static Pip create(Context context, DisplayController displayController, PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm, - PipBoundsState pipBoundsState, PipMediaController pipMediaController, + PipKeepClearAlgorithm pipKeepClearAlgorithm, PipBoundsState pipBoundsState, + PipMotionHelper pipMotionHelper, PipMediaController pipMediaController, PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer, PipTouchHandler pipTouchHandler, PipTransitionController pipTransitionController, WindowManagerShellWrapper windowManagerShellWrapper, @@ -307,9 +314,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb } return new PipController(context, displayController, pipAppOpsListener, pipBoundsAlgorithm, - pipBoundsState, pipMediaController, phonePipMenuController, pipTaskOrganizer, - pipTouchHandler, pipTransitionController, windowManagerShellWrapper, - taskStackListener, oneHandedController, mainExecutor) + pipKeepClearAlgorithm, pipBoundsState, pipMotionHelper, pipMediaController, + phonePipMenuController, pipTaskOrganizer, pipTouchHandler, pipTransitionController, + windowManagerShellWrapper, taskStackListener, oneHandedController, mainExecutor) .mImpl; } @@ -317,7 +324,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb DisplayController displayController, PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm, + PipKeepClearAlgorithm pipKeepClearAlgorithm, @NonNull PipBoundsState pipBoundsState, + PipMotionHelper pipMotionHelper, PipMediaController pipMediaController, PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer, @@ -339,7 +348,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb mWindowManagerShellWrapper = windowManagerShellWrapper; mDisplayController = displayController; mPipBoundsAlgorithm = pipBoundsAlgorithm; + mPipKeepClearAlgorithm = pipKeepClearAlgorithm; mPipBoundsState = pipBoundsState; + mPipMotionHelper = pipMotionHelper; mPipTaskOrganizer = pipTaskOrganizer; mMainExecutor = mainExecutor; mMediaController = pipMediaController; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithm.java new file mode 100644 index 000000000000..a83258f9063b --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithm.java @@ -0,0 +1,44 @@ +/* + * 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.wm.shell.pip.phone; + +import android.graphics.Rect; + +import java.util.Set; + +/** + * Calculates the adjusted position that does not occlude keep clear areas. + */ +public class PipKeepClearAlgorithm { + + /** Returns a new {@code Rect} that does not occlude the provided keep clear areas. */ + public Rect adjust(Rect defaultBounds, Set<Rect> restrictedKeepClearAreas, + Set<Rect> unrestrictedKeepClearAreas) { + if (restrictedKeepClearAreas.isEmpty()) { + return defaultBounds; + } + // TODO(b/183746978): implement the adjustment algorithm + // naively check if areas intersect, an if so move PiP upwards + Rect outBounds = new Rect(defaultBounds); + for (Rect r : restrictedKeepClearAreas) { + if (r.intersect(outBounds)) { + outBounds.offset(0, r.top - outBounds.bottom); + } + } + return outBounds; + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt index 9ede4433a978..239ea38e1e9c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt @@ -363,48 +363,54 @@ class TvPipKeepClearAlgorithm(private val clock: () -> Long) { private fun getNearbyStashedPosition(bounds: Rect, keepClearAreas: Set<Rect>): Rect { val screenBounds = transformedScreenBounds - val stashCandidates = Array(2) { Rect(bounds) } + val stashCandidates = mutableListOf<Rect>() val areasOverlappingPipX = keepClearAreas.filter { it.intersectsX(bounds) } val areasOverlappingPipY = keepClearAreas.filter { it.intersectsY(bounds) } if (screenBounds.bottom - bounds.bottom <= bounds.top - screenBounds.top) { - // bottom is closer than top, stash downwards val fullStashTop = screenBounds.bottom - stashOffset val maxBottom = areasOverlappingPipX.maxByOrNull { it.bottom }!!.bottom val partialStashTop = maxBottom + pipAreaPadding - val downPosition = stashCandidates[0] + val downPosition = Rect(bounds) downPosition.offsetTo(bounds.left, min(fullStashTop, partialStashTop)) - } else { - // top is closer than bottom, stash upwards - val fullStashY = screenBounds.top - bounds.height() + stashOffset + stashCandidates += downPosition + } + if (screenBounds.bottom - bounds.bottom >= bounds.top - screenBounds.top) { + val fullStashBottom = screenBounds.top - bounds.height() + stashOffset val minTop = areasOverlappingPipX.minByOrNull { it.top }!!.top - val partialStashY = minTop - bounds.height() - pipAreaPadding + val partialStashBottom = minTop - bounds.height() - pipAreaPadding - val upPosition = stashCandidates[0] - upPosition.offsetTo(bounds.left, max(fullStashY, partialStashY)) + val upPosition = Rect(bounds) + upPosition.offsetTo(bounds.left, max(fullStashBottom, partialStashBottom)) + stashCandidates += upPosition } if (screenBounds.right - bounds.right <= bounds.left - screenBounds.left) { - // right is closer than left, stash rightwards - val fullStashLeft = screenBounds.right - stashOffset + val fullStashRight = screenBounds.right - stashOffset val maxRight = areasOverlappingPipY.maxByOrNull { it.right }!!.right - val partialStashLeft = maxRight + pipAreaPadding + val partialStashRight = maxRight + pipAreaPadding - val rightPosition = stashCandidates[1] - rightPosition.offsetTo(min(fullStashLeft, partialStashLeft), bounds.top) - } else { - // left is closer than right, stash leftwards + val rightPosition = Rect(bounds) + rightPosition.offsetTo(min(fullStashRight, partialStashRight), bounds.top) + stashCandidates += rightPosition + } + if (screenBounds.right - bounds.right >= bounds.left - screenBounds.left) { val fullStashLeft = screenBounds.left - bounds.width() + stashOffset val minLeft = areasOverlappingPipY.minByOrNull { it.left }!!.left val partialStashLeft = minLeft - bounds.width() - pipAreaPadding - val rightPosition = stashCandidates[1] - rightPosition.offsetTo(max(fullStashLeft, partialStashLeft), bounds.top) + val leftPosition = Rect(bounds) + leftPosition.offsetTo(max(fullStashLeft, partialStashLeft), bounds.top) + stashCandidates += leftPosition + } + + if (stashCandidates.isEmpty()) { + return bounds } return stashCandidates.minByOrNull { 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 f20870ff0b2d..aec51baa4af7 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 @@ -377,7 +377,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return; } - mStageCoordinator.updateSurfaceBounds(null /* layout */, t); + mStageCoordinator.updateSurfaceBounds(null /* layout */, t, + false /* applyResizingOffset */); for (int i = 0; i < apps.length; ++i) { if (apps[i].mode == MODE_OPENING) { t.show(apps[i].leash); 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 e150cf9cd112..45931de5e35e 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 @@ -30,6 +30,7 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.view.WindowManager.transitTypeToString; import static android.window.TransitionInfo.FLAG_IS_DISPLAY; +import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED; @@ -495,7 +496,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, // Using legacy transitions, so we can't use blast sync since it conflicts. mTaskOrganizer.applyTransaction(wct); - mSyncQueue.runInSync(t -> updateSurfaceBounds(mSplitLayout, t)); + mSyncQueue.runInSync(t -> + updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */)); } /** @@ -704,9 +706,11 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, mMainStage.deactivate(wct, !fromEnteringPip && mMainStage == childrenToTop); wct.reorder(mRootTaskInfo.token, false /* onTop */); mTaskOrganizer.applyTransaction(wct); - mSyncQueue.runInSync(t -> t - .setWindowCrop(mMainStage.mRootLeash, null) - .setWindowCrop(mSideStage.mRootLeash, null)); + mSyncQueue.runInSync(t -> { + setResizingSplits(false /* resizing */); + t.setWindowCrop(mMainStage.mRootLeash, null) + .setWindowCrop(mSideStage.mRootLeash, null); + }); // Hide divider and reset its position. mSplitLayout.resetDividerPosition(); @@ -780,7 +784,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, void finishEnterSplitScreen(SurfaceControl.Transaction t) { mSplitLayout.init(); setDividerVisibility(true, t); - updateSurfaceBounds(mSplitLayout, t); + updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */); setSplitsVisible(true); mShouldUpdateRecents = true; updateRecentTasksSplitPair(); @@ -925,7 +929,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, if (mSplitLayout == null) { mSplitLayout = new SplitLayout(TAG + "SplitDivider", mContext, mRootTaskInfo.configuration, this, mParentContainerCallbacks, - mDisplayImeController, mTaskOrganizer, false /* applyDismissingParallax */); + mDisplayImeController, mTaskOrganizer, + PARALLAX_ALIGN_CENTER /* parallaxType */); mDisplayInsetsController.addInsetsChangedListener(mDisplayId, mSplitLayout); } @@ -1075,7 +1080,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, prepareEnterSplitScreen(wct); mSyncQueue.queue(wct); mSyncQueue.runInSync(t -> { - updateSurfaceBounds(mSplitLayout, t); + updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */); setDividerVisibility(true, t); }); } @@ -1094,8 +1099,6 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, @Override public void onSnappedToDismiss(boolean bottomOrRight) { - setResizingSplits(false /* resizing */); - final boolean mainStageToTop = bottomOrRight ? mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT : mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT; @@ -1104,6 +1107,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, return; } + setResizingSplits(false /* resizing */); final int dismissTop = mainStageToTop ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE; final WindowContainerTransaction wct = new WindowContainerTransaction(); prepareExitSplitScreen(dismissTop, wct); @@ -1121,14 +1125,14 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, @Override public void onLayoutPositionChanging(SplitLayout layout) { - mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t)); + mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t, false /* applyResizingOffset */)); } @Override public void onLayoutSizeChanging(SplitLayout layout) { mSyncQueue.runInSync(t -> { setResizingSplits(true /* resizing */); - updateSurfaceBounds(layout, t); + updateSurfaceBounds(layout, t, true /* applyResizingOffset */); mMainStage.onResizing(getMainStageBounds(), t); mSideStage.onResizing(getSideStageBounds(), t); }); @@ -1142,7 +1146,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSyncQueue.queue(wct); mSyncQueue.runInSync(t -> { setResizingSplits(false /* resizing */); - updateSurfaceBounds(layout, t); + updateSurfaceBounds(layout, t, false /* applyResizingOffset */); mMainStage.onResized(t); mSideStage.onResized(t); }); @@ -1174,13 +1178,15 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, layout.applyTaskChanges(wct, topLeftStage.mRootTaskInfo, bottomRightStage.mRootTaskInfo); } - void updateSurfaceBounds(@Nullable SplitLayout layout, @NonNull SurfaceControl.Transaction t) { + void updateSurfaceBounds(@Nullable SplitLayout layout, @NonNull SurfaceControl.Transaction t, + boolean applyResizingOffset) { final StageTaskListener topLeftStage = mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage; final StageTaskListener bottomRightStage = mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage; (layout != null ? layout : mSplitLayout).applySurfaceChanges(t, topLeftStage.mRootLeash, - bottomRightStage.mRootLeash, topLeftStage.mDimLayer, bottomRightStage.mDimLayer); + bottomRightStage.mRootLeash, topLeftStage.mDimLayer, bottomRightStage.mDimLayer, + applyResizingOffset); } void setResizingSplits(boolean resizing) { @@ -1220,7 +1226,6 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, mTaskOrganizer.applyTransaction(wct); } - @Override public void onDisplayAdded(int displayId) { if (displayId != DEFAULT_DISPLAY) { return; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitScreenController.java index f1520edf53b1..07174051a344 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitScreenController.java @@ -253,7 +253,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback, SurfaceControl.Transaction t) { - mStageCoordinator.updateSurfaceBounds(null /* layout */, t); + mStageCoordinator.updateSurfaceBounds(null /* layout */, t, + false /* applyResizingOffset */); if (apps != null) { for (int i = 0; i < apps.length; ++i) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageCoordinator.java index 6ef20e37d5bc..ac25c7510931 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageCoordinator.java @@ -265,7 +265,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, mMainStage.activate(getMainStageBounds(), wct); mSideStage.addTask(task, getSideStageBounds(), wct); mSyncQueue.queue(wct); - mSyncQueue.runInSync(t -> updateSurfaceBounds(null /* layout */, t)); + mSyncQueue.runInSync( + t -> updateSurfaceBounds(null /* layout */, t, false /* applyResizingOffset */)); return true; } @@ -801,12 +802,12 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, @Override public void onLayoutPositionChanging(SplitLayout layout) { - mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t)); + mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t, true /* applyResizingOffset */)); } @Override public void onLayoutSizeChanging(SplitLayout layout) { - mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t)); + mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t, true /* applyResizingOffset */)); mSideStage.setOutlineVisibility(false); } @@ -816,7 +817,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, updateWindowBounds(layout, wct); updateUnfoldBounds(); mSyncQueue.queue(wct); - mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t)); + mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t, false /* applyResizingOffset */)); mSideStage.setOutlineVisibility(true); mLogger.logResize(mSplitLayout.getDividerPositionAsFraction()); } @@ -840,13 +841,15 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, layout.applyTaskChanges(wct, topLeftStage.mRootTaskInfo, bottomRightStage.mRootTaskInfo); } - void updateSurfaceBounds(@Nullable SplitLayout layout, @NonNull SurfaceControl.Transaction t) { + void updateSurfaceBounds(@Nullable SplitLayout layout, @NonNull SurfaceControl.Transaction t, + boolean applyResizingOffset) { final StageTaskListener topLeftStage = mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage; final StageTaskListener bottomRightStage = mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage; (layout != null ? layout : mSplitLayout).applySurfaceChanges(t, topLeftStage.mRootLeash, - bottomRightStage.mRootLeash, topLeftStage.mDimLayer, bottomRightStage.mDimLayer); + bottomRightStage.mRootLeash, topLeftStage.mDimLayer, bottomRightStage.mDimLayer, + applyResizingOffset); } @Override @@ -882,7 +885,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, if (mSplitLayout == null) { mSplitLayout = new SplitLayout(TAG + "SplitDivider", mContext, mDisplayAreaInfo.configuration, this, mParentContainerCallbacks, - mDisplayImeController, mTaskOrganizer, true /* applyDismissingParallax */); + mDisplayImeController, mTaskOrganizer, SplitLayout.PARALLAX_DISMISSING); mDisplayInsetsController.addInsetsChangedListener(mDisplayId, mSplitLayout); if (mMainUnfoldController != null && mSideUnfoldController != null) { diff --git a/libs/WindowManager/Shell/tests/OWNERS b/libs/WindowManager/Shell/tests/OWNERS index a244d14b0e14..f4efc374ecc2 100644 --- a/libs/WindowManager/Shell/tests/OWNERS +++ b/libs/WindowManager/Shell/tests/OWNERS @@ -1,4 +1,4 @@ -# Bug component: 909476 +# Bug component: 1157642 # includes OWNERS from parent directories natanieljr@google.com pablogamito@google.com diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt index fb404b913465..684e5cad0e67 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt @@ -17,6 +17,8 @@ package com.android.wm.shell.flicker.bubble import android.platform.test.annotations.Presubmit +import android.view.WindowInsets +import android.view.WindowManager import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import androidx.test.uiautomator.By @@ -59,6 +61,16 @@ class LaunchBubbleFromLockScreen(testSpec: FlickerTestParameter) : BaseBubbleScr } } transitions { + // Swipe & wait for the notification shade to expand so all can be seen + val wm = context.getSystemService(WindowManager::class.java) + val metricInsets = wm.getCurrentWindowMetrics().windowInsets + val insets = metricInsets.getInsetsIgnoringVisibility( + WindowInsets.Type.statusBars() + or WindowInsets.Type.displayCutout()) + device.swipe(100, insets.top + 100, 100, device.getDisplayHeight() / 2, 4) + device.waitForIdle(2000) + instrumentation.uiAutomation.syncInputTransactions() + val notification = device.wait(Until.findObject( By.text("BubbleChat")), FIND_OBJECT_TIMEOUT) notification?.click() ?: error("Notification not found") diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/BubbleHelper.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/BubbleHelper.java index d743dffd3c9e..6cd93eff2803 100644 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/BubbleHelper.java +++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/BubbleHelper.java @@ -22,7 +22,6 @@ import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Person; -import android.app.RemoteInput; import android.content.Context; import android.content.Intent; import android.graphics.Point; @@ -116,24 +115,20 @@ public class BubbleHelper { private Notification.Builder getNotificationBuilder(int id) { Person chatBot = new Person.Builder() .setBot(true) - .setName("BubbleBot") + .setName("BubbleChat") .setImportant(true) .build(); - - RemoteInput remoteInput = new RemoteInput.Builder("key") - .setLabel("Reply") - .build(); - String shortcutId = "BubbleChat"; return new Notification.Builder(mContext, CHANNEL_ID) .setChannelId(CHANNEL_ID) .setShortcutId(shortcutId) + .setContentTitle("BubbleChat") .setContentIntent(PendingIntent.getActivity(mContext, 0, new Intent(mContext, LaunchBubbleActivity.class), PendingIntent.FLAG_UPDATE_CURRENT)) .setStyle(new Notification.MessagingStyle(chatBot) - .setConversationTitle("Bubble Chat") - .addMessage("Hello? This is bubble: " + id, + .setConversationTitle("BubbleChat") + .addMessage("BubbleChat", SystemClock.currentThreadTimeMillis() - 300000, chatBot) .addMessage("Is it me, " + id + ", you're looking for?", SystemClock.currentThreadTimeMillis(), chatBot) diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java index 8b4e1f8bfdb7..f1e602fcf778 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java @@ -73,7 +73,7 @@ public class SplitLayoutTests extends ShellTestCase { mCallbacks, mDisplayImeController, mTaskOrganizer, - false /* applyDismissingParallax */)); + SplitLayout.PARALLAX_NONE)); } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java index 2886b97a3020..ecf1c5d41864 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java @@ -56,6 +56,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.MockitoAnnotations; @SmallTest @@ -64,13 +65,14 @@ public class OneHandedControllerTest extends OneHandedTestCase { private int mCurrentUser = UserHandle.myUserId(); Display mDisplay; - DisplayLayout mDisplayLayout; OneHandedAccessibilityUtil mOneHandedAccessibilityUtil; OneHandedController mSpiedOneHandedController; OneHandedTimeoutHandler mSpiedTimeoutHandler; OneHandedState mSpiedTransitionState; @Mock + DisplayLayout mDisplayLayout; + @Mock DisplayController mMockDisplayController; @Mock OneHandedDisplayAreaOrganizer mMockDisplayAreaOrganizer; @@ -105,7 +107,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { public void setUp() { MockitoAnnotations.initMocks(this); mDisplay = mContext.getDisplay(); - mDisplayLayout = new DisplayLayout(mContext, mDisplay); + mDisplayLayout = Mockito.mock(DisplayLayout.class); mSpiedTimeoutHandler = spy(new OneHandedTimeoutHandler(mMockShellMainExecutor)); mSpiedTransitionState = spy(new OneHandedState()); @@ -124,7 +126,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { when(mMockSettingsUitl.getShortcutEnabled(any(), anyInt())).thenReturn(false); when(mMockDisplayAreaOrganizer.getLastDisplayBounds()).thenReturn( - new Rect(0, 0, mDisplayLayout.width(), mDisplayLayout.height())); + new Rect(0, 0, 1080, 2400)); when(mMockDisplayAreaOrganizer.getDisplayLayout()).thenReturn(mDisplayLayout); mOneHandedAccessibilityUtil = new OneHandedAccessibilityUtil(mContext); @@ -302,10 +304,9 @@ public class OneHandedControllerTest extends OneHandedTestCase { @Test public void testRotation90CanNotStartOneHanded() { - final DisplayLayout landscapeDisplayLayout = new DisplayLayout(mDisplayLayout); - landscapeDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_90); + mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_90); mSpiedTransitionState.setState(STATE_NONE); - when(mMockDisplayAreaOrganizer.getDisplayLayout()).thenReturn(landscapeDisplayLayout); + when(mDisplayLayout.isLandscape()).thenReturn(true); mSpiedOneHandedController.setOneHandedEnabled(true); mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */); mSpiedOneHandedController.startOneHanded(); @@ -315,11 +316,10 @@ public class OneHandedControllerTest extends OneHandedTestCase { @Test public void testRotation180CanStartOneHanded() { - final DisplayLayout testDisplayLayout = new DisplayLayout(mDisplayLayout); - testDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_180); + mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_180); mSpiedTransitionState.setState(STATE_NONE); when(mMockDisplayAreaOrganizer.isReady()).thenReturn(true); - when(mMockDisplayAreaOrganizer.getDisplayLayout()).thenReturn(testDisplayLayout); + when(mDisplayLayout.isLandscape()).thenReturn(false); mSpiedOneHandedController.setOneHandedEnabled(true); mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */); mSpiedOneHandedController.startOneHanded(); @@ -329,10 +329,9 @@ public class OneHandedControllerTest extends OneHandedTestCase { @Test public void testRotation270CanNotStartOneHanded() { - final DisplayLayout testDisplayLayout = new DisplayLayout(mDisplayLayout); - testDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_270); + mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_270); mSpiedTransitionState.setState(STATE_NONE); - when(mMockDisplayAreaOrganizer.getDisplayLayout()).thenReturn(testDisplayLayout); + when(mDisplayLayout.isLandscape()).thenReturn(true); mSpiedOneHandedController.setOneHandedEnabled(true); mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */); mSpiedOneHandedController.startOneHanded(); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java index aef298ed478a..deb955b30842 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java @@ -74,6 +74,7 @@ public class PipControllerTest extends ShellTestCase { @Mock private PhonePipMenuController mMockPhonePipMenuController; @Mock private PipAppOpsListener mMockPipAppOpsListener; @Mock private PipBoundsAlgorithm mMockPipBoundsAlgorithm; + @Mock private PipKeepClearAlgorithm mMockPipKeepClearAlgorithm; @Mock private PipSnapAlgorithm mMockPipSnapAlgorithm; @Mock private PipMediaController mMockPipMediaController; @Mock private PipTaskOrganizer mMockPipTaskOrganizer; @@ -97,9 +98,10 @@ public class PipControllerTest extends ShellTestCase { return null; }).when(mMockExecutor).execute(any()); mPipController = new PipController(mContext, mMockDisplayController, - mMockPipAppOpsListener, mMockPipBoundsAlgorithm, mMockPipBoundsState, - mMockPipMediaController, mMockPhonePipMenuController, mMockPipTaskOrganizer, - mMockPipTouchHandler, mMockPipTransitionController, mMockWindowManagerShellWrapper, + mMockPipAppOpsListener, mMockPipBoundsAlgorithm, mMockPipKeepClearAlgorithm, + mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController, + mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTouchHandler, + mMockPipTransitionController, mMockWindowManagerShellWrapper, mMockTaskStackListener, mMockOneHandedController, mMockExecutor); when(mMockPipBoundsAlgorithm.getSnapAlgorithm()).thenReturn(mMockPipSnapAlgorithm); when(mMockPipTouchHandler.getMotionHelper()).thenReturn(mMockPipMotionHelper); @@ -128,9 +130,10 @@ public class PipControllerTest extends ShellTestCase { when(spyContext.getPackageManager()).thenReturn(mockPackageManager); assertNull(PipController.create(spyContext, mMockDisplayController, - mMockPipAppOpsListener, mMockPipBoundsAlgorithm, mMockPipBoundsState, - mMockPipMediaController, mMockPhonePipMenuController, mMockPipTaskOrganizer, - mMockPipTouchHandler, mMockPipTransitionController, mMockWindowManagerShellWrapper, + mMockPipAppOpsListener, mMockPipBoundsAlgorithm, mMockPipKeepClearAlgorithm, + mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController, + mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTouchHandler, + mMockPipTransitionController, mMockWindowManagerShellWrapper, mMockTaskStackListener, mMockOneHandedController, mMockExecutor)); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithmTest.java new file mode 100644 index 000000000000..f657b5e62d82 --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithmTest.java @@ -0,0 +1,96 @@ +/* + * 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.wm.shell.pip.phone; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import android.graphics.Rect; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import androidx.test.filters.SmallTest; + +import com.android.wm.shell.ShellTestCase; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Set; + +/** + * Unit tests against {@link PipKeepClearAlgorithm}. + */ +@RunWith(AndroidTestingRunner.class) +@SmallTest +@TestableLooper.RunWithLooper(setAsMainLooper = true) +public class PipKeepClearAlgorithmTest extends ShellTestCase { + + private PipKeepClearAlgorithm mPipKeepClearAlgorithm; + + + @Before + public void setUp() throws Exception { + mPipKeepClearAlgorithm = new PipKeepClearAlgorithm(); + } + + @Test + public void adjust_withCollidingRestrictedKeepClearAreas_movesBounds() { + final Rect inBounds = new Rect(0, 0, 100, 100); + final Rect keepClearRect = new Rect(50, 50, 150, 150); + + final Rect outBounds = mPipKeepClearAlgorithm.adjust(inBounds, Set.of(keepClearRect), + Set.of()); + + assertFalse(outBounds.contains(keepClearRect)); + } + + @Test + public void adjust_withNonCollidingRestrictedKeepClearAreas_boundsDoNotChange() { + final Rect inBounds = new Rect(0, 0, 100, 100); + final Rect keepClearRect = new Rect(100, 100, 150, 150); + + final Rect outBounds = mPipKeepClearAlgorithm.adjust(inBounds, Set.of(keepClearRect), + Set.of()); + + assertEquals(inBounds, outBounds); + } + + @Test + public void adjust_withCollidingUnrestrictedKeepClearAreas_boundsDoNotChange() { + // TODO(b/183746978): update this test to accommodate for the updated algorithm + final Rect inBounds = new Rect(0, 0, 100, 100); + final Rect keepClearRect = new Rect(50, 50, 150, 150); + + final Rect outBounds = mPipKeepClearAlgorithm.adjust(inBounds, Set.of(), + Set.of(keepClearRect)); + + assertEquals(inBounds, outBounds); + } + + @Test + public void adjust_withNonCollidingUnrestrictedKeepClearAreas_boundsDoNotChange() { + final Rect inBounds = new Rect(0, 0, 100, 100); + final Rect keepClearRect = new Rect(100, 100, 150, 150); + + final Rect outBounds = mPipKeepClearAlgorithm.adjust(inBounds, Set.of(), + Set.of(keepClearRect)); + + assertEquals(inBounds, outBounds); + } +} 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 061136c65daf..c571d44d3da9 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 @@ -309,7 +309,7 @@ public class StageCoordinatorTests extends ShellTestCase { public void testFinishEnterSplitScreen_applySurfaceLayout() { mStageCoordinator.finishEnterSplitScreen(new SurfaceControl.Transaction()); - verify(mSplitLayout).applySurfaceChanges(any(), any(), any(), any(), any()); + verify(mSplitLayout).applySurfaceChanges(any(), any(), any(), any(), any(), eq(false)); } private class UnfoldControllerProvider implements diff --git a/packages/SettingsLib/HelpUtils/res/values-ar/strings.xml b/packages/SettingsLib/HelpUtils/res/values-ar/strings.xml index 5b12fc586ef9..0eba119d58ee 100644 --- a/packages/SettingsLib/HelpUtils/res/values-ar/strings.xml +++ b/packages/SettingsLib/HelpUtils/res/values-ar/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="help_feedback_label" msgid="7106780063063027882">"المساعدة والملاحظات والآراء"</string> + <string name="help_feedback_label" msgid="7106780063063027882">"المساعدة والملاحظات"</string> </resources> diff --git a/packages/SettingsLib/SettingsSpinner/res/values-v31/styles.xml b/packages/SettingsLib/SettingsSpinner/res/values-v31/styles.xml index fc3ec4344712..fd45a16f24ba 100644 --- a/packages/SettingsLib/SettingsSpinner/res/values-v31/styles.xml +++ b/packages/SettingsLib/SettingsSpinner/res/values-v31/styles.xml @@ -17,7 +17,8 @@ <resources> <style name="SettingsSpinnerTitleBar"> - <item name="android:textAppearance">?android:attr/textAppearanceButton</item> + <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item> + <item name="android:textSize">16sp</item> <item name="android:textColor">@color/settingslib_spinner_title_color</item> <item name="android:maxLines">1</item> <item name="android:ellipsize">marquee</item> @@ -29,7 +30,8 @@ </style> <style name="SettingsSpinnerDropdown"> - <item name="android:textAppearance">?android:attr/textAppearanceButton</item> + <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item> + <item name="android:textSize">16sp</item> <item name="android:textColor">@color/settingslib_spinner_dropdown_color</item> <item name="android:maxLines">1</item> <item name="android:ellipsize">marquee</item> diff --git a/packages/SettingsLib/res/layout/user_preference.xml b/packages/SettingsLib/res/layout/user_preference.xml deleted file mode 100644 index f13447a4737c..000000000000 --- a/packages/SettingsLib/res/layout/user_preference.xml +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2014 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. ---> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@android:id/widget_frame" - android:layout_width="match_parent" - android:layout_height="@dimen/user_spinner_item_height" - android:paddingStart="@dimen/user_spinner_padding_sides" - android:paddingEnd="@dimen/user_spinner_padding_sides" - android:orientation="horizontal" > - - <ImageView - android:id="@android:id/icon" - android:layout_width="@dimen/user_icon_view_height" - android:layout_height="@dimen/user_icon_view_height" - android:layout_gravity="center" - android:scaleType="fitCenter" /> - - <TextView - android:id="@android:id/title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:singleLine="true" - android:layout_gravity="center" - android:labelFor="@android:id/icon" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - android:paddingStart="@dimen/user_spinner_padding" - android:paddingEnd="@dimen/user_spinner_padding" - android:textAppearance="?android:attr/textAppearanceMedium" /> - -</LinearLayout> diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java index c2e36b79b753..e1a2e8daf971 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java @@ -28,6 +28,7 @@ import android.text.TextUtils; import android.util.Log; import androidx.annotation.IntDef; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; @@ -239,13 +240,24 @@ public class LocalMediaManager implements BluetoothCallback { /** * Dispatch a change in the about-to-connect device. See - * {@link DeviceCallback#onAboutToConnectDeviceChanged} for more information. + * {@link DeviceCallback#onAboutToConnectDeviceAdded} for more information. */ - public void dispatchAboutToConnectDeviceChanged( - @Nullable String deviceName, + public void dispatchAboutToConnectDeviceAdded( + @NonNull String deviceAddress, + @NonNull String deviceName, @Nullable Drawable deviceIcon) { for (DeviceCallback callback : getCallbacks()) { - callback.onAboutToConnectDeviceChanged(deviceName, deviceIcon); + callback.onAboutToConnectDeviceAdded(deviceAddress, deviceName, deviceIcon); + } + } + + /** + * Dispatch a change in the about-to-connect device. See + * {@link DeviceCallback#onAboutToConnectDeviceRemoved} for more information. + */ + public void dispatchAboutToConnectDeviceRemoved() { + for (DeviceCallback callback : getCallbacks()) { + callback.onAboutToConnectDeviceRemoved(); } } @@ -705,13 +717,27 @@ public class LocalMediaManager implements BluetoothCallback { * connect imminently and should be displayed as the current device in the media player. * See [AudioManager.muteAwaitConnection] for more details. * - * @param deviceName the name of the device (displayed to the user). - * @param deviceIcon the icon that should be used with the device. + * The information in the most recent callback should override information from any previous + * callbacks. + * + * @param deviceAddress the address of the device. {@see AudioDeviceAttributes.address}. + * If present, we'll use this address to fetch the full information + * about the device (if we can find that information). + * @param deviceName the name of the device (displayed to the user). Used as a backup in + * case using deviceAddress doesn't work. + * @param deviceIcon the icon that should be used with the device. Used as a backup in case + * using deviceAddress doesn't work. */ - default void onAboutToConnectDeviceChanged( - @Nullable String deviceName, + default void onAboutToConnectDeviceAdded( + @NonNull String deviceAddress, + @NonNull String deviceName, @Nullable Drawable deviceIcon ) {} + + /** + * Callback for notifying that we no longer have an about-to-connect device. + */ + default void onAboutToConnectDeviceRemoved() {} } /** diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEnterpriseRestrictionUtils.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEnterpriseRestrictionUtils.java index fa4ae6712aaa..6535665b7653 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEnterpriseRestrictionUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEnterpriseRestrictionUtils.java @@ -24,6 +24,8 @@ import android.util.Log; import androidx.annotation.ChecksSdkIntAtLeast; +import com.android.internal.annotations.VisibleForTesting; + /* Utility class is to confirm the Wi-Fi function is available by enterprise restriction */ public class WifiEnterpriseRestrictionUtils { private static final String TAG = "WifiEntResUtils"; @@ -76,6 +78,26 @@ public class WifiEnterpriseRestrictionUtils { return true; } + /** + * Confirm Wi-Fi state is allowed to change to whether user restriction is set + * + * @param context A context + * @return whether the device is permitted to change Wi-Fi state + */ + public static boolean isChangeWifiStateAllowed(Context context) { + if (!hasUserRestrictionFromT(context, UserManager.DISALLOW_CHANGE_WIFI_STATE)) return true; + Log.w(TAG, "WI-FI state isn't allowed to change due to user restriction."); + return false; + } + + @VisibleForTesting + static boolean hasUserRestrictionFromT(Context context, String restrictionKey) { + if (!isAtLeastT()) return false; + final UserManager userManager = context.getSystemService(UserManager.class); + if (userManager == null) return false; + return userManager.hasUserRestriction(restrictionKey); + } + @ChecksSdkIntAtLeast(api=Build.VERSION_CODES.TIRAMISU) private static boolean isAtLeastT() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEnterpriseRestrictionUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEnterpriseRestrictionUtilsTest.java index f6af09a34388..e9326dd39faa 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEnterpriseRestrictionUtilsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEnterpriseRestrictionUtilsTest.java @@ -15,8 +15,11 @@ */ package com.android.settingslib.wifi; +import static android.os.UserManager.DISALLOW_CHANGE_WIFI_STATE; + import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -50,6 +53,8 @@ public class WifiEnterpriseRestrictionUtilsTest { mContext = spy(ApplicationProvider.getApplicationContext()); when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); when(mUserManager.getUserRestrictions()).thenReturn(mBundle); + ReflectionHelpers.setStaticField( + Build.VERSION.class, "SDK_INT", Build.VERSION_CODES.TIRAMISU); } @Test @@ -129,4 +134,41 @@ public class WifiEnterpriseRestrictionUtilsTest { assertThat(WifiEnterpriseRestrictionUtils.isAddWifiConfigAllowed(mContext)).isTrue(); } + + @Test + public void isChangeWifiStateAllowed_hasDisallowRestriction_shouldReturnFalse() { + when(mUserManager.hasUserRestriction(DISALLOW_CHANGE_WIFI_STATE)).thenReturn(true); + + assertThat(WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(mContext)).isFalse(); + } + + @Test + public void isChangeWifiStateAllowed_hasNoDisallowRestriction_shouldReturnTrue() { + when(mUserManager.hasUserRestriction(DISALLOW_CHANGE_WIFI_STATE)).thenReturn(false); + + assertThat(WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(mContext)).isTrue(); + } + + @Test + public void hasUserRestrictionFromT_setSDKForS_shouldReturnTrue() { + ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT", Build.VERSION_CODES.S); + + assertThat(WifiEnterpriseRestrictionUtils.hasUserRestrictionFromT(mContext, "key")) + .isFalse(); + } + + @Test + public void hasUserRestrictionFromT_setSDKForT_shouldReturnHasUserRestriction() { + ReflectionHelpers.setStaticField( + Build.VERSION.class, "SDK_INT", Build.VERSION_CODES.TIRAMISU); + when(mUserManager.hasUserRestriction(anyString())).thenReturn(false); + + assertThat(WifiEnterpriseRestrictionUtils.hasUserRestrictionFromT(mContext, "key")) + .isFalse(); + + when(mUserManager.hasUserRestriction(anyString())).thenReturn(true); + + assertThat(WifiEnterpriseRestrictionUtils.hasUserRestrictionFromT(mContext, "key")) + .isTrue(); + } } diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt index 74b759fcdcf9..f934b1f3ab99 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt @@ -432,7 +432,8 @@ class ActivityLaunchAnimator( right = windowBounds.right ) val callback = this@ActivityLaunchAnimator.callback!! - val windowBackgroundColor = callback.getBackgroundColor(window.taskInfo) + val windowBackgroundColor = window.taskInfo?.let { callback.getBackgroundColor(it) } + ?: window.backgroundColor // Make sure we use the modified timings when animating a dialog into an app. val launchAnimator = if (controller.isDialogLaunch) { diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteTransitionAdapter.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteTransitionAdapter.kt index 2e9a16fffe9a..47c11010c072 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteTransitionAdapter.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteTransitionAdapter.kt @@ -138,7 +138,7 @@ class RemoteTransitionAdapter { info: TransitionInfo, t: SurfaceControl.Transaction ): RemoteAnimationTarget { - return RemoteAnimationTarget( + val target = RemoteAnimationTarget( /* taskId */ if (change.taskInfo != null) change.taskInfo!!.taskId else -1, /* mode */ newModeToLegacyMode(change.mode), /* leash */ createLeash(info, change, order, t), @@ -160,6 +160,8 @@ class RemoteTransitionAdapter { /* taskInfo */ change.taskInfo, /* allowEnterPip */ change.allowEnterPip, /* windowType */ WindowManager.LayoutParams.INVALID_WINDOW_TYPE) + target.backgroundColor = change.backgroundColor + return target } /** diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt index d15b8c169535..ca557796462f 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt @@ -37,7 +37,6 @@ class ViewHierarchyAnimator { private const val DEFAULT_DURATION = 500L private val DEFAULT_INTERPOLATOR = Interpolators.STANDARD private val DEFAULT_ADDITION_INTERPOLATOR = Interpolators.STANDARD_DECELERATE - private val DEFAULT_BOUNDS = setOf(Bound.LEFT, Bound.TOP, Bound.RIGHT, Bound.BOTTOM) /** The properties used to animate the view bounds. */ private val PROPERTIES = mapOf( @@ -61,8 +60,7 @@ class ViewHierarchyAnimator { /** * Instruct the animator to watch for changes to the layout of [rootView] and its children - * and animate them. The animation can be limited to a subset of [bounds]. It uses the - * given [interpolator] and [duration]. + * and animate them. It uses the given [interpolator] and [duration]. * * If a new layout change happens while an animation is already in progress, the animation * is updated to continue from the current values to the new end state. @@ -74,40 +72,31 @@ class ViewHierarchyAnimator { * * Returns true if the [rootView] is already visible and will be animated, false otherwise. * To animate the addition of a view, see [animateAddition]. - * - * TODO(b/221418522): remove the ability to select which bounds to animate and always - * animate all of them. */ @JvmOverloads fun animate( rootView: View, - bounds: Set<Bound> = DEFAULT_BOUNDS, interpolator: Interpolator = DEFAULT_INTERPOLATOR, duration: Long = DEFAULT_DURATION ): Boolean { - return animate(rootView, bounds, interpolator, duration, ephemeral = false) + return animate(rootView, interpolator, duration, ephemeral = false) } /** * Like [animate], but only takes effect on the next layout update, then unregisters itself * once the first animation is complete. - * - * TODO(b/221418522): remove the ability to select which bounds to animate and always - * animate all of them. */ @JvmOverloads fun animateNextUpdate( rootView: View, - bounds: Set<Bound> = DEFAULT_BOUNDS, interpolator: Interpolator = DEFAULT_INTERPOLATOR, duration: Long = DEFAULT_DURATION ): Boolean { - return animate(rootView, bounds, interpolator, duration, ephemeral = true) + return animate(rootView, interpolator, duration, ephemeral = true) } private fun animate( rootView: View, - bounds: Set<Bound>, interpolator: Interpolator, duration: Long, ephemeral: Boolean @@ -123,26 +112,24 @@ class ViewHierarchyAnimator { return false } - val listener = createUpdateListener(bounds, interpolator, duration, ephemeral) + val listener = createUpdateListener(interpolator, duration, ephemeral) recursivelyAddListener(rootView, listener) return true } /** * Returns a new [View.OnLayoutChangeListener] that when called triggers a layout animation - * for the specified [bounds], using [interpolator] and [duration]. + * using [interpolator] and [duration]. * * If [ephemeral] is true, the listener is unregistered after the first animation. Otherwise * it keeps listening for further updates. */ private fun createUpdateListener( - bounds: Set<Bound>, interpolator: Interpolator, duration: Long, ephemeral: Boolean ): View.OnLayoutChangeListener { return createListener( - bounds, interpolator, duration, ephemeral @@ -156,17 +143,7 @@ class ViewHierarchyAnimator { * Any animations already in progress continue until their natural conclusion. */ fun stopAnimating(rootView: View) { - val listener = rootView.getTag(R.id.tag_layout_listener) - if (listener != null && listener is View.OnLayoutChangeListener) { - rootView.setTag(R.id.tag_layout_listener, null /* tag */) - rootView.removeOnLayoutChangeListener(listener) - } - - if (rootView is ViewGroup) { - for (i in 0 until rootView.childCount) { - stopAnimating(rootView.getChildAt(i)) - } - } + recursivelyRemoveListener(rootView) } /** @@ -224,7 +201,6 @@ class ViewHierarchyAnimator { ignorePreviousValues: Boolean ): View.OnLayoutChangeListener { return createListener( - DEFAULT_BOUNDS, interpolator, duration, ephemeral = true, @@ -235,7 +211,7 @@ class ViewHierarchyAnimator { /** * Returns a new [View.OnLayoutChangeListener] that when called triggers a layout animation - * for the specified [bounds], using [interpolator] and [duration]. + * using [interpolator] and [duration]. * * If [ephemeral] is true, the listener is unregistered after the first animation. Otherwise * it keeps listening for further updates. @@ -244,7 +220,6 @@ class ViewHierarchyAnimator { * [ignorePreviousValues] controls whether the previous values should be taken into account. */ private fun createListener( - bounds: Set<Bound>, interpolator: Interpolator, duration: Long, ephemeral: Boolean, @@ -300,10 +275,11 @@ class ViewHierarchyAnimator { ) val boundsToAnimate = mutableSetOf<Bound>() - bounds.forEach { bound -> - if (endValues.getValue(bound) != startValues.getValue(bound)) { - boundsToAnimate.add(bound) - } + if (startValues.getValue(Bound.LEFT) != left) boundsToAnimate.add(Bound.LEFT) + if (startValues.getValue(Bound.TOP) != top) boundsToAnimate.add(Bound.TOP) + if (startValues.getValue(Bound.RIGHT) != right) boundsToAnimate.add(Bound.RIGHT) + if (startValues.getValue(Bound.BOTTOM) != bottom) { + boundsToAnimate.add(Bound.BOTTOM) } if (boundsToAnimate.isNotEmpty()) { @@ -462,6 +438,20 @@ class ViewHierarchyAnimator { } } + private fun recursivelyRemoveListener(view: View) { + val listener = view.getTag(R.id.tag_layout_listener) + if (listener != null && listener is View.OnLayoutChangeListener) { + view.setTag(R.id.tag_layout_listener, null /* tag */) + view.removeOnLayoutChangeListener(listener) + } + + if (view is ViewGroup) { + for (i in 0 until view.childCount) { + recursivelyRemoveListener(view.getChildAt(i)) + } + } + } + private fun getBound(view: View, bound: Bound): Int? { return view.getTag(bound.overrideTag) as? Int } @@ -513,11 +503,10 @@ class ViewHierarchyAnimator { // When an animation is cancelled, a new one might be taking over. We shouldn't // unregister the listener yet. if (ephemeral && !cancelled) { - val listener = view.getTag(R.id.tag_layout_listener) - if (listener != null && listener is View.OnLayoutChangeListener) { - view.setTag(R.id.tag_layout_listener, null /* tag */) - view.removeOnLayoutChangeListener(listener) - } + // The duration is the same for the whole hierarchy, so it's safe to remove + // the listener recursively. We do this because some descendant views might + // not change bounds, and therefore not animate and leak the listener. + recursivelyRemoveListener(view) } } @@ -538,8 +527,7 @@ class ViewHierarchyAnimator { CENTER, LEFT, TOP_LEFT, TOP, TOP_RIGHT, RIGHT, BOTTOM_RIGHT, BOTTOM, BOTTOM_LEFT } - // TODO(b/221418522): make this private once it can't be passed as an arg anymore. - enum class Bound(val label: String, val overrideTag: Int) { + private enum class Bound(val label: String, val overrideTag: Int) { LEFT("left", R.id.tag_override_left) { override fun setValue(view: View, value: Int) { view.left = value diff --git a/packages/SystemUI/docs/keyguard/bouncer.md b/packages/SystemUI/docs/device-entry/bouncer.md index 4bfe7340db30..589cb5d300d3 100644 --- a/packages/SystemUI/docs/keyguard/bouncer.md +++ b/packages/SystemUI/docs/device-entry/bouncer.md @@ -2,6 +2,8 @@ [KeyguardBouncer][1] is the component responsible for displaying the security method set by the user (password, PIN, pattern) as well as SIM-related security methods, allowing the user to unlock the device or SIM. + + ## Supported States 1. Phone, portrait mode - The default and typically only way to view the bouncer. Screen cannot rotate. diff --git a/packages/SystemUI/docs/keyguard/doze.md b/packages/SystemUI/docs/device-entry/doze.md index a6ccab9698d4..5ff8851b4c69 100644 --- a/packages/SystemUI/docs/keyguard/doze.md +++ b/packages/SystemUI/docs/device-entry/doze.md @@ -2,6 +2,8 @@ Always-on Display (AOD) provides an alternative 'screen-off' experience. Instead, of completely turning the display off, it provides a distraction-free, glanceable experience for the phone in a low-powered mode. In this low-powered mode, the display will have a lower refresh rate and the UI should frequently shift its displayed contents in order to prevent burn-in. The recommended max on-pixel-ratio (OPR) is 5% to reduce battery consumption. + + The default doze component controls AOD and is specified by `config_dozeComponent` in the [framework config][1]. SystemUI provides a default Doze Component: [DozeService][2]. [DozeService][2] builds a [DozeMachine][3] with dependencies specified in [DozeModule][4] and configurations in [AmbientDisplayConfiguration][13] and [DozeParameters][14]. Note: The default UI used in AOD shares views with the Lock Screen and does not create its own new views. Once dozing begins, [DozeUI][17] informs SystemUI's [DozeServiceHost][18] that dozing has begun - which sends this signal to relevant SystemUI Lock Screen views to animate accordingly. Within SystemUI, [StatusBarStateController][19] #isDozing and #getDozeAmount can be used to query dozing state. diff --git a/packages/SystemUI/docs/device-entry/glossary.md b/packages/SystemUI/docs/device-entry/glossary.md new file mode 100644 index 000000000000..f3d12c21a3a5 --- /dev/null +++ b/packages/SystemUI/docs/device-entry/glossary.md @@ -0,0 +1,48 @@ +# Device Entry Glossary + +## Keyguard + +| Term | Description | +| :-----------: | ----------- | +| Keyguard, [keyguard.md][1] | Coordinates the first experience when turning on the display of a device, as long as the user has not specified a security method of NONE. Consists of the lock screen and bouncer.| +| Lock screen<br><br>| The first screen available when turning on the display of a device, as long as the user has not specified a security method of NONE. On the lock screen, users can access:<ul><li>Quick Settings - users can swipe down from the top of the screen to interact with quick settings tiles</li><li>[Keyguard Status Bar][9] - This special status bar shows SIM related information and system icons.</li><li>Clock - uses the font specified at [clock.xml][8]. If the clock font supports variable weights, users will experience delightful clock weight animations - in particular, on transitions between the lock screen and AOD.</li><li>Notifications - ability to view and interact with notifications depending on user lock screen notification settings: `Settings > Display > Lock screen > Privacy`</li><li>Message area - contains device information like biometric errors, charging information and device policy information. Also includes user configured information from `Settings > Display > Lock screen > Add text on lock screen`. </li><li>Bouncer - if the user has a primary authentication method, they can swipe up from the bottom of the screen to bring up the bouncer.</li></ul>The lock screen is one state of the notification shade. See [StatusBarState#KEYGUARD][10] and [StatusBarState#SHADE_LOCKED][10].| +| Bouncer, [bouncer.md][2]<br><br>| The component responsible for displaying the primary security method set by the user (password, PIN, pattern). The bouncer can also show SIM-related security methods, allowing the user to unlock the device or SIM.| +| Split shade | State of the shade (which keyguard is a part of) in which notifications are on the right side and Quick Settings on the left. For keyguard that means notifications being on the right side and clock with media being on the left.<br><br>Split shade is automatically activated - using resources - for big screens in landscape, see [sw600dp-land/config.xml][3] `config_use_split_notification_shade`.<br><br>In that state we can see the big clock more often - every time when media is not visible on the lock screen. When there is no media and no notifications - or we enter AOD - big clock is always positioned in the center of the screen.<br><br>The magic of positioning views happens by changing constraints of [NotificationsQuickSettingsContainer][4] and positioning elements vertically in [KeyguardClockPositionAlgorithm][5]| +| Ambient display (AOD), [doze.md][6]<br><br>| UI shown when the device is in a low-powered display state. This is controlled by the doze component. The same lock screen views (ie: clock, notification shade) are used on AOD. The AOSP image on the left shows the usage of a clock that does not support variable weights which is why the clock is thicker in that image than what users see on Pixel devices.| + +## General Authentication Terms +| Term | Description | +| ----------- | ----------- | +| Primary Authentication | The strongest form of authentication. Includes: Pin, pattern and password input.| +| Biometric Authentication | Face or fingerprint input. Biometric authentication is categorized into different classes of security. See [Measuring Biometric Security][7].| + +## Face Authentication Terms +| Term | Description | +| ----------- | ----------- | +| Passive Authentication | When a user hasn't explicitly requested an authentication method; however, it may still put the device in an unlocked state.<br><br>For example, face authentication is triggered immediately when waking the device; however, users may not have the intent of unlocking their device. Instead, they could have wanted to just check the lock screen. Because of this, SystemUI provides the option for a bypass OR non-bypass face authentication experience which have different user flows.<br><br>In contrast, fingerprint authentication is considered an active authentication method since users need to actively put their finger on the fingerprint sensor to authenticate. Therefore, it's an explicit request for authentication and SystemUI knows the user has the intent for device-entry.| +| Bypass | Used to refer to the face authentication bypass device entry experience. We have this distinction because face auth is a passive authentication method (see above).| +| Bypass User Journey <br><br>| Once the user successfully authenticates with face, the keyguard immediately dismisses and the user is brought to the home screen/last app. This CUJ prioritizes speed of device entry. SystemUI hides interactive views (notifications) on the lock screen to avoid putting users in a state where the lock screen could immediately disappear while they're interacting with affordances on the lock screen.| +| Non-bypass User Journey | Once the user successfully authenticates with face, the device remains on keyguard until the user performs an action to indicate they'd like to enter the device (ie: swipe up on the lock screen or long press on the unlocked icon). This CUJ prioritizes notification visibility.| + +## Fingerprint Authentication Terms +| Term | Description | +| ----------- | ----------- | +| Under-display fingerprint sensor (UDFPS) | References the HW affordance for a fingerprint sensor that is under the display, which requires a software visual affordance. System UI supports showing the UDFPS affordance on the lock screen and on AOD. Users cannot authenticate from the screen-off state.<br><br>Supported SystemUI CUJs include:<ul><li> sliding finger on the screen to the UDFPS area to being authentication (as opposed to directly placing finger in the UDFPS area) </li><li> when a11y services are enabled, there is a haptic played when a touch is detected on UDFPS</li><li>after two hard-fingerprint-failures, the primary authentication bouncer is shown</li><li> when tapping on an affordance that requests to dismiss the lock screen, the user may see the UDFPS icon highlighted - see UDFPS bouncer</li></ul>| +| UDFPS Bouncer | UI that highlights the UDFPS sensor. Users can get into this state after tapping on a notification from the lock screen or locked expanded shade.| + +## Other Authentication Terms +| Term | Description | +| ---------- | ----------- | +| Trust Agents | Provides signals to the keyguard to allow it to lock less frequently.| + + +[1]: /frameworks/base/packages/SystemUI/docs/device-entry/keyguard.md +[2]: /frameworks/base/packages/SystemUI/docs/device-entry/bouncer.md +[3]: /frameworks/base/packages/SystemUI/res/values-sw600dp-land/config.xml +[4]: /frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java +[5]: /frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java +[6]: /frameworks/base/packages/SystemUI/docs/device-entry/doze.md +[7]: https://source.android.com/security/biometric/measure +[8]: /frameworks/base/packages/SystemUI/res-keyguard/font/clock.xml +[9]: /frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java +[10]: /frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarState.java diff --git a/packages/SystemUI/docs/device-entry/imgs/aod.png b/packages/SystemUI/docs/device-entry/imgs/aod.png Binary files differnew file mode 100644 index 000000000000..abd554a8936f --- /dev/null +++ b/packages/SystemUI/docs/device-entry/imgs/aod.png diff --git a/packages/SystemUI/docs/device-entry/imgs/bouncer_pin.png b/packages/SystemUI/docs/device-entry/imgs/bouncer_pin.png Binary files differnew file mode 100644 index 000000000000..da15e4115ab9 --- /dev/null +++ b/packages/SystemUI/docs/device-entry/imgs/bouncer_pin.png diff --git a/packages/SystemUI/docs/device-entry/imgs/bypass.png b/packages/SystemUI/docs/device-entry/imgs/bypass.png Binary files differnew file mode 100644 index 000000000000..f4cbd3efb6fc --- /dev/null +++ b/packages/SystemUI/docs/device-entry/imgs/bypass.png diff --git a/packages/SystemUI/docs/device-entry/imgs/lockscreen.png b/packages/SystemUI/docs/device-entry/imgs/lockscreen.png Binary files differnew file mode 100644 index 000000000000..d1fe0853f578 --- /dev/null +++ b/packages/SystemUI/docs/device-entry/imgs/lockscreen.png diff --git a/packages/SystemUI/docs/keyguard.md b/packages/SystemUI/docs/device-entry/keyguard.md index 8914042ee3cd..337f73b79260 100644 --- a/packages/SystemUI/docs/keyguard.md +++ b/packages/SystemUI/docs/device-entry/keyguard.md @@ -30,6 +30,12 @@ An indication to power off the device most likely comes from one of two signals: ### How the device locks +## Debugging Tips +Enable verbose keyguard logs that will print to logcat. Should only be used temporarily for debugging. See [KeyguardConstants][5]. +``` +adb shell setprop log.tag.Keyguard DEBUG && adb shell am crash com.android.systemui +``` + More coming * Screen timeout * Smart lock @@ -38,9 +44,8 @@ More coming * Lock timeout after screen timeout setting -[1]: /frameworks/base/packages/SystemUI/docs/keyguard/bouncer.md -[2]: /frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java -[3]: /frameworks/base/packages/SystemUI/docs/keyguard/doze.md -[4]: /frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java - - +[1]: /frameworks/base/packages/SystemUI/docs/device-entry/bouncer.md +[2]: /com/android/server/power/PowerManagerService.java +[3]: /frameworks/base/packages/SystemUI/docs/device-entry/doze.md +[4]: /com/android/server/policy/PhoneWindowManager.java +[5]: /frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardConstants.java diff --git a/packages/SystemUI/docs/user-switching.md b/packages/SystemUI/docs/user-switching.md index dcf66b943f1d..b9509eb41c3c 100644 --- a/packages/SystemUI/docs/user-switching.md +++ b/packages/SystemUI/docs/user-switching.md @@ -37,7 +37,7 @@ A fullscreen user switching activity, supporting add guest/user actions if confi Renders user switching as a dialog over the current surface, and supports add guest user/actions if configured. -[1]: /frameworks/base/packages/SystemUI/docs/keyguard/bouncer.md +[1]: /frameworks/base/packages/SystemUI/docs/device-entry/bouncer.md [2]: /frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserController.java [3]: /frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java [4]: /frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java diff --git a/packages/SystemUI/res-keyguard/layout/footer_actions.xml b/packages/SystemUI/res-keyguard/layout/footer_actions.xml index 6a1d62d5c611..7cab0c9c8d23 100644 --- a/packages/SystemUI/res-keyguard/layout/footer_actions.xml +++ b/packages/SystemUI/res-keyguard/layout/footer_actions.xml @@ -23,7 +23,7 @@ android:layout_height="@dimen/footer_actions_height" android:elevation="@dimen/qs_panel_elevation" android:paddingTop="8dp" - android:paddingBottom="4dp" + android:paddingBottom="@dimen/qs_footer_actions_bottom_padding" android:background="@drawable/qs_footer_actions_background" android:gravity="center_vertical" android:layout_gravity="bottom" diff --git a/packages/SystemUI/res/drawable/ic_media_connecting_container.xml b/packages/SystemUI/res/drawable/ic_media_connecting_container.xml new file mode 100644 index 000000000000..79d2a0601e08 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_media_connecting_container.xml @@ -0,0 +1,40 @@ +<?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
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_1_G"
+ android:translateX="24"
+ android:translateY="24"
+ android:scaleX="0.5"
+ android:scaleY="0.5"/>
+ <group android:name="_R_G_L_0_G"
+ android:translateX="24"
+ android:translateY="24"
+ android:scaleX="0.5"
+ android:scaleY="0.5">
+ <path android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillColor="#ffddb3"
+ android:fillAlpha="1"
+ android:fillType="nonZero"
+ android:pathData=" M48 -16 C48,-16 48,16 48,16 C48,33.67 33.67,48 16,48 C16,48 -16,48 -16,48 C-33.67,48 -48,33.67 -48,16 C-48,16 -48,-16 -48,-16 C-48,-33.67 -33.67,-48 -16,-48 C-16,-48 16,-48 16,-48 C33.67,-48 48,-33.67 48,-16c "/>
+ </group>
+ </group>
+</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/screenshot_static.xml b/packages/SystemUI/res/layout/screenshot_static.xml index 8de80844d784..c60609b06d38 100644 --- a/packages/SystemUI/res/layout/screenshot_static.xml +++ b/packages/SystemUI/res/layout/screenshot_static.xml @@ -98,6 +98,7 @@ android:scaleType="fitEnd" android:background="@drawable/overlay_preview_background" android:adjustViewBounds="true" + android:clickable="true" app:layout_constraintBottom_toBottomOf="@id/screenshot_preview_border" app:layout_constraintStart_toStartOf="@id/screenshot_preview_border" app:layout_constraintEnd_toEndOf="@id/screenshot_preview_border" diff --git a/packages/SystemUI/res/values-land/config.xml b/packages/SystemUI/res/values-land/config.xml index 062e33ce7e30..d800d49634d2 100644 --- a/packages/SystemUI/res/values-land/config.xml +++ b/packages/SystemUI/res/values-land/config.xml @@ -39,4 +39,7 @@ <!-- Max number of rows for power menu lite --> <integer name="power_menu_lite_max_rows">2</integer> + <!-- Whether we use large screen shade header which takes only one row compared to QS header --> + <bool name="config_use_large_screen_shade_header">true</bool> + </resources> diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml index 609713bb2357..9d7b01c8d252 100644 --- a/packages/SystemUI/res/values-land/dimens.xml +++ b/packages/SystemUI/res/values-land/dimens.xml @@ -57,4 +57,6 @@ <dimen name="wallet_card_carousel_container_top_margin">24dp</dimen> <dimen name="large_dialog_width">348dp</dimen> + + <dimen name="qs_panel_padding_top">@dimen/qqs_layout_margin_top</dimen> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 767225106f0d..101db839336e 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -340,6 +340,7 @@ <!-- (48dp - 40dp) / 2 --> <dimen name="qs_footer_action_inset">4dp</dimen> + <dimen name="qs_footer_actions_bottom_padding">4dp</dimen> <dimen name="qs_footer_action_inset_negative">-4dp</dimen> <!-- Margins on each side of QS Footer --> diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml index 926734c2749f..ff71b4f5e405 100644 --- a/packages/SystemUI/res/values/ids.xml +++ b/packages/SystemUI/res/values/ids.xml @@ -23,6 +23,7 @@ <item type="id" name="scale_x_animator_tag"/> <item type="id" name="scale_y_animator_tag"/> <item type="id" name="top_inset_animator_tag"/> + <item type="id" name="bottom_inset_animator_tag"/> <item type="id" name="height_animator_tag"/> <item type="id" name="x_animator_tag"/> <item type="id" name="y_animator_tag"/> @@ -33,6 +34,7 @@ <item type="id" name="scale_y_animator_end_value_tag"/> <item type="id" name="alpha_animator_end_value_tag"/> <item type="id" name="top_inset_animator_end_value_tag"/> + <item type="id" name="bottom_inset_animator_end_value_tag"/> <item type="id" name="height_animator_end_value_tag"/> <item type="id" name="x_animator_tag_end_value"/> <item type="id" name="y_animator_tag_end_value"/> @@ -43,6 +45,7 @@ <item type="id" name="scale_y_animator_start_value_tag"/> <item type="id" name="alpha_animator_start_value_tag"/> <item type="id" name="top_inset_animator_start_value_tag"/> + <item type="id" name="bottom_inset_animator_start_value_tag"/> <item type="id" name="height_animator_start_value_tag"/> <item type="id" name="x_animator_tag_start_value"/> <item type="id" name="y_animator_tag_start_value"/> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 33ed7b8421db..b248efe93e98 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2199,6 +2199,8 @@ <string name="controls_media_button_prev">Previous track</string> <!-- Description for button in media controls. Pressing button goes to next track [CHAR_LIMIT=NONE] --> <string name="controls_media_button_next">Next track</string> + <!-- Description for button in media controls. Used when media is connecting to a remote device (via something like chromecast). Pressing button does nothing [CHAR_LIMIT=NONE] --> + <string name="controls_media_button_connecting">Connecting</string> <!-- Title for Smartspace recommendation card within media controls. The "Play" means the action to play a media [CHAR_LIMIT=10] --> <string name="controls_media_smartspace_rec_title">Play</string> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java index 120b09a2ad31..de35514be2cb 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java @@ -41,6 +41,7 @@ import android.os.Parcelable; import android.os.RemoteException; import android.util.ArrayMap; import android.util.Log; +import android.util.SparseArray; import android.view.IRecentsAnimationController; import android.view.SurfaceControl; import android.window.IRemoteTransition; @@ -244,22 +245,28 @@ public class RemoteTransitionCompat implements Parcelable { @SuppressLint("NewApi") boolean merge(TransitionInfo info, SurfaceControl.Transaction t, RecentsAnimationListener recents) { - ArrayList<TransitionInfo.Change> openingTasks = null; + SparseArray<TransitionInfo.Change> openingTasks = null; boolean cancelRecents = false; boolean homeGoingAway = false; boolean hasChangingApp = false; for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) { - if (change.getTaskInfo() != null) { - if (change.getTaskInfo().topActivityType == ACTIVITY_TYPE_HOME) { + final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo(); + if (taskInfo != null) { + if (taskInfo.topActivityType == ACTIVITY_TYPE_HOME) { // canceling recents animation cancelRecents = true; } if (openingTasks == null) { - openingTasks = new ArrayList<>(); + openingTasks = new SparseArray<>(); + } + if (taskInfo.hasParentTask()) { + // Collects opening leaf tasks only since Launcher monitors leaf task + // ids to perform recents animation. + openingTasks.remove(taskInfo.parentTaskId); } - openingTasks.add(change); + openingTasks.put(taskInfo.taskId, change); } } else if (change.getMode() == TRANSIT_CLOSE || change.getMode() == TRANSIT_TO_BACK) { @@ -287,7 +294,7 @@ public class RemoteTransitionCompat implements Parcelable { int pauseMatches = 0; if (!cancelRecents) { for (int i = 0; i < openingTasks.size(); ++i) { - if (mPausingTasks.contains(openingTasks.get(i).getContainer())) { + if (mPausingTasks.contains(openingTasks.valueAt(i).getContainer())) { ++pauseMatches; } } @@ -308,10 +315,11 @@ public class RemoteTransitionCompat implements Parcelable { final RemoteAnimationTargetCompat[] targets = new RemoteAnimationTargetCompat[openingTasks.size()]; for (int i = 0; i < openingTasks.size(); ++i) { - mOpeningLeashes.add(openingTasks.get(i).getLeash()); + final TransitionInfo.Change change = openingTasks.valueAt(i); + mOpeningLeashes.add(change.getLeash()); // We are receiving new opening tasks, so convert to onTasksAppeared. final RemoteAnimationTargetCompat target = new RemoteAnimationTargetCompat( - openingTasks.get(i), layer, info, t); + change, layer, info, t); mLeashMap.put(mOpeningLeashes.get(i), target.leash); t.reparent(target.leash, mInfo.getRootLeash()); t.setLayer(target.leash, layer); diff --git a/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.kt b/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.kt index ad8c126aa2fa..19d39d515325 100644 --- a/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.kt +++ b/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.kt @@ -22,6 +22,7 @@ import android.annotation.IntRange import android.annotation.SuppressLint import android.content.Context import android.graphics.Canvas +import android.text.TextUtils import android.text.format.DateFormat import android.util.AttributeSet import android.util.Log @@ -125,13 +126,30 @@ class AnimatableClockView @JvmOverloads constructor( fun refreshTime() { time.timeInMillis = System.currentTimeMillis() - text = DateFormat.format(format, time) contentDescription = DateFormat.format(descFormat, time) - Log.d(tag, "refreshTime this=$this" + - " currTimeContextDesc=$contentDescription" + - " measuredHeight=$measuredHeight" + - " lastMeasureCall=$lastMeasureCall" + - " isSingleLineInternal=$isSingleLineInternal") + val formattedText = DateFormat.format(format, time) + // Setting text actually triggers a layout pass (because the text view is set to + // wrap_content width and TextView always relayouts for this). Avoid needless + // relayout if the text didn't actually change. + if (!TextUtils.equals(text, formattedText)) { + text = formattedText + Log.d( + tag, "refreshTime this=$this" + + " currTimeContextDesc=$contentDescription" + + " measuredHeight=$measuredHeight" + + " lastMeasureCall=$lastMeasureCall" + + " isSingleLineInternal=$isSingleLineInternal" + ) + } else { + Log.d( + tag, "refreshTime (skipped due to unchanged text)" + + " this=$this" + + " currTimeContextDesc=$contentDescription" + + " measuredHeight=$measuredHeight" + + " lastMeasureCall=$lastMeasureCall" + + " isSingleLineInternal=$isSingleLineInternal" + ) + } } fun onTimeZoneChanged(timeZone: TimeZone?) { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java index fcac6813ae7a..422772de11f2 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java @@ -25,6 +25,7 @@ import static com.android.keyguard.KeyguardClockSwitch.SMALL; import android.app.WallpaperManager; import android.content.res.Resources; import android.database.ContentObserver; +import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.view.View; @@ -264,10 +265,11 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS mKeyguardUnlockAnimationController.setLockscreenSmartspace(mSmartspaceView); } - mSecureSettings.registerContentObserver( + mSecureSettings.registerContentObserverForUser( Settings.Secure.getUriFor(Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK), false, /* notifyForDescendants */ - mDoubleLineClockObserver + mDoubleLineClockObserver, + UserHandle.USER_ALL ); updateDoubleLineClock(); @@ -476,8 +478,9 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS } private void updateDoubleLineClock() { - mCanShowDoubleLineClock = mSecureSettings.getInt( - Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK, 1) != 0; + mCanShowDoubleLineClock = mSecureSettings.getIntForUser( + Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK, 1, + UserHandle.USER_CURRENT) != 0; if (!mCanShowDoubleLineClock) { mUiExecutor.execute(() -> displayClock(KeyguardClockSwitch.SMALL, /* animate */ true)); diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java index 2b0c083e2f31..f444b373947f 100644 --- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java +++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java @@ -32,6 +32,7 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.UserHandle; import android.provider.Settings; +import android.text.TextUtils; import android.util.AttributeSet; import android.util.TypedValue; import android.view.Gravity; @@ -267,8 +268,15 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver { if (mBatteryPercentView == null) { return; } - mBatteryPercentView.setText( - NumberFormat.getPercentInstance().format(mLevel / 100f)); + + String percentText = NumberFormat.getPercentInstance().format(mLevel / 100f); + // Setting text actually triggers a layout pass (because the text view is set to + // wrap_content width and TextView always relayouts for this). Avoid needless + // relayout if the text didn't actually change. + if (!TextUtils.equals(mBatteryPercentView.getText(), percentText)) { + mBatteryPercentView.setText(percentText); + } + setContentDescription( getContext().getString(mCharging ? R.string.accessibility_battery_level_charging : R.string.accessibility_battery_level, mLevel)); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 63b2b201c498..2ac240885faa 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -376,7 +376,6 @@ public class UdfpsController implements DozeReceiver { boolean withinSensorArea = isWithinSensorArea(udfpsView, event.getX(), event.getY(), fromUdfpsView); if (withinSensorArea) { - mLatencyTracker.onActionStart(LatencyTracker.ACTION_UDFPS_ILLUMINATE); Trace.beginAsyncSection("UdfpsController.e2e.onPointerDown", 0); Log.v(TAG, "onTouch | action down"); // The pointer that causes ACTION_DOWN is always at index 0. @@ -792,6 +791,7 @@ public class UdfpsController implements DozeReceiver { + " current: " + mOverlay.getRequestId()); return; } + mLatencyTracker.onActionStart(LatencyTracker.ACTION_UDFPS_ILLUMINATE); if (!mOnFingerDown) { playStartHaptic(); @@ -806,11 +806,9 @@ public class UdfpsController implements DozeReceiver { final UdfpsView view = mOverlay.getOverlayView(); if (view != null) { - Trace.beginAsyncSection("UdfpsController.e2e.startIllumination", 0); view.startIllumination(() -> { mFingerprintManager.onUiReady(requestId, mSensorProps.sensorId); mLatencyTracker.onActionEnd(LatencyTracker.ACTION_UDFPS_ILLUMINATE); - Trace.endAsyncSection("UdfpsController.e2e.startIllumination", 0); }); } diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java index f710d0154060..0d8987988f0a 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java @@ -95,7 +95,7 @@ public class EditTextActivity extends Activity private void share() { Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); - sendIntent.putExtra(Intent.EXTRA_TEXT, mEditText.getText()); + sendIntent.putExtra(Intent.EXTRA_TEXT, mEditText.getText().toString()); sendIntent.setType("text/plain"); Intent shareIntent = Intent.createChooser(sendIntent, null); diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt index b8e6d9f0f60a..2fd373105745 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt @@ -19,6 +19,7 @@ package com.android.systemui.controls.dagger import android.content.ContentResolver import android.content.Context import android.database.ContentObserver +import android.os.UserHandle import android.provider.Settings import com.android.systemui.controls.controller.ControlsController import com.android.systemui.controls.management.ControlsListingController @@ -73,10 +74,11 @@ class ControlsComponent @Inject constructor( init { if (featureEnabled) { - secureSettings.registerContentObserver( + secureSettings.registerContentObserverForUser( Settings.Secure.getUriFor(Settings.Secure.LOCKSCREEN_SHOW_CONTROLS), false, /* notifyForDescendants */ - showWhileLockedObserver + showWhileLockedObserver, + UserHandle.USER_ALL ) updateShowWhileLocked() } @@ -123,8 +125,8 @@ class ControlsComponent @Inject constructor( } private fun updateShowWhileLocked() { - canShowWhileLockedSetting = secureSettings.getInt( - Settings.Secure.LOCKSCREEN_SHOW_CONTROLS, 0) != 0 + canShowWhileLockedSetting = secureSettings.getIntForUser( + Settings.Secure.LOCKSCREEN_SHOW_CONTROLS, 0, UserHandle.USER_CURRENT) != 0 } enum class Visibility { diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt index 73faa3459c7b..44879aa9e85b 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt @@ -27,6 +27,7 @@ import android.content.pm.ResolveInfo import android.database.ContentObserver import android.net.Uri import android.os.Handler +import android.os.UserHandle import android.os.VibrationEffect import android.provider.Settings.Secure import android.service.controls.Control @@ -74,10 +75,10 @@ class ControlActionCoordinatorImpl @Inject constructor( private var actionsInProgress = mutableSetOf<String>() private val isLocked: Boolean get() = !keyguardStateController.isUnlocked() - private var mAllowTrivialControls: Boolean = secureSettings.getInt( - Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0) != 0 - private var mShowDeviceControlsInLockscreen: Boolean = secureSettings.getInt( - Secure.LOCKSCREEN_SHOW_CONTROLS, 0) != 0 + private var mAllowTrivialControls: Boolean = secureSettings.getIntForUser( + Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0, UserHandle.USER_CURRENT) != 0 + private var mShowDeviceControlsInLockscreen: Boolean = secureSettings.getIntForUser( + Secure.LOCKSCREEN_SHOW_CONTROLS, 0, UserHandle.USER_CURRENT) != 0 override lateinit var activityContext: Context companion object { @@ -95,23 +96,25 @@ class ControlActionCoordinatorImpl @Inject constructor( super.onChange(selfChange, uri) when (uri) { lockScreenShowControlsUri -> { - mAllowTrivialControls = secureSettings.getInt( - Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0) != 0 + mAllowTrivialControls = secureSettings.getIntForUser( + Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, + 0, UserHandle.USER_CURRENT) != 0 } showControlsUri -> { mShowDeviceControlsInLockscreen = secureSettings - .getInt(Secure.LOCKSCREEN_SHOW_CONTROLS, 0) != 0 + .getIntForUser(Secure.LOCKSCREEN_SHOW_CONTROLS, + 0, UserHandle.USER_CURRENT) != 0 } } } } - secureSettings.registerContentObserver( + secureSettings.registerContentObserverForUser( lockScreenShowControlsUri, - false /* notifyForDescendants */, controlsContentObserver + false /* notifyForDescendants */, controlsContentObserver, UserHandle.USER_ALL ) - secureSettings.registerContentObserver( + secureSettings.registerContentObserverForUser( showControlsUri, - false /* notifyForDescendants */, controlsContentObserver + false /* notifyForDescendants */, controlsContentObserver, UserHandle.USER_ALL ) } @@ -311,7 +314,8 @@ class ControlActionCoordinatorImpl @Inject constructor( MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG) .commit() } - secureSettings.putInt(Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 1) + secureSettings.putIntForUser(Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 1, + UserHandle.USER_CURRENT) true } .create() @@ -325,8 +329,10 @@ class ControlActionCoordinatorImpl @Inject constructor( MAX_NUMBER_ATTEMPTS_CONTROLS_DIALOG) .commit() } - secureSettings.putInt(Secure.LOCKSCREEN_SHOW_CONTROLS, 1) - secureSettings.putInt(Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 1) + secureSettings.putIntForUser(Secure.LOCKSCREEN_SHOW_CONTROLS, + 1, UserHandle.USER_CURRENT) + secureSettings.putIntForUser(Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, + 1, UserHandle.USER_CURRENT) true } .create() diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java index 6d727b4cf966..b172e92871ce 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java @@ -65,6 +65,7 @@ import android.safetycenter.SafetyCenterManager; import android.service.dreams.DreamService; import android.service.dreams.IDreamManager; import android.telecom.TelecomManager; +import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.view.CrossWindowBlurListeners; @@ -452,6 +453,12 @@ public class FrameworkServicesModule { @Provides @Singleton + static CarrierConfigManager provideCarrierConfigManager(Context context) { + return context.getSystemService(CarrierConfigManager.class); + } + + @Provides + @Singleton static WindowManager provideWindowManager(Context context) { return context.getSystemService(WindowManager.class); } diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java index 3335c8d62f46..be6f732ee5f7 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java +++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java @@ -31,6 +31,7 @@ import android.content.IntentFilter; import android.content.res.Resources; import android.os.Bundle; import android.os.RemoteException; +import android.os.UserHandle; import android.util.Log; import androidx.annotation.NonNull; @@ -210,7 +211,8 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { Log.w(TAG, "Failed to set id " + id + " to " + value); return; } - mSecureSettings.putString(mFlagManager.idToSettingsKey(id), data); + mSecureSettings.putStringForUser(mFlagManager.idToSettingsKey(id), data, + UserHandle.USER_CURRENT); Log.i(TAG, "Set id " + id + " to " + value); removeFromCache(id); mFlagManager.dispatchListenersAndMaybeRestart(id, this::restartSystemUI); @@ -238,7 +240,8 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { /** Works just like {@link #eraseFlag(int)} except that it doesn't restart SystemUI. */ private void eraseInternal(int id) { // We can't actually "erase" things from sysprops, but we can set them to empty! - mSecureSettings.putString(mFlagManager.idToSettingsKey(id), ""); + mSecureSettings.putStringForUser(mFlagManager.idToSettingsKey(id), "", + UserHandle.USER_CURRENT); Log.i(TAG, "Erase id " + id); } diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java index c9a61a8a09df..44580aa4230a 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java @@ -162,6 +162,17 @@ public class Flags { public static final SysPropBooleanFlag WM_ENABLE_SHELL_TRANSITIONS = new SysPropBooleanFlag(1100, "persist.wm.debug.shell_transit", false); + // 1200 - predictive back + @Keep + public static final SysPropBooleanFlag WM_ENABLE_PREDICTIVE_BACK = new SysPropBooleanFlag( + 1200, "persist.wm.debug.predictive_back", true); + @Keep + public static final SysPropBooleanFlag WM_ENABLE_PREDICTIVE_BACK_ANIM = new SysPropBooleanFlag( + 1201, "persist.wm.debug.predictive_back_anim", false); + @Keep + public static final SysPropBooleanFlag WM_ALWAYS_ENFORCE_PREDICTIVE_BACK = + new SysPropBooleanFlag(1202, "persist.wm.debug.predictive_back_always_enforce", false); + // Pay no attention to the reflection behind the curtain. // ========================== Curtain ========================== // | | diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java index 96ae646ac7f9..290bf0d0734c 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java @@ -41,26 +41,23 @@ import com.android.systemui.statusbar.policy.KeyguardStateController; import javax.inject.Inject; -import dagger.Lazy; - public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks { private final Context mContext; - private final Lazy<GlobalActionsDialogLite> mGlobalActionsDialogLazy; private final KeyguardStateController mKeyguardStateController; private final DeviceProvisionedController mDeviceProvisionedController; private final BlurUtils mBlurUtils; private final CommandQueue mCommandQueue; - private GlobalActionsDialogLite mGlobalActionsDialog; + private final GlobalActionsDialogLite mGlobalActionsDialog; private boolean mDisabled; @Inject public GlobalActionsImpl(Context context, CommandQueue commandQueue, - Lazy<GlobalActionsDialogLite> globalActionsDialogLazy, BlurUtils blurUtils, + GlobalActionsDialogLite globalActionsDialog, BlurUtils blurUtils, KeyguardStateController keyguardStateController, DeviceProvisionedController deviceProvisionedController) { mContext = context; - mGlobalActionsDialogLazy = globalActionsDialogLazy; + mGlobalActionsDialog = globalActionsDialog; mKeyguardStateController = keyguardStateController; mDeviceProvisionedController = deviceProvisionedController; mCommandQueue = commandQueue; @@ -71,16 +68,12 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks @Override public void destroy() { mCommandQueue.removeCallback(this); - if (mGlobalActionsDialog != null) { - mGlobalActionsDialog.destroy(); - mGlobalActionsDialog = null; - } + mGlobalActionsDialog.destroy(); } @Override public void showGlobalActions(GlobalActionsManager manager) { if (mDisabled) return; - mGlobalActionsDialog = mGlobalActionsDialogLazy.get(); mGlobalActionsDialog.showOrHideDialog(mKeyguardStateController.isShowing(), mDeviceProvisionedController.isDeviceProvisioned(), null /* view */); } @@ -189,7 +182,7 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks final boolean disabled = (state2 & DISABLE2_GLOBAL_ACTIONS) != 0; if (displayId != mContext.getDisplayId() || disabled == mDisabled) return; mDisabled = disabled; - if (disabled && mGlobalActionsDialog != null) { + if (disabled) { mGlobalActionsDialog.dismissDialog(); } } diff --git a/packages/SystemUI/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageHelper.java b/packages/SystemUI/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageHelper.java index 1f58112c5dc6..1f61647b713f 100644 --- a/packages/SystemUI/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageHelper.java +++ b/packages/SystemUI/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageHelper.java @@ -16,6 +16,7 @@ package com.android.systemui.hdmi; +import android.os.UserHandle; import android.provider.Settings; import com.android.internal.app.LocalePicker; @@ -50,8 +51,8 @@ public class HdmiCecSetMenuLanguageHelper { SecureSettings secureSettings) { mBackgroundExecutor = executor; mSecureSettings = secureSettings; - String denylist = mSecureSettings.getString( - Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST); + String denylist = mSecureSettings.getStringForUser( + Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST, UserHandle.USER_CURRENT); mDenylist = new HashSet<>(denylist == null ? Collections.EMPTY_SET : Arrays.asList(denylist.split(SEPARATOR))); @@ -91,7 +92,7 @@ public class HdmiCecSetMenuLanguageHelper { */ public void declineLocale() { mDenylist.add(mLocale.toLanguageTag()); - mSecureSettings.putString(Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST, - String.join(SEPARATOR, mDenylist)); + mSecureSettings.putStringForUser(Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST, + String.join(SEPARATOR, mDenylist), UserHandle.USER_CURRENT); } } diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt index b93239ba7197..d674b2b85db4 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt @@ -690,6 +690,11 @@ class MediaCarouselController @Inject constructor( startDelay: Long = 0 ) { desiredHostState?.let { + if (this.desiredLocation != desiredLocation) { + // Only log an event when location changes + logger.logCarouselPosition(desiredLocation) + } + // This is a hosting view, let's remeasure our players this.desiredLocation = desiredLocation this.desiredHostState = it diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java index 5ead375a1084..3a727ba7b70c 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java @@ -333,7 +333,7 @@ public class MediaControlPanel { mMediaViewHolder.getPlayer().setOnClickListener(v -> { if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return; if (mMediaViewController.isGutsVisible()) return; - + mLogger.logTapContentView(mUid, mPackageName, mInstanceId); logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT); mActivityStarter.postStartActivityDismissingKeyguard(clickIntent, buildLaunchAnimatorController(mMediaViewHolder.getPlayer())); @@ -660,38 +660,42 @@ public class MediaControlPanel { final ImageButton button, MediaAction mediaAction, ConstraintSet collapsedSet, ConstraintSet expandedSet, boolean showInCompact) { - animHandler.unregisterAll(); if (mediaAction != null) { - final Drawable icon = mediaAction.getIcon(); - button.setImageDrawable(icon); - button.setContentDescription(mediaAction.getContentDescription()); - final Drawable bgDrawable = mediaAction.getBackground(); - button.setBackground(bgDrawable); - - animHandler.tryRegister(icon); - animHandler.tryRegister(bgDrawable); - - Runnable action = mediaAction.getAction(); - if (action == null) { - button.setEnabled(false); - } else { - button.setEnabled(true); - button.setOnClickListener(v -> { - if (!mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { - mLogger.logTapAction(button.getId(), mUid, mPackageName, mInstanceId); - logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT); - action.run(); - - if (icon instanceof Animatable) { - ((Animatable) icon).start(); - } - if (bgDrawable instanceof Animatable) { - ((Animatable) bgDrawable).start(); + if (animHandler.updateRebindId(mediaAction.getRebindId())) { + animHandler.unregisterAll(); + + final Drawable icon = mediaAction.getIcon(); + button.setImageDrawable(icon); + button.setContentDescription(mediaAction.getContentDescription()); + final Drawable bgDrawable = mediaAction.getBackground(); + button.setBackground(bgDrawable); + + animHandler.tryRegister(icon); + animHandler.tryRegister(bgDrawable); + + Runnable action = mediaAction.getAction(); + if (action == null) { + button.setEnabled(false); + } else { + button.setEnabled(true); + button.setOnClickListener(v -> { + if (!mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { + mLogger.logTapAction(button.getId(), mUid, mPackageName, mInstanceId); + logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT); + action.run(); + + if (icon instanceof Animatable) { + ((Animatable) icon).start(); + } + if (bgDrawable instanceof Animatable) { + ((Animatable) bgDrawable).start(); + } } - } - }); + }); + } } } else { + animHandler.unregisterAll(); button.setImageDrawable(null); button.setContentDescription(null); button.setEnabled(false); @@ -702,9 +706,29 @@ public class MediaControlPanel { setVisibleAndAlpha(expandedSet, button.getId(), mediaAction != null); } + // 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) { diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt index a4d2f7bc96c4..bc8cca55154d 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt @@ -184,7 +184,12 @@ data class MediaAction( val icon: Drawable?, val action: Runnable?, val contentDescription: CharSequence?, - val background: Drawable? + val background: Drawable?, + + // Rebind Id is used to detect identical rebinds and ignore them. It is intended + // to prevent continuously looping animations from restarting due to the arrival + // of repeated media notifications that are visually identical. + val rebindId: Int? = null ) /** State of the media device. */ diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index 908aef41034e..57c93bae3bbf 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -30,6 +30,7 @@ import android.content.IntentFilter import android.content.pm.PackageManager import android.graphics.Bitmap import android.graphics.ImageDecoder +import android.graphics.drawable.Animatable import android.graphics.drawable.Icon import android.media.MediaDescription import android.media.MediaMetadata @@ -57,6 +58,7 @@ import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.BcSmartspaceDataPlugin import com.android.systemui.statusbar.NotificationMediaManager.isPlayingState +import com.android.systemui.statusbar.NotificationMediaManager.isConnectingState import com.android.systemui.statusbar.notification.row.HybridGroupManager import com.android.systemui.tuner.TunerService import com.android.systemui.util.Assert @@ -777,7 +779,20 @@ class MediaDataManager( val actions = MediaButton() controller.playbackState?.let { state -> // First, check for standard actions - actions.playOrPause = if (isPlayingState(state.state)) { + 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) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt index 824a6fd9d96e..d6231911244f 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt @@ -164,7 +164,7 @@ class MediaDeviceManager @Inject constructor( } // A device that is not yet connected but is expected to connect imminently. Because it's // expected to connect imminently, it should be displayed as the current device. - private var aboutToConnectDeviceOverride: MediaDeviceData? = null + private var aboutToConnectDeviceOverride: AboutToConnectDevice? = null @AnyThread fun start() = bgExecutor.execute { @@ -222,22 +222,34 @@ class MediaDeviceManager @Inject constructor( } } - override fun onAboutToConnectDeviceChanged(deviceName: String?, deviceIcon: Drawable?) { - aboutToConnectDeviceOverride = if (deviceName == null || deviceIcon == null) { - null - } else { - MediaDeviceData(enabled = true, deviceIcon, deviceName) - } + override fun onAboutToConnectDeviceAdded( + deviceAddress: String, + deviceName: String, + deviceIcon: Drawable? + ) { + aboutToConnectDeviceOverride = AboutToConnectDevice( + fullMediaDevice = localMediaManager.getMediaDeviceById(deviceAddress), + backupMediaDeviceData = MediaDeviceData(enabled = true, deviceIcon, deviceName) + ) + updateCurrent() + } + + override fun onAboutToConnectDeviceRemoved() { + aboutToConnectDeviceOverride = null updateCurrent() } @WorkerThread private fun updateCurrent() { - if (aboutToConnectDeviceOverride != null) { - current = aboutToConnectDeviceOverride - return + val aboutToConnect = aboutToConnectDeviceOverride + if (aboutToConnect != null && + aboutToConnect.fullMediaDevice == null && + aboutToConnect.backupMediaDeviceData != null) { + // Only use [backupMediaDeviceData] when we don't have [fullMediaDevice]. + current = aboutToConnect.backupMediaDeviceData + return } - val device = localMediaManager.currentConnectedDevice + val device = aboutToConnect?.fullMediaDevice ?: localMediaManager.currentConnectedDevice val route = controller?.let { mr2manager.getRoutingSessionForMediaController(it) } // If we have a controller but get a null route, then don't trust the device @@ -247,3 +259,17 @@ class MediaDeviceManager @Inject constructor( } } } + +/** + * A class storing information for the about-to-connect device. See + * [LocalMediaManager.DeviceCallback.onAboutToConnectDeviceAdded] for more information. + * + * @property fullMediaDevice a full-fledged [MediaDevice] object representing the device. If + * non-null, prefer using [fullMediaDevice] over [backupMediaDeviceData]. + * @property backupMediaDeviceData a backup [MediaDeviceData] object containing the minimum + * information required to display the device. Only use if [fullMediaDevice] is null. + */ +private data class AboutToConnectDevice( + val fullMediaDevice: MediaDevice? = null, + val backupMediaDeviceData: MediaDeviceData? = null +) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt index 3d9f933b3a05..30771c728e86 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt @@ -1146,7 +1146,10 @@ private val EMPTY_RECT = Rect() @Retention(AnnotationRetention.SOURCE) private annotation class TransformationType -@IntDef(prefix = ["LOCATION_"], value = [MediaHierarchyManager.LOCATION_QS, - MediaHierarchyManager.LOCATION_QQS, MediaHierarchyManager.LOCATION_LOCKSCREEN]) +@IntDef(prefix = ["LOCATION_"], value = [ + MediaHierarchyManager.LOCATION_QS, + MediaHierarchyManager.LOCATION_QQS, + MediaHierarchyManager.LOCATION_LOCKSCREEN, + MediaHierarchyManager.LOCATION_DREAM_OVERLAY]) @Retention(AnnotationRetention.SOURCE) annotation class MediaLocation diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt index 862b2797b77c..3eba3b55b7e8 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt @@ -134,6 +134,23 @@ class MediaUiEventLogger @Inject constructor(private val logger: UiEventLogger) fun logOpenOutputSwitcher(uid: Int, packageName: String, instanceId: InstanceId) { logger.logWithInstanceId(MediaUiEvent.OPEN_OUTPUT_SWITCHER, uid, packageName, instanceId) } + + fun logTapContentView(uid: Int, packageName: String, instanceId: InstanceId) { + logger.logWithInstanceId(MediaUiEvent.MEDIA_TAP_CONTENT_VIEW, uid, packageName, instanceId) + } + + fun logCarouselPosition(@MediaLocation location: Int) { + val event = when (location) { + MediaHierarchyManager.LOCATION_QQS -> MediaUiEvent.MEDIA_CAROUSEL_LOCATION_QQS + MediaHierarchyManager.LOCATION_QS -> MediaUiEvent.MEDIA_CAROUSEL_LOCATION_QS + MediaHierarchyManager.LOCATION_LOCKSCREEN -> + MediaUiEvent.MEDIA_CAROUSEL_LOCATION_LOCKSCREEN + MediaHierarchyManager.LOCATION_DREAM_OVERLAY -> + MediaUiEvent.MEDIA_CAROUSEL_LOCATION_DREAM + else -> throw IllegalArgumentException("Unknown media carousel location $location") + } + logger.log(event) + } } enum class MediaUiEvent(val metricId: Int) : UiEventLogger.UiEventEnum { @@ -161,7 +178,7 @@ enum class MediaUiEvent(val metricId: Int) : UiEventLogger.UiEventEnum { @UiEvent(doc = "An existing active media control was converted into resumable media") ACTIVE_TO_RESUME(1014), - @UiEvent(doc = "Media timed out") + @UiEvent(doc = "A media control timed out") MEDIA_TIMEOUT(1015), @UiEvent(doc = "A media control was removed from the carousel") @@ -173,35 +190,50 @@ enum class MediaUiEvent(val metricId: Int) : UiEventLogger.UiEventEnum { @UiEvent(doc = "The user swiped away the media carousel") DISMISS_SWIPE(1018), - @UiEvent(doc = "The user opened the long press menu") + @UiEvent(doc = "The user long pressed on a media control") OPEN_LONG_PRESS(1019), - @UiEvent(doc = "The user dismissed via long press menu") + @UiEvent(doc = "The user dismissed a media control via its long press menu") DISMISS_LONG_PRESS(1020), - @UiEvent(doc = "The user opened settings from long press menu") + @UiEvent(doc = "The user opened media settings from a media control's long press menu") OPEN_SETTINGS_LONG_PRESS(1021), - @UiEvent(doc = "The user opened settings from the carousel") + @UiEvent(doc = "The user opened media settings from the media carousel") OPEN_SETTINGS_CAROUSEL(1022), - @UiEvent(doc = "The play/pause button was tapped") + @UiEvent(doc = "The play/pause button on a media control was tapped") TAP_ACTION_PLAY_PAUSE(1023), - @UiEvent(doc = "The previous button was tapped") + @UiEvent(doc = "The previous button on a media control was tapped") TAP_ACTION_PREV(1024), - @UiEvent(doc = "The next button was tapped") + @UiEvent(doc = "The next button on a media control was tapped") TAP_ACTION_NEXT(1025), - @UiEvent(doc = "A custom or generic action button was tapped") + @UiEvent(doc = "A custom or generic action button on a media control was tapped") TAP_ACTION_OTHER(1026), - @UiEvent(doc = "The user seeked using the seekbar") + @UiEvent(doc = "The user seeked on a media control using the seekbar") ACTION_SEEK(1027), @UiEvent(doc = "The user opened the output switcher from a media control") - OPEN_OUTPUT_SWITCHER(1028); + OPEN_OUTPUT_SWITCHER(1028), + + @UiEvent(doc = "The user tapped on a media control view") + MEDIA_TAP_CONTENT_VIEW(1036), + + @UiEvent(doc = "The media carousel moved to QQS") + MEDIA_CAROUSEL_LOCATION_QQS(1037), + + @UiEvent(doc = "THe media carousel moved to QS") + MEDIA_CAROUSEL_LOCATION_QS(1038), + + @UiEvent(doc = "The media carousel moved to the lockscreen") + MEDIA_CAROUSEL_LOCATION_LOCKSCREEN(1039), + + @UiEvent(doc = "The media carousel moved to the dream state") + MEDIA_CAROUSEL_LOCATION_DREAM(1040); override fun getId() = metricId }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java index 807f0f1bb0ba..ec2a950051b7 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java @@ -721,7 +721,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, boolean isVolumeControlEnabled(@NonNull MediaDevice device) { return isPlayBackInfoLocal() - || mLocalMediaManager.isMediaSessionAvailableForVolumeControl(); + || device.getDeviceType() != MediaDevice.MediaDeviceType.TYPE_CAST_GROUP_DEVICE; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManager.kt b/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManager.kt index 22bc5572f5a5..2783532aff97 100644 --- a/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManager.kt @@ -52,7 +52,9 @@ class MediaMuteAwaitConnectionManager constructor( // There should only be one device that's mutedUntilConnection at a time, so we can // safely override any previous value. currentMutedDevice = device - localMediaManager.dispatchAboutToConnectDeviceChanged(device.name, device.getIcon()) + localMediaManager.dispatchAboutToConnectDeviceAdded( + device.address, device.name, device.getIcon() + ) } } @@ -63,7 +65,7 @@ class MediaMuteAwaitConnectionManager constructor( ) { if (currentMutedDevice == device && USAGE_MEDIA in mutedUsages) { currentMutedDevice = null - localMediaManager.dispatchAboutToConnectDeviceChanged(null, null) + localMediaManager.dispatchAboutToConnectDeviceRemoved() } } } @@ -76,8 +78,8 @@ class MediaMuteAwaitConnectionManager constructor( val currentDevice = audioManager.mutingExpectedDevice if (currentDevice != null) { currentMutedDevice = currentDevice - localMediaManager.dispatchAboutToConnectDeviceChanged( - currentDevice.name, currentDevice.getIcon() + localMediaManager.dispatchAboutToConnectDeviceAdded( + currentDevice.address, currentDevice.name, currentDevice.getIcon() ) } } diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt index 3c6805b4e881..cd86fff1c6f8 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt @@ -19,6 +19,7 @@ package com.android.systemui.media.taptotransfer.sender import android.app.StatusBarManager import android.content.Context import android.media.MediaRoute2Info +import android.util.Log import android.view.View import androidx.annotation.StringRes import com.android.internal.logging.UiEventLogger @@ -221,7 +222,12 @@ enum class ChipStateSender( */ fun getSenderStateFromId( @StatusBarManager.MediaTransferSenderState displayState: Int, - ): ChipStateSender = values().first { it.stateInt == displayState } + ): ChipStateSender? = try { + values().first { it.stateInt == displayState } + } catch (e: NoSuchElementException) { + Log.e(TAG, "Could not find requested state $displayState", e) + null + } /** * Returns the state int from [StatusBarManager] associated with the given sender state @@ -238,3 +244,5 @@ enum class ChipStateSender( // process and we should keep the user informed about it as long as possible (but don't allow it to // continue indefinitely). private const val TRANSFER_TRIGGERED_TIMEOUT_MILLIS = 15000L + +private const val TAG = "ChipStateSender" diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java index f5abe28914c3..40265a367a06 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java @@ -143,6 +143,7 @@ public class NavigationBarView extends FrameLayout { private boolean mDeadZoneConsuming = false; private final NavigationBarTransitions mBarTransitions; private final OverviewProxyService mOverviewProxyService; + @Nullable private AutoHideController mAutoHideController; // performs manual animation in sync with layout transitions @@ -316,7 +317,7 @@ public class NavigationBarView extends FrameLayout { }; private final Consumer<Boolean> mNavbarOverlayVisibilityChangeCallback = (visible) -> { - if (visible) { + if (visible && mAutoHideController != null) { mAutoHideController.touchAutoHide(); } notifyActiveTouchRegions(); diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java index c01d6dcd7d64..c6c9aca0b161 100644 --- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java +++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java @@ -466,7 +466,7 @@ public class PeopleSpaceUtils { } } } catch (SQLException e) { - Log.e(TAG, "Failed to query contact: " + e); + Log.e(TAG, "Failed to query contact", e); } finally { if (cursor != null) { cursor.close(); @@ -527,7 +527,7 @@ public class PeopleSpaceUtils { lookupKeysWithBirthdaysToday.add(lookupKey); } } catch (SQLException e) { - Log.e(TAG, "Failed to query birthdays: " + e); + Log.e(TAG, "Failed to query birthdays", e); } finally { if (cursor != null) { cursor.close(); diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java index f6e1cd49eb40..1a7bd8cb6cf9 100644 --- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java +++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java @@ -275,7 +275,7 @@ public class PeopleSpaceWidgetManager { updateSingleConversationWidgets(widgetIds); } } catch (Exception e) { - Log.e(TAG, "Exception: " + e); + Log.e(TAG, "failed to update widgets", e); } } @@ -348,7 +348,7 @@ public class PeopleSpaceWidgetManager { try { return getTileForExistingWidgetThrowing(appWidgetId); } catch (Exception e) { - Log.e(TAG, "Failed to retrieve conversation for tile: " + e); + Log.e(TAG, "failed to retrieve tile for widget ID " + appWidgetId, e); return null; } } @@ -423,7 +423,7 @@ public class PeopleSpaceWidgetManager { // Add current state. return getTileWithCurrentState(storedTile.build(), ACTION_BOOT_COMPLETED); } catch (RemoteException e) { - Log.e(TAG, "Could not retrieve data: " + e); + Log.e(TAG, "getTileFromPersistentStorage failing", e); return null; } } @@ -441,12 +441,16 @@ public class PeopleSpaceWidgetManager { Log.d(TAG, "Notification removed, key: " + sbn.getKey()); } } + if (DEBUG) Log.d(TAG, "Fetching notifications"); + Collection<NotificationEntry> notifications = mNotifCollection.getAllNotifs(); mBgExecutor.execute( - () -> updateWidgetsWithNotificationChangedInBackground(sbn, notificationAction)); + () -> updateWidgetsWithNotificationChangedInBackground( + sbn, notificationAction, notifications)); } private void updateWidgetsWithNotificationChangedInBackground(StatusBarNotification sbn, - PeopleSpaceUtils.NotificationAction action) { + PeopleSpaceUtils.NotificationAction action, + Collection<NotificationEntry> notifications) { try { PeopleTileKey key = new PeopleTileKey( sbn.getShortcutId(), sbn.getUser().getIdentifier(), sbn.getPackageName()); @@ -469,23 +473,23 @@ public class PeopleSpaceWidgetManager { Log.d(TAG, "Widgets by URI to be updated:" + tilesUpdatedByUri.toString()); } tilesUpdated.addAll(tilesUpdatedByUri); - updateWidgetIdsBasedOnNotifications(tilesUpdated); + updateWidgetIdsBasedOnNotifications(tilesUpdated, notifications); } } catch (Exception e) { - Log.e(TAG, "Throwing exception: " + e); + Log.e(TAG, "updateWidgetsWithNotificationChangedInBackground failing", e); } } /** Updates {@code widgetIdsToUpdate} with {@code action}. */ - private void updateWidgetIdsBasedOnNotifications(Set<String> widgetIdsToUpdate) { + private void updateWidgetIdsBasedOnNotifications(Set<String> widgetIdsToUpdate, + Collection<NotificationEntry> ungroupedNotifications) { if (widgetIdsToUpdate.isEmpty()) { if (DEBUG) Log.d(TAG, "No widgets to update, returning."); return; } try { - if (DEBUG) Log.d(TAG, "Fetching grouped notifications"); Map<PeopleTileKey, Set<NotificationEntry>> groupedNotifications = - getGroupedConversationNotifications(); + groupConversationNotifications(ungroupedNotifications); widgetIdsToUpdate .stream() @@ -495,7 +499,7 @@ public class PeopleSpaceWidgetManager { id -> getAugmentedTileForExistingWidget(id, groupedNotifications))) .forEach((id, tile) -> updateAppWidgetOptionsAndViewOptional(id, tile)); } catch (Exception e) { - Log.e(TAG, "Exception updating widgets: " + e); + Log.e(TAG, "updateWidgetIdsBasedOnNotifications failing", e); } } @@ -510,7 +514,7 @@ public class PeopleSpaceWidgetManager { "Augmenting tile from NotificationEntryManager widget: " + key.toString()); } Map<PeopleTileKey, Set<NotificationEntry>> notifications = - getGroupedConversationNotifications(); + groupConversationNotifications(mNotifCollection.getAllNotifs()); String contactUri = null; if (tile.getContactUri() != null) { contactUri = tile.getContactUri().toString(); @@ -518,9 +522,10 @@ public class PeopleSpaceWidgetManager { return augmentTileFromNotifications(tile, key, contactUri, notifications, appWidgetId); } - /** Returns active and pending notifications grouped by {@link PeopleTileKey}. */ - public Map<PeopleTileKey, Set<NotificationEntry>> getGroupedConversationNotifications() { - Collection<NotificationEntry> notifications = mNotifCollection.getAllNotifs(); + /** Groups active and pending notifications grouped by {@link PeopleTileKey}. */ + public Map<PeopleTileKey, Set<NotificationEntry>> groupConversationNotifications( + Collection<NotificationEntry> notifications + ) { if (DEBUG) Log.d(TAG, "Number of total notifications: " + notifications.size()); Map<PeopleTileKey, Set<NotificationEntry>> groupedNotifications = notifications @@ -846,7 +851,7 @@ public class PeopleSpaceWidgetManager { Collections.singletonList(tile.getId()), tile.getUserHandle(), LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS); } catch (Exception e) { - Log.w(TAG, "Exception caching shortcut:" + e); + Log.w(TAG, "failed to cache shortcut", e); } PeopleSpaceTile finalTile = tile; mBgExecutor.execute( @@ -954,7 +959,7 @@ public class PeopleSpaceWidgetManager { UserHandle.of(key.getUserId()), LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS); } catch (Exception e) { - Log.d(TAG, "Exception uncaching shortcut:" + e); + Log.d(TAG, "failed to uncache shortcut", e); } } @@ -1037,7 +1042,7 @@ public class PeopleSpaceWidgetManager { packageName, userHandle.getIdentifier(), shortcutId); tile = PeopleSpaceUtils.getTile(channel, mLauncherApps); } catch (Exception e) { - Log.w(TAG, "Exception getting tiles: " + e); + Log.w(TAG, "failed to get conversation or tile", e); return null; } if (tile == null) { @@ -1086,7 +1091,7 @@ public class PeopleSpaceWidgetManager { } } catch (PackageManager.NameNotFoundException e) { // Delete data for uninstalled widgets. - Log.e(TAG, "Package no longer found for tile: " + e); + Log.e(TAG, "package no longer found for tile", e); JobScheduler jobScheduler = mContext.getSystemService(JobScheduler.class); if (jobScheduler != null && jobScheduler.getPendingJob(PeopleBackupFollowUpJob.JOB_ID) != null) { @@ -1296,7 +1301,7 @@ public class PeopleSpaceWidgetManager { try { editor.putString(newId, (String) entry.getValue()); } catch (Exception e) { - Log.e(TAG, "Malformed entry value: " + entry.getValue()); + Log.e(TAG, "malformed entry value: " + entry.getValue(), e); } editor.remove(key); break; @@ -1306,7 +1311,7 @@ public class PeopleSpaceWidgetManager { try { oldWidgetIds = (Set<String>) entry.getValue(); } catch (Exception e) { - Log.e(TAG, "Malformed entry value: " + entry.getValue()); + Log.e(TAG, "malformed entry value: " + entry.getValue(), e); editor.remove(key); break; } @@ -1337,7 +1342,7 @@ public class PeopleSpaceWidgetManager { try { oldWidgetIds = (Set<String>) entry.getValue(); } catch (Exception e) { - Log.e(TAG, "Malformed entry value: " + entry.getValue()); + Log.e(TAG, "malformed entry value: " + entry.getValue(), e); followUpEditor.remove(key); continue; } diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java index 2435497193e4..3e00a5f74d8f 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java @@ -18,6 +18,7 @@ package com.android.systemui.power; import static android.app.PendingIntent.FLAG_IMMUTABLE; +import android.app.Dialog; import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationManager; @@ -60,20 +61,25 @@ import com.android.settingslib.fuelgauge.BatterySaverUtils; import com.android.settingslib.utils.PowerUtil; import com.android.systemui.R; import com.android.systemui.SystemUIApplication; +import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.phone.SystemUIDialog; +import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.util.NotificationChannels; import com.android.systemui.volume.Events; import java.io.PrintWriter; +import java.lang.ref.WeakReference; import java.text.NumberFormat; import java.util.Locale; import java.util.Objects; import javax.inject.Inject; +import dagger.Lazy; + /** */ @SysUISingleton @@ -164,11 +170,15 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { private ActivityStarter mActivityStarter; private final BroadcastSender mBroadcastSender; + private final Lazy<BatteryController> mBatteryControllerLazy; + private final DialogLaunchAnimator mDialogLaunchAnimator; + /** */ @Inject public PowerNotificationWarnings(Context context, ActivityStarter activityStarter, - BroadcastSender broadcastSender) { + BroadcastSender broadcastSender, Lazy<BatteryController> batteryControllerLazy, + DialogLaunchAnimator dialogLaunchAnimator) { mContext = context; mNoMan = mContext.getSystemService(NotificationManager.class); mPowerMan = (PowerManager) context.getSystemService(Context.POWER_SERVICE); @@ -176,6 +186,8 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { mReceiver.init(); mActivityStarter = activityStarter; mBroadcastSender = broadcastSender; + mBatteryControllerLazy = batteryControllerLazy; + mDialogLaunchAnimator = dialogLaunchAnimator; mUseSevereDialog = mContext.getResources().getBoolean(R.bool.config_severe_battery_dialog); } @@ -685,8 +697,19 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { } d.setShowForAllUsers(true); d.setOnDismissListener((dialog) -> mSaverConfirmation = null); - d.show(); + WeakReference<View> ref = mBatteryControllerLazy.get().getLastPowerSaverStartView(); + if (ref != null && ref.get() != null && ref.get().isAggregatedVisible()) { + mDialogLaunchAnimator.showFromView(d, ref.get()); + } else { + d.show(); + } mSaverConfirmation = d; + mBatteryControllerLazy.get().clearLastPowerSaverStartView(); + } + + @VisibleForTesting + Dialog getSaverConfirmationDialog() { + return mSaverConfirmation; } private boolean isEnglishLocale() { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java index 7d8a28fc011e..1004fcae3827 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java @@ -116,6 +116,11 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements public void handleSetListening(boolean listening) { super.handleSetListening(listening); mSetting.setListening(listening); + if (!listening) { + // If we stopped listening, it means that the tile is not visible. In that case, we + // don't need to save the view anymore + mBatteryController.clearLastPowerSaverStartView(); + } } @Override @@ -128,7 +133,7 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements if (getState().state == Tile.STATE_UNAVAILABLE) { return; } - mBatteryController.setPowerSaveMode(!mPowerSave); + mBatteryController.setPowerSaveMode(!mPowerSave, view); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java index 5ed9ab9c4f65..772e9faf6feb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java @@ -25,6 +25,7 @@ import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; +import android.os.UserHandle; import android.service.quickaccesswallet.GetWalletCardsError; import android.service.quickaccesswallet.GetWalletCardsResponse; import android.service.quickaccesswallet.QuickAccessWalletClient; @@ -182,7 +183,8 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> { public boolean isAvailable() { return mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION) && !mPackageManager.hasSystemFeature(FEATURE_CHROME_OS) - && mSecureSettings.getString(NFC_PAYMENT_DEFAULT_COMPONENT) != null; + && mSecureSettings.getStringForUser(NFC_PAYMENT_DEFAULT_COMPONENT, + UserHandle.USER_CURRENT) != null; } @Nullable diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java index 41e468d382a3..50ee1f7ba97a 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java @@ -246,7 +246,9 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { new ClipData.Item(uri)); sharingIntent.setClipData(clipdata); sharingIntent.putExtra(Intent.EXTRA_SUBJECT, subject); - sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + // Make sure pending intents for the system user are still unique across users // by setting the (otherwise unused) request code to the current user id. @@ -256,6 +258,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK) .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + // cancel current pending intent (if any) since clipData isn't used for matching PendingIntent pendingIntent = PendingIntent.getActivityAsUser( context, 0, sharingChooserIntent, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java index d785059e3de7..27586b4f5caa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java @@ -60,6 +60,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.Co import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.util.settings.SecureSettings; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -84,6 +85,7 @@ public class NotificationLockscreenUserManagerImpl implements private final DeviceProvisionedController mDeviceProvisionedController; private final KeyguardStateController mKeyguardStateController; + private final SecureSettings mSecureSettings; private final Object mLock = new Object(); // Lazy @@ -187,6 +189,7 @@ public class NotificationLockscreenUserManagerImpl implements protected NotificationPresenter mPresenter; protected ContentObserver mLockscreenSettingsObserver; protected ContentObserver mSettingsObserver; + private boolean mHideSilentNotificationsOnLockscreen; private NotificationEntryManager getEntryManager() { if (mEntryManager == null) { @@ -208,6 +211,7 @@ public class NotificationLockscreenUserManagerImpl implements @Main Handler mainHandler, DeviceProvisionedController deviceProvisionedController, KeyguardStateController keyguardStateController, + SecureSettings secureSettings, DumpManager dumpManager) { mContext = context; mMainHandler = mainHandler; @@ -222,6 +226,7 @@ public class NotificationLockscreenUserManagerImpl implements mKeyguardManager = keyguardManager; mBroadcastDispatcher = broadcastDispatcher; mDeviceProvisionedController = deviceProvisionedController; + mSecureSettings = secureSettings; mKeyguardStateController = keyguardStateController; dumpManager.registerDumpable(this); @@ -256,12 +261,18 @@ public class NotificationLockscreenUserManagerImpl implements }; mContext.getContentResolver().registerContentObserver( - Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS), false, + mSecureSettings.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS), false, mLockscreenSettingsObserver, UserHandle.USER_ALL); mContext.getContentResolver().registerContentObserver( - Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS), + mSecureSettings.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS), + true, + mLockscreenSettingsObserver, + UserHandle.USER_ALL); + + mContext.getContentResolver().registerContentObserver( + mSecureSettings.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS), true, mLockscreenSettingsObserver, UserHandle.USER_ALL); @@ -272,7 +283,7 @@ public class NotificationLockscreenUserManagerImpl implements if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) { mContext.getContentResolver().registerContentObserver( - Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT), + mSecureSettings.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT), false, mSettingsObserver, UserHandle.USER_ALL); @@ -366,7 +377,7 @@ public class NotificationLockscreenUserManagerImpl implements } } boolean exceedsPriorityThreshold; - if (hideSilentNotificationsOnLockscreen()) { + if (mHideSilentNotificationsOnLockscreen) { exceedsPriorityThreshold = entry.getBucket() == BUCKET_MEDIA_CONTROLS || (entry.getBucket() != BUCKET_SILENT @@ -377,11 +388,6 @@ public class NotificationLockscreenUserManagerImpl implements return mShowLockscreenNotifications && exceedsPriorityThreshold; } - private boolean hideSilentNotificationsOnLockscreen() { - return whitelistIpcs(() -> Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1) == 0); - } - private void setShowLockscreenNotifications(boolean show) { mShowLockscreenNotifications = show; } @@ -391,7 +397,7 @@ public class NotificationLockscreenUserManagerImpl implements } protected void updateLockscreenNotificationSetting() { - final boolean show = Settings.Secure.getIntForUser(mContext.getContentResolver(), + final boolean show = mSecureSettings.getIntForUser( Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1, mCurrentUserId) != 0; @@ -400,10 +406,13 @@ public class NotificationLockscreenUserManagerImpl implements final boolean allowedByDpm = (dpmFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS) == 0; + mHideSilentNotificationsOnLockscreen = mSecureSettings.getIntForUser( + Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1, mCurrentUserId) == 0; + setShowLockscreenNotifications(show && allowedByDpm); if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) { - final boolean remoteInput = Settings.Secure.getIntForUser(mContext.getContentResolver(), + final boolean remoteInput = mSecureSettings.getIntForUser( Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT, 0, mCurrentUserId) != 0; @@ -426,8 +435,7 @@ public class NotificationLockscreenUserManagerImpl implements } if (mUsersAllowingPrivateNotifications.indexOfKey(userHandle) < 0) { - final boolean allowedByUser = 0 != Settings.Secure.getIntForUser( - mContext.getContentResolver(), + final boolean allowedByUser = 0 != mSecureSettings.getIntForUser( Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userHandle); final boolean allowedByDpm = adminAllowsKeyguardFeature(userHandle, DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS); @@ -492,8 +500,7 @@ public class NotificationLockscreenUserManagerImpl implements } if (mUsersAllowingNotifications.indexOfKey(userHandle) < 0) { - final boolean allowedByUser = 0 != Settings.Secure.getIntForUser( - mContext.getContentResolver(), + final boolean allowedByUser = 0 != mSecureSettings.getIntForUser( Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userHandle); final boolean allowedByDpm = adminAllowsKeyguardFeature(userHandle, DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java index 7239d0cc361b..1df40915a52c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java @@ -102,12 +102,14 @@ public class NotificationMediaManager implements Dumpable { KeyguardStateController.class); private final KeyguardBypassController mKeyguardBypassController; private static final HashSet<Integer> PAUSED_MEDIA_STATES = new HashSet<>(); + private static final HashSet<Integer> CONNECTING_MEDIA_STATES = new HashSet<>(); static { PAUSED_MEDIA_STATES.add(PlaybackState.STATE_NONE); PAUSED_MEDIA_STATES.add(PlaybackState.STATE_STOPPED); PAUSED_MEDIA_STATES.add(PlaybackState.STATE_PAUSED); PAUSED_MEDIA_STATES.add(PlaybackState.STATE_ERROR); - PAUSED_MEDIA_STATES.add(PlaybackState.STATE_CONNECTING); + CONNECTING_MEDIA_STATES.add(PlaybackState.STATE_CONNECTING); + CONNECTING_MEDIA_STATES.add(PlaybackState.STATE_BUFFERING); } private final NotificationVisibilityProvider mVisibilityProvider; @@ -363,7 +365,17 @@ public class NotificationMediaManager implements Dumpable { * @return true if playing */ public static boolean isPlayingState(int state) { - return !PAUSED_MEDIA_STATES.contains(state); + return !PAUSED_MEDIA_STATES.contains(state) + && !CONNECTING_MEDIA_STATES.contains(state); + } + + /** + * Check if a state should be considered as connecting + * @param state a PlaybackState + * @return true if connecting or buffering + */ + public static boolean isConnectingState(int state) { + return CONNECTING_MEDIA_STATES.contains(state); } public void setUpWithPresenter(NotificationPresenter presenter) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index eaa66bbc15ac..633786ffa787 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -594,16 +594,13 @@ public class NotificationShelf extends ActivatableNotificationView implements } else { shouldClipOwnTop = view.showingPulsing(); } - if (viewEnd > notificationClipEnd && !shouldClipOwnTop - && (mAmbientState.isShadeExpanded() || !isPinned)) { - int clipBottomAmount = (int) (viewEnd - notificationClipEnd); - if (isPinned) { - clipBottomAmount = Math.min(view.getIntrinsicHeight() - view.getCollapsedHeight(), - clipBottomAmount); + if (!isPinned) { + if (viewEnd > notificationClipEnd && !shouldClipOwnTop) { + int clipBottomAmount = (int) (viewEnd - notificationClipEnd); + view.setClipBottomAmount(clipBottomAmount); + } else { + view.setClipBottomAmount(0); } - view.setClipBottomAmount(clipBottomAmount); - } else { - view.setClipBottomAmount(0); } if (shouldClipOwnTop) { return (int) (viewEnd - getTranslationY()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java index 4a6d7e184ec2..8d7fc98164c0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java @@ -21,8 +21,6 @@ import android.widget.TextView; import com.android.settingslib.WirelessUtils; -import java.util.List; - /** Shows the operator name */ public class OperatorNameView extends TextView { private boolean mDemoMode; @@ -43,8 +41,10 @@ public class OperatorNameView extends TextView { mDemoMode = demoMode; } - void update(boolean showOperatorName, boolean hasMobile, - List<OperatorNameViewController.SubInfo> subs) { + void update(boolean showOperatorName, + boolean hasMobile, + OperatorNameViewController.SubInfo sub + ) { setVisibility(showOperatorName ? VISIBLE : GONE); boolean airplaneMode = WirelessUtils.isAirplaneModeOn(mContext); @@ -55,24 +55,21 @@ public class OperatorNameView extends TextView { } if (!mDemoMode) { - updateText(subs); + updateText(sub); } } - void updateText(List<OperatorNameViewController.SubInfo> subs) { + void updateText(OperatorNameViewController.SubInfo subInfo) { + CharSequence carrierName = null; CharSequence displayText = null; - final int N = subs.size(); - for (int i = 0; i < N; i++) { - OperatorNameViewController.SubInfo subInfo = subs.get(i); - CharSequence carrierName = subs.get(i).getCarrierName(); - if (!TextUtils.isEmpty(carrierName) && subInfo.simReady()) { - if (subInfo.stateInService()) { - displayText = subInfo.getCarrierName(); - break; - } + if (subInfo != null) { + carrierName = subInfo.getCarrierName(); + } + if (!TextUtils.isEmpty(carrierName) && subInfo.simReady()) { + if (subInfo.stateInService()) { + displayText = carrierName; } } - setText(displayText); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java index 8a4c4b5ac5c6..8afc72f08656 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.os.Bundle; import android.telephony.ServiceState; import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.view.View; @@ -30,12 +31,11 @@ import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.connectivity.IconState; import com.android.systemui.statusbar.connectivity.NetworkController; import com.android.systemui.statusbar.connectivity.SignalCallback; +import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment; import com.android.systemui.tuner.TunerService; +import com.android.systemui.util.CarrierConfigTracker; import com.android.systemui.util.ViewController; -import java.util.ArrayList; -import java.util.List; - import javax.inject.Inject; /** Controller for {@link OperatorNameView}. */ @@ -47,19 +47,22 @@ public class OperatorNameViewController extends ViewController<OperatorNameView> private final TunerService mTunerService; private final TelephonyManager mTelephonyManager; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; + private final CarrierConfigTracker mCarrierConfigTracker; private OperatorNameViewController(OperatorNameView view, DarkIconDispatcher darkIconDispatcher, NetworkController networkController, TunerService tunerService, TelephonyManager telephonyManager, - KeyguardUpdateMonitor keyguardUpdateMonitor) { + KeyguardUpdateMonitor keyguardUpdateMonitor, + CarrierConfigTracker carrierConfigTracker) { super(view); mDarkIconDispatcher = darkIconDispatcher; mNetworkController = networkController; mTunerService = tunerService; mTelephonyManager = telephonyManager; mKeyguardUpdateMonitor = keyguardUpdateMonitor; + mCarrierConfigTracker = carrierConfigTracker; } @Override @@ -79,24 +82,22 @@ public class OperatorNameViewController extends ViewController<OperatorNameView> } private void update() { - mView.update(mTunerService.getValue(KEY_SHOW_OPERATOR_NAME, 1) != 0, - mTelephonyManager.isDataCapable(), getSubInfos()); + SubInfo defaultSubInfo = getDefaultSubInfo(); + boolean showOperatorName = + mCarrierConfigTracker + .getShowOperatorNameInStatusBarConfig(defaultSubInfo.getSubId()) + && (mTunerService.getValue(KEY_SHOW_OPERATOR_NAME, 1) != 0); + mView.update(showOperatorName, mTelephonyManager.isDataCapable(), getDefaultSubInfo()); } - private List<SubInfo> getSubInfos() { - List<SubInfo> result = new ArrayList<>(); - List<SubscriptionInfo> subscritionInfos = - mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(false); - - for (SubscriptionInfo subscriptionInfo : subscritionInfos) { - int subId = subscriptionInfo.getSubscriptionId(); - result.add(new SubInfo( - subscriptionInfo.getCarrierName(), - mKeyguardUpdateMonitor.getSimState(subId), - mKeyguardUpdateMonitor.getServiceState(subId))); - } - - return result; + private SubInfo getDefaultSubInfo() { + int defaultSubId = SubscriptionManager.getDefaultDataSubscriptionId(); + SubscriptionInfo sI = mKeyguardUpdateMonitor.getSubscriptionInfoForSubId(defaultSubId); + return new SubInfo( + sI.getSubscriptionId(), + sI.getCarrierName(), + mKeyguardUpdateMonitor.getSimState(defaultSubId), + mKeyguardUpdateMonitor.getServiceState(defaultSubId)); } /** Factory for constructing an {@link OperatorNameViewController}. */ @@ -106,22 +107,32 @@ public class OperatorNameViewController extends ViewController<OperatorNameView> private final TunerService mTunerService; private final TelephonyManager mTelephonyManager; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; + private final CarrierConfigTracker mCarrierConfigTracker; @Inject - public Factory(DarkIconDispatcher darkIconDispatcher, NetworkController networkController, - TunerService tunerService, TelephonyManager telephonyManager, - KeyguardUpdateMonitor keyguardUpdateMonitor) { + public Factory(DarkIconDispatcher darkIconDispatcher, + NetworkController networkController, + TunerService tunerService, + TelephonyManager telephonyManager, + KeyguardUpdateMonitor keyguardUpdateMonitor, + CarrierConfigTracker carrierConfigTracker) { mDarkIconDispatcher = darkIconDispatcher; mNetworkController = networkController; mTunerService = tunerService; mTelephonyManager = telephonyManager; mKeyguardUpdateMonitor = keyguardUpdateMonitor; + mCarrierConfigTracker = carrierConfigTracker; } /** Create an {@link OperatorNameViewController}. */ public OperatorNameViewController create(OperatorNameView view) { - return new OperatorNameViewController(view, mDarkIconDispatcher, mNetworkController, - mTunerService, mTelephonyManager, mKeyguardUpdateMonitor); + return new OperatorNameViewController(view, + mDarkIconDispatcher, + mNetworkController, + mTunerService, + mTelephonyManager, + mKeyguardUpdateMonitor, + mCarrierConfigTracker); } } @@ -152,7 +163,7 @@ public class OperatorNameViewController extends ViewController<OperatorNameView> new KeyguardUpdateMonitorCallback() { @Override public void onRefreshCarrierInfo() { - mView.updateText(getSubInfos()); + mView.updateText(getDefaultSubInfo()); } }; @@ -176,17 +187,26 @@ public class OperatorNameViewController extends ViewController<OperatorNameView> }; static class SubInfo { + private final int mSubId; private final CharSequence mCarrierName; private final int mSimState; private final ServiceState mServiceState; - private SubInfo(CharSequence carrierName, - int simState, ServiceState serviceState) { + private SubInfo( + int subId, + CharSequence carrierName, + int simState, + ServiceState serviceState) { + mSubId = subId; mCarrierName = carrierName; mSimState = simState; mServiceState = serviceState; } + int getSubId() { + return mSubId; + } + boolean simReady() { return mSimState == TelephonyManager.SIM_STATE_READY; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt index e436ccfd66c6..5646545dcd23 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt @@ -200,7 +200,8 @@ private class KeyguardNotificationVisibilityProviderImpl @Inject constructor( private fun readShowSilentNotificationSetting() { val showSilentNotifs = - secureSettings.getBool(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, true) + secureSettings.getBoolForUser(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, + true, UserHandle.USER_CURRENT) hideSilentNotificationsOnLockscreen = !showSilentNotifs } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java index c640ab6c3a90..7d0f00abcc98 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java @@ -270,8 +270,8 @@ public class NotificationBackgroundView extends View { /** Set the current expand animation size. */ public void setExpandAnimationSize(int width, int height) { - mExpandAnimationHeight = width; - mExpandAnimationWidth = height; + mExpandAnimationHeight = height; + mExpandAnimationWidth = width; invalidate(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java index b95d153e8bd1..7f3381ccd38a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java @@ -34,10 +34,13 @@ public class ExpandableViewState extends ViewState { private static final int TAG_ANIMATOR_HEIGHT = R.id.height_animator_tag; private static final int TAG_ANIMATOR_TOP_INSET = R.id.top_inset_animator_tag; + private static final int TAG_ANIMATOR_BOTTOM_INSET = R.id.bottom_inset_animator_tag; private static final int TAG_END_HEIGHT = R.id.height_animator_end_value_tag; private static final int TAG_END_TOP_INSET = R.id.top_inset_animator_end_value_tag; + private static final int TAG_END_BOTTOM_INSET = R.id.bottom_inset_animator_end_value_tag; private static final int TAG_START_HEIGHT = R.id.height_animator_start_value_tag; private static final int TAG_START_TOP_INSET = R.id.top_inset_animator_start_value_tag; + private static final int TAG_START_BOTTOM_INSET = R.id.bottom_inset_animator_start_value_tag; // These are flags such that we can create masks for filtering. @@ -96,12 +99,17 @@ public class ExpandableViewState extends ViewState { public boolean headsUpIsVisible; /** - * How much the child overlaps with the previous child on top. This is used to - * show the background properly when the child on top is translating away. + * How much the child overlaps on top with the child above. */ public int clipTopAmount; /** + * How much the child overlaps on bottom with the child above. This is used to + * show the background properly when the child on top is translating away. + */ + public int clipBottomAmount; + + /** * The index of the view, only accounting for views not equal to GONE */ public int notGoneIndex; @@ -138,8 +146,8 @@ public class ExpandableViewState extends ViewState { if (view instanceof ExpandableView) { ExpandableView expandableView = (ExpandableView) view; - int height = expandableView.getActualHeight(); - int newHeight = this.height; + final int height = expandableView.getActualHeight(); + final int newHeight = this.height; // apply height if (height != newHeight) { @@ -157,10 +165,14 @@ public class ExpandableViewState extends ViewState { expandableView.setBelowSpeedBump(this.belowSpeedBump); // apply clipping - float oldClipTopAmount = expandableView.getClipTopAmount(); + final float oldClipTopAmount = expandableView.getClipTopAmount(); if (oldClipTopAmount != this.clipTopAmount) { expandableView.setClipTopAmount(this.clipTopAmount); } + final float oldClipBottomAmount = expandableView.getClipBottomAmount(); + if (oldClipBottomAmount != this.clipBottomAmount) { + expandableView.setClipBottomAmount(this.clipBottomAmount); + } expandableView.setTransformingInShelf(false); expandableView.setInShelf(inShelf); @@ -187,13 +199,20 @@ public class ExpandableViewState extends ViewState { abortAnimation(child, TAG_ANIMATOR_HEIGHT); } - // start top inset animation + // start clip top animation if (this.clipTopAmount != expandableView.getClipTopAmount()) { - startInsetAnimation(expandableView, properties); + startClipAnimation(expandableView, properties, /* clipTop */true); } else { abortAnimation(child, TAG_ANIMATOR_TOP_INSET); } + // start clip bottom animation + if (this.clipBottomAmount != expandableView.getClipBottomAmount()) { + startClipAnimation(expandableView, properties, /* clipTop */ false); + } else { + abortAnimation(child, TAG_ANIMATOR_BOTTOM_INSET); + } + // start dimmed animation expandableView.setDimmed(this.dimmed, animationFilter.animateDimmed); @@ -301,16 +320,20 @@ public class ExpandableViewState extends ViewState { child.setActualHeightAnimating(true); } - private void startInsetAnimation(final ExpandableView child, AnimationProperties properties) { - Integer previousStartValue = getChildTag(child, TAG_START_TOP_INSET); - Integer previousEndValue = getChildTag(child, TAG_END_TOP_INSET); - int newEndValue = this.clipTopAmount; + private void startClipAnimation(final ExpandableView child, AnimationProperties properties, + boolean clipTop) { + Integer previousStartValue = getChildTag(child, + clipTop ? TAG_START_TOP_INSET : TAG_START_BOTTOM_INSET); + Integer previousEndValue = getChildTag(child, + clipTop ? TAG_END_TOP_INSET : TAG_END_BOTTOM_INSET); + int newEndValue = clipTop ? this.clipTopAmount : this.clipBottomAmount; if (previousEndValue != null && previousEndValue == newEndValue) { return; } - ValueAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_TOP_INSET); + ValueAnimator previousAnimator = getChildTag(child, + clipTop ? TAG_ANIMATOR_TOP_INSET : TAG_ANIMATOR_BOTTOM_INSET); AnimationFilter filter = properties.getAnimationFilter(); - if (!filter.animateTopInset) { + if (clipTop && !filter.animateTopInset || !clipTop) { // just a local update was performed if (previousAnimator != null) { // we need to increase all animation keyframes of the previous animator by the @@ -319,22 +342,28 @@ public class ExpandableViewState extends ViewState { int relativeDiff = newEndValue - previousEndValue; int newStartValue = previousStartValue + relativeDiff; values[0].setIntValues(newStartValue, newEndValue); - child.setTag(TAG_START_TOP_INSET, newStartValue); - child.setTag(TAG_END_TOP_INSET, newEndValue); + child.setTag(clipTop ? TAG_START_TOP_INSET : TAG_START_BOTTOM_INSET, newStartValue); + child.setTag(clipTop ? TAG_END_TOP_INSET : TAG_END_BOTTOM_INSET, newEndValue); previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); return; } else { // no new animation needed, let's just apply the value - child.setClipTopAmount(newEndValue); + if (clipTop) { + child.setClipTopAmount(newEndValue); + } else { + child.setClipBottomAmount(newEndValue); + } return; } } - ValueAnimator animator = ValueAnimator.ofInt(child.getClipTopAmount(), newEndValue); - animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { + ValueAnimator animator = ValueAnimator.ofInt( + clipTop ? child.getClipTopAmount() : child.getClipBottomAmount(), newEndValue); + animator.addUpdateListener(animation -> { + if (clipTop) { child.setClipTopAmount((int) animation.getAnimatedValue()); + } else { + child.setClipBottomAmount((int) animation.getAnimatedValue()); } }); animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); @@ -353,15 +382,16 @@ public class ExpandableViewState extends ViewState { animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - child.setTag(TAG_ANIMATOR_TOP_INSET, null); - child.setTag(TAG_START_TOP_INSET, null); - child.setTag(TAG_END_TOP_INSET, null); + child.setTag(clipTop ? TAG_ANIMATOR_TOP_INSET : TAG_ANIMATOR_BOTTOM_INSET, null); + child.setTag(clipTop ? TAG_START_TOP_INSET : TAG_START_BOTTOM_INSET, null); + child.setTag(clipTop ? TAG_END_TOP_INSET : TAG_END_BOTTOM_INSET, null); } }); startAnimator(animator, listener); - child.setTag(TAG_ANIMATOR_TOP_INSET, animator); - child.setTag(TAG_START_TOP_INSET, child.getClipTopAmount()); - child.setTag(TAG_END_TOP_INSET, newEndValue); + child.setTag(clipTop ? TAG_ANIMATOR_TOP_INSET:TAG_ANIMATOR_BOTTOM_INSET, animator); + child.setTag(clipTop ? TAG_START_TOP_INSET: TAG_START_BOTTOM_INSET, + clipTop ? child.getClipTopAmount() : child.getClipBottomAmount()); + child.setTag(clipTop ? TAG_END_TOP_INSET: TAG_END_BOTTOM_INSET, newEndValue); } /** 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 6c6ed850f45a..d68f37103510 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 @@ -139,6 +139,8 @@ constructor( height += spaceNeeded count += 1 } else { + val gapBeforeFirstViewInShelf = current.calculateGapHeight(stack, previous, count) + height += gapBeforeFirstViewInShelf height += shelfHeight log { "returning height with shelf -> $height" } return height @@ -178,7 +180,9 @@ constructor( if (visibleIndex != 0) { size += notificationPadding } - size += calculateGapHeight(stack, previousView, visibleIndex) + val gapHeight = calculateGapHeight(stack, previousView, visibleIndex) + log { "\ti=$visibleIndex gapHeight=$gapHeight"} + size += gapHeight return size } 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 e1f8c35c3755..c0971337a19f 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 @@ -192,6 +192,7 @@ public class StackScrollAlgorithm { float clipStart = 0; int childCount = algorithmState.visibleChildren.size(); boolean firstHeadsUp = true; + float firstHeadsUpEnd = 0; for (int i = 0; i < childCount; i++) { ExpandableView child = algorithmState.visibleChildren.get(i); ExpandableViewState state = child.getViewState(); @@ -203,14 +204,18 @@ public class StackScrollAlgorithm { float newNotificationEnd = newYTranslation + newHeight; boolean isHeadsUp = (child instanceof ExpandableNotificationRow) && child.isPinned(); if (mClipNotificationScrollToTop - && (!state.inShelf || (isHeadsUp && !firstHeadsUp)) - && newYTranslation < clipStart + && ((isHeadsUp && !firstHeadsUp) || child.isHeadsUpAnimatingAway()) + && newNotificationEnd > firstHeadsUpEnd && !ambientState.isShadeExpanded()) { - // The previous view is overlapping on top, clip! - float overlapAmount = clipStart - newYTranslation; - state.clipTopAmount = (int) overlapAmount; + // The bottom of this view is peeking out from under the previous view. + // Clip the part that is peeking out. + float overlapAmount = newNotificationEnd - firstHeadsUpEnd; + state.clipBottomAmount = (int) overlapAmount; } else { - state.clipTopAmount = 0; + state.clipBottomAmount = 0; + } + if (firstHeadsUp) { + firstHeadsUpEnd = newNotificationEnd; } if (isHeadsUp) { firstHeadsUp = false; @@ -635,8 +640,6 @@ public class StackScrollAlgorithm { // Ensure that a headsUp doesn't vertically extend further than the heads-up at // the top most z-position childState.height = row.getIntrinsicHeight(); - childState.yTranslation = Math.min(topState.yTranslation + topState.height - - childState.height, childState.yTranslation); } // heads up notification show and this row is the top entry of heads up 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 600732373cae..6887741f37bd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -405,7 +405,7 @@ public class NotificationPanelViewController extends PanelViewController { * Determines if QS should be already expanded when expanding shade. * Used for split shade, two finger gesture as well as accessibility shortcut to QS. */ - private boolean mQsExpandImmediate; + @VisibleForTesting boolean mQsExpandImmediate; private boolean mTwoFingerQsExpandPossible; private String mHeaderDebugInfo; @@ -430,7 +430,6 @@ public class NotificationPanelViewController extends PanelViewController { private boolean mExpandingFromHeadsUp; private boolean mCollapsedOnDown; private int mPositionMinSideMargin; - private int mLastOrientation = -1; private boolean mClosingWithAlphaFadeOut; private boolean mHeadsUpAnimatingAway; private boolean mLaunchingAffordance; @@ -955,7 +954,6 @@ public class NotificationPanelViewController extends PanelViewController { mKeyguardBottomArea = mView.findViewById(R.id.keyguard_bottom_area); mPreviewContainer = mView.findViewById(R.id.preview_container); mKeyguardBottomArea.setPreviewContainer(mPreviewContainer); - mLastOrientation = mResources.getConfiguration().orientation; initBottomArea(); @@ -1994,9 +1992,6 @@ public class NotificationPanelViewController extends PanelViewController { if (!isFullyCollapsed()) { return; } - if (mShouldUseSplitNotificationShade) { - mQsExpandImmediate = true; - } mExpectingSynthesizedDown = true; onTrackingStarted(); updatePanelExpanded(); @@ -3172,6 +3167,9 @@ public class NotificationPanelViewController extends PanelViewController { mFalsingCollector.onTrackingStarted(!mKeyguardStateController.canDismissLockScreen()); super.onTrackingStarted(); mScrimController.onTrackingStarted(); + if (mShouldUseSplitNotificationShade) { + mQsExpandImmediate = true; + } if (mQsFullyExpanded) { mQsExpandImmediate = true; setShowShelfOnly(true); @@ -4876,7 +4874,6 @@ public class NotificationPanelViewController extends PanelViewController { public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mAffordanceHelper.onConfigurationChanged(); - mLastOrientation = newConfig.orientation; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt index 491e9fde5c9c..1206d0540fd2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt @@ -26,6 +26,7 @@ import com.android.systemui.util.ViewController import com.android.systemui.util.concurrency.DelayableExecutor import java.util.function.Consumer import javax.inject.Inject +import kotlin.reflect.KMutableProperty0 @VisibleForTesting internal const val INSET_DEBOUNCE_MILLIS = 500L @@ -54,6 +55,7 @@ class NotificationsQSContainerController @Inject constructor( private var largeScreenShadeHeaderActive = false private var notificationsBottomMargin = 0 private var scrimShadeBottomMargin = 0 + private var footerActionsOffset = 0 private var bottomStableInsets = 0 private var bottomCutoutInsets = 0 private var panelMarginHorizontal = 0 @@ -132,18 +134,17 @@ class NotificationsQSContainerController @Inject constructor( resources.getDimensionPixelSize(R.dimen.notification_panel_margin_top) } updateConstraints() - if (splitShadeEnabledChanged) { - // Let's do it at the end when all margins/paddings were already applied. - // We need to updateBottomSpacing() in case device configuration changed while showing - // QS details/customizer - updateBottomSpacing() - } - val previousScrimShadeBottomMargin = scrimShadeBottomMargin - scrimShadeBottomMargin = resources.getDimensionPixelSize( - R.dimen.split_shade_notifications_scrim_margin_bottom + + val scrimMarginChanged = ::scrimShadeBottomMargin.setAndReportChange( + resources.getDimensionPixelSize(R.dimen.split_shade_notifications_scrim_margin_bottom) + ) + val footerOffsetChanged = ::footerActionsOffset.setAndReportChange( + resources.getDimensionPixelSize(R.dimen.qs_footer_action_inset) + + resources.getDimensionPixelSize(R.dimen.qs_footer_actions_bottom_padding) ) + val dimensChanged = scrimMarginChanged || footerOffsetChanged - if (previousScrimShadeBottomMargin != scrimShadeBottomMargin) { + if (splitShadeEnabledChanged || dimensChanged) { updateBottomSpacing() } } @@ -166,22 +167,13 @@ class NotificationsQSContainerController @Inject constructor( } private fun updateBottomSpacing() { - val (containerPadding, notificationsMargin) = calculateBottomSpacing() - var qsScrollPaddingBottom = 0 - if (!(isQSCustomizing || isQSDetailShowing)) { - // With the new footer, we also want this padding in the bottom in these cases - qsScrollPaddingBottom = if (splitShadeEnabled) { - notificationsMargin - scrimShadeBottomMargin - } else { - bottomStableInsets - } - } + val (containerPadding, notificationsMargin, qsContainerPadding) = calculateBottomSpacing() mView.setPadding(0, 0, 0, containerPadding) mView.setNotificationsMarginBottom(notificationsMargin) - mView.setQSContainerPaddingBottom(qsScrollPaddingBottom) + mView.setQSContainerPaddingBottom(qsContainerPadding) } - private fun calculateBottomSpacing(): Pair<Int, Int> { + private fun calculateBottomSpacing(): Paddings { val containerPadding: Int var stackScrollMargin = notificationsBottomMargin if (splitShadeEnabled) { @@ -210,7 +202,17 @@ class NotificationsQSContainerController @Inject constructor( containerPadding = 0 } } - return containerPadding to stackScrollMargin + val qsContainerPadding = if (!(isQSCustomizing || isQSDetailShowing)) { + // We also want this padding in the bottom in these cases + if (splitShadeEnabled) { + stackScrollMargin - scrimShadeBottomMargin - footerActionsOffset + } else { + bottomStableInsets + } + } else { + 0 + } + return Paddings(containerPadding, stackScrollMargin, qsContainerPadding) } fun updateConstraints() { @@ -275,3 +277,15 @@ class NotificationsQSContainerController @Inject constructor( } } } + +private data class Paddings( + val containerPadding: Int, + val notificationsMargin: Int, + val qsContainerPadding: Int +) + +private fun KMutableProperty0<Int>.setAndReportChange(newValue: Int): Boolean { + val oldValue = get() + set(newValue) + return oldValue != newValue +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java index 6fe92fafc075..87ca942edff2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java @@ -489,7 +489,7 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte ExpandableNotificationRow row, boolean animate, boolean isActivityIntent) { - mLogger.logStartNotificationIntent(entry.getKey(), intent); + mLogger.logStartNotificationIntent(entry.getKey()); try { Runnable onFinishAnimationCallback = animate ? () -> mLaunchEventsEmitter.notifyFinishLaunchNotifActivity(entry) @@ -513,8 +513,10 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte mKeyguardStateController.isShowing(), eventTime) : getActivityOptions(mCentralSurfaces.getDisplayId(), adapter); - return intent.sendAndReturnResult(mContext, 0, fillInIntent, null, + int result = intent.sendAndReturnResult(mContext, 0, fillInIntent, null, null, null, options); + mLogger.logSendPendingIntent(entry.getKey(), intent, result); + return result; }); } catch (PendingIntent.CanceledException e) { // the stack trace isn't very helpful here. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt index d118747a0365..2fbe520a4b61 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt @@ -32,7 +32,7 @@ class StatusBarNotificationActivityStarterLogger @Inject constructor( buffer.log(TAG, DEBUG, { str1 = key }, { - "(1/4) onNotificationClicked: $str1" + "(1/5) onNotificationClicked: $str1" }) } @@ -40,7 +40,7 @@ class StatusBarNotificationActivityStarterLogger @Inject constructor( buffer.log(TAG, DEBUG, { str1 = key }, { - "(2/4) handleNotificationClickAfterKeyguardDismissed: $str1" + "(2/5) handleNotificationClickAfterKeyguardDismissed: $str1" }) } @@ -48,16 +48,25 @@ class StatusBarNotificationActivityStarterLogger @Inject constructor( buffer.log(TAG, DEBUG, { str1 = key }, { - "(3/4) handleNotificationClickAfterPanelCollapsed: $str1" + "(3/5) handleNotificationClickAfterPanelCollapsed: $str1" }) } - fun logStartNotificationIntent(key: String, pendingIntent: PendingIntent) { + fun logStartNotificationIntent(key: String) { + buffer.log(TAG, INFO, { + str1 = key + }, { + "(4/5) startNotificationIntent: $str1" + }) + } + + fun logSendPendingIntent(key: String, pendingIntent: PendingIntent, result: Int) { buffer.log(TAG, INFO, { str1 = key str2 = pendingIntent.intent.toString() + int1 = result }, { - "(4/4) Starting $str2 for notification $str1" + "(5/5) Started intent $str2 for notification $str1 with result code $int1" }) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java index 6c6ec192646d..06532c4f9d17 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java @@ -61,6 +61,7 @@ import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.tuner.TunerService; +import com.android.systemui.util.CarrierConfigTracker; import com.android.systemui.util.settings.SecureSettings; import java.util.concurrent.Executor; @@ -263,6 +264,7 @@ public abstract class StatusBarViewModule { NetworkController networkController, StatusBarStateController statusBarStateController, CommandQueue commandQueue, + CarrierConfigTracker carrierConfigTracker, CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger, OperatorNameViewController.Factory operatorNameViewControllerFactory, SecureSettings secureSettings, @@ -282,6 +284,7 @@ public abstract class StatusBarViewModule { networkController, statusBarStateController, commandQueue, + carrierConfigTracker, collapsedStatusBarFragmentLogger, operatorNameViewControllerFactory, secureSettings, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java index 8194957c52fc..597c949168d4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java @@ -31,7 +31,9 @@ import android.app.Fragment; import android.database.ContentObserver; import android.os.Bundle; import android.os.Parcelable; +import android.os.UserHandle; import android.provider.Settings; +import android.telephony.SubscriptionManager; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; @@ -69,6 +71,9 @@ import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallListener; import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager; import com.android.systemui.statusbar.policy.EncryptionHelper; import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.util.CarrierConfigTracker; +import com.android.systemui.util.CarrierConfigTracker.CarrierConfigChangedListener; +import com.android.systemui.util.CarrierConfigTracker.DefaultDataSubscriptionChangedListener; import com.android.systemui.util.settings.SecureSettings; import java.util.ArrayList; @@ -115,6 +120,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue private final NotificationIconAreaController mNotificationIconAreaController; private final PanelExpansionStateManager mPanelExpansionStateManager; private final StatusBarIconController mStatusBarIconController; + private final CarrierConfigTracker mCarrierConfigTracker; private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager; private final SecureSettings mSecureSettings; private final Executor mMainExecutor; @@ -137,6 +143,28 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue private OperatorNameViewController mOperatorNameViewController; private StatusBarSystemEventAnimator mSystemEventAnimator; + private final CarrierConfigChangedListener mCarrierConfigCallback = + new CarrierConfigChangedListener() { + @Override + public void onCarrierConfigChanged() { + if (mOperatorNameViewController == null) { + initOperatorName(); + } else { + // Already initialized, KeyguardUpdateMonitorCallback will handle the update + } + } + }; + + private final DefaultDataSubscriptionChangedListener mDefaultDataListener = + new DefaultDataSubscriptionChangedListener() { + @Override + public void onDefaultSubscriptionChanged(int subId) { + if (mOperatorNameViewController == null) { + initOperatorName(); + } + } + }; + @SuppressLint("ValidFragment") public CollapsedStatusBarFragment( StatusBarFragmentComponent.Factory statusBarFragmentComponentFactory, @@ -153,6 +181,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue NetworkController networkController, StatusBarStateController statusBarStateController, CommandQueue commandQueue, + CarrierConfigTracker carrierConfigTracker, CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger, OperatorNameViewController.Factory operatorNameViewControllerFactory, SecureSettings secureSettings, @@ -172,6 +201,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue mNetworkController = networkController; mStatusBarStateController = statusBarStateController; mCommandQueue = commandQueue; + mCarrierConfigTracker = carrierConfigTracker; mCollapsedStatusBarFragmentLogger = collapsedStatusBarFragmentLogger; mOperatorNameViewControllerFactory = operatorNameViewControllerFactory; mSecureSettings = secureSettings; @@ -212,6 +242,8 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue initNotificationIconArea(); mSystemEventAnimator = new StatusBarSystemEventAnimator(mSystemIconArea, getResources()); + mCarrierConfigTracker.addCallback(mCarrierConfigCallback); + mCarrierConfigTracker.addDefaultDataSubscriptionChangedListener(mDefaultDataListener); } @VisibleForTesting @@ -223,7 +255,10 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue R.array.config_collapsed_statusbar_icon_blocklist)); String vibrateIconSlot = getString(com.android.internal.R.string.status_bar_volume); boolean showVibrateIcon = - mSecureSettings.getInt(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 0) == 0; + mSecureSettings.getIntForUser( + Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, + 0, + UserHandle.USER_CURRENT) == 0; // Filter out vibrate icon from the blocklist if the setting is on for (int i = 0; i < blockList.size(); i++) { @@ -260,10 +295,11 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue initOngoingCallChip(); mAnimationScheduler.addCallback(this); - mSecureSettings.registerContentObserver( + mSecureSettings.registerContentObserverForUser( Settings.Secure.getUriFor(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON), false, - mVolumeSettingObserver); + mVolumeSettingObserver, + UserHandle.USER_ALL); } @Override @@ -283,6 +319,8 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue if (mNetworkController.hasEmergencyCryptKeeperText()) { mNetworkController.removeCallback(mSignalCallback); } + mCarrierConfigTracker.removeCallback(mCarrierConfigCallback); + mCarrierConfigTracker.removeDataSubscriptionChangedListener(mDefaultDataListener); } /** Initializes views related to the notification icon area. */ @@ -569,11 +607,16 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue } private void initOperatorName() { - if (getResources().getBoolean(R.bool.config_showOperatorNameInStatusBar)) { + int subId = SubscriptionManager.getDefaultDataSubscriptionId(); + if (mCarrierConfigTracker.getShowOperatorNameInStatusBarConfig(subId)) { ViewStub stub = mStatusBar.findViewById(R.id.operator_name); mOperatorNameViewController = mOperatorNameViewControllerFactory.create((OperatorNameView) stub.inflate()); mOperatorNameViewController.init(); + // This view should not be visible on lock-screen + if (mKeyguardStateController.isShowing()) { + hideOperatorName(false); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java index 95a7316f7a58..ecaa28b0d4eb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.policy; import android.annotation.Nullable; +import android.view.View; import com.android.systemui.Dumpable; import com.android.systemui.demomode.DemoMode; @@ -24,6 +25,7 @@ import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChang import java.io.FileDescriptor; import java.io.PrintWriter; +import java.lang.ref.WeakReference; public interface BatteryController extends DemoMode, Dumpable, CallbackController<BatteryStateChangeCallback> { @@ -35,7 +37,32 @@ public interface BatteryController extends DemoMode, Dumpable, /** * Sets if the current device is in power save mode. */ - void setPowerSaveMode(boolean powerSave); + default void setPowerSaveMode(boolean powerSave) { + setPowerSaveMode(powerSave, null); + } + + /** + * Sets if the current device is in power save mode. + * + * Can pass the view that triggered the request. + */ + void setPowerSaveMode(boolean powerSave, @Nullable View view); + + /** + * Gets a reference to the last view used when called {@link #setPowerSaveMode}. + */ + @Nullable + default WeakReference<View> getLastPowerSaverStartView() { + return null; + } + + /** + * Clears the last view used when called {@link #setPowerSaveMode}. + * + * Immediately after calling this, a call to {@link #getLastPowerSaverStartView()} should return + * {@code null}. + */ + default void clearLastPowerSaverStartView() {} /** * Returns {@code true} if the device is currently plugged in. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java index 9e2c478fbd69..f4e83dd71cb7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.policy; import static android.os.BatteryManager.EXTRA_PRESENT; +import android.annotation.WorkerThread; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -28,6 +29,7 @@ import android.os.Handler; import android.os.PowerManager; import android.os.PowerSaveState; import android.util.Log; +import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -42,11 +44,14 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.demomode.DemoMode; import com.android.systemui.demomode.DemoModeController; import com.android.systemui.power.EnhancedEstimates; +import com.android.systemui.util.Assert; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.atomic.AtomicReference; /** * Default implementation of a {@link BatteryController}. This controller monitors for battery @@ -85,6 +90,11 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC private Estimate mEstimate; private boolean mFetchingEstimate = false; + // Use AtomicReference because we may request it from a different thread + // Use WeakReference because we are keeping a reference to a View that's not as long lived + // as this controller. + private AtomicReference<WeakReference<View>> mPowerSaverStartView = new AtomicReference<>(); + @VisibleForTesting public BatteryControllerImpl( Context context, @@ -126,7 +136,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC } mDemoModeController.addCallback(this); updatePowerSave(); - updateEstimate(); + updateEstimateInBackground(); } @Override @@ -141,11 +151,22 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC } @Override - public void setPowerSaveMode(boolean powerSave) { + public void setPowerSaveMode(boolean powerSave, View view) { + if (powerSave) mPowerSaverStartView.set(new WeakReference<>(view)); BatterySaverUtils.setPowerSaveMode(mContext, powerSave, /*needFirstTimeWarning*/ true); } @Override + public WeakReference<View> getLastPowerSaverStartView() { + return mPowerSaverStartView.get(); + } + + @Override + public void clearLastPowerSaverStartView() { + mPowerSaverStartView.set(null); + } + + @Override public void addCallback(@NonNull BatteryController.BatteryStateChangeCallback cb) { synchronized (mChangeCallbacks) { mChangeCallbacks.add(cb); @@ -320,7 +341,9 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC } } + @WorkerThread private void updateEstimate() { + Assert.isNotMainThread(); // if the estimate has been cached we can just use that, otherwise get a new one and // throw it in the cache. mEstimate = Estimate.getCachedEstimateIfAvailable(mContext); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java index 9e1e87b9856f..4c43734836c4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java @@ -31,6 +31,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.text.Spannable; import android.text.SpannableStringBuilder; +import android.text.TextUtils; import android.text.format.DateFormat; import android.text.style.CharacterStyle; import android.text.style.RelativeSizeSpan; @@ -291,7 +292,13 @@ public class Clock extends TextView implements final void updateClock() { if (mDemoMode) return; mCalendar.setTimeInMillis(System.currentTimeMillis()); - setText(getSmallTime()); + CharSequence smallTime = getSmallTime(); + // Setting text actually triggers a layout pass (because the text view is set to + // wrap_content width and TextView always relayouts for this). Avoid needless + // relayout if the text didn't actually change. + if (!TextUtils.equals(smallTime, getText())) { + setText(smallTime); + } setContentDescription(mContentDescriptionFormat.format(mCalendar.getTime())); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java index 3e50acb75401..f26176c15451 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java @@ -119,8 +119,8 @@ public class LocationControllerImpl extends BroadcastReceiver implements Locatio }; // Register to listen for changes in Settings.Secure settings. - mSecureSettings.registerContentObserver( - Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, mContentObserver); + mSecureSettings.registerContentObserverForUser( + Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, mContentObserver, UserHandle.USER_ALL); // Register to listen for changes in DeviceConfig settings. mDeviceConfigProxy.addOnPropertiesChangedListener( @@ -230,7 +230,8 @@ public class LocationControllerImpl extends BroadcastReceiver implements Locatio } private boolean getShowSystemSetting() { - return mSecureSettings.getInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0) == 1; + return mSecureSettings.getIntForUser(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0, + UserHandle.USER_CURRENT) == 1; } private boolean getExperimentStarted() { diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java index c06b8e67c2f8..2424dc5cf0fb 100644 --- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java @@ -306,8 +306,9 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable { Log.d(TAG, "Updating theme setting from " + overlayPackageJson + " to " + jsonObject.toString()); } - mSecureSettings.putString(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES, - jsonObject.toString()); + mSecureSettings.putStringForUser( + Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES, + jsonObject.toString(), UserHandle.USER_CURRENT); } } catch (JSONException e) { Log.i(TAG, "Failed to parse THEME_CUSTOMIZATION_OVERLAY_PACKAGES.", e); diff --git a/packages/SystemUI/src/com/android/systemui/util/CarrierConfigTracker.java b/packages/SystemUI/src/com/android/systemui/util/CarrierConfigTracker.java index 14190fa752c3..5f7d74542fff 100644 --- a/packages/SystemUI/src/com/android/systemui/util/CarrierConfigTracker.java +++ b/packages/SystemUI/src/com/android/systemui/util/CarrierConfigTracker.java @@ -23,43 +23,73 @@ import android.content.IntentFilter; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; +import android.util.ArraySet; import android.util.SparseBooleanArray; +import androidx.annotation.NonNull; + +import com.android.internal.telephony.TelephonyIntents; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.statusbar.policy.CallbackController; + +import java.util.Set; import javax.inject.Inject; /** - * Tracks the Carrier Config values. + * Tracks CarrierConfigs for each subId, as well as the default configuration. CarrierConfigurations + * do not trigger a device configuration event, so any UI that relies on carrier configurations must + * register with the tracker to get proper updates. + * + * The tracker also listens for `TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED` + * + * @see CarrierConfigChangedListener to listen for updates */ @SysUISingleton -public class CarrierConfigTracker extends BroadcastReceiver { +public class CarrierConfigTracker + extends BroadcastReceiver + implements CallbackController<CarrierConfigTracker.CarrierConfigChangedListener> { private final SparseBooleanArray mCallStrengthConfigs = new SparseBooleanArray(); private final SparseBooleanArray mNoCallingConfigs = new SparseBooleanArray(); private final SparseBooleanArray mCarrierProvisionsWifiMergedNetworks = new SparseBooleanArray(); + private final SparseBooleanArray mShowOperatorNameConfigs = new SparseBooleanArray(); private final CarrierConfigManager mCarrierConfigManager; + private final Set<CarrierConfigChangedListener> mListeners = new ArraySet<>(); + private final Set<DefaultDataSubscriptionChangedListener> mDataListeners = + new ArraySet<>(); private boolean mDefaultCallStrengthConfigLoaded; private boolean mDefaultCallStrengthConfig; private boolean mDefaultNoCallingConfigLoaded; private boolean mDefaultNoCallingConfig; private boolean mDefaultCarrierProvisionsWifiMergedNetworksLoaded; private boolean mDefaultCarrierProvisionsWifiMergedNetworks; + private boolean mDefaultShowOperatorNameConfigLoaded; + private boolean mDefaultShowOperatorNameConfig; @Inject - public CarrierConfigTracker(Context context, BroadcastDispatcher broadcastDispatcher) { - mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class); - broadcastDispatcher.registerReceiver( - this, new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)); + public CarrierConfigTracker( + CarrierConfigManager carrierConfigManager, + BroadcastDispatcher broadcastDispatcher) { + mCarrierConfigManager = carrierConfigManager; + IntentFilter filter = new IntentFilter(); + filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); + filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED); + broadcastDispatcher.registerReceiver(this, filter); } @Override public void onReceive(Context context, Intent intent) { - if (!CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) { - return; + String action = intent.getAction(); + if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)) { + updateFromNewCarrierConfig(intent); + } else if (TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED.equals(action)) { + updateDefaultDataSubscription(intent); } + } + private void updateFromNewCarrierConfig(Intent intent) { final int subId = intent.getIntExtra( CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, SubscriptionManager.INVALID_SUBSCRIPTION_ID); @@ -84,6 +114,29 @@ public class CarrierConfigTracker extends BroadcastReceiver { mCarrierProvisionsWifiMergedNetworks.put(subId, config.getBoolean( CarrierConfigManager.KEY_CARRIER_PROVISIONS_WIFI_MERGED_NETWORKS_BOOL)); } + synchronized (mShowOperatorNameConfigs) { + mShowOperatorNameConfigs.put(subId, config.getBoolean( + CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL)); + } + + notifyCarrierConfigChanged(); + } + + private void updateDefaultDataSubscription(Intent intent) { + int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, -1); + notifyDefaultDataSubscriptionChanged(subId); + } + + private void notifyCarrierConfigChanged() { + for (CarrierConfigChangedListener l : mListeners) { + l.onCarrierConfigChanged(); + } + } + + private void notifyDefaultDataSubscriptionChanged(int subId) { + for (DefaultDataSubscriptionChangedListener l : mDataListeners) { + l.onDefaultSubscriptionChanged(subId); + } } /** @@ -139,4 +192,73 @@ public class CarrierConfigTracker extends BroadcastReceiver { } return mDefaultCarrierProvisionsWifiMergedNetworks; } + + /** + * Returns the KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL value for the default config + */ + public boolean getShowOperatorNameInStatusBarConfigDefault() { + if (!mDefaultShowOperatorNameConfigLoaded) { + mDefaultShowOperatorNameConfig = CarrierConfigManager.getDefaultConfig().getBoolean( + CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL); + mDefaultShowOperatorNameConfigLoaded = true; + } + + return mDefaultShowOperatorNameConfig; + } + + /** + * Returns the KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL value for the given subId, or the + * default value if no override exists + * + * @param subId the subscription id for which to query the config + */ + public boolean getShowOperatorNameInStatusBarConfig(int subId) { + if (mShowOperatorNameConfigs.indexOfKey(subId) >= 0) { + return mShowOperatorNameConfigs.get(subId); + } else { + return getShowOperatorNameInStatusBarConfigDefault(); + } + } + + @Override + public void addCallback(@NonNull CarrierConfigChangedListener listener) { + mListeners.add(listener); + } + + @Override + public void removeCallback(@NonNull CarrierConfigChangedListener listener) { + mListeners.remove(listener); + } + + /** */ + public void addDefaultDataSubscriptionChangedListener( + @NonNull DefaultDataSubscriptionChangedListener listener) { + mDataListeners.add(listener); + } + + /** */ + public void removeDataSubscriptionChangedListener( + DefaultDataSubscriptionChangedListener listener) { + mDataListeners.remove(listener); + } + + /** + * Called when carrier config changes + */ + public interface CarrierConfigChangedListener { + /** */ + void onCarrierConfigChanged(); + } + + /** + * Called when the default data subscription changes. Listeners may want to query + * subId-dependent configuration values when this event happens + */ + public interface DefaultDataSubscriptionChangedListener { + /** + * @param subId the new default data subscription id per + * {@link SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX} + */ + void onDefaultSubscriptionChanged(int subId); + } } diff --git a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java index de25ca981a65..acff8712e92e 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java @@ -24,6 +24,7 @@ import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.database.ContentObserver; +import android.os.UserHandle; import android.provider.Settings; import android.service.quickaccesswallet.GetWalletCardsRequest; import android.service.quickaccesswallet.QuickAccessWalletClient; @@ -275,10 +276,11 @@ public class QuickAccessWalletController { } }; - mSecureSettings.registerContentObserver( + mSecureSettings.registerContentObserverForUser( Settings.Secure.getUriFor(Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT), false /* notifyForDescendants */, - mDefaultPaymentAppObserver); + mDefaultPaymentAppObserver, + UserHandle.USER_ALL); } mDefaultPaymentAppChangeEvents++; } @@ -294,10 +296,11 @@ public class QuickAccessWalletController { } }; - mSecureSettings.registerContentObserver( + mSecureSettings.registerContentObserverForUser( Settings.Secure.getUriFor(QuickAccessWalletClientImpl.SETTING_KEY), false /* notifyForDescendants */, - mWalletPreferenceObserver); + mWalletPreferenceObserver, + UserHandle.USER_ALL); } mWalletPreferenceChangeEvents++; } diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java index 4d34aa38b3cd..b70220d09749 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java @@ -576,7 +576,9 @@ public class BubblesManager implements Dumpable { @Override public void onEntryRemoved(NotificationEntry entry, @NotifCollection.CancellationReason int reason) { - BubblesManager.this.onEntryRemoved(entry); + if (reason == REASON_APP_CANCEL || reason == REASON_APP_CANCEL_ALL) { + BubblesManager.this.onEntryRemoved(entry); + } } @Override diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java index 3e1b4d63f36a..fe9e75c4ce00 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; @@ -30,6 +31,7 @@ import static org.mockito.Mockito.when; import android.content.res.Resources; import android.database.ContentObserver; import android.net.Uri; +import android.os.UserHandle; import android.provider.Settings; import android.testing.AndroidTestingRunner; import android.view.View; @@ -250,13 +252,14 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase { @Test public void testChangeToDoubleLineClockSetsSmallClock() { - when(mSecureSettings.getInt(Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK, 1)) + when(mSecureSettings.getIntForUser(Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK, 1, + UserHandle.USER_CURRENT)) .thenReturn(0); ArgumentCaptor<ContentObserver> observerCaptor = ArgumentCaptor.forClass(ContentObserver.class); mController.init(); - verify(mSecureSettings).registerContentObserver(any(Uri.class), - anyBoolean(), observerCaptor.capture()); + verify(mSecureSettings).registerContentObserverForUser(any(Uri.class), + anyBoolean(), observerCaptor.capture(), eq(UserHandle.USER_ALL)); ContentObserver observer = observerCaptor.getValue(); mExecutor.runAllReady(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt index 98d57a3c5da8..23129d247ad5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt @@ -21,7 +21,8 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidTestingRunner::class) @TestableLooper.RunWithLooper -class ViewHierarchyAnimatorTest : SysuiTestCase() { +class +ViewHierarchyAnimatorTest : SysuiTestCase() { companion object { private const val TEST_DURATION = 1000L private val TEST_INTERPOLATOR = Interpolators.LINEAR @@ -522,6 +523,38 @@ class ViewHierarchyAnimatorTest : SysuiTestCase() { } @Test + fun cleansUpListenersCorrectly() { + val firstChild = View(mContext) + firstChild.layoutParams = LinearLayout.LayoutParams(50 /* width */, 100 /* height */) + rootView.addView(firstChild) + val secondChild = View(mContext) + secondChild.layoutParams = LinearLayout.LayoutParams(50 /* width */, 100 /* height */) + rootView.addView(secondChild) + rootView.measure( + View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY) + ) + rootView.layout(0 /* l */, 0 /* t */, 100 /* r */, 100 /* b */) + + val success = ViewHierarchyAnimator.animateNextUpdate(rootView) + // Change all bounds. + rootView.measure( + View.MeasureSpec.makeMeasureSpec(150, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY) + ) + rootView.layout(0 /* l */, 0 /* t */, 150 /* r */, 100 /* b */) + + assertTrue(success) + assertNotNull(rootView.getTag(R.id.tag_layout_listener)) + assertNotNull(firstChild.getTag(R.id.tag_layout_listener)) + assertNotNull(secondChild.getTag(R.id.tag_layout_listener)) + endAnimation(rootView) + assertNull(rootView.getTag(R.id.tag_layout_listener)) + assertNull(firstChild.getTag(R.id.tag_layout_listener)) + assertNull(secondChild.getTag(R.id.tag_layout_listener)) + } + + @Test fun doesNotAnimateInvisibleViews() { rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */) @@ -625,27 +658,6 @@ class ViewHierarchyAnimatorTest : SysuiTestCase() { } @Test - fun doesNotAnimateExcludedBounds() { - rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */) - - val success = ViewHierarchyAnimator.animate( - rootView, - bounds = setOf(ViewHierarchyAnimator.Bound.LEFT, ViewHierarchyAnimator.Bound.TOP), - interpolator = TEST_INTERPOLATOR - ) - // Change all bounds. - rootView.layout(0 /* l */, 20 /* t */, 70 /* r */, 80 /* b */) - - assertTrue(success) - assertNotNull(rootView.getTag(R.id.tag_animator)) - advanceAnimation(rootView, 0.5f) - checkBounds(rootView, l = 5, t = 15, r = 70, b = 80) - endAnimation(rootView) - assertNull(rootView.getTag(R.id.tag_animator)) - checkBounds(rootView, l = 0, t = 20, r = 70, b = 80) - } - - @Test fun stopsAnimatingAfterSingleLayout() { rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */) diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt index bbae5dca10c1..4ed5649c9c50 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt @@ -21,6 +21,7 @@ import android.content.SharedPreferences import android.database.ContentObserver import android.net.Uri import android.os.Handler +import android.os.UserHandle import android.provider.Settings import android.test.suitebuilder.annotation.SmallTest import android.testing.AndroidTestingRunner @@ -40,6 +41,7 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Answers +import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.Mockito import org.mockito.Mockito.`when` @@ -97,7 +99,8 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() { `when`(secureSettings.getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS)) .thenReturn(Settings.Secure .getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS)) - `when`(secureSettings.getInt(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0)) + `when`(secureSettings.getIntForUser(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, + 0, UserHandle.USER_CURRENT)) .thenReturn(1) coordinator = spy(ControlActionCoordinatorImpl( @@ -125,8 +128,8 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() { `when`(pref.getInt(DeviceControlsControllerImpl.PREFS_SETTINGS_DIALOG_ATTEMPTS, 0)) .thenReturn(2) - verify(secureSettings).registerContentObserver(any(Uri::class.java), - anyBoolean(), any(ContentObserver::class.java)) + verify(secureSettings).registerContentObserverForUser(any(Uri::class.java), + anyBoolean(), any(ContentObserver::class.java), anyInt()) `when`(cvh.cws.ci.controlId).thenReturn(ID) `when`(cvh.cws.control?.isAuthRequired()).thenReturn(true) diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/dagger/ControlsComponentTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/dagger/ControlsComponentTest.kt index c415c1fabdf3..77f451f61c3c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/dagger/ControlsComponentTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/dagger/ControlsComponentTest.kt @@ -137,7 +137,8 @@ class ControlsComponentTest : SysuiTestCase() { `when`(lockPatternUtils.getStrongAuthForUser(anyInt())) .thenReturn(STRONG_AUTH_NOT_REQUIRED) `when`(keyguardStateController.isUnlocked()).thenReturn(false) - `when`(secureSettings.getInt(eq(Settings.Secure.LOCKSCREEN_SHOW_CONTROLS), anyInt())) + `when`(secureSettings.getIntForUser(eq(Settings.Secure.LOCKSCREEN_SHOW_CONTROLS), + anyInt(), anyInt())) .thenReturn(1) val component = setupComponent(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 50b779cb6bf5..95fed6ca063f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt @@ -34,6 +34,7 @@ import com.google.common.truth.Truth.assertThat import org.junit.Assert import org.junit.Before import org.junit.Test +import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.Mockito.anyBoolean import org.mockito.Mockito.anyString @@ -321,7 +322,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { inOrder(mFlagManager, mSecureSettings).apply { verify(mFlagManager, times(numReads)).readFlagValue(eq(id), any<FlagSerializer<*>>()) verify(mFlagManager).idToSettingsKey(eq(id)) - verify(mSecureSettings).putString(eq("key-$id"), eq(data)) + verify(mSecureSettings).putStringForUser(eq("key-$id"), eq(data), anyInt()) verify(mFlagManager).dispatchListenersAndMaybeRestart(eq(id), any()) }.verifyNoMoreInteractions() verifyNoMoreInteractions(mFlagManager, mSecureSettings) diff --git a/packages/SystemUI/tests/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageHelperTest.java index 1171bd299c1f..eb998cc588fd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageHelperTest.java @@ -22,6 +22,7 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.os.UserHandle; import android.provider.Settings; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; @@ -53,8 +54,9 @@ public class HdmiCecSetMenuLanguageHelperTest extends SysuiTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); - when(mSecureSettings.getString( - Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST)).thenReturn(null); + when(mSecureSettings.getStringForUser( + Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST, + UserHandle.USER_CURRENT)).thenReturn(null); mHdmiCecSetMenuLanguageHelper = new HdmiCecSetMenuLanguageHelper(mExecutor, mSecureSettings); } @@ -84,8 +86,9 @@ public class HdmiCecSetMenuLanguageHelperTest extends SysuiTestCase { mHdmiCecSetMenuLanguageHelper.setLocale("de"); mHdmiCecSetMenuLanguageHelper.declineLocale(); assertThat(mHdmiCecSetMenuLanguageHelper.isLocaleDenylisted()).isEqualTo(true); - verify(mSecureSettings).putString( - Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST, "de"); + verify(mSecureSettings).putStringForUser( + Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST, "de", + UserHandle.USER_CURRENT); } @Test @@ -93,12 +96,14 @@ public class HdmiCecSetMenuLanguageHelperTest extends SysuiTestCase { mHdmiCecSetMenuLanguageHelper.setLocale("de"); mHdmiCecSetMenuLanguageHelper.declineLocale(); assertThat(mHdmiCecSetMenuLanguageHelper.isLocaleDenylisted()).isEqualTo(true); - verify(mSecureSettings).putString( - Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST, "de"); + verify(mSecureSettings).putStringForUser( + Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST, "de", + UserHandle.USER_CURRENT); mHdmiCecSetMenuLanguageHelper.setLocale("pl"); mHdmiCecSetMenuLanguageHelper.declineLocale(); assertThat(mHdmiCecSetMenuLanguageHelper.isLocaleDenylisted()).isEqualTo(true); - verify(mSecureSettings).putString( - Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST, "de,pl"); + verify(mSecureSettings).putStringForUser( + Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST, "de,pl", + UserHandle.USER_CURRENT); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt index 26296d67c71a..67fe0445e225 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt @@ -52,6 +52,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { @Mock lateinit var panel: MediaControlPanel @Mock lateinit var visualStabilityProvider: VisualStabilityProvider @Mock lateinit var mediaHostStatesManager: MediaHostStatesManager + @Mock lateinit var mediaHostState: MediaHostState @Mock lateinit var activityStarter: ActivityStarter @Mock @Main private lateinit var executor: DelayableExecutor @Mock lateinit var mediaDataManager: MediaDataManager @@ -188,4 +189,40 @@ class MediaCarouselControllerTest : SysuiTestCase() { verify(logger).logCarouselSettings() } + + @Test + fun testLocationChangeQs_logged() { + mediaCarouselController.onDesiredLocationChanged( + MediaHierarchyManager.LOCATION_QS, + mediaHostState, + animate = false) + verify(logger).logCarouselPosition(MediaHierarchyManager.LOCATION_QS) + } + + @Test + fun testLocationChangeQqs_logged() { + mediaCarouselController.onDesiredLocationChanged( + MediaHierarchyManager.LOCATION_QQS, + mediaHostState, + animate = false) + verify(logger).logCarouselPosition(MediaHierarchyManager.LOCATION_QQS) + } + + @Test + fun testLocationChangeLockscreen_logged() { + mediaCarouselController.onDesiredLocationChanged( + MediaHierarchyManager.LOCATION_LOCKSCREEN, + mediaHostState, + animate = false) + verify(logger).logCarouselPosition(MediaHierarchyManager.LOCATION_LOCKSCREEN) + } + + @Test + fun testLocationChangeDream_logged() { + mediaCarouselController.onDesiredLocationChanged( + MediaHierarchyManager.LOCATION_DREAM_OVERLAY, + mediaHostState, + animate = false) + verify(logger).logCarouselPosition(MediaHierarchyManager.LOCATION_DREAM_OVERLAY) + } }
\ No newline at end of file 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 f2e3edbc0761..538a9c763438 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,7 @@ package com.android.systemui.media +import android.app.PendingIntent import org.mockito.Mockito.`when` as whenever import android.content.Intent import android.graphics.Color @@ -104,6 +105,7 @@ public class MediaControlPanelTest : SysuiTestCase() { @Mock private lateinit var mediaOutputDialogFactory: MediaOutputDialogFactory @Mock private lateinit var mediaCarouselController: MediaCarouselController @Mock private lateinit var falsingManager: FalsingManager + @Mock private lateinit var transitionParent: ViewGroup private lateinit var appIcon: ImageView private lateinit var albumView: ImageView private lateinit var titleText: TextView @@ -241,6 +243,10 @@ public class MediaControlPanelTest : SysuiTestCase() { whenever(viewHolder.seamlessText).thenReturn(seamlessText) whenever(viewHolder.seekBar).thenReturn(seekBar) + // Transition View + whenever(view.parent).thenReturn(transitionParent) + whenever(view.rootView).thenReturn(transitionParent) + // Action buttons whenever(viewHolder.actionPlayPause).thenReturn(actionPlayPause) whenever(viewHolder.getAction(R.id.actionPlayPause)).thenReturn(actionPlayPause) @@ -749,6 +755,20 @@ public class MediaControlPanelTest : SysuiTestCase() { } @Test + fun tapContentView_isLogged() { + val pendingIntent = mock(PendingIntent::class.java) + 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()) + + captor.value.onClick(viewHolder.player) + + verify(logger).logTapContentView(anyInt(), eq(PACKAGE), eq(instanceId)) + } + + @Test fun logSeek() { player.attachPlayer(viewHolder) player.bindPlayer(mediaData, KEY) 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 b9ff8775f2b8..1921cb624fde 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt @@ -726,6 +726,25 @@ class MediaDataManagerTest : SysuiTestCase() { } @Test + fun testPlaybackActions_connecting() { + whenever(mediaFlags.areMediaSessionActionsEnabled(any(), any())).thenReturn(true) + val stateActions = PlaybackState.ACTION_PLAY + val stateBuilder = PlaybackState.Builder() + .setState(PlaybackState.STATE_BUFFERING, 0, 10f) + .setActions(stateActions) + whenever(controller.playbackState).thenReturn(stateBuilder.build()) + + addNotificationAndLoad() + + assertThat(mediaDataCaptor.value!!.semanticActions).isNotNull() + val actions = mediaDataCaptor.value!!.semanticActions!! + + assertThat(actions.playOrPause).isNotNull() + assertThat(actions.playOrPause!!.contentDescription).isEqualTo( + context.getString(R.string.controls_media_button_connecting)) + } + + @Test fun testPlaybackActions_reservedSpace() { val customDesc = arrayOf("custom 1", "custom 2", "custom 3", "custom 4") whenever(mediaFlags.areMediaSessionActionsEnabled(any(), any())).thenReturn(true) diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt index e6f48ecd37de..10eeb11faa05 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt @@ -265,20 +265,58 @@ public class MediaDeviceManagerTest : SysuiTestCase() { } @Test - fun onAboutToConnectDeviceChangedWithNonNullParams() { + fun onAboutToConnectDeviceAdded_findsDeviceInfoFromAddress() { manager.onMediaDataLoaded(KEY, null, mediaData) // Run and reset the executors and listeners so we only focus on new events. fakeBgExecutor.runAllReady() fakeFgExecutor.runAllReady() reset(listener) + // Ensure we'll get device info when using the address + val fullMediaDevice = mock(MediaDevice::class.java) + val address = "fakeAddress" + val nameFromDevice = "nameFromDevice" + val iconFromDevice = mock(Drawable::class.java) + whenever(lmm.getMediaDeviceById(eq(address))).thenReturn(fullMediaDevice) + whenever(fullMediaDevice.name).thenReturn(nameFromDevice) + whenever(fullMediaDevice.iconWithoutBackground).thenReturn(iconFromDevice) + + // WHEN the about-to-connect device changes to non-null val deviceCallback = captureCallback() + val nameFromParam = "nameFromParam" + val iconFromParam = mock(Drawable::class.java) + deviceCallback.onAboutToConnectDeviceAdded(address, nameFromParam, iconFromParam) + assertThat(fakeFgExecutor.runAllReady()).isEqualTo(1) + + // THEN the about-to-connect device based on the address is returned + val data = captureDeviceData(KEY) + assertThat(data.enabled).isTrue() + assertThat(data.name).isEqualTo(nameFromDevice) + assertThat(data.name).isNotEqualTo(nameFromParam) + assertThat(data.icon).isEqualTo(iconFromDevice) + assertThat(data.icon).isNotEqualTo(iconFromParam) + } + + @Test + fun onAboutToConnectDeviceAdded_cantFindDeviceInfoFromAddress() { + manager.onMediaDataLoaded(KEY, null, mediaData) + // Run and reset the executors and listeners so we only focus on new events. + fakeBgExecutor.runAllReady() + fakeFgExecutor.runAllReady() + reset(listener) + + // Ensure we can't get device info based on the address + val address = "fakeAddress" + whenever(lmm.getMediaDeviceById(eq(address))).thenReturn(null) + // WHEN the about-to-connect device changes to non-null + val deviceCallback = captureCallback() val name = "AboutToConnectDeviceName" val mockIcon = mock(Drawable::class.java) - deviceCallback.onAboutToConnectDeviceChanged(name, mockIcon) + deviceCallback.onAboutToConnectDeviceAdded(address, name, mockIcon) assertThat(fakeFgExecutor.runAllReady()).isEqualTo(1) - // THEN the about-to-connect device is returned + + // THEN the about-to-connect device based on the parameters is returned val data = captureDeviceData(KEY) assertThat(data.enabled).isTrue() assertThat(data.name).isEqualTo(name) @@ -286,21 +324,21 @@ public class MediaDeviceManagerTest : SysuiTestCase() { } @Test - fun onAboutToConnectDeviceChangedWithNullParams() { + fun onAboutToConnectDeviceAddedThenRemoved_usesNormalDevice() { manager.onMediaDataLoaded(KEY, null, mediaData) fakeBgExecutor.runAllReady() val deviceCallback = captureCallback() // First set a non-null about-to-connect device - deviceCallback.onAboutToConnectDeviceChanged( - "AboutToConnectDeviceName", mock(Drawable::class.java) + deviceCallback.onAboutToConnectDeviceAdded( + "fakeAddress", "AboutToConnectDeviceName", mock(Drawable::class.java) ) // Run and reset the executors and listeners so we only focus on new events. fakeBgExecutor.runAllReady() fakeFgExecutor.runAllReady() reset(listener) - // WHEN the about-to-connect device changes to null - deviceCallback.onAboutToConnectDeviceChanged(null, null) + // WHEN hasDevice switches to false + deviceCallback.onAboutToConnectDeviceRemoved() assertThat(fakeFgExecutor.runAllReady()).isEqualTo(1) // THEN the normal device is returned val data = captureDeviceData(KEY) diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt index 88c451499d21..27c039dcf29c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt @@ -24,7 +24,7 @@ import android.media.AudioDeviceAttributes import android.media.AudioDeviceInfo import android.media.AudioManager import android.media.AudioManager.MuteAwaitConnectionCallback.EVENT_CONNECTION -import android.test.suitebuilder.annotation.SmallTest +import androidx.test.filters.SmallTest import com.android.settingslib.media.DeviceIconUtil import com.android.settingslib.media.LocalMediaManager import com.android.systemui.R @@ -95,7 +95,7 @@ class MediaMuteAwaitConnectionManagerTest : SysuiTestCase() { muteAwaitConnectionManager.startListening() - verify(localMediaManager, never()).dispatchAboutToConnectDeviceChanged(any(), any()) + verify(localMediaManager, never()).dispatchAboutToConnectDeviceAdded(any(), any(), any()) } @Test @@ -104,7 +104,9 @@ class MediaMuteAwaitConnectionManagerTest : SysuiTestCase() { muteAwaitConnectionManager.startListening() - verify(localMediaManager).dispatchAboutToConnectDeviceChanged(eq(DEVICE_NAME), eq(icon)) + verify(localMediaManager).dispatchAboutToConnectDeviceAdded( + eq(DEVICE_ADDRESS), eq(DEVICE_NAME), eq(icon) + ) } @Test @@ -114,7 +116,7 @@ class MediaMuteAwaitConnectionManagerTest : SysuiTestCase() { muteAwaitListener.onMutedUntilConnection(DEVICE, intArrayOf(USAGE_UNKNOWN)) - verify(localMediaManager, never()).dispatchAboutToConnectDeviceChanged(any(), any()) + verify(localMediaManager, never()).dispatchAboutToConnectDeviceAdded(any(), any(), any()) } @Test @@ -125,7 +127,9 @@ class MediaMuteAwaitConnectionManagerTest : SysuiTestCase() { muteAwaitListener.onMutedUntilConnection(DEVICE, intArrayOf(USAGE_MEDIA)) - verify(localMediaManager).dispatchAboutToConnectDeviceChanged(eq(DEVICE_NAME), eq(icon)) + verify(localMediaManager).dispatchAboutToConnectDeviceAdded( + eq(DEVICE_ADDRESS), eq(DEVICE_NAME), eq(icon) + ) } @Test @@ -135,7 +139,7 @@ class MediaMuteAwaitConnectionManagerTest : SysuiTestCase() { muteAwaitListener.onUnmutedEvent(EVENT_CONNECTION, DEVICE, intArrayOf(USAGE_MEDIA)) - verify(localMediaManager, never()).dispatchAboutToConnectDeviceChanged(any(), any()) + verify(localMediaManager, never()).dispatchAboutToConnectDeviceAdded(any(), any(), any()) } @Test @@ -155,7 +159,7 @@ class MediaMuteAwaitConnectionManagerTest : SysuiTestCase() { ) muteAwaitListener.onUnmutedEvent(EVENT_CONNECTION, otherDevice, intArrayOf(USAGE_MEDIA)) - verify(localMediaManager, never()).dispatchAboutToConnectDeviceChanged(any(), any()) + verify(localMediaManager, never()).dispatchAboutToConnectDeviceAdded(any(), any(), any()) } @Test @@ -167,7 +171,7 @@ class MediaMuteAwaitConnectionManagerTest : SysuiTestCase() { muteAwaitListener.onUnmutedEvent(EVENT_CONNECTION, DEVICE, intArrayOf(USAGE_UNKNOWN)) - verify(localMediaManager, never()).dispatchAboutToConnectDeviceChanged(any(), any()) + verify(localMediaManager, never()).dispatchAboutToConnectDeviceAdded(any(), any(), any()) } @Test @@ -179,7 +183,7 @@ class MediaMuteAwaitConnectionManagerTest : SysuiTestCase() { muteAwaitListener.onUnmutedEvent(EVENT_CONNECTION, DEVICE, intArrayOf(USAGE_MEDIA)) - verify(localMediaManager).dispatchAboutToConnectDeviceChanged(eq(null), eq(null)) + verify(localMediaManager).dispatchAboutToConnectDeviceRemoved() } private fun getMuteAwaitListener(): AudioManager.MuteAwaitConnectionCallback { @@ -191,11 +195,12 @@ class MediaMuteAwaitConnectionManagerTest : SysuiTestCase() { } } +private const val DEVICE_ADDRESS = "DeviceAddress" private const val DEVICE_NAME = "DeviceName" private val DEVICE = AudioDeviceAttributes( AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_USB_HEADSET, - "address", + DEVICE_ADDRESS, DEVICE_NAME, listOf(), listOf(), diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt index ef5315428a60..9a01464fc869 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt @@ -277,6 +277,17 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { } @Test + fun commandQueueCallback_invalidStateParam_noChipShown() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + 100, + routeInfo, + null + ) + + verify(windowManager, never()).addView(any(), any()) + } + + @Test fun receivesNewStateFromCommandQueue_isLogged() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST, 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 a156820ad141..1ffa9dd57aa9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java @@ -25,29 +25,48 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import android.app.Notification; import android.app.NotificationManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.ContextWrapper; +import android.content.Intent; +import android.content.IntentFilter; import android.os.BatteryManager; +import android.os.Bundle; +import android.os.Handler; +import android.os.UserHandle; import android.test.suitebuilder.annotation.SmallTest; - -import androidx.test.runner.AndroidJUnit4; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.view.View; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; +import com.android.settingslib.fuelgauge.BatterySaverUtils; import com.android.systemui.SysuiTestCase; +import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.util.NotificationChannels; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.lang.ref.WeakReference; @SmallTest -@RunWith(AndroidJUnit4.class) +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper public class PowerNotificationWarningsTest extends SysuiTestCase { public static final String FORMATTED_45M = "0h 45m"; @@ -55,14 +74,34 @@ public class PowerNotificationWarningsTest extends SysuiTestCase { private final NotificationManager mMockNotificationManager = mock(NotificationManager.class); private PowerNotificationWarnings mPowerNotificationWarnings; + @Mock + private BatteryController mBatteryController; + @Mock + private DialogLaunchAnimator mDialogLaunchAnimator; + @Mock + private View mView; + + private BroadcastReceiver mReceiver; + @Before public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + Context wrapper = new ContextWrapper(mContext) { + @Override + public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, + IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) { + mReceiver = receiver; + return null; + } + }; + // Test Instance. mContext.addMockSystemService(NotificationManager.class, mMockNotificationManager); ActivityStarter starter = mDependency.injectMockDependency(ActivityStarter.class); BroadcastSender broadcastSender = mDependency.injectMockDependency(BroadcastSender.class); - mPowerNotificationWarnings = new PowerNotificationWarnings(mContext, starter, - broadcastSender); + mPowerNotificationWarnings = new PowerNotificationWarnings(wrapper, starter, + broadcastSender, () -> mBatteryController, mDialogLaunchAnimator); BatteryStateSnapshot snapshot = new BatteryStateSnapshot(100, false, false, 1, BatteryManager.BATTERY_HEALTH_GOOD, 5, 15); mPowerNotificationWarnings.updateSnapshot(snapshot); @@ -168,4 +207,52 @@ public class PowerNotificationWarningsTest extends SysuiTestCase { mPowerNotificationWarnings.mUsbHighTempDialog.dismiss(); } + + @Test + public void testDialogStartedFromLauncher_viewVisible() { + when(mBatteryController.getLastPowerSaverStartView()) + .thenReturn(new WeakReference<>(mView)); + when(mView.isAggregatedVisible()).thenReturn(true); + + Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION); + intent.putExtras(new Bundle()); + + mReceiver.onReceive(mContext, intent); + + verify(mDialogLaunchAnimator).showFromView(any(), eq(mView)); + + mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss(); + } + + @Test + public void testDialogStartedNotFromLauncher_viewNotVisible() { + when(mBatteryController.getLastPowerSaverStartView()) + .thenReturn(new WeakReference<>(mView)); + when(mView.isAggregatedVisible()).thenReturn(false); + + Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION); + intent.putExtras(new Bundle()); + + mReceiver.onReceive(mContext, intent); + + verify(mDialogLaunchAnimator, never()).showFromView(any(), any()); + + assertThat(mPowerNotificationWarnings.getSaverConfirmationDialog().isShowing()).isTrue(); + mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss(); + } + + @Test + public void testDialogShownNotFromLauncher() { + when(mBatteryController.getLastPowerSaverStartView()).thenReturn(null); + + Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION); + intent.putExtras(new Bundle()); + + mReceiver.onReceive(mContext, intent); + + verify(mDialogLaunchAnimator, never()).showFromView(any(), any()); + + assertThat(mPowerNotificationWarnings.getSaverConfirmationDialog().isShowing()).isTrue(); + mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss(); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt index 1bf83513d472..3d9205ee0354 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt @@ -21,6 +21,7 @@ import android.os.Handler import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.testing.TestableLooper.RunWithLooper +import android.view.View import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger import com.android.systemui.SysuiTestCase @@ -38,6 +39,9 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.`when` +import org.mockito.Mockito.clearInvocations +import org.mockito.Mockito.never +import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @RunWith(AndroidTestingRunner::class) @@ -63,6 +67,8 @@ class BatterySaverTileTest : SysuiTestCase() { private lateinit var qsLogger: QSLogger @Mock private lateinit var batteryController: BatteryController + @Mock + private lateinit var view: View private lateinit var secureSettings: SecureSettings private lateinit var testableLooper: TestableLooper private lateinit var tile: BatterySaverTile @@ -105,4 +111,26 @@ class BatterySaverTileTest : SysuiTestCase() { assertEquals(USER + 1, tile.mSetting.currentUser) } + + @Test + fun testClickingPowerSavePassesView() { + tile.onPowerSaveChanged(true) + tile.handleClick(view) + + tile.onPowerSaveChanged(false) + tile.handleClick(view) + + verify(batteryController).setPowerSaveMode(true, view) + verify(batteryController).setPowerSaveMode(false, view) + } + + @Test + fun testStopListeningClearsViewInController() { + clearInvocations(batteryController) + tile.handleSetListening(true) + verify(batteryController, never()).clearLastPowerSaverStartView() + + tile.handleSetListening(false) + verify(batteryController).clearLastPowerSaverStartView() + } }
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java index 1e5acde8bef5..c88ceac458ee 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java @@ -45,6 +45,7 @@ import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.os.Handler; +import android.os.UserHandle; import android.service.quickaccesswallet.GetWalletCardsError; import android.service.quickaccesswallet.GetWalletCardsResponse; import android.service.quickaccesswallet.QuickAccessWalletClient; @@ -186,7 +187,8 @@ public class QuickAccessWalletTileTest extends SysuiTestCase { public void testIsAvailable_qawFeatureAvailable() { when(mPackageManager.hasSystemFeature(FEATURE_NFC_HOST_CARD_EMULATION)).thenReturn(true); when(mPackageManager.hasSystemFeature("org.chromium.arc")).thenReturn(false); - when(mSecureSettings.getString(NFC_PAYMENT_DEFAULT_COMPONENT)).thenReturn("Component"); + when(mSecureSettings.getStringForUser(NFC_PAYMENT_DEFAULT_COMPONENT, + UserHandle.USER_CURRENT)).thenReturn("Component"); assertTrue(mTile.isAvailable()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java index 48f820626fac..7687d1204541 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java @@ -66,6 +66,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.Co import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.util.settings.FakeSettings; import com.google.android.collect.Lists; @@ -109,6 +110,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { private UserInfo mCurrentUser; private UserInfo mSecondaryUser; private UserInfo mWorkUser; + private FakeSettings mSettings; private TestNotificationLockscreenUserManager mLockscreenUserManager; private NotificationEntry mCurrentUserNotif; private NotificationEntry mSecondaryUserNotif; @@ -120,6 +122,8 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager); int currentUserId = ActivityManager.getCurrentUser(); + mSettings = new FakeSettings(); + mSettings.setUserId(ActivityManager.getCurrentUser()); mCurrentUser = new UserInfo(currentUserId, "", 0); mSecondaryUser = new UserInfo(currentUserId + 1, "", 0); mWorkUser = new UserInfo(currentUserId + 2, "" /* name */, null /* iconPath */, 0, @@ -157,48 +161,45 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { @Test public void testLockScreenShowNotificationsFalse() { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0); + mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); assertFalse(mLockscreenUserManager.shouldShowLockscreenNotifications()); } @Test public void testLockScreenShowNotificationsTrue() { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); + mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); assertTrue(mLockscreenUserManager.shouldShowLockscreenNotifications()); } @Test public void testLockScreenAllowPrivateNotificationsTrue() { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1); + mSettings.putInt(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); assertTrue(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mCurrentUser.id)); } @Test public void testLockScreenAllowPrivateNotificationsFalse() { - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id); + mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, + mCurrentUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); assertFalse(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mCurrentUser.id)); } @Test public void testLockScreenAllowsWorkPrivateNotificationsFalse() { - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mWorkUser.id); + mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, + mWorkUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); assertFalse(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mWorkUser.id)); } @Test public void testLockScreenAllowsWorkPrivateNotificationsTrue() { - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mWorkUser.id); + mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, + mWorkUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); assertTrue(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mWorkUser.id)); } @@ -206,8 +207,8 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { @Test public void testCurrentUserPrivateNotificationsNotRedacted() { // GIVEN current user doesn't allow private notifications to show - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id); + mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, + mCurrentUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); // THEN current user's notification is redacted @@ -217,8 +218,8 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { @Test public void testCurrentUserPrivateNotificationsRedacted() { // GIVEN current user allows private notifications to show - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mCurrentUser.id); + mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, + mCurrentUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); // THEN current user's notification isn't redacted @@ -228,8 +229,8 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { @Test public void testWorkPrivateNotificationsRedacted() { // GIVEN work profile doesn't private notifications to show - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mWorkUser.id); + mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, + mWorkUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); // THEN work profile notification is redacted @@ -239,8 +240,8 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { @Test public void testWorkPrivateNotificationsNotRedacted() { // GIVEN work profile allows private notifications to show - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mWorkUser.id); + mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, + mWorkUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); // THEN work profile notification isn't redacted @@ -250,12 +251,11 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { @Test public void testWorkPrivateNotificationsNotRedacted_otherUsersRedacted() { // GIVEN work profile allows private notifications to show but the other users don't - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mWorkUser.id); - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id); - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, + mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, + mWorkUser.id); + mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, + mCurrentUser.id); + mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mSecondaryUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); @@ -270,12 +270,11 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { @Test public void testWorkProfileRedacted_otherUsersNotRedacted() { // GIVEN work profile doesn't allow private notifications to show but the other users do - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mWorkUser.id); - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mCurrentUser.id); - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, + mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, + mWorkUser.id); + mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, + mCurrentUser.id); + mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mSecondaryUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); @@ -291,10 +290,9 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { public void testSecondaryUserNotRedacted_currentUserRedacted() { // GIVEN secondary profile allows private notifications to show but the current user // doesn't allow private notifications to show - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id); - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, + mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, + mCurrentUser.id); + mSettings.putIntForUser(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mSecondaryUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); @@ -328,10 +326,9 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { @Test public void testShowSilentNotifications_settingSaysShow() { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1); + mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); + mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); NotificationEntry entry = new NotificationEntryBuilder() .setImportance(IMPORTANCE_LOW) @@ -343,10 +340,9 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { @Test public void testShowSilentNotifications_settingSaysHide() { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0); + mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); + mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); final Notification notification = mock(Notification.class); when(notification.isForegroundService()).thenReturn(true); @@ -360,10 +356,9 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { @Test public void testShowSilentNotificationsPeopleBucket_settingSaysHide() { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0); + mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); + mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); final Notification notification = mock(Notification.class); when(notification.isForegroundService()).thenReturn(true); @@ -377,10 +372,9 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { @Test public void testShowSilentNotificationsMediaBucket_settingSaysHide() { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0); + mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); + mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); final Notification notification = mock(Notification.class); when(notification.isForegroundService()).thenReturn(true); @@ -396,8 +390,8 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { @Test public void testKeyguardNotificationSuppressors() { // GIVEN a notification that should be shown on the lockscreen - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); + mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); final NotificationEntry entry = new NotificationEntryBuilder() .setImportance(IMPORTANCE_HIGH) .build(); @@ -433,6 +427,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { Handler.createAsync(Looper.myLooper()), mDeviceProvisionedController, mKeyguardStateController, + mSettings, mock(DumpManager.class)); } 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 9a4e10cec159..497a857d1deb 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 @@ -22,8 +22,6 @@ import android.view.View.VISIBLE import androidx.test.filters.SmallTest import com.android.systemui.R import com.android.systemui.SysuiTestCase -import com.android.systemui.statusbar.StatusBarState.KEYGUARD -import com.android.systemui.statusbar.StatusBarState.SHADE import com.android.systemui.statusbar.SysuiStatusBarStateController import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow @@ -142,11 +140,13 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() { } @Test - fun computeHeight_returnsLessThanAvailableSpaceUsedToCalculateMaxNotifications() { + fun computeHeight_returnsAtMostSpaceAvailable_withGapBeforeShelf() { val rowHeight = ROW_HEIGHT val shelfHeight = SHELF_HEIGHT val totalSpaceForEachRow = GAP_HEIGHT + rowHeight + NOTIFICATION_PADDING val availableSpace = totalSpaceForEachRow * 2 + + // All rows in separate sections (default setup). val rows = listOf( createMockRow(rowHeight), @@ -157,6 +157,28 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() { assertThat(maxNotifications).isEqualTo(2) val height = sizeCalculator.computeHeight(stackLayout, maxNotifications, SHELF_HEIGHT) + assertThat(height).isAtMost(availableSpace + GAP_HEIGHT + SHELF_HEIGHT) + } + + @Test + fun computeHeight_returnsAtMostSpaceAvailable_noGapBeforeShelf() { + val rowHeight = ROW_HEIGHT + val shelfHeight = SHELF_HEIGHT + val totalSpaceForEachRow = GAP_HEIGHT + rowHeight + NOTIFICATION_PADDING + val availableSpace = totalSpaceForEachRow * 1 + + // Both rows are in the same section. + whenever(stackLayout.calculateGapHeight(nullable(), nullable(), any())) + .thenReturn(0f) + 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) } 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 7ef656c780a6..8f3df09d913d 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 @@ -947,6 +947,15 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { verify(mKeyguardStatusBarViewController).setAlpha(statusBarAlpha); } + @Test + public void testQsToBeImmediatelyExpandedInSplitShade() { + enableSplitShade(/* enabled= */ true); + + mNotificationPanelViewController.onTrackingStarted(); + + assertThat(mNotificationPanelViewController.mQsExpandImmediate).isTrue(); + } + private void triggerPositionClockAndNotifications() { mNotificationPanelViewController.closeQs(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt index e2fabbd1c270..003245298fa9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt @@ -50,6 +50,10 @@ class NotificationQSContainerControllerTest : SysuiTestCase() { const val BUTTONS_NAVIGATION = WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON const val NOTIFICATIONS_MARGIN = 50 const val SCRIM_MARGIN = 10 + const val FOOTER_ACTIONS_INSET = 2 + const val FOOTER_ACTIONS_PADDING = 2 + const val FOOTER_ACTIONS_OFFSET = FOOTER_ACTIONS_INSET + FOOTER_ACTIONS_PADDING + const val QS_PADDING_OFFSET = SCRIM_MARGIN + FOOTER_ACTIONS_OFFSET } @Mock @@ -95,6 +99,8 @@ class NotificationQSContainerControllerTest : SysuiTestCase() { overrideResource(R.dimen.split_shade_notifications_scrim_margin_bottom, SCRIM_MARGIN) overrideResource(R.dimen.notification_panel_margin_bottom, NOTIFICATIONS_MARGIN) overrideResource(R.bool.config_use_split_notification_shade, false) + overrideResource(R.dimen.qs_footer_actions_bottom_padding, FOOTER_ACTIONS_PADDING) + overrideResource(R.dimen.qs_footer_action_inset, FOOTER_ACTIONS_INSET) whenever(navigationModeController.addListener(navigationModeCaptor.capture())) .thenReturn(GESTURES_NAVIGATION) doNothing().`when`(overviewProxyService).addCallback(taskbarVisibilityCaptor.capture()) @@ -119,14 +125,14 @@ class NotificationQSContainerControllerTest : SysuiTestCase() { insets = windowInsets().withStableBottom()) then(expectedContainerPadding = 0, // taskbar should disappear when shade is expanded expectedNotificationsMargin = NOTIFICATIONS_MARGIN, - expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN) + expectedQsPadding = NOTIFICATIONS_MARGIN - QS_PADDING_OFFSET) given(taskbarVisible = true, navigationMode = BUTTONS_NAVIGATION, insets = windowInsets().withStableBottom()) then(expectedContainerPadding = STABLE_INSET_BOTTOM, expectedNotificationsMargin = NOTIFICATIONS_MARGIN, - expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN) + expectedQsPadding = NOTIFICATIONS_MARGIN - QS_PADDING_OFFSET) } @Test @@ -138,14 +144,14 @@ class NotificationQSContainerControllerTest : SysuiTestCase() { navigationMode = GESTURES_NAVIGATION, insets = windowInsets().withStableBottom()) then(expectedContainerPadding = 0, - expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN) + expectedQsPadding = NOTIFICATIONS_MARGIN - QS_PADDING_OFFSET) given(taskbarVisible = false, navigationMode = BUTTONS_NAVIGATION, insets = windowInsets().withStableBottom()) then(expectedContainerPadding = 0, // qs goes full height as it's not obscuring nav buttons expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN, - expectedQsPadding = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN - SCRIM_MARGIN) + expectedQsPadding = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN - QS_PADDING_OFFSET) } @Test @@ -156,14 +162,14 @@ class NotificationQSContainerControllerTest : SysuiTestCase() { navigationMode = GESTURES_NAVIGATION, insets = windowInsets().withCutout()) then(expectedContainerPadding = CUTOUT_HEIGHT, - expectedQsPadding = NOTIFICATIONS_MARGIN - SCRIM_MARGIN) + expectedQsPadding = NOTIFICATIONS_MARGIN - QS_PADDING_OFFSET) given(taskbarVisible = false, navigationMode = BUTTONS_NAVIGATION, insets = windowInsets().withCutout().withStableBottom()) then(expectedContainerPadding = 0, expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN, - expectedQsPadding = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN - SCRIM_MARGIN) + expectedQsPadding = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN - QS_PADDING_OFFSET) } @Test @@ -365,7 +371,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() { container.addView(newViewWithId(View.NO_ID)) val controller = NotificationsQSContainerController(container, navigationModeController, overviewProxyService, featureFlags, delayableExecutor) - controller.updateResources() + controller.updateConstraints() assertThat(container.getChildAt(0).id).isEqualTo(1) assertThat(container.getChildAt(1).id).isNotEqualTo(View.NO_ID) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java index 509509401d13..98397fb01b6b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java @@ -29,6 +29,7 @@ import android.app.Fragment; import android.app.StatusBarManager; import android.content.Context; import android.os.Bundle; +import android.os.UserHandle; import android.provider.Settings; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; @@ -59,6 +60,7 @@ import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentCom import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager; import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.util.CarrierConfigTracker; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.settings.SecureSettings; import com.android.systemui.util.time.FakeSystemClock; @@ -90,6 +92,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { private OperatorNameViewController mOperatorNameViewController; private SecureSettings mSecureSettings; private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock()); + private final CarrierConfigTracker mCarrierConfigTracker = mock(CarrierConfigTracker.class); @Mock private StatusBarFragmentComponent.Factory mStatusBarFragmentComponentFactory; @@ -329,7 +332,8 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { String str = mContext.getString(com.android.internal.R.string.status_bar_volume); // GIVEN the setting is ON - when(mSecureSettings.getInt(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 0)) + when(mSecureSettings.getIntForUser(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 0, + UserHandle.USER_CURRENT)) .thenReturn(1); // WHEN CollapsedStatusBarFragment builds the blocklist @@ -373,6 +377,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { mNetworkController, mStatusBarStateController, mCommandQueue, + mCarrierConfigTracker, new CollapsedStatusBarFragmentLogger( new LogBuffer("TEST", 1, 1, mock(LogcatEchoTracker.class)), new DisableFlagsLogger() diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java index 2577dbdbb593..fec2123b304a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java @@ -18,6 +18,10 @@ package com.android.systemui.statusbar.policy; import static android.os.BatteryManager.EXTRA_PRESENT; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.staticMockMarker; + import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -30,20 +34,24 @@ import android.os.PowerSaveState; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import android.view.View; +import com.android.dx.mockito.inline.extended.StaticInOrder; +import com.android.settingslib.fuelgauge.BatterySaverUtils; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.demomode.DemoModeController; import com.android.systemui.power.EnhancedEstimates; import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback; +import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; - +import org.mockito.MockitoSession; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -53,11 +61,19 @@ public class BatteryControllerTest extends SysuiTestCase { @Mock private PowerManager mPowerManager; @Mock private BroadcastDispatcher mBroadcastDispatcher; @Mock private DemoModeController mDemoModeController; + @Mock private View mView; private BatteryControllerImpl mBatteryController; + private MockitoSession mMockitoSession; + @Before - public void setUp() { + public void setUp() throws IllegalStateException { MockitoAnnotations.initMocks(this); + mMockitoSession = mockitoSession() + .initMocks(this) + .mockStatic(BatterySaverUtils.class) + .startMocking(); + mBatteryController = new BatteryControllerImpl(getContext(), mock(EnhancedEstimates.class), mPowerManager, @@ -65,9 +81,15 @@ public class BatteryControllerTest extends SysuiTestCase { mDemoModeController, new Handler(), new Handler()); + // Can throw if updateEstimate is called on the main thread mBatteryController.init(); } + @After + public void tearDown() { + mMockitoSession.finishMocking(); + } + @Test public void testBatteryInitialized() { Assert.assertTrue(mBatteryController.mHasReceivedBattery); @@ -135,4 +157,43 @@ public class BatteryControllerTest extends SysuiTestCase { // THEN it is informed about the battery state verify(cb, atLeastOnce()).onBatteryUnknownStateChanged(true); } + + @Test + public void testBatteryUtilsCalledOnSetPowerSaveMode() { + mBatteryController.setPowerSaveMode(true, mView); + mBatteryController.setPowerSaveMode(false, mView); + + StaticInOrder inOrder = inOrder(staticMockMarker(BatterySaverUtils.class)); + inOrder.verify(() -> BatterySaverUtils.setPowerSaveMode(getContext(), true, true)); + inOrder.verify(() -> BatterySaverUtils.setPowerSaveMode(getContext(), false, true)); + } + + @Test + public void testSaveViewReferenceWhenSettingPowerSaveMode() { + mBatteryController.setPowerSaveMode(false, mView); + + Assert.assertNull(mBatteryController.getLastPowerSaverStartView()); + + mBatteryController.setPowerSaveMode(true, mView); + + Assert.assertSame(mView, mBatteryController.getLastPowerSaverStartView().get()); + } + + @Test + public void testClearViewReference() { + mBatteryController.setPowerSaveMode(true, mView); + mBatteryController.clearLastPowerSaverStartView(); + + Assert.assertNull(mBatteryController.getLastPowerSaverStartView()); + } + + @Test + public void testBatteryEstimateFetch_doesNotThrow() throws IllegalStateException { + mBatteryController.getEstimatedTimeRemainingString( + (String estimate) -> { + // don't care about the result + }); + TestableLooper.get(this).processAllMessages(); + // Should not throw an exception + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java index b8f66fc41f04..3dfc94bcd5b6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java @@ -292,8 +292,9 @@ public class ThemeOverlayControllerTest extends SysuiTestCase { USER_SYSTEM); ArgumentCaptor<String> updatedSetting = ArgumentCaptor.forClass(String.class); - verify(mSecureSettings).putString( - eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), updatedSetting.capture()); + verify(mSecureSettings).putStringForUser( + eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), updatedSetting.capture(), + anyInt()); assertThat(updatedSetting.getValue().contains("android.theme.customization.accent_color")) .isFalse(); @@ -330,8 +331,9 @@ public class ThemeOverlayControllerTest extends SysuiTestCase { USER_SYSTEM); ArgumentCaptor<String> updatedSetting = ArgumentCaptor.forClass(String.class); - verify(mSecureSettings).putString( - eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), updatedSetting.capture()); + verify(mSecureSettings).putStringForUser( + eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), updatedSetting.capture(), + anyInt()); assertThat(updatedSetting.getValue().contains( "android.theme.customization.color_both\":\"0")).isTrue(); @@ -396,8 +398,9 @@ public class ThemeOverlayControllerTest extends SysuiTestCase { WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK, USER_SYSTEM); ArgumentCaptor<String> updatedSetting = ArgumentCaptor.forClass(String.class); - verify(mSecureSettings).putString( - eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), updatedSetting.capture()); + verify(mSecureSettings).putStringForUser( + eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), updatedSetting.capture(), + anyInt()); assertThat(updatedSetting.getValue().contains( "android.theme.customization.color_both\":\"1")).isTrue(); @@ -426,8 +429,9 @@ public class ThemeOverlayControllerTest extends SysuiTestCase { USER_SYSTEM); ArgumentCaptor<String> updatedSetting = ArgumentCaptor.forClass(String.class); - verify(mSecureSettings).putString( - eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), updatedSetting.capture()); + verify(mSecureSettings).putStringForUser( + eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), updatedSetting.capture(), + anyInt()); assertThat(updatedSetting.getValue().contains( "android.theme.customization.color_source\":\"lock_wallpaper")).isTrue(); assertThat(updatedSetting.getValue().contains("android.theme.customization.color_index")) @@ -456,8 +460,9 @@ public class ThemeOverlayControllerTest extends SysuiTestCase { USER_SYSTEM); ArgumentCaptor<String> updatedSetting = ArgumentCaptor.forClass(String.class); - verify(mSecureSettings).putString( - eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), updatedSetting.capture()); + verify(mSecureSettings).putStringForUser( + eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), updatedSetting.capture(), + anyInt()); assertThat(updatedSetting.getValue().contains( "android.theme.customization.color_source\":\"home_wallpaper")).isTrue(); assertThat(updatedSetting.getValue().contains("android.theme.customization.color_index")) @@ -491,8 +496,9 @@ public class ThemeOverlayControllerTest extends SysuiTestCase { USER_SYSTEM); ArgumentCaptor<String> updatedSetting = ArgumentCaptor.forClass(String.class); - verify(mSecureSettings).putString( - eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), updatedSetting.capture()); + verify(mSecureSettings).putStringForUser( + eq(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES), updatedSetting.capture(), + anyInt()); verify(mThemeOverlayApplier) .applyCurrentUserOverlays(any(), any(), anyInt(), any()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/settings/FakeSettings.java b/packages/SystemUI/tests/src/com/android/systemui/util/settings/FakeSettings.java index e66491e4cbd1..e660e1f2d845 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/settings/FakeSettings.java +++ b/packages/SystemUI/tests/src/com/android/systemui/util/settings/FakeSettings.java @@ -16,6 +16,7 @@ package com.android.systemui.util.settings; +import android.annotation.UserIdInt; import android.content.ContentResolver; import android.database.ContentObserver; import android.net.Uri; @@ -34,6 +35,8 @@ public class FakeSettings implements SecureSettings, GlobalSettings, SystemSetti private final Map<String, List<ContentObserver>> mContentObserversAllUsers = new HashMap<>(); public static final Uri CONTENT_URI = Uri.parse("content://settings/fake"); + @UserIdInt + private int mUserId = UserHandle.USER_CURRENT; public FakeSettings() { } @@ -85,9 +88,13 @@ public class FakeSettings implements SecureSettings, GlobalSettings, SystemSetti return Uri.withAppendedPath(CONTENT_URI, name); } + public void setUserId(@UserIdInt int userId) { + mUserId = userId; + } + @Override public int getUserId() { - return UserHandle.USER_CURRENT; + return mUserId; } @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java index 50c1e73f6aac..9ca4db4c1843 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java +++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeBatteryController.java @@ -16,6 +16,7 @@ package com.android.systemui.utils.leaks; import android.os.Bundle; import android.testing.LeakCheck; +import android.view.View; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback; @@ -47,6 +48,11 @@ public class FakeBatteryController extends BaseLeakChecker<BatteryStateChangeCal } @Override + public void setPowerSaveMode(boolean powerSave, View view) { + + } + + @Override public boolean isPluggedIn() { return false; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java index 40657fb61412..ce7924a2a4a2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java @@ -807,7 +807,7 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase { assertTrue(mBubbleController.hasBubbles()); // Removes the notification - mEntryListener.onEntryRemoved(mRow, 0); + mEntryListener.onEntryRemoved(mRow, REASON_APP_CANCEL); assertFalse(mBubbleController.hasBubbles()); } @@ -938,7 +938,7 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase { mBubblesManager.handleDismissalInterception(groupSummary.getEntry()); // WHEN the summary is cancelled by the app - mEntryListener.onEntryRemoved(groupSummary.getEntry(), 0); + mEntryListener.onEntryRemoved(groupSummary.getEntry(), REASON_APP_CANCEL); // THEN the summary and its children are removed from bubble data assertFalse(mBubbleData.hasBubbleInStackWithKey(groupedBubble.getEntry().getKey())); diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java index 62ba0c821f4e..b263fb377e82 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java @@ -40,6 +40,8 @@ import android.provider.Settings; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; +import android.util.SparseIntArray; +import android.util.SparseLongArray; import android.view.accessibility.MagnificationAnimationCallback; import com.android.internal.accessibility.util.AccessibilityStatsLogUtils; @@ -97,20 +99,22 @@ public class MagnificationController implements WindowMagnificationManager.Callb private final boolean mSupportWindowMagnification; @GuardedBy("mLock") - private int mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_NONE; + private final SparseIntArray mCurrentMagnificationModeArray = new SparseIntArray(); @GuardedBy("mLock") - private int mLastActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN; + private final SparseIntArray mLastMagnificationActivatedModeArray = new SparseIntArray(); // Track the active user to reset the magnification and get the associated user settings. private @UserIdInt int mUserId = UserHandle.USER_SYSTEM; @GuardedBy("mLock") private final SparseBooleanArray mIsImeVisibleArray = new SparseBooleanArray(); - private long mWindowModeEnabledTime = 0; - private long mFullScreenModeEnabledTime = 0; + @GuardedBy("mLock") + private final SparseLongArray mWindowModeEnabledTimeArray = new SparseLongArray(); + @GuardedBy("mLock") + private final SparseLongArray mFullScreenModeEnabledTimeArray = new SparseLongArray(); @GuardedBy("mLock") - @Nullable - private WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks - mAccessibilityCallbacksDelegate; + private final SparseArray<WindowManagerInternal.AccessibilityControllerInternal + .UiChangesForAccessibilityCallbacks> mAccessibilityCallbacksDelegateArray = + new SparseArray<>(); /** * A callback to inform the magnification transition result on the given display. @@ -333,20 +337,20 @@ public class MagnificationController implements WindowMagnificationManager.Callb } @GuardedBy("mLock") - private void setActivatedModeAndSwitchDelegate(int mode) { - mActivatedMode = mode; - assignMagnificationWindowManagerDelegateByMode(mode); + private void setCurrentMagnificationModeAndSwitchDelegate(int displayId, int mode) { + mCurrentMagnificationModeArray.put(displayId, mode); + assignMagnificationWindowManagerDelegateByMode(displayId, mode); } - private void assignMagnificationWindowManagerDelegateByMode(int mode) { - synchronized (mLock) { - if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) { - mAccessibilityCallbacksDelegate = getFullScreenMagnificationController(); - } else if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) { - mAccessibilityCallbacksDelegate = getWindowMagnificationMgr(); - } else { - mAccessibilityCallbacksDelegate = null; - } + @GuardedBy("mLock") + private void assignMagnificationWindowManagerDelegateByMode(int displayId, int mode) { + if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) { + mAccessibilityCallbacksDelegateArray.put(displayId, + getFullScreenMagnificationController()); + } else if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) { + mAccessibilityCallbacksDelegateArray.put(displayId, getWindowMagnificationMgr()); + } else { + mAccessibilityCallbacksDelegateArray.delete(displayId); } } @@ -356,7 +360,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks delegate; synchronized (mLock) { - delegate = mAccessibilityCallbacksDelegate; + delegate = mAccessibilityCallbacksDelegateArray.get(displayId); } if (delegate != null) { delegate.onRectangleOnScreenRequested(displayId, left, top, right, bottom); @@ -378,25 +382,26 @@ public class MagnificationController implements WindowMagnificationManager.Callb } } - // TODO : supporting multi-display (b/182227245). @Override public void onWindowMagnificationActivationState(int displayId, boolean activated) { if (activated) { - mWindowModeEnabledTime = SystemClock.uptimeMillis(); - synchronized (mLock) { - setActivatedModeAndSwitchDelegate(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW); - mLastActivatedMode = mActivatedMode; + mWindowModeEnabledTimeArray.put(displayId, SystemClock.uptimeMillis()); + setCurrentMagnificationModeAndSwitchDelegate(displayId, + ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW); + mLastMagnificationActivatedModeArray.put(displayId, + ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW); } logMagnificationModeWithImeOnIfNeeded(displayId); disableFullScreenMagnificationIfNeeded(displayId); } else { - logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW, - SystemClock.uptimeMillis() - mWindowModeEnabledTime); - + long duration; synchronized (mLock) { - setActivatedModeAndSwitchDelegate(ACCESSIBILITY_MAGNIFICATION_MODE_NONE); + setCurrentMagnificationModeAndSwitchDelegate(displayId, + ACCESSIBILITY_MAGNIFICATION_MODE_NONE); + duration = SystemClock.uptimeMillis() - mWindowModeEnabledTimeArray.get(displayId); } + logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW, duration); } updateMagnificationButton(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW); } @@ -437,21 +442,24 @@ public class MagnificationController implements WindowMagnificationManager.Callb @Override public void onFullScreenMagnificationActivationState(int displayId, boolean activated) { if (activated) { - mFullScreenModeEnabledTime = SystemClock.uptimeMillis(); - synchronized (mLock) { - setActivatedModeAndSwitchDelegate(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); - mLastActivatedMode = mActivatedMode; + mFullScreenModeEnabledTimeArray.put(displayId, SystemClock.uptimeMillis()); + setCurrentMagnificationModeAndSwitchDelegate(displayId, + ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); + mLastMagnificationActivatedModeArray.put(displayId, + ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); } logMagnificationModeWithImeOnIfNeeded(displayId); disableWindowMagnificationIfNeeded(displayId); } else { - logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN, - SystemClock.uptimeMillis() - mFullScreenModeEnabledTime); - + long duration; synchronized (mLock) { - setActivatedModeAndSwitchDelegate(ACCESSIBILITY_MAGNIFICATION_MODE_NONE); + setCurrentMagnificationModeAndSwitchDelegate(displayId, + ACCESSIBILITY_MAGNIFICATION_MODE_NONE); + duration = SystemClock.uptimeMillis() + - mFullScreenModeEnabledTimeArray.get(displayId); } + logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN, duration); } updateMagnificationButton(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); } @@ -477,9 +485,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb * Returns the last activated magnification mode. If there is no activated magnifier before, it * returns fullscreen mode by default. */ - public int getLastActivatedMode() { + public int getLastMagnificationActivatedMode(int displayId) { synchronized (mLock) { - return mLastActivatedMode; + return mLastMagnificationActivatedModeArray.get(displayId, + ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); } } @@ -522,7 +531,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb synchronized (mLock) { fullMagnificationController = mFullScreenMagnificationController; windowMagnificationManager = mWindowMagnificationMgr; - mLastActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN; + mAccessibilityCallbacksDelegateArray.clear(); + mCurrentMagnificationModeArray.clear(); + mLastMagnificationActivatedModeArray.clear(); + mIsImeVisibleArray.clear(); } mScaleProvider.onUserChanged(userId); @@ -547,6 +559,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb if (mWindowMagnificationMgr != null) { mWindowMagnificationMgr.onDisplayRemoved(displayId); } + mAccessibilityCallbacksDelegateArray.delete(displayId); + mCurrentMagnificationModeArray.delete(displayId); + mLastMagnificationActivatedModeArray.delete(displayId); + mIsImeVisibleArray.delete(displayId); } mScaleProvider.onDisplayRemoved(displayId); } @@ -587,16 +603,17 @@ public class MagnificationController implements WindowMagnificationManager.Callb } private void logMagnificationModeWithImeOnIfNeeded(int displayId) { - final int mode; + final int currentActivateMode; synchronized (mLock) { + currentActivateMode = mCurrentMagnificationModeArray.get(displayId, + ACCESSIBILITY_MAGNIFICATION_MODE_NONE); if (!mIsImeVisibleArray.get(displayId, false) - || mActivatedMode == ACCESSIBILITY_MAGNIFICATION_MODE_NONE) { + || currentActivateMode == ACCESSIBILITY_MAGNIFICATION_MODE_NONE) { return; } - mode = mActivatedMode; } - logMagnificationModeWithIme(mode); + logMagnificationModeWithIme(currentActivateMode); } /** diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java index 3e07b095fd29..a356ae6799d7 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java @@ -341,7 +341,8 @@ public class MagnificationProcessor { ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN)) { return MAGNIFICATION_MODE_FULLSCREEN; } else { - return (mController.getLastActivatedMode() == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) + return (mController.getLastMagnificationActivatedMode(displayId) + == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) ? MAGNIFICATION_MODE_WINDOW : MAGNIFICATION_MODE_FULLSCREEN; } diff --git a/services/backup/backuplib/java/com/android/server/backup/transport/BackupTransportClient.java b/services/backup/backuplib/java/com/android/server/backup/transport/BackupTransportClient.java index 7e3ede15aa04..d75d6484bec3 100644 --- a/services/backup/backuplib/java/com/android/server/backup/transport/BackupTransportClient.java +++ b/services/backup/backuplib/java/com/android/server/backup/transport/BackupTransportClient.java @@ -34,6 +34,7 @@ import java.util.HashSet; import java.util.List; import java.util.Queue; import java.util.Set; +import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -374,7 +375,8 @@ public class BackupTransportClient { private <T> T getFutureResult(AndroidFuture<T> future) { try { return future.get(600, TimeUnit.SECONDS); - } catch (InterruptedException | ExecutionException | TimeoutException e) { + } catch (InterruptedException | ExecutionException | TimeoutException + | CancellationException e) { Slog.w(TAG, "Failed to get result from transport:", e); return null; } finally { @@ -403,7 +405,11 @@ public class BackupTransportClient { void cancelActiveFutures() { synchronized (mActiveFuturesLock) { for (AndroidFuture<?> future : mActiveFutures) { - future.cancel(true); + try { + future.cancel(true); + } catch (CancellationException ignored) { + // This is expected, so ignore the exception. + } } mActiveFutures.clear(); } diff --git a/services/core/Android.bp b/services/core/Android.bp index 5406f711b73d..89c8ca567dd9 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -120,7 +120,6 @@ java_library_static { "java/com/android/server/am/EventLogTags.logtags", "java/com/android/server/wm/EventLogTags.logtags", "java/com/android/server/policy/EventLogTags.logtags", - ":services.connectivity-tiramisu-sources", ], libs: [ @@ -174,9 +173,6 @@ java_library_static { "overlayable_policy_aidl-java", "SurfaceFlingerProperties", "com.android.sysprop.watchdog", - // This is used for services.connectivity-tiramisu-sources. - // TODO: delete when NetworkStatsService is moved to the mainline module. - "net-utils-device-common-bpf", ], javac_shard_size: 50, } diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java index f34c5062144e..06f698efde2b 100644 --- a/services/core/java/android/content/pm/PackageManagerInternal.java +++ b/services/core/java/android/content/pm/PackageManagerInternal.java @@ -1208,6 +1208,11 @@ public abstract class PackageManagerInternal { public abstract SharedUserApi getSharedUserApi(int sharedUserAppId); /** + * Returns if the given uid is privileged or not. + */ + public abstract boolean isUidPrivileged(int uid); + + /** * Initiates a package state mutation request, returning the current state as known by * PackageManager. This allows the later commit request to compare the initial values and * determine if any state was changed or any packages were updated since the whole request diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index e6bf109ff84c..7ab3008585ce 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -2132,15 +2132,19 @@ class StorageManagerService extends IStorageManager.Stub } } - PackageMonitor monitor = new PackageMonitor() { + if (mPackageMonitorsForUser.get(userId) == null) { + PackageMonitor monitor = new PackageMonitor() { @Override public void onPackageRemoved(String packageName, int uid) { updateLegacyStorageApps(packageName, uid, false); } }; - // TODO(b/149391976): Use different handler? - monitor.register(mContext, user, true, mHandler); - mPackageMonitorsForUser.put(userId, monitor); + // TODO(b/149391976): Use different handler? + monitor.register(mContext, user, true, mHandler); + mPackageMonitorsForUser.put(userId, monitor); + } else { + Slog.w(TAG, "PackageMonitor is already registered for: " + userId); + } } private static long getLastAccessTime(AppOpsManager manager, diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index e6b7a4c287cd..b059cc7e2aa2 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -2977,19 +2977,21 @@ public class AccountManagerService * outside of those expected to be injected by the AccountManager, e.g. * ANDORID_PACKAGE_NAME. */ - String token = readCachedTokenInternal( + TokenCache.Value cachedToken = readCachedTokenInternal( accounts, account, authTokenType, callerPkg, callerPkgSigDigest); - if (token != null) { + if (cachedToken != null) { logGetAuthTokenMetrics(callerPkg, account.type); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "getAuthToken: cache hit ofr custom token authenticator."); } Bundle result = new Bundle(); - result.putString(AccountManager.KEY_AUTHTOKEN, token); + result.putString(AccountManager.KEY_AUTHTOKEN, cachedToken.token); + result.putLong(AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY, + cachedToken.expiryEpochMillis); result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type); onResult(response, result); @@ -6121,7 +6123,7 @@ public class AccountManagerService } } - protected String readCachedTokenInternal( + protected TokenCache.Value readCachedTokenInternal( UserAccounts accounts, Account account, String tokenType, diff --git a/services/core/java/com/android/server/accounts/TokenCache.java b/services/core/java/com/android/server/accounts/TokenCache.java index 66e550fe3c4c..9427ee41cfdc 100644 --- a/services/core/java/com/android/server/accounts/TokenCache.java +++ b/services/core/java/com/android/server/accounts/TokenCache.java @@ -20,8 +20,6 @@ import android.accounts.Account; import android.util.LruCache; import android.util.Pair; -import com.android.internal.util.Preconditions; - import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -35,7 +33,8 @@ import java.util.Objects; private static final int MAX_CACHE_CHARS = 64000; - private static class Value { + /** Package private*/ + static class Value { public final String token; public final long expiryEpochMillis; @@ -217,12 +216,12 @@ import java.util.Objects; /** * Gets a token from the cache if possible. */ - public String get(Account account, String tokenType, String packageName, byte[] sigDigest) { + public Value get(Account account, String tokenType, String packageName, byte[] sigDigest) { Key k = new Key(account, tokenType, packageName, sigDigest); Value v = mCachedTokens.get(k); long currentTime = System.currentTimeMillis(); if (v != null && currentTime < v.expiryEpochMillis) { - return v.token; + return v; } else if (v != null) { remove(account.type, v.token); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 07c281864c9c..0da14bc2a96a 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -310,7 +310,6 @@ import android.sysprop.InitProperties; import android.sysprop.VoldProperties; import android.telephony.TelephonyManager; import android.text.TextUtils; -import android.text.format.DateUtils; import android.text.style.SuggestionSpan; import android.util.ArrayMap; import android.util.ArraySet; @@ -8685,7 +8684,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } - private final ArrayMap<String, long[]> mErrorClusterRecords = new ArrayMap<>(); + private final DropboxRateLimiter mDropboxRateLimiter = new DropboxRateLimiter(); /** * Write a description of an error (crash, WTF, ANR) to the drop box. @@ -8720,22 +8719,8 @@ public class ActivityManagerService extends IActivityManager.Stub final String dropboxTag = processClass(process) + "_" + eventType; if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; - // Rate-limit how often we're willing to do the heavy lifting below to - // collect and record logs; currently 5 logs per 10 second period per eventType. - final long now = SystemClock.elapsedRealtime(); - synchronized (mErrorClusterRecords) { - long[] errRecord = mErrorClusterRecords.get(eventType); - if (errRecord == null) { - errRecord = new long[2]; // [0]: startTime, [1]: count - mErrorClusterRecords.put(eventType, errRecord); - } - if (now - errRecord[0] > 10 * DateUtils.SECOND_IN_MILLIS) { - errRecord[0] = now; - errRecord[1] = 1L; - } else { - if (errRecord[1]++ >= 5) return; - } - } + // Check if we should rate limit and abort early if needed. + if (mDropboxRateLimiter.shouldRateLimit(eventType, processName)) return; final StringBuilder sb = new StringBuilder(1024); appendDropBoxProcessHeaders(process, processName, sb); diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java index 032b129c4256..64ff532b026a 100644 --- a/services/core/java/com/android/server/am/AppBatteryTracker.java +++ b/services/core/java/com/android/server/am/AppBatteryTracker.java @@ -49,6 +49,7 @@ import android.content.Context; import android.content.pm.ServiceInfo; import android.content.res.Resources; import android.content.res.TypedArray; +import android.os.AppBackgroundRestrictionsInfo; import android.os.AppBatteryStatsProto; import android.os.BatteryConsumer; import android.os.BatteryConsumer.Dimensions; @@ -74,6 +75,7 @@ import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; +import com.android.internal.util.FrameworkStatsLog; import com.android.server.am.AppBatteryTracker.AppBatteryPolicy; import com.android.server.am.AppRestrictionController.TrackerType; import com.android.server.am.AppRestrictionController.UidBatteryUsageProvider; @@ -175,6 +177,12 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> @GuardedBy("mLock") private long mLastUidBatteryUsageStartTs; + /** + * elapseRealTime of last time the AppBatteryTracker is reported to statsd. + */ + @GuardedBy("mLock") + private long mLastReportTime = 0; + // For debug only. private final SparseArray<ImmutableBatteryUsage> mDebugUidPercentages = new SparseArray<>(); @@ -228,9 +236,92 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> mBgHandler.postDelayed(mBgBatteryUsageStatsPolling, delay); } } + logAppBatteryTrackerIfNeeded(); } } + /** + * Log per-uid BatteryTrackerInfo to statsd every 24 hours (as the window specified in + * {@link AppBatteryPolicy#mBgCurrentDrainWindowMs}) + */ + private void logAppBatteryTrackerIfNeeded() { + final long now = SystemClock.elapsedRealtime(); + synchronized (mLock) { + final AppBatteryPolicy bgPolicy = mInjector.getPolicy(); + if (now - mLastReportTime < bgPolicy.mBgCurrentDrainWindowMs) { + return; + } else { + mLastReportTime = now; + } + } + updateBatteryUsageStatsIfNecessary(mInjector.currentTimeMillis(), true); + synchronized (mLock) { + for (int i = 0, size = mUidBatteryUsageInWindow.size(); i < size; i++) { + final int uid = mUidBatteryUsageInWindow.keyAt(i); + if (!UserHandle.isCore(uid) && !UserHandle.isApp(uid)) { + continue; + } + if (BATTERY_USAGE_NONE.equals(mUidBatteryUsageInWindow.valueAt(i))) { + continue; + } + 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, + 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, + isLowRamDeviceStatic()); + } + } + } + + /** + * Get the BatteryTrackerInfo proto of a UID. + * @param uid + * @return byte array of the proto. + */ + @NonNull byte[] getBatteryTrackerInfoProtoLocked(int uid) { + final ImmutableBatteryUsage temp = mUidBatteryUsageInWindow.get(uid); + if (temp == null) { + return new byte[0]; + } + final BatteryUsage bgUsage = temp.calcPercentage(uid, mInjector.getPolicy()); + final double allUsage = bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_UNSPECIFIED] + + bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_FOREGROUND] + + bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_BACKGROUND] + + bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_FOREGROUND_SERVICE] + + bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_CACHED]; + final double usageBackground = + bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_BACKGROUND]; + final double usageFgs = + bgUsage.mPercentage[BatteryUsage.BATTERY_USAGE_INDEX_FOREGROUND_SERVICE]; + Slog.d(TAG, "getBatteryTrackerInfoProtoLocked uid:" + uid + + " allUsage:" + String.format("%4.2f%%", allUsage) + + " usageBackground:" + String.format("%4.2f%%", usageBackground) + + " usageFgs:" + String.format("%4.2f%%", usageFgs)); + final ProtoOutputStream proto = new ProtoOutputStream(); + proto.write(AppBackgroundRestrictionsInfo.BatteryTrackerInfo.BATTERY_24H, + allUsage * 10000); + proto.write(AppBackgroundRestrictionsInfo.BatteryTrackerInfo.BATTERY_USAGE_BACKGROUND, + usageBackground * 10000); + proto.write(AppBackgroundRestrictionsInfo.BatteryTrackerInfo.BATTERY_USAGE_FGS, + usageFgs * 10000); + proto.flush(); + return proto.getBytes(); + } + @Override void onUserStarted(final @UserIdInt int userId) { synchronized (mLock) { diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java index 6f7435943d45..798647e04325 100644 --- a/services/core/java/com/android/server/am/AppRestrictionController.java +++ b/services/core/java/com/android/server/am/AppRestrictionController.java @@ -2292,9 +2292,10 @@ public final class AppRestrictionController { void postRequestBgRestrictedIfNecessary(String packageName, int uid) { 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); final PendingIntent pendingIntent = PendingIntent.getActivityAsUser(mContext, 0, - intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE, null, + intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE, null, UserHandle.of(UserHandle.getUserId(uid))); Notification.Action[] actions = null; final boolean hasForegroundServices = @@ -2350,13 +2351,14 @@ public final class AppRestrictionController { intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); // Task manager runs in SystemUI, which is SYSTEM user only. pendingIntent = PendingIntent.getBroadcastAsUser(mContext, 0, - intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE, + intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE, UserHandle.SYSTEM); } 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); pendingIntent = PendingIntent.getActivityAsUser(mContext, 0, - intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE, + intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE, null, UserHandle.of(UserHandle.getUserId(uid))); } diff --git a/services/core/java/com/android/server/am/BroadcastDispatcher.java b/services/core/java/com/android/server/am/BroadcastDispatcher.java index 01d8109a82a0..872531a47bc9 100644 --- a/services/core/java/com/android/server/am/BroadcastDispatcher.java +++ b/services/core/java/com/android/server/am/BroadcastDispatcher.java @@ -580,6 +580,11 @@ public class BroadcastDispatcher { // ---------------------------------- // BroadcastQueue operation support void enqueueOrderedBroadcastLocked(BroadcastRecord r) { + if (r.receivers == null || r.receivers.isEmpty()) { + mOrderedBroadcasts.add(r); + return; + } + if (Intent.ACTION_LOCKED_BOOT_COMPLETED.equals(r.intent.getAction())) { // Create one BroadcastRecord for each UID that can be deferred. final SparseArray<BroadcastRecord> deferred = diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java index 2ee32b6abe96..5343af25fd39 100644 --- a/services/core/java/com/android/server/am/BroadcastRecord.java +++ b/services/core/java/com/android/server/am/BroadcastRecord.java @@ -414,6 +414,10 @@ final class BroadcastRecord extends Binder { return ret; } + if (receivers == null) { + return ret; + } + final String action = intent.getAction(); if (!Intent.ACTION_LOCKED_BOOT_COMPLETED.equals(action) && !Intent.ACTION_BOOT_COMPLETED.equals(action)) { diff --git a/services/core/java/com/android/server/am/DropboxRateLimiter.java b/services/core/java/com/android/server/am/DropboxRateLimiter.java new file mode 100644 index 000000000000..c51702359a6b --- /dev/null +++ b/services/core/java/com/android/server/am/DropboxRateLimiter.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.am; + +import android.os.SystemClock; +import android.text.format.DateUtils; +import android.util.ArrayMap; + +import com.android.internal.annotations.GuardedBy; + +/** Rate limiter for adding errors into dropbox. */ +public class DropboxRateLimiter { + private static final long RATE_LIMIT_BUFFER_EXPIRY = 15 * DateUtils.SECOND_IN_MILLIS; + private static final long RATE_LIMIT_BUFFER_DURATION = 10 * DateUtils.SECOND_IN_MILLIS; + private static final int RATE_LIMIT_ALLOWED_ENTRIES = 5; + + @GuardedBy("mErrorClusterRecords") + private final ArrayMap<String, ErrorRecord> mErrorClusterRecords = new ArrayMap<>(); + private final Clock mClock; + + private long mLastMapCleanUp = 0L; + + public DropboxRateLimiter() { + this(new DefaultClock()); + } + + public DropboxRateLimiter(Clock clock) { + mClock = clock; + } + + /** The interface clock to use for tracking the time elapsed. */ + public interface Clock { + /** How long in millis has passed since the device came online. */ + long uptimeMillis(); + } + + /** Determines whether dropbox entries of a specific tag and process should be rate limited. */ + public boolean shouldRateLimit(String eventType, String processName) { + // Rate-limit how often we're willing to do the heavy lifting to collect and record logs. + final long now = mClock.uptimeMillis(); + synchronized (mErrorClusterRecords) { + // Remove expired records if enough time has passed since the last cleanup. + maybeRemoveExpiredRecords(now); + + ErrorRecord errRecord = mErrorClusterRecords.get(errorKey(eventType, processName)); + if (errRecord == null) { + errRecord = new ErrorRecord(now, 1); + mErrorClusterRecords.put(errorKey(eventType, processName), errRecord); + } else if (now - errRecord.getStartTime() > RATE_LIMIT_BUFFER_DURATION) { + errRecord.setStartTime(now); + errRecord.setCount(1); + } else { + errRecord.incrementCount(); + if (errRecord.getCount() > RATE_LIMIT_ALLOWED_ENTRIES) return true; + } + } + return false; + } + + private void maybeRemoveExpiredRecords(long now) { + if (now - mLastMapCleanUp <= RATE_LIMIT_BUFFER_EXPIRY) return; + + for (int i = mErrorClusterRecords.size() - 1; i >= 0; i--) { + if (now - mErrorClusterRecords.valueAt(i).getStartTime() > RATE_LIMIT_BUFFER_EXPIRY) { + mErrorClusterRecords.removeAt(i); + } + } + + mLastMapCleanUp = now; + } + + String errorKey(String eventType, String processName) { + return eventType + processName; + } + + private class ErrorRecord { + long mStartTime; + int mCount; + + ErrorRecord(long startTime, int count) { + mStartTime = startTime; + mCount = count; + } + + public void setStartTime(long startTime) { + mStartTime = startTime; + } + + public void setCount(int count) { + mCount = count; + } + + public void incrementCount() { + mCount++; + } + + public long getStartTime() { + return mStartTime; + } + + public int getCount() { + return mCount; + } + } + + private static class DefaultClock implements Clock { + public long uptimeMillis() { + return SystemClock.uptimeMillis(); + } + } +} diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java index d22a562651dc..04fcda7835fa 100644 --- a/services/core/java/com/android/server/audio/SpatializerHelper.java +++ b/services/core/java/com/android/server/audio/SpatializerHelper.java @@ -327,15 +327,29 @@ public class SpatializerHelper { setDispatchAvailableState(false); } - if (able && enabledAvailable.first) { + boolean enabled = able && enabledAvailable.first; + if (enabled) { loglogi("Enabling Spatial Audio since enabled for media device:" + ROUTING_DEVICES[0]); } else { loglogi("Disabling Spatial Audio since disabled for media device:" + ROUTING_DEVICES[0]); } - setDispatchFeatureEnabledState(able && enabledAvailable.first, - "onRoutingUpdated"); + if (mSpat != null) { + byte level = enabled ? (byte) Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL + : (byte) Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE; + loglogi("Setting spatialization level to: " + level); + try { + mSpat.setLevel(level); + } catch (RemoteException e) { + Log.e(TAG, "Can't set spatializer level", e); + mState = STATE_NOT_SUPPORTED; + mCapableSpatLevel = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE; + enabled = false; + } + } + + setDispatchFeatureEnabledState(enabled, "onRoutingUpdated"); if (mDesiredHeadTrackingMode != Spatializer.HEAD_TRACKING_MODE_UNSUPPORTED && mDesiredHeadTrackingMode != Spatializer.HEAD_TRACKING_MODE_DISABLED) { @@ -635,7 +649,6 @@ public class SpatializerHelper { init(true); } setSpatializerEnabledInt(true); - onRoutingUpdated(); } else { setSpatializerEnabledInt(false); } @@ -657,6 +670,7 @@ public class SpatializerHelper { case STATE_DISABLED_AVAILABLE: if (enabled) { createSpat(); + onRoutingUpdated(); break; } else { // already in disabled state @@ -823,14 +837,13 @@ public class SpatializerHelper { mSpatHeadTrackingCallback = new SpatializerHeadTrackingCallback(); mSpat = AudioSystem.getSpatializer(mSpatCallback); try { - mSpat.setLevel((byte) Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL); mIsHeadTrackingSupported = mSpat.isHeadTrackingSupported(); //TODO: register heatracking callback only when sensors are registered if (mIsHeadTrackingSupported) { mSpat.registerHeadTrackingCallback(mSpatHeadTrackingCallback); } } catch (RemoteException e) { - Log.e(TAG, "Can't set spatializer level", e); + Log.e(TAG, "Can't configure head tracking", e); mState = STATE_NOT_SUPPORTED; mCapableSpatLevel = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE; } diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 35217dba7c28..4c9b28b1bd18 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -2313,6 +2313,13 @@ public class Vpn { "usepeerdns", "idle", "1800", "mtu", "1270", "mru", "1270", (profile.mppe ? "+mppe" : "nomppe"), }; + if (profile.mppe) { + // Disallow PAP authentication when MPPE is requested, as MPPE cannot work + // with PAP anyway, and users may not expect PAP (plain text) to be used when + // MPPE was requested. + mtpd = Arrays.copyOf(mtpd, mtpd.length + 1); + mtpd[mtpd.length - 1] = "-pap"; + } break; case VpnProfile.TYPE_L2TP_IPSEC_PSK: case VpnProfile.TYPE_L2TP_IPSEC_RSA: diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 5a105f551ab2..5fcdc8a08b5d 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -70,6 +70,8 @@ import android.hardware.display.DisplayManagerGlobal; import android.hardware.display.DisplayManagerInternal; import android.hardware.display.DisplayManagerInternal.DisplayGroupListener; import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener; +import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation; +import android.hardware.display.DisplayManagerInternal.RefreshRateRange; import android.hardware.display.DisplayViewport; import android.hardware.display.DisplayedContentSample; import android.hardware.display.DisplayedContentSamplingAttributes; @@ -708,9 +710,6 @@ public final class DisplayManagerService extends SystemService { synchronized (mSyncRoot) { final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); if (display != null) { - // Do not let constrain be overwritten by override from WindowManager. - info.shouldConstrainMetricsForLauncher = - display.getDisplayInfoLocked().shouldConstrainMetricsForLauncher; if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) { handleLogicalDisplayChangedLocked(display); } @@ -2212,21 +2211,6 @@ public final class DisplayManagerService extends SystemService { } } - void setShouldConstrainMetricsForLauncher(boolean constrain) { - // Apply constrain for every display. - synchronized (mSyncRoot) { - int[] displayIds = mLogicalDisplayMapper.getDisplayIdsLocked(Process.myUid()); - for (int i : displayIds) { - final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(i); - if (display == null) { - return; - } - display.getDisplayInfoLocked().shouldConstrainMetricsForLauncher = constrain; - setDisplayInfoOverrideFromWindowManagerInternal(i, display.getDisplayInfoLocked()); - } - } - } - void setDockedAndIdleEnabled(boolean enabled, int displayId) { synchronized (mSyncRoot) { final DisplayPowerController displayPowerController = mDisplayPowerControllers.get( diff --git a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java index bfdac5781b75..7dce2380407e 100644 --- a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java +++ b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java @@ -60,8 +60,6 @@ class DisplayManagerShellCommand extends ShellCommand { return setDisplayModeDirectorLoggingEnabled(false); case "dwb-set-cct": return setAmbientColorTemperatureOverride(); - case "constrain-launcher-metrics": - return setConstrainLauncherMetrics(); case "set-user-preferred-display-mode": return setUserPreferredDisplayMode(); case "clear-user-preferred-display-mode": @@ -112,9 +110,6 @@ class DisplayManagerShellCommand extends ShellCommand { pw.println(" Disable display mode director logging."); pw.println(" dwb-set-cct CCT"); pw.println(" Sets the ambient color temperature override to CCT (use -1 to disable)."); - pw.println(" constrain-launcher-metrics [true|false]"); - pw.println(" Sets if Display#getRealSize and getRealMetrics should be constrained for "); - pw.println(" Launcher."); pw.println(" set-user-preferred-display-mode WIDTH HEIGHT REFRESH-RATE " + "DISPLAY_ID (optional)"); pw.println(" Sets the user preferred display mode which has fields WIDTH, HEIGHT and " @@ -205,17 +200,6 @@ class DisplayManagerShellCommand extends ShellCommand { return 0; } - private int setConstrainLauncherMetrics() { - String constrainText = getNextArg(); - if (constrainText == null) { - getErrPrintWriter().println("Error: no value specified"); - return 1; - } - boolean constrain = Boolean.parseBoolean(constrainText); - mService.setShouldConstrainMetricsForLauncher(constrain); - return 0; - } - private int setUserPreferredDisplayMode() { final String widthText = getNextArg(); if (widthText == null) { diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index b7ad4ed4f98d..a640497d7e10 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -233,8 +233,6 @@ final class LogicalDisplay { info.displayCutout = mOverrideDisplayInfo.displayCutout; info.logicalDensityDpi = mOverrideDisplayInfo.logicalDensityDpi; info.roundedCorners = mOverrideDisplayInfo.roundedCorners; - info.shouldConstrainMetricsForLauncher = - mOverrideDisplayInfo.shouldConstrainMetricsForLauncher; } mInfo.set(info); } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java index ccb27eef2075..576a5ff4305e 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java @@ -396,7 +396,9 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { try { String iso3Language = new String(message.getParams(), 0, 3, "US-ASCII"); Locale currentLocale = mService.getContext().getResources().getConfiguration().locale; - if (currentLocale.getISO3Language().equals(iso3Language)) { + String curIso3Language = mService.localeToMenuLanguage(currentLocale); + HdmiLogger.debug("handleSetMenuLanguage " + iso3Language + " cur:" + curIso3Language); + if (curIso3Language.equals(iso3Language)) { // Do not switch language if the new language is the same as the current one. // This helps avoid accidental country variant switching from en_US to en_AU // due to the limitation of CEC. See the warning below. @@ -408,7 +410,7 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource { final List<LocaleInfo> localeInfos = LocalePicker.getAllAssetLocales( mService.getContext(), false); for (LocaleInfo localeInfo : localeInfos) { - if (localeInfo.getLocale().getISO3Language().equals(iso3Language)) { + if (mService.localeToMenuLanguage(localeInfo.getLocale()).equals(iso3Language)) { // WARNING: CEC adopts ISO/FDIS-2 for language code, while Android requires // additional country variant to pinpoint the locale. This keeps the right // locale from being chosen. 'eng' in the CEC command, for instance, diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 385aa698543d..603d0128cc44 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -74,7 +74,6 @@ import android.os.InputEventInjectionSync; import android.os.LocaleList; import android.os.Looper; import android.os.Message; -import android.os.MessageQueue; import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; @@ -112,6 +111,7 @@ import android.widget.Toast; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.SomeArgs; @@ -147,9 +147,7 @@ import java.util.Map; import java.util.Objects; import java.util.OptionalInt; -/* - * Wraps the C++ InputManager and provides its callbacks. - */ +/** The system implementation of {@link IInputManager} that manages input devices. */ public class InputManagerService extends IInputManager.Stub implements Watchdog.Monitor { static final String TAG = "InputManager"; @@ -183,8 +181,7 @@ public class InputManagerService extends IInputManager.Stub /** TODO(b/169067926): Remove this. */ private static final boolean UNTRUSTED_TOUCHES_TOAST = false; - // Pointer to native input manager service object. - private final long mPtr; + private final NativeInputManagerService mNative; private final Context mContext; private final InputManagerHandler mHandler; @@ -299,91 +296,6 @@ public class InputManagerService extends IInputManager.Stub @GuardedBy("mInputMonitors") final Map<IBinder, GestureMonitorSpyWindow> mInputMonitors = new HashMap<>(); - private static native long nativeInit(InputManagerService service, - Context context, MessageQueue messageQueue); - private static native void nativeStart(long ptr); - private static native void nativeSetDisplayViewports(long ptr, - DisplayViewport[] viewports); - - private static native int nativeGetScanCodeState(long ptr, - int deviceId, int sourceMask, int scanCode); - private static native int nativeGetKeyCodeState(long ptr, - int deviceId, int sourceMask, int keyCode); - private static native int nativeGetSwitchState(long ptr, - int deviceId, int sourceMask, int sw); - private static native boolean nativeHasKeys(long ptr, - int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists); - private static native int nativeGetKeyCodeForKeyLocation(long ptr, int deviceId, - int locationKeyCode); - private static native InputChannel nativeCreateInputChannel(long ptr, String name); - private static native InputChannel nativeCreateInputMonitor(long ptr, int displayId, - String name, int pid); - private static native void nativeRemoveInputChannel(long ptr, IBinder connectionToken); - private static native void nativePilferPointers(long ptr, IBinder token); - private static native void nativeSetInputFilterEnabled(long ptr, boolean enable); - private static native boolean nativeSetInTouchMode(long ptr, boolean inTouchMode, int pid, - int uid, boolean hasPermission); - private static native void nativeSetMaximumObscuringOpacityForTouch(long ptr, float opacity); - private static native void nativeSetBlockUntrustedTouchesMode(long ptr, int mode); - private static native int nativeInjectInputEvent(long ptr, InputEvent event, - boolean injectIntoUid, int uid, int syncMode, int timeoutMillis, int policyFlags); - private static native VerifiedInputEvent nativeVerifyInputEvent(long ptr, InputEvent event); - private static native void nativeToggleCapsLock(long ptr, int deviceId); - private static native void nativeDisplayRemoved(long ptr, int displayId); - private static native void nativeSetInputDispatchMode(long ptr, boolean enabled, boolean frozen); - private static native void nativeSetSystemUiLightsOut(long ptr, boolean lightsOut); - private static native void nativeSetFocusedApplication(long ptr, - int displayId, InputApplicationHandle application); - private static native void nativeSetFocusedDisplay(long ptr, int displayId); - private static native boolean nativeTransferTouchFocus(long ptr, - IBinder fromChannelToken, IBinder toChannelToken, boolean isDragDrop); - private static native boolean nativeTransferTouch(long ptr, IBinder destChannelToken); - private static native void nativeSetPointerSpeed(long ptr, int speed); - private static native void nativeSetPointerAcceleration(long ptr, float acceleration); - private static native void nativeSetShowTouches(long ptr, boolean enabled); - private static native void nativeSetInteractive(long ptr, boolean interactive); - private static native void nativeReloadCalibration(long ptr); - private static native void nativeVibrate(long ptr, int deviceId, long[] pattern, - int[] amplitudes, int repeat, int token); - private static native void nativeVibrateCombined(long ptr, int deviceId, long[] pattern, - SparseArray<int[]> amplitudes, int repeat, int token); - private static native void nativeCancelVibrate(long ptr, int deviceId, int token); - private static native boolean nativeIsVibrating(long ptr, int deviceId); - private static native int[] nativeGetVibratorIds(long ptr, int deviceId); - private static native int nativeGetBatteryCapacity(long ptr, int deviceId); - private static native int nativeGetBatteryStatus(long ptr, int deviceId); - private static native List<Light> nativeGetLights(long ptr, int deviceId); - private static native int nativeGetLightPlayerId(long ptr, int deviceId, int lightId); - private static native int nativeGetLightColor(long ptr, int deviceId, int lightId); - private static native void nativeSetLightPlayerId(long ptr, int deviceId, int lightId, - int playerId); - private static native void nativeSetLightColor(long ptr, int deviceId, int lightId, int color); - private static native void nativeReloadKeyboardLayouts(long ptr); - private static native void nativeReloadDeviceAliases(long ptr); - private static native String nativeDump(long ptr); - private static native void nativeMonitor(long ptr); - private static native boolean nativeIsInputDeviceEnabled(long ptr, int deviceId); - private static native void nativeEnableInputDevice(long ptr, int deviceId); - private static native void nativeDisableInputDevice(long ptr, int deviceId); - private static native void nativeSetPointerIconType(long ptr, int iconId); - private static native void nativeReloadPointerIcons(long ptr); - private static native void nativeSetCustomPointerIcon(long ptr, PointerIcon icon); - private static native void nativeRequestPointerCapture(long ptr, IBinder windowToken, - boolean enabled); - private static native boolean nativeCanDispatchToDisplay(long ptr, int deviceId, int displayId); - private static native void nativeNotifyPortAssociationsChanged(long ptr); - private static native void nativeChangeUniqueIdAssociation(long ptr); - private static native void nativeNotifyPointerDisplayIdChanged(long ptr); - private static native void nativeSetDisplayEligibilityForPointerCapture(long ptr, int displayId, - boolean enabled); - private static native void nativeSetMotionClassifierEnabled(long ptr, boolean enabled); - private static native InputSensorInfo[] nativeGetSensorList(long ptr, int deviceId); - private static native boolean nativeFlushSensor(long ptr, int deviceId, int sensorType); - private static native boolean nativeEnableSensor(long ptr, int deviceId, int sensorType, - int samplingPeriodUs, int maxBatchReportLatencyUs); - private static native void nativeDisableSensor(long ptr, int deviceId, int sensorType); - private static native void nativeCancelCurrentTouch(long ptr); - // Maximum number of milliseconds to wait for input event injection. private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000; @@ -450,18 +362,47 @@ public class InputManagerService extends IInputManager.Stub /** Whether to use the dev/input/event or uevent subsystem for the audio jack. */ final boolean mUseDevInputEventForAudioJack; + /** Point of injection for test dependencies. */ + @VisibleForTesting + static class Injector { + private final Context mContext; + private final Looper mLooper; + + Injector(Context context, Looper looper) { + mContext = context; + mLooper = looper; + } + + Context getContext() { + return mContext; + } + + Looper getLooper() { + return mLooper; + } + + NativeInputManagerService getNativeService(InputManagerService service) { + return new NativeInputManagerService.NativeImpl(service, mContext, mLooper.getQueue()); + } + } + public InputManagerService(Context context) { - this.mContext = context; - this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper()); + this(new Injector(context, DisplayThread.get().getLooper())); + } + + @VisibleForTesting + InputManagerService(Injector injector) { + mContext = injector.getContext(); + mHandler = new InputManagerHandler(injector.getLooper()); + mNative = injector.getNativeService(this); mStaticAssociations = loadStaticInputPortAssociations(); mUseDevInputEventForAudioJack = - context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack); + mContext.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack); Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack=" + mUseDevInputEventForAudioJack); - mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue()); - String doubleTouchGestureEnablePath = context.getResources().getString( + String doubleTouchGestureEnablePath = mContext.getResources().getString( R.string.config_doubleTouchGestureEnableFile); mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null : new File(doubleTouchGestureEnablePath); @@ -504,9 +445,9 @@ public class InputManagerService extends IInputManager.Stub public void start() { Slog.i(TAG, "Starting input manager"); - nativeStart(mPtr); + mNative.start(); - // Add ourself to the Watchdog monitors. + // Add ourselves to the Watchdog monitors. Watchdog.getInstance().addMonitor(this); registerPointerSpeedSettingObserver(); @@ -599,14 +540,14 @@ public class InputManagerService extends IInputManager.Stub if (DEBUG) { Slog.d(TAG, "Reloading keyboard layouts."); } - nativeReloadKeyboardLayouts(mPtr); + mNative.reloadKeyboardLayouts(); } private void reloadDeviceAliases() { if (DEBUG) { Slog.d(TAG, "Reloading device names."); } - nativeReloadDeviceAliases(mPtr); + mNative.reloadDeviceAliases(); } private void setDisplayViewportsInternal(List<DisplayViewport> viewports) { @@ -615,7 +556,7 @@ public class InputManagerService extends IInputManager.Stub for (int i = viewports.size() - 1; i >= 0; --i) { vArray[i] = viewports.get(i); } - nativeSetDisplayViewports(mPtr, vArray); + mNative.setDisplayViewports(vArray); if (mOverriddenPointerDisplayId != Display.INVALID_DISPLAY) { final AdditionalDisplayInputProperties properties = @@ -642,7 +583,7 @@ public class InputManagerService extends IInputManager.Stub * @return The key state. */ public int getKeyCodeState(int deviceId, int sourceMask, int keyCode) { - return nativeGetKeyCodeState(mPtr, deviceId, sourceMask, keyCode); + return mNative.getKeyCodeState(deviceId, sourceMask, keyCode); } /** @@ -655,7 +596,7 @@ public class InputManagerService extends IInputManager.Stub * @return The key state. */ public int getScanCodeState(int deviceId, int sourceMask, int scanCode) { - return nativeGetScanCodeState(mPtr, deviceId, sourceMask, scanCode); + return mNative.getScanCodeState(deviceId, sourceMask, scanCode); } /** @@ -668,7 +609,7 @@ public class InputManagerService extends IInputManager.Stub * @return The switch state. */ public int getSwitchState(int deviceId, int sourceMask, int switchCode) { - return nativeGetSwitchState(mPtr, deviceId, sourceMask, switchCode); + return mNative.getSwitchState(deviceId, sourceMask, switchCode); } /** @@ -691,7 +632,7 @@ public class InputManagerService extends IInputManager.Stub throw new IllegalArgumentException("keyExists must be at least as large as keyCodes"); } - return nativeHasKeys(mPtr, deviceId, sourceMask, keyCodes, keyExists); + return mNative.hasKeys(deviceId, sourceMask, keyCodes, keyExists); } /** @@ -707,7 +648,7 @@ public class InputManagerService extends IInputManager.Stub if (locationKeyCode <= KEYCODE_UNKNOWN || locationKeyCode > KeyEvent.getMaxKeyCode()) { return KEYCODE_UNKNOWN; } - return nativeGetKeyCodeForKeyLocation(mPtr, deviceId, locationKeyCode); + return mNative.getKeyCodeForKeyLocation(deviceId, locationKeyCode); } /** @@ -720,7 +661,7 @@ public class InputManagerService extends IInputManager.Stub public boolean transferTouch(IBinder destChannelToken) { // TODO(b/162194035): Replace this with a SPY window Objects.requireNonNull(destChannelToken, "destChannelToken must not be null"); - return nativeTransferTouch(mPtr, destChannelToken); + return mNative.transferTouch(destChannelToken); } /** @@ -736,7 +677,7 @@ public class InputManagerService extends IInputManager.Stub throw new IllegalArgumentException("displayId must >= 0."); } - return nativeCreateInputMonitor(mPtr, displayId, inputChannelName, Binder.getCallingPid()); + return mNative.createInputMonitor(displayId, inputChannelName, Binder.getCallingPid()); } @NonNull @@ -818,7 +759,7 @@ public class InputManagerService extends IInputManager.Stub * @param name The name of this input channel */ public InputChannel createInputChannel(String name) { - return nativeCreateInputChannel(mPtr, name); + return mNative.createInputChannel(name); } /** @@ -827,7 +768,7 @@ public class InputManagerService extends IInputManager.Stub */ public void removeInputChannel(IBinder connectionToken) { Objects.requireNonNull(connectionToken, "connectionToken must not be null"); - nativeRemoveInputChannel(mPtr, connectionToken); + mNative.removeInputChannel(connectionToken); } /** @@ -869,7 +810,7 @@ public class InputManagerService extends IInputManager.Stub } } - nativeSetInputFilterEnabled(mPtr, filter != null); + mNative.setInputFilterEnabled(filter != null); } } @@ -893,7 +834,7 @@ public class InputManagerService extends IInputManager.Stub * @return {@code true} if the touch mode was successfully changed, {@code false} otherwise */ public boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission) { - return nativeSetInTouchMode(mPtr, inTouchMode, pid, uid, hasPermission); + return mNative.setInTouchMode(inTouchMode, pid, uid, hasPermission); } @Override // Binder call @@ -918,7 +859,7 @@ public class InputManagerService extends IInputManager.Stub final boolean injectIntoUid = targetUid != Process.INVALID_UID; final int result; try { - result = nativeInjectInputEvent(mPtr, event, injectIntoUid, + result = mNative.injectInputEvent(event, injectIntoUid, targetUid, mode, INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT); } finally { @@ -962,7 +903,7 @@ public class InputManagerService extends IInputManager.Stub @Override // Binder call public VerifiedInputEvent verifyInputEvent(InputEvent event) { Objects.requireNonNull(event, "event must not be null"); - return nativeVerifyInputEvent(mPtr, event); + return mNative.verifyInputEvent(event); } /** @@ -985,7 +926,7 @@ public class InputManagerService extends IInputManager.Stub // Binder call @Override public boolean isInputDeviceEnabled(int deviceId) { - return nativeIsInputDeviceEnabled(mPtr, deviceId); + return mNative.isInputDeviceEnabled(deviceId); } // Binder call @@ -995,7 +936,7 @@ public class InputManagerService extends IInputManager.Stub "enableInputDevice()")) { throw new SecurityException("Requires DISABLE_INPUT_DEVICE permission"); } - nativeEnableInputDevice(mPtr, deviceId); + mNative.enableInputDevice(deviceId); } // Binder call @@ -1005,7 +946,7 @@ public class InputManagerService extends IInputManager.Stub "disableInputDevice()")) { throw new SecurityException("Requires DISABLE_INPUT_DEVICE permission"); } - nativeDisableInputDevice(mPtr, deviceId); + mNative.disableInputDevice(deviceId); } /** @@ -1251,7 +1192,7 @@ public class InputManagerService extends IInputManager.Stub try { if (mDataStore.setTouchCalibration(inputDeviceDescriptor, surfaceRotation, calibration)) { - nativeReloadCalibration(mPtr); + mNative.reloadCalibration(); } } finally { mDataStore.saveIfNeeded(); @@ -1763,11 +1704,11 @@ public class InputManagerService extends IInputManager.Stub } public void setFocusedApplication(int displayId, InputApplicationHandle application) { - nativeSetFocusedApplication(mPtr, displayId, application); + mNative.setFocusedApplication(displayId, application); } public void setFocusedDisplay(int displayId) { - nativeSetFocusedDisplay(mPtr, displayId); + mNative.setFocusedDisplay(displayId); } /** Clean up input window handles of the given display. */ @@ -1777,22 +1718,22 @@ public class InputManagerService extends IInputManager.Stub mPointerIconDisplayContext = null; } - nativeDisplayRemoved(mPtr, displayId); + mNative.displayRemoved(displayId); } @Override public void requestPointerCapture(IBinder inputChannelToken, boolean enabled) { Objects.requireNonNull(inputChannelToken, "event must not be null"); - nativeRequestPointerCapture(mPtr, inputChannelToken, enabled); + mNative.requestPointerCapture(inputChannelToken, enabled); } public void setInputDispatchMode(boolean enabled, boolean frozen) { - nativeSetInputDispatchMode(mPtr, enabled, frozen); + mNative.setInputDispatchMode(enabled, frozen); } public void setSystemUiLightsOut(boolean lightsOut) { - nativeSetSystemUiLightsOut(mPtr, lightsOut); + mNative.setSystemUiLightsOut(lightsOut); } /** @@ -1811,7 +1752,7 @@ public class InputManagerService extends IInputManager.Stub */ public boolean transferTouchFocus(@NonNull InputChannel fromChannel, @NonNull InputChannel toChannel, boolean isDragDrop) { - return nativeTransferTouchFocus(mPtr, fromChannel.getToken(), toChannel.getToken(), + return mNative.transferTouchFocus(fromChannel.getToken(), toChannel.getToken(), isDragDrop); } @@ -1832,7 +1773,7 @@ public class InputManagerService extends IInputManager.Stub @NonNull IBinder toChannelToken) { Objects.nonNull(fromChannelToken); Objects.nonNull(toChannelToken); - return nativeTransferTouchFocus(mPtr, fromChannelToken, toChannelToken, + return mNative.transferTouchFocus(fromChannelToken, toChannelToken, false /* isDragDrop */); } @@ -1858,7 +1799,7 @@ public class InputManagerService extends IInputManager.Stub private void setPointerSpeedUnchecked(int speed) { speed = Math.min(Math.max(speed, InputManager.MIN_POINTER_SPEED), InputManager.MAX_POINTER_SPEED); - nativeSetPointerSpeed(mPtr, speed); + mNative.setPointerSpeed(speed); } private void setPointerAcceleration(float acceleration, int displayId) { @@ -1881,7 +1822,7 @@ public class InputManagerService extends IInputManager.Stub @GuardedBy("mAdditionalDisplayInputPropertiesLock") private void updatePointerAccelerationLocked(float acceleration) { - nativeSetPointerAcceleration(mPtr, acceleration); + mNative.setPointerAcceleration(acceleration); } private void setPointerIconVisible(boolean visible, int displayId) { @@ -1906,12 +1847,12 @@ public class InputManagerService extends IInputManager.Stub private void updatePointerIconVisibleLocked(boolean visible) { if (visible) { if (mIconType == PointerIcon.TYPE_CUSTOM) { - nativeSetCustomPointerIcon(mPtr, mIcon); + mNative.setCustomPointerIcon(mIcon); } else { - nativeSetPointerIconType(mPtr, mIconType); + mNative.setPointerIconType(mIconType); } } else { - nativeSetPointerIconType(mPtr, PointerIcon.TYPE_NULL); + mNative.setPointerIconType(PointerIcon.TYPE_NULL); } } @@ -1938,7 +1879,7 @@ public class InputManagerService extends IInputManager.Stub private void updateShowTouchesFromSettings() { int setting = getShowTouchesSetting(0); - nativeSetShowTouches(mPtr, setting != 0); + mNative.setShowTouches(setting != 0); } private void registerShowTouchesSettingObserver() { @@ -1957,7 +1898,7 @@ public class InputManagerService extends IInputManager.Stub mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 0, UserHandle.USER_CURRENT); PointerIcon.setUseLargeIcons(accessibilityConfig == 1); - nativeReloadPointerIcons(mPtr); + mNative.reloadPointerIcons(); } private void registerAccessibilityLargePointerSettingObserver() { @@ -1985,7 +1926,7 @@ public class InputManagerService extends IInputManager.Stub (enabled ? "Enabling" : "Disabling") + " motion classifier because " + reason + ": feature " + (featureEnabledFlag ? "enabled" : "disabled") + ", long press timeout = " + timeout); - nativeSetMotionClassifierEnabled(mPtr, enabled); + mNative.setMotionClassifierEnabled(enabled); } private void registerLongPressTimeoutObserver() { @@ -2013,7 +1954,7 @@ public class InputManagerService extends IInputManager.Stub private void updateBlockUntrustedTouchesModeFromSettings() { final int mode = InputManager.getInstance().getBlockUntrustedTouchesMode(mContext); - nativeSetBlockUntrustedTouchesMode(mPtr, mode); + mNative.setBlockUntrustedTouchesMode(mode); } private void registerMaximumObscuringOpacityForTouchSettingObserver() { @@ -2035,7 +1976,7 @@ public class InputManagerService extends IInputManager.Stub + ", it should be >= 0 and <= 1, rejecting update."); return; } - nativeSetMaximumObscuringOpacityForTouch(mPtr, opacity); + mNative.setMaximumObscuringOpacityForTouch(opacity); } private int getShowTouchesSetting(int defaultValue) { @@ -2061,7 +2002,7 @@ public class InputManagerService extends IInputManager.Stub } } // TODO(b/215597605): trigger MousePositionTracker update - nativeNotifyPointerDisplayIdChanged(mPtr); + mNative.notifyPointerDisplayIdChanged(); } private int getVirtualMousePointerDisplayId() { @@ -2071,7 +2012,7 @@ public class InputManagerService extends IInputManager.Stub } private void setDisplayEligibilityForPointerCapture(int displayId, boolean isEligible) { - nativeSetDisplayEligibilityForPointerCapture(mPtr, displayId, isEligible); + mNative.setDisplayEligibilityForPointerCapture(displayId, isEligible); } private static class VibrationInfo { @@ -2170,7 +2111,7 @@ public class InputManagerService extends IInputManager.Stub VibratorToken v = getVibratorToken(deviceId, token); synchronized (v) { v.mVibrating = true; - nativeVibrate(mPtr, deviceId, info.getPattern(), info.getAmplitudes(), + mNative.vibrate(deviceId, info.getPattern(), info.getAmplitudes(), info.getRepeatIndex(), v.mTokenValue); } } @@ -2178,13 +2119,13 @@ public class InputManagerService extends IInputManager.Stub // Binder call @Override public int[] getVibratorIds(int deviceId) { - return nativeGetVibratorIds(mPtr, deviceId); + return mNative.getVibratorIds(deviceId); } // Binder call @Override public boolean isVibrating(int deviceId) { - return nativeIsVibrating(mPtr, deviceId); + return mNative.isVibrating(deviceId); } // Binder call @@ -2202,7 +2143,7 @@ public class InputManagerService extends IInputManager.Stub if (effect instanceof CombinedVibration.Mono) { CombinedVibration.Mono mono = (CombinedVibration.Mono) effect; VibrationInfo info = new VibrationInfo(mono.getEffect()); - nativeVibrate(mPtr, deviceId, info.getPattern(), info.getAmplitudes(), + mNative.vibrate(deviceId, info.getPattern(), info.getAmplitudes(), info.getRepeatIndex(), v.mTokenValue); } else if (effect instanceof CombinedVibration.Stereo) { CombinedVibration.Stereo stereo = (CombinedVibration.Stereo) effect; @@ -2221,7 +2162,7 @@ public class InputManagerService extends IInputManager.Stub } amplitudes.put(effects.keyAt(i), info.getAmplitudes()); } - nativeVibrateCombined(mPtr, deviceId, pattern, amplitudes, repeat, + mNative.vibrateCombined(deviceId, pattern, amplitudes, repeat, v.mTokenValue); } } @@ -2252,7 +2193,7 @@ public class InputManagerService extends IInputManager.Stub private void cancelVibrateIfNeeded(VibratorToken v) { synchronized (v) { if (v.mVibrating) { - nativeCancelVibrate(mPtr, v.mDeviceId, v.mTokenValue); + mNative.cancelVibrate(v.mDeviceId, v.mTokenValue); v.mVibrating = false; } } @@ -2348,13 +2289,13 @@ public class InputManagerService extends IInputManager.Stub // Binder call @Override public int getBatteryStatus(int deviceId) { - return nativeGetBatteryStatus(mPtr, deviceId); + return mNative.getBatteryStatus(deviceId); } // Binder call @Override public int getBatteryCapacity(int deviceId) { - return nativeGetBatteryCapacity(mPtr, deviceId); + return mNative.getBatteryCapacity(deviceId); } // Binder call @@ -2370,10 +2311,10 @@ public class InputManagerService extends IInputManager.Stub final AdditionalDisplayInputProperties properties = mAdditionalDisplayInputProperties.get(mOverriddenPointerDisplayId); if (properties == null || properties.pointerIconVisible) { - nativeSetPointerIconType(mPtr, mIconType); + mNative.setPointerIconType(mIconType); } } else { - nativeSetPointerIconType(mPtr, mIconType); + mNative.setPointerIconType(mIconType); } } } @@ -2391,10 +2332,10 @@ public class InputManagerService extends IInputManager.Stub if (properties == null || properties.pointerIconVisible) { // Only set the icon if it is not currently hidden; otherwise, it will be set // once it's no longer hidden. - nativeSetCustomPointerIcon(mPtr, mIcon); + mNative.setCustomPointerIcon(mIcon); } } else { - nativeSetCustomPointerIcon(mPtr, mIcon); + mNative.setCustomPointerIcon(mIcon); } } } @@ -2418,7 +2359,7 @@ public class InputManagerService extends IInputManager.Stub synchronized (mAssociationsLock) { mRuntimeAssociations.put(inputPort, displayPort); } - nativeNotifyPortAssociationsChanged(mPtr); + mNative.notifyPortAssociationsChanged(); } /** @@ -2439,7 +2380,7 @@ public class InputManagerService extends IInputManager.Stub synchronized (mAssociationsLock) { mRuntimeAssociations.remove(inputPort); } - nativeNotifyPortAssociationsChanged(mPtr); + mNative.notifyPortAssociationsChanged(); } @Override // Binder call @@ -2456,7 +2397,7 @@ public class InputManagerService extends IInputManager.Stub synchronized (mAssociationsLock) { mUniqueIdAssociations.put(inputPort, displayUniqueId); } - nativeChangeUniqueIdAssociation(mPtr); + mNative.changeUniqueIdAssociation(); } @Override // Binder call @@ -2472,12 +2413,12 @@ public class InputManagerService extends IInputManager.Stub synchronized (mAssociationsLock) { mUniqueIdAssociations.remove(inputPort); } - nativeChangeUniqueIdAssociation(mPtr); + mNative.changeUniqueIdAssociation(); } @Override // Binder call public InputSensorInfo[] getSensorList(int deviceId) { - return nativeGetSensorList(mPtr, deviceId); + return mNative.getSensorList(deviceId); } @Override // Binder call @@ -2538,7 +2479,7 @@ public class InputManagerService extends IInputManager.Stub int callingPid = Binder.getCallingPid(); SensorEventListenerRecord listener = mSensorEventListeners.get(callingPid); if (listener != null) { - return nativeFlushSensor(mPtr, deviceId, sensorType); + return mNative.flushSensor(deviceId, sensorType); } return false; } @@ -2548,7 +2489,7 @@ public class InputManagerService extends IInputManager.Stub public boolean enableSensor(int deviceId, int sensorType, int samplingPeriodUs, int maxBatchReportLatencyUs) { synchronized (mInputDevicesLock) { - return nativeEnableSensor(mPtr, deviceId, sensorType, samplingPeriodUs, + return mNative.enableSensor(deviceId, sensorType, samplingPeriodUs, maxBatchReportLatencyUs); } } @@ -2556,7 +2497,7 @@ public class InputManagerService extends IInputManager.Stub @Override // Binder call public void disableSensor(int deviceId, int sensorType) { synchronized (mInputDevicesLock) { - nativeDisableSensor(mPtr, deviceId, sensorType); + mNative.disableSensor(deviceId, sensorType); } } @@ -2595,7 +2536,7 @@ public class InputManagerService extends IInputManager.Stub */ @Override // Binder call public List<Light> getLights(int deviceId) { - return nativeGetLights(mPtr, deviceId); + return mNative.getLights(deviceId); } /** @@ -2608,11 +2549,11 @@ public class InputManagerService extends IInputManager.Stub + "lightState " + lightState); } if (light.getType() == Light.LIGHT_TYPE_PLAYER_ID) { - nativeSetLightPlayerId(mPtr, deviceId, light.getId(), lightState.getPlayerId()); + mNative.setLightPlayerId(deviceId, light.getId(), lightState.getPlayerId()); } else { // Set ARGB format color to input device light // Refer to https://developer.android.com/reference/kotlin/android/graphics/Color - nativeSetLightColor(mPtr, deviceId, light.getId(), lightState.getColor()); + mNative.setLightColor(deviceId, light.getId(), lightState.getColor()); } } @@ -2620,7 +2561,7 @@ public class InputManagerService extends IInputManager.Stub * Set multiple light states with multiple light ids for a specific input device. */ private void setLightStatesInternal(int deviceId, int[] lightIds, LightState[] lightStates) { - final List<Light> lights = nativeGetLights(mPtr, deviceId); + final List<Light> lights = mNative.getLights(deviceId); SparseArray<Light> lightArray = new SparseArray<>(); for (int i = 0; i < lights.size(); i++) { lightArray.put(lights.get(i).getId(), lights.get(i)); @@ -2656,8 +2597,8 @@ public class InputManagerService extends IInputManager.Stub @Override public @Nullable LightState getLightState(int deviceId, int lightId) { synchronized (mLightLock) { - int color = nativeGetLightColor(mPtr, deviceId, lightId); - int playerId = nativeGetLightPlayerId(mPtr, deviceId, lightId); + int color = mNative.getLightColor(deviceId, lightId); + int playerId = mNative.getLightPlayerId(deviceId, lightId); return new LightState(color, playerId); } @@ -2709,7 +2650,7 @@ public class InputManagerService extends IInputManager.Stub throw new SecurityException("Requires MONITOR_INPUT permission"); } - nativeCancelCurrentTouch(mPtr); + mNative.cancelCurrentTouch(); } @Override @@ -2717,7 +2658,7 @@ public class InputManagerService extends IInputManager.Stub if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; pw.println("INPUT MANAGER (dumpsys input)\n"); - String dumpStr = nativeDump(mPtr); + String dumpStr = mNative.dump(); if (dumpStr != null) { pw.println(dumpStr); } @@ -2826,7 +2767,7 @@ public class InputManagerService extends IInputManager.Stub synchronized (mLidSwitchLock) { /* Test if blocked by lid switch lock. */ } synchronized (mInputMonitors) { /* Test if blocked by input monitor lock. */ } synchronized (mAdditionalDisplayInputPropertiesLock) { /* Test if blocked by props lock */ } - nativeMonitor(mPtr); + mNative.monitor(); } // Native callback. @@ -3153,7 +3094,7 @@ public class InputManagerService extends IInputManager.Stub * @return True if the device could dispatch to the given display, false otherwise. */ public boolean canDispatchToDisplay(int deviceId, int displayId) { - return nativeCanDispatchToDisplay(mPtr, deviceId, displayId); + return mNative.canDispatchToDisplay(deviceId, displayId); } // Native callback. @@ -3504,7 +3445,7 @@ public class InputManagerService extends IInputManager.Stub synchronized (mInputFilterLock) { if (!mDisconnected) { - nativeInjectInputEvent(mPtr, event, false /* injectIntoUid */, -1 /* uid */, + mNative.injectInputEvent(event, false /* injectIntoUid */, -1 /* uid */, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0 /* timeout */, policyFlags | WindowManagerPolicy.FLAG_FILTERED); } @@ -3524,7 +3465,7 @@ public class InputManagerService extends IInputManager.Stub @Override public void pilferPointers() { - nativePilferPointers(mPtr, mInputChannelToken); + mNative.pilferPointers(mInputChannelToken); } @Override @@ -3702,12 +3643,12 @@ public class InputManagerService extends IInputManager.Stub @Override public void setInteractive(boolean interactive) { - nativeSetInteractive(mPtr, interactive); + mNative.setInteractive(interactive); } @Override public void toggleCapsLock(int deviceId) { - nativeToggleCapsLock(mPtr, deviceId); + mNative.toggleCapsLock(deviceId); } @Override @@ -3778,7 +3719,7 @@ public class InputManagerService extends IInputManager.Stub @Override public void pilferPointers(IBinder token) { - nativePilferPointers(mPtr, token); + mNative.pilferPointers(token); } } diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java new file mode 100644 index 000000000000..7178d20786e3 --- /dev/null +++ b/services/core/java/com/android/server/input/NativeInputManagerService.java @@ -0,0 +1,389 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.input; + +import android.content.Context; +import android.hardware.display.DisplayViewport; +import android.hardware.input.InputSensorInfo; +import android.hardware.lights.Light; +import android.os.IBinder; +import android.os.MessageQueue; +import android.util.SparseArray; +import android.view.InputApplicationHandle; +import android.view.InputChannel; +import android.view.InputEvent; +import android.view.PointerIcon; +import android.view.VerifiedInputEvent; + +import com.android.internal.annotations.VisibleForTesting; + +import java.util.List; + +/** + * An interface for the native methods of InputManagerService. We use a public interface so that + * this can be mocked for testing by Mockito. + */ +@VisibleForTesting +public interface NativeInputManagerService { + + void start(); + + void setDisplayViewports(DisplayViewport[] viewports); + + int getScanCodeState(int deviceId, int sourceMask, int scanCode); + + int getKeyCodeState(int deviceId, int sourceMask, int keyCode); + + int getSwitchState(int deviceId, int sourceMask, int sw); + + boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists); + + int getKeyCodeForKeyLocation(int deviceId, int locationKeyCode); + + InputChannel createInputChannel(String name); + + InputChannel createInputMonitor(int displayId, String name, int pid); + + void removeInputChannel(IBinder connectionToken); + + void pilferPointers(IBinder token); + + void setInputFilterEnabled(boolean enable); + + boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission); + + void setMaximumObscuringOpacityForTouch(float opacity); + + void setBlockUntrustedTouchesMode(int mode); + + int injectInputEvent(InputEvent event, boolean injectIntoUid, int uid, int syncMode, + int timeoutMillis, int policyFlags); + + VerifiedInputEvent verifyInputEvent(InputEvent event); + + void toggleCapsLock(int deviceId); + + void displayRemoved(int displayId); + + void setInputDispatchMode(boolean enabled, boolean frozen); + + void setSystemUiLightsOut(boolean lightsOut); + + void setFocusedApplication(int displayId, InputApplicationHandle application); + + void setFocusedDisplay(int displayId); + + boolean transferTouchFocus(IBinder fromChannelToken, IBinder toChannelToken, + boolean isDragDrop); + + boolean transferTouch(IBinder destChannelToken); + + void setPointerSpeed(int speed); + + void setPointerAcceleration(float acceleration); + + void setShowTouches(boolean enabled); + + void setInteractive(boolean interactive); + + void reloadCalibration(); + + void vibrate(int deviceId, long[] pattern, int[] amplitudes, int repeat, int token); + + void vibrateCombined(int deviceId, long[] pattern, SparseArray<int[]> amplitudes, + int repeat, int token); + + void cancelVibrate(int deviceId, int token); + + boolean isVibrating(int deviceId); + + int[] getVibratorIds(int deviceId); + + int getBatteryCapacity(int deviceId); + + int getBatteryStatus(int deviceId); + + List<Light> getLights(int deviceId); + + int getLightPlayerId(int deviceId, int lightId); + + int getLightColor(int deviceId, int lightId); + + void setLightPlayerId(int deviceId, int lightId, int playerId); + + void setLightColor(int deviceId, int lightId, int color); + + void reloadKeyboardLayouts(); + + void reloadDeviceAliases(); + + String dump(); + + void monitor(); + + boolean isInputDeviceEnabled(int deviceId); + + void enableInputDevice(int deviceId); + + void disableInputDevice(int deviceId); + + void setPointerIconType(int iconId); + + void reloadPointerIcons(); + + void setCustomPointerIcon(PointerIcon icon); + + void requestPointerCapture(IBinder windowToken, boolean enabled); + + boolean canDispatchToDisplay(int deviceId, int displayId); + + void notifyPortAssociationsChanged(); + + void changeUniqueIdAssociation(); + + void notifyPointerDisplayIdChanged(); + + void setDisplayEligibilityForPointerCapture(int displayId, boolean enabled); + + void setMotionClassifierEnabled(boolean enabled); + + InputSensorInfo[] getSensorList(int deviceId); + + boolean flushSensor(int deviceId, int sensorType); + + boolean enableSensor(int deviceId, int sensorType, int samplingPeriodUs, + int maxBatchReportLatencyUs); + + void disableSensor(int deviceId, int sensorType); + + void cancelCurrentTouch(); + + /** The native implementation of InputManagerService methods. */ + class NativeImpl implements NativeInputManagerService { + /** Pointer to native input manager service object, used by native code. */ + @SuppressWarnings({"unused", "FieldCanBeLocal"}) + private final long mPtr; + + NativeImpl(InputManagerService service, Context context, MessageQueue messageQueue) { + mPtr = init(service, context, messageQueue); + } + + private native long init(InputManagerService service, Context context, + MessageQueue messageQueue); + + @Override + public native void start(); + + @Override + public native void setDisplayViewports(DisplayViewport[] viewports); + + @Override + public native int getScanCodeState(int deviceId, int sourceMask, int scanCode); + + @Override + public native int getKeyCodeState(int deviceId, int sourceMask, int keyCode); + + @Override + public native int getSwitchState(int deviceId, int sourceMask, int sw); + + @Override + public native boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, + boolean[] keyExists); + + @Override + public native int getKeyCodeForKeyLocation(int deviceId, int locationKeyCode); + + @Override + public native InputChannel createInputChannel(String name); + + @Override + public native InputChannel createInputMonitor(int displayId, String name, int pid); + + @Override + public native void removeInputChannel(IBinder connectionToken); + + @Override + public native void pilferPointers(IBinder token); + + @Override + public native void setInputFilterEnabled(boolean enable); + + @Override + public native boolean setInTouchMode(boolean inTouchMode, int pid, int uid, + boolean hasPermission); + + @Override + public native void setMaximumObscuringOpacityForTouch(float opacity); + + @Override + public native void setBlockUntrustedTouchesMode(int mode); + + @Override + public native int injectInputEvent(InputEvent event, boolean injectIntoUid, int uid, + int syncMode, + int timeoutMillis, int policyFlags); + + @Override + public native VerifiedInputEvent verifyInputEvent(InputEvent event); + + @Override + public native void toggleCapsLock(int deviceId); + + @Override + public native void displayRemoved(int displayId); + + @Override + public native void setInputDispatchMode(boolean enabled, boolean frozen); + + @Override + public native void setSystemUiLightsOut(boolean lightsOut); + + @Override + public native void setFocusedApplication(int displayId, InputApplicationHandle application); + + @Override + public native void setFocusedDisplay(int displayId); + + @Override + public native boolean transferTouchFocus(IBinder fromChannelToken, IBinder toChannelToken, + boolean isDragDrop); + + @Override + public native boolean transferTouch(IBinder destChannelToken); + + @Override + public native void setPointerSpeed(int speed); + + @Override + public native void setPointerAcceleration(float acceleration); + + @Override + public native void setShowTouches(boolean enabled); + + @Override + public native void setInteractive(boolean interactive); + + @Override + public native void reloadCalibration(); + + @Override + public native void vibrate(int deviceId, long[] pattern, int[] amplitudes, int repeat, + int token); + + @Override + public native void vibrateCombined(int deviceId, long[] pattern, + SparseArray<int[]> amplitudes, + int repeat, int token); + + @Override + public native void cancelVibrate(int deviceId, int token); + + @Override + public native boolean isVibrating(int deviceId); + + @Override + public native int[] getVibratorIds(int deviceId); + + @Override + public native int getBatteryCapacity(int deviceId); + + @Override + public native int getBatteryStatus(int deviceId); + + @Override + public native List<Light> getLights(int deviceId); + + @Override + public native int getLightPlayerId(int deviceId, int lightId); + + @Override + public native int getLightColor(int deviceId, int lightId); + + @Override + public native void setLightPlayerId(int deviceId, int lightId, int playerId); + + @Override + public native void setLightColor(int deviceId, int lightId, int color); + + @Override + public native void reloadKeyboardLayouts(); + + @Override + public native void reloadDeviceAliases(); + + @Override + public native String dump(); + + @Override + public native void monitor(); + + @Override + public native boolean isInputDeviceEnabled(int deviceId); + + @Override + public native void enableInputDevice(int deviceId); + + @Override + public native void disableInputDevice(int deviceId); + + @Override + public native void setPointerIconType(int iconId); + + @Override + public native void reloadPointerIcons(); + + @Override + public native void setCustomPointerIcon(PointerIcon icon); + + @Override + public native void requestPointerCapture(IBinder windowToken, boolean enabled); + + @Override + public native boolean canDispatchToDisplay(int deviceId, int displayId); + + @Override + public native void notifyPortAssociationsChanged(); + + @Override + public native void changeUniqueIdAssociation(); + + @Override + public native void notifyPointerDisplayIdChanged(); + + @Override + public native void setDisplayEligibilityForPointerCapture(int displayId, boolean enabled); + + @Override + public native void setMotionClassifierEnabled(boolean enabled); + + @Override + public native InputSensorInfo[] getSensorList(int deviceId); + + @Override + public native boolean flushSensor(int deviceId, int sensorType); + + @Override + public native boolean enableSensor(int deviceId, int sensorType, int samplingPeriodUs, + int maxBatchReportLatencyUs); + + @Override + public native void disableSensor(int deviceId, int sensorType); + + @Override + public native void cancelCurrentTouch(); + } +} diff --git a/services/core/java/com/android/server/locales/LocaleManagerService.java b/services/core/java/com/android/server/locales/LocaleManagerService.java index 9ef14cc38993..fc7be7ff8d1c 100644 --- a/services/core/java/com/android/server/locales/LocaleManagerService.java +++ b/services/core/java/com/android/server/locales/LocaleManagerService.java @@ -186,7 +186,7 @@ public class LocaleManagerService extends SystemService { userId = mActivityManagerInternal.handleIncomingUser( Binder.getCallingPid(), Binder.getCallingUid(), userId, false /* allowAll */, ActivityManagerInternal.ALLOW_NON_FULL, - "setApplicationLocales", appPackageName); + "setApplicationLocales", /* callerPackage= */ null); // This function handles two types of set operations: // 1.) A normal, non-privileged app setting its own locale. @@ -355,7 +355,7 @@ public class LocaleManagerService extends SystemService { userId = mActivityManagerInternal.handleIncomingUser( Binder.getCallingPid(), Binder.getCallingUid(), userId, false /* allowAll */, ActivityManagerInternal.ALLOW_NON_FULL, - "getApplicationLocales", appPackageName); + "getApplicationLocales", /* callerPackage= */ null); // This function handles three types of query operations: // 1.) A normal, non-privileged app querying its own locale. diff --git a/services/core/java/com/android/server/locales/OWNERS b/services/core/java/com/android/server/locales/OWNERS index be284a766c50..4d93bff6f7d3 100644 --- a/services/core/java/com/android/server/locales/OWNERS +++ b/services/core/java/com/android/server/locales/OWNERS @@ -1,3 +1,4 @@ roosa@google.com pratyushmore@google.com goldmanj@google.com +ankitavyas@google.com diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java index a73c8e0c914a..0e4bbbb7a412 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java @@ -18,12 +18,14 @@ package com.android.server.locksettings; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; import android.app.ActivityManager; import android.app.admin.PasswordMetrics; import android.content.Context; import android.os.ShellCommand; import android.os.SystemProperties; +import android.os.UserHandle; import android.text.TextUtils; import android.util.Slog; @@ -48,6 +50,8 @@ class LockSettingsShellCommand extends ShellCommand { private static final String COMMAND_REMOVE_CACHE = "remove-cache"; private static final String COMMAND_SET_ROR_PROVIDER_PACKAGE = "set-resume-on-reboot-provider-package"; + private static final String COMMAND_REQUIRE_STRONG_AUTH = + "require-strong-auth"; private static final String COMMAND_HELP = "help"; private int mCurrentUserId; @@ -97,6 +101,9 @@ class LockSettingsShellCommand extends ShellCommand { case COMMAND_SET_ROR_PROVIDER_PACKAGE: runSetResumeOnRebootProviderPackage(); return 0; + case COMMAND_REQUIRE_STRONG_AUTH: + runRequireStrongAuth(); + return 0; case COMMAND_HELP: onHelp(); return 0; @@ -192,6 +199,10 @@ class LockSettingsShellCommand extends ShellCommand { pw.println(" Sets the package name for server based resume on reboot service " + "provider."); pw.println(""); + pw.println(" require-strong-auth [--user USER_ID] <reason>"); + pw.println(" Requires the strong authentication. The current supported reasons: " + + "STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN."); + pw.println(""); } } @@ -288,6 +299,24 @@ class LockSettingsShellCommand extends ShellCommand { return true; } + private boolean runRequireStrongAuth() { + final String reason = mNew; + int strongAuthReason; + switch (reason) { + case "STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN": + strongAuthReason = STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; + mCurrentUserId = UserHandle.USER_ALL; + break; + default: + getErrPrintWriter().println("Unsupported reason: " + reason); + return false; + } + mLockPatternUtils.requireStrongAuth(strongAuthReason, mCurrentUserId); + getOutPrintWriter().println("Require strong auth for USER_ID " + + mCurrentUserId + " because of " + mNew); + return true; + } + private boolean runClear() { LockscreenCredential none = LockscreenCredential.createNone(); if (!isNewCredentialSufficient(none)) { diff --git a/services/core/java/com/android/server/logcat/LogAccessDialogActivity.java b/services/core/java/com/android/server/logcat/LogAccessDialogActivity.java index 8be90e0cc622..b45bfb1c2d92 100644 --- a/services/core/java/com/android/server/logcat/LogAccessDialogActivity.java +++ b/services/core/java/com/android/server/logcat/LogAccessDialogActivity.java @@ -30,6 +30,7 @@ import android.os.ServiceManager; import android.os.UserHandle; import android.os.logcat.ILogcatManagerService; import android.util.Slog; +import android.view.InflateException; import android.view.View; import android.widget.Button; import android.widget.TextView; @@ -56,33 +57,46 @@ public class LogAccessDialogActivity extends Activity implements private String mAlertTitle; private AlertDialog.Builder mAlertDialog; private AlertDialog mAlert; + private View mAlertView; private static final int DIALOG_TIME_OUT = Build.IS_DEBUGGABLE ? 60000 : 300000; private static final int MSG_DISMISS_DIALOG = 0; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mContext = this; - Intent intent = getIntent(); - mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME); - mUid = intent.getIntExtra("com.android.server.logcat.uid", 0); - mGid = intent.getIntExtra("com.android.server.logcat.gid", 0); - mPid = intent.getIntExtra("com.android.server.logcat.pid", 0); - mFd = intent.getIntExtra("com.android.server.logcat.fd", 0); - mAlertTitle = getTitleString(mContext, mPackageName, mUid); + try { + mContext = this; + + // retrieve Intent extra information + Intent intent = getIntent(); + getIntentInfo(intent); - if (mAlertTitle != null) { + // retrieve the title string from passed intent extra + mAlertTitle = getTitleString(mContext, mPackageName, mUid); + // creaet View + mAlertView = createView(); + + // create AlertDialog mAlertDialog = new AlertDialog.Builder(this); - mAlertDialog.setView(createView()); + mAlertDialog.setView(mAlertView); + // show Alert mAlert = mAlertDialog.create(); mAlert.show(); + + // set Alert Timeout mHandler.sendEmptyMessageDelayed(MSG_DISMISS_DIALOG, DIALOG_TIME_OUT); + } catch (Exception e) { + try { + Slog.e(TAG, "onCreate failed, declining the logd access", e); + mLogcatManagerService.decline(mUid, mGid, mPid, mFd); + } catch (RemoteException ex) { + Slog.e(TAG, "Fails to call remote functions", ex); + } } } @@ -95,6 +109,19 @@ public class LogAccessDialogActivity extends Activity implements mAlert = null; } + private void getIntentInfo(Intent intent) throws Exception { + + if (intent == null) { + throw new NullPointerException("Intent is null"); + } + + mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME); + mUid = intent.getIntExtra("com.android.server.logcat.uid", 0); + mGid = intent.getIntExtra("com.android.server.logcat.gid", 0); + mPid = intent.getIntExtra("com.android.server.logcat.pid", 0); + mFd = intent.getIntExtra("com.android.server.logcat.fd", 0); + } + private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { @@ -116,26 +143,41 @@ public class LogAccessDialogActivity extends Activity implements } }; - private String getTitleString(Context context, String callingPackage, int uid) { + private String getTitleString(Context context, String callingPackage, int uid) + throws Exception { + PackageManager pm = context.getPackageManager(); - try { - return context.getString( - com.android.internal.R.string.log_access_confirmation_title, - pm.getApplicationInfoAsUser(callingPackage, - PackageManager.MATCH_DIRECT_BOOT_AUTO, - UserHandle.getUserId(uid)).loadLabel(pm)); - } catch (NameNotFoundException e) { - Slog.e(TAG, "App name is unknown.", e); - return null; + if (pm == null) { + throw new NullPointerException("PackageManager is null"); } + + CharSequence appLabel = pm.getApplicationInfoAsUser(callingPackage, + PackageManager.MATCH_DIRECT_BOOT_AUTO, + UserHandle.getUserId(uid)).loadLabel(pm); + if (appLabel == null) { + throw new NameNotFoundException("Application Label is null"); + } + + return context.getString(com.android.internal.R.string.log_access_confirmation_title, + appLabel); } - private View createView() { + /** + * Returns the dialog view. + * If we cannot retrieve the package name, it returns null and we decline the full device log + * access + */ + private View createView() throws Exception { + final View view = getLayoutInflater().inflate( R.layout.log_access_user_consent_dialog_permission, null /*root*/); + if (view == null) { + throw new InflateException(); + } + ((TextView) view.findViewById(R.id.log_access_dialog_title)) - .setText(mAlertTitle); + .setText(mAlertTitle); Button button_allow = (Button) view.findViewById(R.id.log_access_dialog_allow_button); button_allow.setOnClickListener(this); @@ -144,6 +186,7 @@ public class LogAccessDialogActivity extends Activity implements button_deny.setOnClickListener(this); return view; + } @Override diff --git a/services/core/java/com/android/server/logcat/LogcatManagerService.java b/services/core/java/com/android/server/logcat/LogcatManagerService.java index 015bf3c5e390..4c265ad5ff88 100644 --- a/services/core/java/com/android/server/logcat/LogcatManagerService.java +++ b/services/core/java/com/android/server/logcat/LogcatManagerService.java @@ -102,16 +102,27 @@ public final class LogcatManagerService extends SystemService { } } - private void showDialog(int uid, int gid, int pid, int fd) { + /** + * Returns the package name. + * If we cannot retrieve the package name, it returns null and we decline the full device log + * access + */ + private String getPackageName(int uid, int gid, int pid, int fd) { + final ActivityManagerInternal activityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); + if (activityManagerInternal != null) { + String packageName = activityManagerInternal.getPackageNameByPid(pid); + if (packageName != null) { + return packageName; + } + } PackageManager pm = mContext.getPackageManager(); - String packageName = activityManagerInternal.getPackageNameByPid(pid); - if (packageName != null) { - Intent mIntent = createIntent(packageName, uid, gid, pid, fd); - mContext.startActivityAsUser(mIntent, UserHandle.SYSTEM); - return; + if (pm == null) { + // Decline the logd access if PackageManager is null + Slog.e(TAG, "PackageManager is null, declining the logd access"); + return null; } String[] packageNames = pm.getPackagesForUid(uid); @@ -119,21 +130,19 @@ public final class LogcatManagerService extends SystemService { if (ArrayUtils.isEmpty(packageNames)) { // Decline the logd access if the app name is unknown Slog.e(TAG, "Unknown calling package name, declining the logd access"); - declineLogdAccess(uid, gid, pid, fd); - return; + return null; } String firstPackageName = packageNames[0]; - if (firstPackageName.isEmpty() || firstPackageName == null) { + if (firstPackageName == null || firstPackageName.isEmpty()) { // Decline the logd access if the package name from uid is unknown Slog.e(TAG, "Unknown calling package name, declining the logd access"); - declineLogdAccess(uid, gid, pid, fd); - return; + return null; } - final Intent mIntent = createIntent(firstPackageName, uid, gid, pid, fd); - mContext.startActivityAsUser(mIntent, UserHandle.SYSTEM); + return firstPackageName; + } private void declineLogdAccess(int uid, int gid, int pid, int fd) { @@ -198,16 +207,23 @@ public final class LogcatManagerService extends SystemService { final int procState = LocalServices.getService(ActivityManagerInternal.class) .getUidProcessState(mUid); - // If the process is foreground, show a dialog for user consent + // If the process is foreground and we can retrieve the package name, show a dialog + // for user consent if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { - showDialog(mUid, mGid, mPid, mFd); - } else { - /** - * If the process is background, decline the logd access. - **/ - declineLogdAccess(mUid, mGid, mPid, mFd); - return; + String packageName = getPackageName(mUid, mGid, mPid, mFd); + if (packageName != null) { + final Intent mIntent = createIntent(packageName, mUid, mGid, mPid, mFd); + mContext.startActivityAsUser(mIntent, UserHandle.SYSTEM); + return; + } } + + /** + * If the process is background or cannot retrieve the package name, + * decline the logd access. + **/ + declineLogdAccess(mUid, mGid, mPid, mFd); + return; } } } diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java index 728782ccee0b..d0651ed176cf 100644 --- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java +++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java @@ -133,6 +133,10 @@ class BluetoothRouteProvider { mIntentFilter, null, null); } + public void stop() { + mContext.unregisterReceiver(mBroadcastReceiver); + } + /** * Transfers to a given bluetooth route. * The dedicated BT device with the route would be activated. diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index b3072667130b..e27cbeaab139 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -1150,6 +1150,8 @@ class MediaRouter2ServiceImpl { if (DEBUG) { Slog.d(TAG, userRecord + ": Disposed"); } + userRecord.mHandler.sendMessage( + obtainMessage(UserHandler::stop, userRecord.mHandler)); mUserRecords.remove(userRecord.mUserId); // Note: User already stopped (by switchUser) so no need to send stop message here. } @@ -1330,6 +1332,7 @@ class MediaRouter2ServiceImpl { private void start() { if (!mRunning) { mRunning = true; + mSystemProvider.start(); mWatcher.start(); } } @@ -1338,6 +1341,7 @@ class MediaRouter2ServiceImpl { if (mRunning) { mRunning = false; mWatcher.stop(); // also stops all providers + mSystemProvider.stop(); } } diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java index 78781591a79e..d91bf8c00044 100644 --- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java @@ -71,6 +71,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { private final IAudioService mAudioService; private final Handler mHandler; private final Context mContext; + private final UserHandle mUser; private final BluetoothRouteProvider mBtRouteProvider; private static ComponentName sComponentName = new ComponentName( @@ -86,6 +87,9 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo(); int mDeviceVolume; + private final AudioManagerBroadcastReceiver mAudioReceiver = + new AudioManagerBroadcastReceiver(); + private final Object mRequestLock = new Object(); @GuardedBy("mRequestLock") private volatile SessionCreationRequest mPendingSessionCreationRequest; @@ -108,6 +112,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { mIsSystemRouteProvider = true; mContext = context; + mUser = user; mHandler = new Handler(Looper.getMainLooper()); mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); @@ -128,21 +133,33 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { } }); updateSessionInfosIfNeeded(); + } + public void start() { IntentFilter intentFilter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION); intentFilter.addAction(AudioManager.STREAM_DEVICES_CHANGED_ACTION); - mContext.registerReceiverAsUser(new AudioManagerBroadcastReceiver(), user, + mContext.registerReceiverAsUser(mAudioReceiver, mUser, intentFilter, null, null); if (mBtRouteProvider != null) { mHandler.post(() -> { - mBtRouteProvider.start(user); + mBtRouteProvider.start(mUser); notifyProviderState(); }); } updateVolume(); } + public void stop() { + mContext.unregisterReceiver(mAudioReceiver); + if (mBtRouteProvider != null) { + mHandler.post(() -> { + mBtRouteProvider.stop(); + notifyProviderState(); + }); + } + } + @Override public void setCallback(Callback callback) { super.setCallback(callback); diff --git a/services/core/java/com/android/server/net/TEST_MAPPING b/services/core/java/com/android/server/net/TEST_MAPPING index 02095eb70c0e..4ccf09e5e020 100644 --- a/services/core/java/com/android/server/net/TEST_MAPPING +++ b/services/core/java/com/android/server/net/TEST_MAPPING @@ -2,12 +2,8 @@ "presubmit-large": [ { "name": "CtsHostsideNetworkTests", - "file_patterns": ["(/|^)NetworkPolicy[^/]*\\.java"], "options": [ { - "include-filter": "com.android.cts.net.HostsideRestrictBackgroundNetworkTests" - }, - { "exclude-annotation": "androidx.test.filters.FlakyTest" }, { diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilterImpl.java index 29ee28175f57..5865adb96333 100644 --- a/services/core/java/com/android/server/pm/AppsFilter.java +++ b/services/core/java/com/android/server/pm/AppsFilterImpl.java @@ -44,7 +44,6 @@ import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; -import android.util.SparseSetArray; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; @@ -64,14 +63,18 @@ import com.android.server.pm.pkg.component.ParsedMainComponent; import com.android.server.pm.pkg.component.ParsedProvider; import com.android.server.utils.Snappable; import com.android.server.utils.SnapshotCache; -import com.android.server.utils.Snapshots; import com.android.server.utils.Watchable; import com.android.server.utils.WatchableImpl; +import com.android.server.utils.Watched; +import com.android.server.utils.WatchedArrayList; import com.android.server.utils.WatchedArrayMap; +import com.android.server.utils.WatchedArraySet; import com.android.server.utils.WatchedSparseBooleanMatrix; +import com.android.server.utils.WatchedSparseSetArray; import com.android.server.utils.Watcher; import java.io.PrintWriter; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -84,7 +87,7 @@ import java.util.concurrent.Executor; * manifests. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) -public class AppsFilter implements Watchable, Snappable { +public class AppsFilterImpl implements AppsFilterSnapshot, Watchable, Snappable { private static final String TAG = "AppsFilter"; @@ -99,32 +102,43 @@ public class AppsFilter implements Watchable, Snappable { * application B is implicitly allowed to query for application A; regardless of any manifest * entries. */ - private final SparseSetArray<Integer> mImplicitlyQueryable = new SparseSetArray<>(); + @Watched + private final WatchedSparseSetArray<Integer> mImplicitlyQueryable; + private final SnapshotCache<WatchedSparseSetArray<Integer>> mImplicitQueryableSnapshot; /** * This contains a list of app UIDs that are implicitly queryable because another app explicitly * interacted with it, but could keep across package updates. For example, if application A * grants persistable uri permission to application B; regardless of any manifest entries. */ - private final SparseSetArray<Integer> mRetainedImplicitlyQueryable = new SparseSetArray<>(); + @Watched + private final WatchedSparseSetArray<Integer> mRetainedImplicitlyQueryable; + private final SnapshotCache<WatchedSparseSetArray<Integer>> + mRetainedImplicitlyQueryableSnapshot; /** * A mapping from the set of App IDs that query other App IDs via package name to the * list of packages that they can see. */ - private final SparseSetArray<Integer> mQueriesViaPackage = new SparseSetArray<>(); + @Watched + private final WatchedSparseSetArray<Integer> mQueriesViaPackage; + private final SnapshotCache<WatchedSparseSetArray<Integer>> mQueriesViaPackageSnapshot; /** * A mapping from the set of App IDs that query others via component match to the list * of packages that the they resolve to. */ - private final SparseSetArray<Integer> mQueriesViaComponent = new SparseSetArray<>(); + @Watched + private final WatchedSparseSetArray<Integer> mQueriesViaComponent; + private final SnapshotCache<WatchedSparseSetArray<Integer>> mQueriesViaComponentSnapshot; /** * A mapping from the set of App IDs that query other App IDs via library name to the * list of packages that they can see. */ - private final SparseSetArray<Integer> mQueryableViaUsesLibrary = new SparseSetArray<>(); + @Watched + private final WatchedSparseSetArray<Integer> mQueryableViaUsesLibrary; + private final SnapshotCache<WatchedSparseSetArray<Integer>> mQueryableViaUsesLibrarySnapshot; /** * Executor for running reasonably short background tasks such as building the initial @@ -144,7 +158,9 @@ public class AppsFilter implements Watchable, Snappable { * A set of App IDs that are always queryable by any package, regardless of their manifest * content. */ - private final ArraySet<Integer> mForceQueryable = new ArraySet<>(); + @Watched + private final WatchedArraySet<Integer> mForceQueryable; + private final SnapshotCache<WatchedArraySet<Integer>> mForceQueryableSnapshot; /** * The set of package names provided by the device that should be force queryable regardless of @@ -154,14 +170,15 @@ public class AppsFilter implements Watchable, Snappable { /** True if all system apps should be made queryable by default. */ private final boolean mSystemAppsQueryable; - private final FeatureConfig mFeatureConfig; private final OverlayReferenceMapper mOverlayReferenceMapper; private final StateProvider mStateProvider; private final PackageManagerInternal mPmInternal; - private SigningDetails mSystemSigningDetails; - private Set<String> mProtectedBroadcasts = new ArraySet<>(); + + @Watched + private final WatchedArrayList<String> mProtectedBroadcasts; + private final SnapshotCache<WatchedArrayList<String>> mProtectedBroadcastsSnapshot; private final Object mCacheLock = new Object(); @@ -175,19 +192,21 @@ public class AppsFilter implements Watchable, Snappable { @GuardedBy("mCacheLock") @NonNull private final WatchedSparseBooleanMatrix mShouldFilterCache; + private final SnapshotCache<WatchedSparseBooleanMatrix> mShouldFilterCacheSnapshot; private volatile boolean mSystemReady = false; /** * A cached snapshot. */ - private final SnapshotCache<AppsFilter> mSnapshot; + private final SnapshotCache<AppsFilterImpl> mSnapshot; - private SnapshotCache<AppsFilter> makeCache() { - return new SnapshotCache<AppsFilter>(this, this) { + private SnapshotCache<AppsFilterImpl> makeCache() { + return new SnapshotCache<AppsFilterImpl>(this, this) { @Override - public AppsFilter createSnapshot() { - AppsFilter s = new AppsFilter(mSource); + public AppsFilterImpl createSnapshot() { + AppsFilterImpl s = new AppsFilterImpl(mSource); + s.mWatchable.seal(); return s; } }; @@ -197,6 +216,15 @@ public class AppsFilter implements Watchable, Snappable { * 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 @@ -251,7 +279,7 @@ public class AppsFilter implements Watchable, Snappable { } @VisibleForTesting(visibility = PRIVATE) - AppsFilter(StateProvider stateProvider, + AppsFilterImpl(StateProvider stateProvider, FeatureConfig featureConfig, String[] forceQueryableList, boolean systemAppsQueryable, @@ -267,31 +295,67 @@ public class AppsFilter implements Watchable, Snappable { mPmInternal = pmInternal; mBackgroundExecutor = backgroundExecutor; mShouldFilterCache = new WatchedSparseBooleanMatrix(); + mShouldFilterCacheSnapshot = new SnapshotCache.Auto<>( + mShouldFilterCache, mShouldFilterCache, "AppsFilter.mShouldFilterCache"); + mImplicitlyQueryable = new WatchedSparseSetArray<>(); + mImplicitQueryableSnapshot = new SnapshotCache.Auto<>( + mImplicitlyQueryable, mImplicitlyQueryable, "AppsFilter.mImplicitlyQueryable"); + mRetainedImplicitlyQueryable = new WatchedSparseSetArray<>(); + mRetainedImplicitlyQueryableSnapshot = new SnapshotCache.Auto<>( + mRetainedImplicitlyQueryable, mRetainedImplicitlyQueryable, + "AppsFilter.mRetainedImplicitlyQueryable"); + mQueriesViaPackage = new WatchedSparseSetArray<>(); + mQueriesViaPackageSnapshot = new SnapshotCache.Auto<>( + mQueriesViaPackage, mQueriesViaPackage, "AppsFilter.mQueriesViaPackage"); + mQueriesViaComponent = new WatchedSparseSetArray<>(); + mQueriesViaComponentSnapshot = new SnapshotCache.Auto<>( + mQueriesViaComponent, mQueriesViaComponent, "AppsFilter.mQueriesViaComponent"); + mQueryableViaUsesLibrary = new WatchedSparseSetArray<>(); + mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Auto<>( + mQueryableViaUsesLibrary, mQueryableViaUsesLibrary, + "AppsFilter.mQueryableViaUsesLibrary"); + mForceQueryable = new WatchedArraySet<>(); + mForceQueryableSnapshot = new SnapshotCache.Auto<>( + mForceQueryable, mForceQueryable, "AppsFilter.mForceQueryable"); + mProtectedBroadcasts = new WatchedArrayList<>(); + mProtectedBroadcastsSnapshot = new SnapshotCache.Auto<>( + mProtectedBroadcasts, mProtectedBroadcasts, "AppsFilter.mProtectedBroadcasts"); + + registerObservers(); + Watchable.verifyWatchedAttributes(this, mObserver); mSnapshot = makeCache(); } /** * The copy constructor is used by PackageManagerService to construct a snapshot. - * Attributes are not deep-copied since these are supposed to be immutable. - * TODO: deep-copy the attributes, if necessary. */ - private AppsFilter(AppsFilter orig) { - Snapshots.copy(mImplicitlyQueryable, orig.mImplicitlyQueryable); - Snapshots.copy(mRetainedImplicitlyQueryable, orig.mRetainedImplicitlyQueryable); - Snapshots.copy(mQueriesViaPackage, orig.mQueriesViaPackage); - Snapshots.copy(mQueriesViaComponent, orig.mQueriesViaComponent); - Snapshots.copy(mQueryableViaUsesLibrary, orig.mQueryableViaUsesLibrary); + private AppsFilterImpl(AppsFilterImpl orig) { + mImplicitlyQueryable = orig.mImplicitQueryableSnapshot.snapshot(); + mImplicitQueryableSnapshot = new SnapshotCache.Sealed<>(); + mRetainedImplicitlyQueryable = orig.mRetainedImplicitlyQueryableSnapshot.snapshot(); + mRetainedImplicitlyQueryableSnapshot = new SnapshotCache.Sealed<>(); + mQueriesViaPackage = orig.mQueriesViaPackageSnapshot.snapshot(); + mQueriesViaPackageSnapshot = new SnapshotCache.Sealed<>(); + mQueriesViaComponent = orig.mQueriesViaComponentSnapshot.snapshot(); + mQueriesViaComponentSnapshot = new SnapshotCache.Sealed<>(); + mQueryableViaUsesLibrary = orig.mQueryableViaUsesLibrarySnapshot.snapshot(); + mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Sealed<>(); + mForceQueryable = orig.mForceQueryableSnapshot.snapshot(); + mForceQueryableSnapshot = new SnapshotCache.Sealed<>(); + mProtectedBroadcasts = orig.mProtectedBroadcastsSnapshot.snapshot(); + mProtectedBroadcastsSnapshot = new SnapshotCache.Sealed<>(); mQueriesViaComponentRequireRecompute = orig.mQueriesViaComponentRequireRecompute; - mForceQueryable.addAll(orig.mForceQueryable); - mForceQueryableByDevicePackageNames = orig.mForceQueryableByDevicePackageNames; + mForceQueryableByDevicePackageNames = + Arrays.copyOf(orig.mForceQueryableByDevicePackageNames, + orig.mForceQueryableByDevicePackageNames.length); mSystemAppsQueryable = orig.mSystemAppsQueryable; mFeatureConfig = orig.mFeatureConfig; mOverlayReferenceMapper = orig.mOverlayReferenceMapper; mStateProvider = orig.mStateProvider; mSystemSigningDetails = orig.mSystemSigningDetails; - mProtectedBroadcasts = orig.mProtectedBroadcasts; synchronized (orig.mCacheLock) { - mShouldFilterCache = orig.mShouldFilterCache.snapshot(); + mShouldFilterCache = orig.mShouldFilterCacheSnapshot.snapshot(); + mShouldFilterCacheSnapshot = new SnapshotCache.Sealed<>(); } mBackgroundExecutor = null; @@ -300,12 +364,24 @@ public class AppsFilter implements Watchable, Snappable { 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 * condition causes the cached snapshot to be cleared asynchronously to this method. */ - public AppsFilter snapshot() { + public AppsFilterSnapshot snapshot() { return mSnapshot.snapshot(); } @@ -366,7 +442,7 @@ public class AppsFilter implements Watchable, Snappable { @Nullable private SparseBooleanArray mLoggingEnabled = null; - private AppsFilter mAppsFilter; + private AppsFilterImpl mAppsFilter; private FeatureConfigImpl( PackageManagerInternal pmInternal, PackageManagerServiceInjector injector) { @@ -374,7 +450,7 @@ public class AppsFilter implements Watchable, Snappable { mInjector = injector; } - public void setAppsFilter(AppsFilter filter) { + public void setAppsFilter(AppsFilterImpl filter) { mAppsFilter = filter; } @@ -478,8 +554,9 @@ public class AppsFilter implements Watchable, Snappable { @Override public void updatePackageState(PackageStateInternal setting, boolean removed) { - final boolean enableLogging = setting.getPkg() != null && - !removed && (setting.getPkg().isTestOnly() || setting.getPkg().isDebuggable()); + final boolean enableLogging = setting.getPkg() != null + && !removed && (setting.getPkg().isTestOnly() + || setting.getPkg().isDebuggable()); enableLogging(setting.getAppId(), enableLogging); if (removed) { mDisabledPackages.remove(setting.getPackageName()); @@ -490,7 +567,7 @@ public class AppsFilter implements Watchable, Snappable { } /** Builder method for an AppsFilter */ - public static AppsFilter create(@NonNull PackageManagerServiceInjector injector, + public static AppsFilterImpl create(@NonNull PackageManagerServiceInjector injector, @NonNull PackageManagerInternal pmInt) { final boolean forceSystemAppsQueryable = injector.getContext().getResources() @@ -514,7 +591,7 @@ public class AppsFilter implements Watchable, Snappable { injector.getUserManagerInternal().getUserInfos()); } }; - AppsFilter appsFilter = new AppsFilter(stateProvider, featureConfig, + AppsFilterImpl appsFilter = new AppsFilterImpl(stateProvider, featureConfig, forcedQueryablePackageNames, forceSystemAppsQueryable, null, injector.getBackgroundExecutor(), pmInt); featureConfig.setAppsFilter(appsFilter); @@ -527,7 +604,7 @@ public class AppsFilter implements Watchable, Snappable { /** Returns true if the querying package may query for the potential target package */ private static boolean canQueryViaComponents(AndroidPackage querying, - AndroidPackage potentialTarget, Set<String> protectedBroadcasts) { + AndroidPackage potentialTarget, WatchedArrayList<String> protectedBroadcasts) { if (!querying.getQueriesIntents().isEmpty()) { for (Intent intent : querying.getQueriesIntents()) { if (matchesPackage(intent, potentialTarget, protectedBroadcasts)) { @@ -599,7 +676,7 @@ public class AppsFilter implements Watchable, Snappable { } private static boolean matchesPackage(Intent intent, AndroidPackage potentialTarget, - Set<String> protectedBroadcasts) { + WatchedArrayList<String> protectedBroadcasts) { if (matchesAnyComponents( intent, potentialTarget.getServices(), null /*protectedBroadcasts*/)) { return true; @@ -620,7 +697,7 @@ public class AppsFilter implements Watchable, Snappable { private static boolean matchesAnyComponents(Intent intent, List<? extends ParsedMainComponent> components, - Set<String> protectedBroadcasts) { + WatchedArrayList<String> protectedBroadcasts) { for (int i = ArrayUtils.size(components) - 1; i >= 0; i--) { ParsedMainComponent component = components.get(i); if (!component.isExported()) { @@ -634,7 +711,7 @@ public class AppsFilter implements Watchable, Snappable { } private static boolean matchesAnyFilter(Intent intent, ParsedComponent component, - Set<String> protectedBroadcasts) { + WatchedArrayList<String> protectedBroadcasts) { List<ParsedIntentInfo> intents = component.getIntents(); for (int i = ArrayUtils.size(intents) - 1; i >= 0; i--) { IntentFilter intentFilter = intents.get(i).getIntentFilter(); @@ -646,10 +723,10 @@ public class AppsFilter implements Watchable, Snappable { } private static boolean matchesIntentFilter(Intent intent, IntentFilter intentFilter, - @Nullable Set<String> protectedBroadcasts) { + @Nullable WatchedArrayList<String> protectedBroadcasts) { return intentFilter.match(intent.getAction(), intent.getType(), intent.getScheme(), - intent.getData(), intent.getCategories(), "AppsFilter", true, protectedBroadcasts) - > 0; + intent.getData(), intent.getCategories(), "AppsFilter", true, + protectedBroadcasts != null ? protectedBroadcasts.untrackedStorage() : null) > 0; } /** @@ -665,7 +742,8 @@ public class AppsFilter implements Watchable, Snappable { if (recipientUid == visibleUid) { return false; } - final boolean changed = retainOnUpdate + final boolean changed; + changed = retainOnUpdate ? mRetainedImplicitlyQueryable.add(recipientUid, visibleUid) : mImplicitlyQueryable.add(recipientUid, visibleUid); if (changed && DEBUG_LOGGING) { @@ -787,7 +865,8 @@ public class AppsFilter implements Watchable, Snappable { for (int i = existingSettings.size() - 1; i >= 0; i--) { final PackageStateInternal existingSetting = existingSettings.valueAt(i); - if (existingSetting.getAppId() == newPkgSetting.getAppId() || existingSetting.getPkg() + if (existingSetting.getAppId() == newPkgSetting.getAppId() + || existingSetting.getPkg() == null) { continue; } @@ -796,11 +875,13 @@ public class AppsFilter implements Watchable, Snappable { if (!newIsForceQueryable) { if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(existingPkg, newPkg, mProtectedBroadcasts)) { - mQueriesViaComponent.add(existingSetting.getAppId(), newPkgSetting.getAppId()); + mQueriesViaComponent.add(existingSetting.getAppId(), + newPkgSetting.getAppId()); } if (canQueryViaPackage(existingPkg, newPkg) || canQueryAsInstaller(existingSetting, newPkg)) { - mQueriesViaPackage.add(existingSetting.getAppId(), newPkgSetting.getAppId()); + mQueriesViaPackage.add(existingSetting.getAppId(), + newPkgSetting.getAppId()); } if (canQueryViaUsesLibrary(existingPkg, newPkg)) { mQueryableViaUsesLibrary.add(existingSetting.getAppId(), @@ -811,11 +892,13 @@ public class AppsFilter implements Watchable, Snappable { if (!mForceQueryable.contains(existingSetting.getAppId())) { if (!mQueriesViaComponentRequireRecompute && canQueryViaComponents(newPkg, existingPkg, mProtectedBroadcasts)) { - mQueriesViaComponent.add(newPkgSetting.getAppId(), existingSetting.getAppId()); + mQueriesViaComponent.add(newPkgSetting.getAppId(), + existingSetting.getAppId()); } if (canQueryViaPackage(newPkg, existingPkg) || canQueryAsInstaller(newPkgSetting, existingPkg)) { - mQueriesViaPackage.add(newPkgSetting.getAppId(), existingSetting.getAppId()); + mQueriesViaPackage.add(newPkgSetting.getAppId(), + existingSetting.getAppId()); } if (canQueryViaUsesLibrary(newPkg, existingPkg)) { mQueryableViaUsesLibrary.add(newPkgSetting.getAppId(), @@ -1048,10 +1131,10 @@ public class AppsFilter implements Watchable, Snappable { && pkgSetting.getSigningDetails().signaturesMatchExactly(sysSigningDetails); } - private ArraySet<String> collectProtectedBroadcasts( + private void collectProtectedBroadcasts( ArrayMap<String, ? extends PackageStateInternal> existingSettings, @Nullable String excludePackage) { - ArraySet<String> ret = new ArraySet<>(); + mProtectedBroadcasts.clear(); for (int i = existingSettings.size() - 1; i >= 0; i--) { PackageStateInternal setting = existingSettings.valueAt(i); if (setting.getPkg() == null || setting.getPkg().getPackageName().equals( @@ -1060,10 +1143,9 @@ public class AppsFilter implements Watchable, Snappable { } final List<String> protectedBroadcasts = setting.getPkg().getProtectedBroadcasts(); if (!protectedBroadcasts.isEmpty()) { - ret.addAll(protectedBroadcasts); + mProtectedBroadcasts.addAll(protectedBroadcasts); } } - return ret; } /** @@ -1097,19 +1179,9 @@ public class AppsFilter implements Watchable, Snappable { } /** - * Fetches all app Ids that a given setting is currently visible to, per provided user. This - * only includes UIDs >= {@link Process#FIRST_APPLICATION_UID} as all other UIDs can already see - * all applications. - * - * If the setting is visible to all UIDs, null is returned. If an app is not visible to any - * applications, the int array will be empty. - * - * @param users the set of users that should be evaluated for this calculation - * @param existingSettings the set of all package settings that currently exist on device - * @return a SparseArray mapping userIds to a sorted int array of appIds that may view the - * provided setting or null if the app is visible to all and no allow list should be - * applied. + * See {@link AppsFilterSnapshot#getVisibilityAllowList(PackageStateInternal, int[], ArrayMap)} */ + @Override @Nullable public SparseArray<int[]> getVisibilityAllowList(PackageStateInternal setting, int[] users, ArrayMap<String, ? extends PackageStateInternal> existingSettings) { @@ -1164,7 +1236,7 @@ public class AppsFilter implements Watchable, Snappable { * Equivalent to calling {@link #addPackage(PackageStateInternal, boolean)} with * {@code isReplace} equal to {@code false}. * - * @see AppsFilter#addPackage(PackageStateInternal, boolean) + * @see AppsFilterImpl#addPackage(PackageStateInternal, boolean) */ public void addPackage(PackageStateInternal newPkgSetting) { addPackage(newPkgSetting, false /* isReplace */); @@ -1178,13 +1250,15 @@ public class AppsFilter implements Watchable, Snappable { */ public void removePackage(PackageStateInternal setting, boolean isReplace) { mStateProvider.runWithState((settings, users) -> { + final ArraySet<String> additionalChangedPackages; final int userCount = users.length; for (int u = 0; u < userCount; u++) { final int userId = users[u].id; final int removingUid = UserHandle.getUid(userId, setting.getAppId()); mImplicitlyQueryable.remove(removingUid); for (int i = mImplicitlyQueryable.size() - 1; i >= 0; i--) { - mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i), removingUid); + mImplicitlyQueryable.remove(mImplicitlyQueryable.keyAt(i), + removingUid); } if (isReplace) { @@ -1201,12 +1275,14 @@ public class AppsFilter implements Watchable, Snappable { if (!mQueriesViaComponentRequireRecompute) { mQueriesViaComponent.remove(setting.getAppId()); for (int i = mQueriesViaComponent.size() - 1; i >= 0; i--) { - mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), setting.getAppId()); + mQueriesViaComponent.remove(mQueriesViaComponent.keyAt(i), + setting.getAppId()); } } mQueriesViaPackage.remove(setting.getAppId()); for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) { - mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), setting.getAppId()); + mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), + setting.getAppId()); } mQueryableViaUsesLibrary.remove(setting.getAppId()); for (int i = mQueryableViaUsesLibrary.size() - 1; i >= 0; i--) { @@ -1216,23 +1292,26 @@ public class AppsFilter implements Watchable, Snappable { mForceQueryable.remove(setting.getAppId()); - if (setting.getPkg() != null && !setting.getPkg().getProtectedBroadcasts().isEmpty()) { + if (setting.getPkg() != null + && !setting.getPkg().getProtectedBroadcasts().isEmpty()) { final String removingPackageName = setting.getPkg().getPackageName(); - final Set<String> protectedBroadcasts = mProtectedBroadcasts; - mProtectedBroadcasts = collectProtectedBroadcasts(settings, removingPackageName); + final ArrayList<String> protectedBroadcasts = new ArrayList<>(); + protectedBroadcasts.addAll(mProtectedBroadcasts.untrackedStorage()); + collectProtectedBroadcasts(settings, removingPackageName); if (!mProtectedBroadcasts.containsAll(protectedBroadcasts)) { mQueriesViaComponentRequireRecompute = true; } } - ArraySet<String> additionalChangedPackages = - mOverlayReferenceMapper.removePkg(setting.getPackageName()); - + additionalChangedPackages = mOverlayReferenceMapper.removePkg(setting.getPackageName()); mFeatureConfig.updatePackageState(setting, true /*removed*/); - // After removing all traces of the package, if it's part of a shared user, re-add other - // shared user members to re-establish visibility between them and other packages. - // NOTE: this must come after all removals from data structures but before we update the + // After removing all traces of the package, if it's part of a shared user, + // re-add other + // shared user members to re-establish visibility between them and other + // packages. + // NOTE: this must come after all removals from data structures but before we + // update the // cache if (setting.hasSharedUser()) { final ArraySet<PackageStateInternal> sharedUserPackages = @@ -1285,15 +1364,11 @@ public class AppsFilter implements Watchable, Snappable { } /** - * Returns true if the calling package should not be able to see the target package, false if no - * filtering should be done. - * - * @param callingUid the uid of the caller attempting to access a package - * @param callingSetting the setting attempting to access a package or null if it could not be - * found - * @param targetPkgSetting the package being accessed - * @param userId the user in which this access is being attempted + * See + * {@link AppsFilterSnapshot#shouldFilterApplication(int, Object, PackageStateInternal, + * int)} */ + @Override public boolean shouldFilterApplication(int callingUid, @Nullable Object callingSetting, PackageStateInternal targetPkgSetting, int userId) { if (DEBUG_TRACING) { @@ -1610,7 +1685,11 @@ public class AppsFilter implements Watchable, Snappable { } } - boolean canQueryPackage(@NonNull AndroidPackage querying, String potentialTarget) { + /** + * See {@link AppsFilterSnapshot#canQueryPackage(AndroidPackage, String)} + */ + @Override + public boolean canQueryPackage(@NonNull AndroidPackage querying, String potentialTarget) { int appId = UserHandle.getAppId(querying.getUid()); if (appId < Process.FIRST_APPLICATION_UID) { return true; @@ -1665,6 +1744,11 @@ public class AppsFilter implements Watchable, Snappable { + targetPkgSetting + " " + description); } + /** + * See {@link AppsFilterSnapshot#dumpQueries(PrintWriter, Integer, DumpState, int[], + * QuadFunction)} + */ + @Override public void dumpQueries( PrintWriter pw, @Nullable Integer filteringAppId, DumpState dumpState, int[] users, QuadFunction<Integer, Integer, Integer, Boolean, String[]> getPackagesForUid) { @@ -1699,7 +1783,8 @@ public class AppsFilter implements Watchable, Snappable { } } pw.println(" system apps queryable: " + mSystemAppsQueryable); - dumpPackageSet(pw, filteringAppId, mForceQueryable, "forceQueryable", " ", expandPackages); + dumpPackageSet(pw, filteringAppId, mForceQueryable.untrackedStorage(), + "forceQueryable", " ", expandPackages); pw.println(" queries via package name:"); dumpQueriesMap(pw, filteringAppId, mQueriesViaPackage, " ", expandPackages); pw.println(" queries via component:"); @@ -1715,11 +1800,12 @@ public class AppsFilter implements Watchable, Snappable { mRetainedImplicitlyQueryable, " ", expandPackages); } pw.println(" queryable via uses-library:"); - dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, " ", expandPackages); + dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, " ", + expandPackages); } private static void dumpQueriesMap(PrintWriter pw, @Nullable Integer filteringId, - SparseSetArray<Integer> queriesMap, String spacing, + WatchedSparseSetArray<Integer> queriesMap, String spacing, @Nullable ToString<Integer> toString) { for (int i = 0; i < queriesMap.size(); i++) { Integer callingId = queriesMap.keyAt(i); @@ -1748,7 +1834,7 @@ public class AppsFilter implements Watchable, Snappable { } private static <T> void dumpPackageSet(PrintWriter pw, @Nullable T filteringId, - Set<T> targetPkgSet, String subTitle, String spacing, + ArraySet<T> targetPkgSet, String subTitle, String spacing, @Nullable ToString<T> toString) { if (targetPkgSet != null && targetPkgSet.size() > 0 && (filteringId == null || targetPkgSet.contains(filteringId))) { diff --git a/services/core/java/com/android/server/pm/AppsFilterSnapshot.java b/services/core/java/com/android/server/pm/AppsFilterSnapshot.java new file mode 100644 index 000000000000..cb8c649ded00 --- /dev/null +++ b/services/core/java/com/android/server/pm/AppsFilterSnapshot.java @@ -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.server.pm; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Process; +import android.util.ArrayMap; +import android.util.SparseArray; + +import com.android.internal.util.function.QuadFunction; +import com.android.server.pm.parsing.pkg.AndroidPackage; +import com.android.server.pm.pkg.PackageStateInternal; + +import java.io.PrintWriter; + +/** + * Read-only interface used by computer and snapshots to query the visibility of packages + */ +public interface AppsFilterSnapshot { + /** + * Fetches all app Ids that a given setting is currently visible to, per provided user. This + * only includes UIDs >= {@link Process#FIRST_APPLICATION_UID} as all other UIDs can already see + * all applications. + * + * If the setting is visible to all UIDs, null is returned. If an app is not visible to any + * applications, the int array will be empty. + * + * @param users the set of users that should be evaluated for this calculation + * @param existingSettings the set of all package settings that currently exist on device + * @return a SparseArray mapping userIds to a sorted int array of appIds that may view the + * provided setting or null if the app is visible to all and no allow list should be + * applied. + */ + SparseArray<int[]> getVisibilityAllowList(PackageStateInternal setting, int[] users, + ArrayMap<String, ? extends PackageStateInternal> existingSettings); + + /** + * Returns true if the calling package should not be able to see the target package, false if no + * filtering should be done. + * + * @param callingUid the uid of the caller attempting to access a package + * @param callingSetting the setting attempting to access a package or null if it could not be + * found + * @param targetPkgSetting the package being accessed + * @param userId the user in which this access is being attempted + */ + boolean shouldFilterApplication(int callingUid, @Nullable Object callingSetting, + PackageStateInternal targetPkgSetting, int userId); + + /** + * Returns whether the querying package is allowed to see the target package. + * + * @param querying the querying package + * @param potentialTarget the package name of the target package + */ + boolean canQueryPackage(@NonNull AndroidPackage querying, String potentialTarget); + + /** + * Dump the packages that are queryable by the querying package. + * + * @param pw the output print writer + * @param filteringAppId the querying package's app ID + * @param dumpState the state of the dumping + * @param users the users for which the packages are installed + * @param getPackagesForUid the function that produces the package names for given uids + */ + void dumpQueries(PrintWriter pw, @Nullable Integer filteringAppId, DumpState dumpState, + int[] users, + QuadFunction<Integer, Integer, Integer, Boolean, String[]> getPackagesForUid); + +} diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java index df7c3ec6f260..80d61b593fd2 100644 --- a/services/core/java/com/android/server/pm/ComputerEngine.java +++ b/services/core/java/com/android/server/pm/ComputerEngine.java @@ -385,7 +385,7 @@ public class ComputerEngine implements Computer { private final ResolveInfo mInstantAppInstallerInfo; private final InstantAppRegistry mInstantAppRegistry; private final ApplicationInfo mLocalAndroidApplication; - private final AppsFilter mAppsFilter; + private final AppsFilterSnapshot mAppsFilter; private final WatchedArrayMap<String, Integer> mFrozenPackages; // Immutable service attribute diff --git a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java index 2fe7913342a2..ec6443db9f0f 100644 --- a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java +++ b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java @@ -722,6 +722,11 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal { return snapshot().getSharedUser(sharedUserAppId); } + @Override + public boolean isUidPrivileged(int uid) { + return snapshot().isUidPrivileged(uid); + } + @NonNull @Override @Deprecated diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index f6d8d72cc382..e1af9a7ab96f 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -720,7 +720,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService } @Watched - final AppsFilter mAppsFilter; + final AppsFilterImpl mAppsFilter; final PackageParser2.Callback mPackageParserCallback; @@ -979,7 +979,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService public final InstantAppRegistry instantAppRegistry; public final ApplicationInfo androidApplication; public final String appPredictionServicePackage; - public final AppsFilter appsFilter; + public final AppsFilterSnapshot appsFilter; public final ComponentResolverApi componentResolver; public final PackageManagerService service; public final WatchedArrayMap<String, Integer> frozenPackages; @@ -1431,7 +1431,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService RuntimePermissionsPersistence.createInstance(), i.getPermissionManagerServiceInternal(), domainVerificationService, lock), - (i, pm) -> AppsFilter.create(i, i.getLocalService(PackageManagerInternal.class)), + (i, pm) -> AppsFilterImpl.create(i, + i.getLocalService(PackageManagerInternal.class)), (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"), (i, pm) -> SystemConfig.getInstance(), (i, pm) -> new PackageDexOptimizer(i.getInstaller(), i.getInstallLock(), diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java b/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java index a02237fa90ce..396994b04514 100644 --- a/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java +++ b/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java @@ -99,7 +99,7 @@ public class PackageManagerServiceInjector { private final Singleton<UserManagerService> mUserManagerProducer; private final Singleton<Settings> mSettingsProducer; - private final Singleton<AppsFilter> mAppsFilterProducer; + private final Singleton<AppsFilterImpl> mAppsFilterProducer; private final Singleton<PlatformCompat> mPlatformCompatProducer; private final Singleton<SystemConfig> mSystemConfigProducer; @@ -148,7 +148,7 @@ public class PackageManagerServiceInjector { Producer<PermissionManagerServiceInternal> permissionManagerServiceProducer, Producer<UserManagerService> userManagerProducer, Producer<Settings> settingsProducer, - Producer<AppsFilter> appsFilterProducer, + Producer<AppsFilterImpl> appsFilterProducer, Producer<PlatformCompat> platformCompatProducer, Producer<SystemConfig> systemConfigProducer, Producer<PackageDexOptimizer> packageDexOptimizerProducer, @@ -282,7 +282,7 @@ public class PackageManagerServiceInjector { return mSettingsProducer.get(this, mPackageManager); } - public AppsFilter getAppsFilter() { + public AppsFilterImpl getAppsFilter() { return mAppsFilterProducer.get(this, mPackageManager); } diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index d340561c2862..ee0fdc07f841 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -5413,190 +5413,170 @@ public class UserManagerService extends IUserManager.Stub { (new Shell()).exec(this, in, out, err, args, callback, resultReceiver); } - private static final String PREFIX_HELP_COMMAND = " "; - private static final String PREFIX_HELP_DESCRIPTION = " "; - private static final String PREFIX_HELP_DESCRIPTION_EXTRA_LINES = " "; - - private static final String CMD_HELP = "help"; - private static final String CMD_LIST = "list"; - private static final String CMD_REPORT_SYSTEM_USER_PACKAGE_ALLOWLIST_PROBLEMS = - "report-system-user-package-whitelist-problems"; - - private static final String ARG_V = "-v"; - private static final String ARG_VERBOSE = "--verbose"; - private static final String ARG_ALL = "--all"; - private static final String ARG_CRITICAL_ONLY = "--critical-only"; - private static final String ARG_MODE = "--mode"; - private final class Shell extends ShellCommand { - @Override - public void onHelp() { - final PrintWriter pw = getOutPrintWriter(); - pw.printf("User manager (user) commands:\n"); - - pw.printf("%s%s\n", PREFIX_HELP_COMMAND, CMD_HELP); - pw.printf("%sPrints this help text.\n\n", PREFIX_HELP_DESCRIPTION); - - pw.printf("%s%s [%s] [%s]\n", PREFIX_HELP_COMMAND, CMD_LIST, ARG_V, ARG_ALL); - pw.printf("%sPrints all users on the system.\n\n", PREFIX_HELP_DESCRIPTION); - - pw.printf("%s%s [%s | %s] [%s] [%s MODE]\n", PREFIX_HELP_COMMAND, - CMD_REPORT_SYSTEM_USER_PACKAGE_ALLOWLIST_PROBLEMS, - ARG_V, ARG_VERBOSE, ARG_CRITICAL_ONLY, ARG_MODE); - - pw.printf("%sReports all issues on user-type package allowlist XML files. Options:\n", - PREFIX_HELP_DESCRIPTION); - pw.printf("%s%s | %s: shows extra info, like number of issues\n", - PREFIX_HELP_DESCRIPTION, ARG_V, ARG_VERBOSE); - pw.printf("%s%s: show only critical issues, excluding warnings\n", - PREFIX_HELP_DESCRIPTION, ARG_CRITICAL_ONLY); - pw.printf("%s%s MODE: shows what errors would be if device used mode MODE\n" - + "%s(where MODE is the allowlist mode integer as defined by " - + "config_userTypePackageWhitelistMode)\n\n", - PREFIX_HELP_DESCRIPTION, ARG_MODE, PREFIX_HELP_DESCRIPTION_EXTRA_LINES); - } - - @Override - public int onCommand(String cmd) { - if (cmd == null) { - return handleDefaultCommands(cmd); + @Override + public void onHelp() { + final PrintWriter pw = getOutPrintWriter(); + pw.println("User manager (user) commands:"); + pw.println(" help"); + pw.println(" Prints this help text."); + pw.println(); + pw.println(" list [-v | --verbose] [--all]"); + pw.println(" Prints all users on the system."); + pw.println(); + pw.println(" report-system-user-package-whitelist-problems [-v | --verbose] " + + "[--critical-only] [--mode MODE]"); + pw.println(" Reports all issues on user-type package allowlist XML files. Options:"); + pw.println(" -v | --verbose: shows extra info, like number of issues"); + pw.println(" --critical-only: show only critical issues, excluding warnings"); + pw.println(" --mode MODE: shows what errors would be if device used mode MODE"); + pw.println(" (where MODE is the allowlist mode integer as defined by " + + "config_userTypePackageWhitelistMode)"); } - try { - switch(cmd) { - case CMD_LIST: - return runList(); - case CMD_REPORT_SYSTEM_USER_PACKAGE_ALLOWLIST_PROBLEMS: - return runReportPackageAllowlistProblems(); - default: - return handleDefaultCommands(cmd); + @Override + public int onCommand(String cmd) { + if (cmd == null) { + return handleDefaultCommands(cmd); } - } catch (RemoteException e) { - getOutPrintWriter().println("Remote exception: " + e); + + try { + switch(cmd) { + case "list": + return runList(); + case "report-system-user-package-whitelist-problems": + return runReportPackageAllowlistProblems(); + default: + return handleDefaultCommands(cmd); + } + } catch (RemoteException e) { + getOutPrintWriter().println("Remote exception: " + e); + } + return -1; } - return -1; - } - private int runList() throws RemoteException { - final PrintWriter pw = getOutPrintWriter(); - boolean all = false; - boolean verbose = false; - String opt; - while ((opt = getNextOption()) != null) { - switch (opt) { - case ARG_V: - verbose = true; - break; - case ARG_ALL: - all = true; - break; - default: - pw.println("Invalid option: " + opt); - return -1; - } - } - final IActivityManager am = ActivityManager.getService(); - final List<UserInfo> users = getUsers(/* excludePartial= */ !all, - /* excludingDying=*/ false, /* excludePreCreated= */ !all); - if (users == null) { - pw.println("Error: couldn't get users"); - return 1; - } else { - final int size = users.size(); - int currentUser = UserHandle.USER_NULL; - if (verbose) { - pw.printf("%d users:\n\n", size); - currentUser = am.getCurrentUser().id; - } else { - // NOTE: the standard "list users" command is used by integration tests and - // hence should not be changed. If you need to add more info, use the - // verbose option. - pw.println("Users:"); + private int runList() throws RemoteException { + final PrintWriter pw = getOutPrintWriter(); + boolean all = false; + boolean verbose = false; + String opt; + while ((opt = getNextOption()) != null) { + switch (opt) { + case "-v": + case "--verbose": + verbose = true; + break; + case "--all": + all = true; + break; + default: + pw.println("Invalid option: " + opt); + return -1; + } } - for (int i = 0; i < size; i++) { - final UserInfo user = users.get(i); - final boolean running = am.isUserRunning(user.id, 0); - final boolean current = user.id == currentUser; - final boolean hasParent = user.profileGroupId != user.id - && user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID; + final IActivityManager am = ActivityManager.getService(); + final List<UserInfo> users = getUsers(/* excludePartial= */ !all, + /* excludeDying= */ false, /* excludePreCreated= */ !all); + if (users == null) { + pw.println("Error: couldn't get users"); + return 1; + } else { + final int size = users.size(); + int currentUser = UserHandle.USER_NULL; if (verbose) { - final DevicePolicyManagerInternal dpm = getDevicePolicyManagerInternal(); - String deviceOwner = ""; - String profileOwner = ""; - if (dpm != null) { - final long ident = Binder.clearCallingIdentity(); - // NOTE: dpm methods below CANNOT be called while holding the mUsersLock - try { - if (dpm.getDeviceOwnerUserId() == user.id) { - deviceOwner = " (device-owner)"; - } - if (dpm.getProfileOwnerAsUser(user.id) != null) { - profileOwner = " (profile-owner)"; - } - } finally { - Binder.restoreCallingIdentity(ident); - } - } - pw.printf("%d: id=%d, name=%s, type=%s, flags=%s%s%s%s%s%s%s%s%s\n", - i, - user.id, - user.name, - user.userType.replace("android.os.usertype.", ""), - UserInfo.flagsToString(user.flags), - hasParent ? " (parentId=" + user.profileGroupId + ")" : "", - running ? " (running)" : "", - user.partial ? " (partial)" : "", - user.preCreated ? " (pre-created)" : "", - user.convertedFromPreCreated ? " (converted)" : "", - deviceOwner, profileOwner, - current ? " (current)" : ""); + pw.printf("%d users:\n\n", size); + currentUser = am.getCurrentUser().id; } else { // NOTE: the standard "list users" command is used by integration tests and // hence should not be changed. If you need to add more info, use the // verbose option. - pw.printf("\t%s%s\n", user, running ? " running" : ""); + pw.println("Users:"); } + for (int i = 0; i < size; i++) { + final UserInfo user = users.get(i); + final boolean running = am.isUserRunning(user.id, 0); + final boolean current = user.id == currentUser; + final boolean hasParent = user.profileGroupId != user.id + && user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID; + if (verbose) { + final DevicePolicyManagerInternal dpm = getDevicePolicyManagerInternal(); + String deviceOwner = ""; + String profileOwner = ""; + if (dpm != null) { + final long ident = Binder.clearCallingIdentity(); + // NOTE: dpm methods below CANNOT be called while holding the mUsersLock + try { + if (dpm.getDeviceOwnerUserId() == user.id) { + deviceOwner = " (device-owner)"; + } + if (dpm.getProfileOwnerAsUser(user.id) != null) { + profileOwner = " (profile-owner)"; + } + } finally { + Binder.restoreCallingIdentity(ident); + } + } + pw.printf("%d: id=%d, name=%s, type=%s, flags=%s%s%s%s%s%s%s%s%s\n", + i, + user.id, + user.name, + user.userType.replace("android.os.usertype.", ""), + UserInfo.flagsToString(user.flags), + hasParent ? " (parentId=" + user.profileGroupId + ")" : "", + running ? " (running)" : "", + user.partial ? " (partial)" : "", + user.preCreated ? " (pre-created)" : "", + user.convertedFromPreCreated ? " (converted)" : "", + deviceOwner, profileOwner, + current ? " (current)" : ""); + } else { + // NOTE: the standard "list users" command is used by integration tests and + // hence should not be changed. If you need to add more info, use the + // verbose option. + pw.printf("\t%s%s\n", user, running ? " running" : ""); + } + } + return 0; } - return 0; } - } - private int runReportPackageAllowlistProblems() { - final PrintWriter pw = getOutPrintWriter(); - boolean verbose = false; - boolean criticalOnly = false; - int mode = UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_NONE; - String opt; - while ((opt = getNextOption()) != null) { - switch (opt) { - case ARG_V: - case ARG_VERBOSE: - verbose = true; - break; - case ARG_CRITICAL_ONLY: - criticalOnly = true; - break; - case ARG_MODE: - mode = Integer.parseInt(getNextArgRequired()); - break; - default: - pw.println("Invalid option: " + opt); - return -1; + private int runReportPackageAllowlistProblems() { + final PrintWriter pw = getOutPrintWriter(); + boolean verbose = false; + boolean criticalOnly = false; + int mode = UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_NONE; + String opt; + while ((opt = getNextOption()) != null) { + switch (opt) { + case "-v": + case "--verbose": + verbose = true; + break; + case "--critical-only": + criticalOnly = true; + break; + case "--mode": + mode = Integer.parseInt(getNextArgRequired()); + break; + default: + pw.println("Invalid option: " + opt); + return -1; + } } - } - Slog.d(LOG_TAG, "runReportPackageAllowlistProblems(): verbose=" + verbose - + ", criticalOnly=" + criticalOnly - + ", mode=" + UserSystemPackageInstaller.modeToString(mode)); + Slog.d(LOG_TAG, "runReportPackageAllowlistProblems(): verbose=" + verbose + + ", criticalOnly=" + criticalOnly + + ", mode=" + UserSystemPackageInstaller.modeToString(mode)); - try (IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ")) { - mSystemPackageInstaller.dumpPackageWhitelistProblems(ipw, mode, verbose, - criticalOnly); + try (IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ")) { + mSystemPackageInstaller.dumpPackageWhitelistProblems(ipw, mode, verbose, + criticalOnly); + } + return 0; } - return 0; - } - } + + } // class Shell @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { diff --git a/services/core/java/com/android/server/pm/parsing/library/ApexSharedLibraryUpdater.java b/services/core/java/com/android/server/pm/parsing/library/ApexSharedLibraryUpdater.java index 0418afbf29ee..1a2ff264319e 100644 --- a/services/core/java/com/android/server/pm/parsing/library/ApexSharedLibraryUpdater.java +++ b/services/core/java/com/android/server/pm/parsing/library/ApexSharedLibraryUpdater.java @@ -19,6 +19,7 @@ package com.android.server.pm.parsing.library; import android.util.ArrayMap; import com.android.internal.annotations.VisibleForTesting; +import com.android.modules.utils.build.UnboundedSdkLevel; import com.android.server.SystemConfig; import com.android.server.pm.parsing.pkg.ParsedPackage; @@ -51,8 +52,11 @@ public class ApexSharedLibraryUpdater extends PackageSharedLibraryUpdater { private void updateSharedLibraryForPackage(SystemConfig.SharedLibraryEntry entry, ParsedPackage parsedPackage) { - if (entry.onBootclasspathBefore != 0 - && parsedPackage.getTargetSdkVersion() < entry.onBootclasspathBefore) { + if (entry.onBootclasspathBefore != null + && isTargetSdkAtMost( + parsedPackage.getTargetSdkVersion(), + entry.onBootclasspathBefore) + && UnboundedSdkLevel.isAtLeast(entry.onBootclasspathBefore)) { // this package targets an API where this library was in the BCP, so add // the library transparently in case the package is using it prefixRequiredLibrary(parsedPackage, entry.name); @@ -64,4 +68,19 @@ public class ApexSharedLibraryUpdater extends PackageSharedLibraryUpdater { removeLibrary(parsedPackage, entry.name); } } + + private static boolean isTargetSdkAtMost(int targetSdk, String onBcpBefore) { + if (isCodename(onBcpBefore)) { + return targetSdk < 10000; + } + return targetSdk < Integer.parseInt(onBcpBefore); + } + + private static boolean isCodename(String version) { + if (version.length() == 0) { + throw new IllegalArgumentException(); + } + // assume Android codenames start with upper case letters. + return Character.isUpperCase((version.charAt(0))); + } } diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java index 70d69c663572..e157a277366f 100644 --- a/services/core/java/com/android/server/policy/AppOpsPolicy.java +++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java @@ -187,8 +187,12 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat initializeActivityRecognizersTags(); - // If this device does not have telephony, restrict the phone call ops - if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { + // Restrict phone call ops if the TelecomService will not start (conditioned on having + // FEATURE_MICROPHONE, FEATURE_TELECOM, or FEATURE_TELEPHONY). + PackageManager pm = mContext.getPackageManager(); + if (!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) + && !pm.hasSystemFeature(PackageManager.FEATURE_MICROPHONE) + && !pm.hasSystemFeature(PackageManager.FEATURE_TELECOM)) { AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class); appOps.setUserRestrictionForUser(AppOpsManager.OP_PHONE_CALL_MICROPHONE, true, mToken, null, UserHandle.USER_ALL); diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java index c0ab65a3215c..05d92beed11f 100644 --- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java +++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandler.java @@ -17,7 +17,6 @@ package com.android.server.soundtrigger_middleware; import android.annotation.NonNull; -import android.media.permission.SafeCloseable; import android.media.soundtrigger.ModelParameterRange; import android.media.soundtrigger.PhraseRecognitionEvent; import android.media.soundtrigger.PhraseSoundModel; @@ -30,6 +29,7 @@ import android.media.soundtrigger.Status; import android.os.IBinder; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import java.util.Queue; @@ -63,18 +63,24 @@ import java.util.concurrent.ConcurrentHashMap; */ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal, ICaptureStateNotifier.Listener { - private final @NonNull ISoundTriggerHal mDelegate; + @NonNull private final ISoundTriggerHal mDelegate; private GlobalCallback mGlobalCallback; + /** + * This lock must be held to synchronize forward calls (start/stop/onCaptureStateChange) that + * update the mActiveModels set and mCaptureState. + * It must not be locked in HAL callbacks to avoid deadlocks. + */ + @NonNull private final Object mStartStopLock = new Object(); /** * Information about a model that is currently loaded. This is needed in order to be able to * send abort events to its designated callback. */ private static class LoadedModel { - final int type; - final @NonNull ModelCallback callback; + public final int type; + @NonNull public final ModelCallback callback; - private LoadedModel(int type, @NonNull ModelCallback callback) { + LoadedModel(int type, @NonNull ModelCallback callback) { this.type = type; this.callback = callback; } @@ -83,19 +89,19 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal /** * This map holds the model type for every model that is loaded. */ - private final @NonNull Map<Integer, LoadedModel> mLoadedModels = new ConcurrentHashMap<>(); + @NonNull private final Map<Integer, LoadedModel> mLoadedModels = new ConcurrentHashMap<>(); /** * A set of all models that are currently active. * We use this in order to know which models to stop in case of external capture. * Used as a lock to synchronize operations that effect activity. */ - private final @NonNull Set<Integer> mActiveModels = new HashSet<>(); + @NonNull private final Set<Integer> mActiveModels = new HashSet<>(); /** * Notifier for changes in capture state. */ - private final @NonNull ICaptureStateNotifier mNotifier; + @NonNull private final ICaptureStateNotifier mNotifier; /** * Whether capture is active. @@ -106,10 +112,10 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal * Since we're wrapping the death recipient, we need to keep a translation map for unlinking. * Key is the client recipient, value is the wrapper. */ - private final @NonNull Map<IBinder.DeathRecipient, IBinder.DeathRecipient> + @NonNull private final Map<IBinder.DeathRecipient, IBinder.DeathRecipient> mDeathRecipientMap = new ConcurrentHashMap<>(); - private final @NonNull CallbackThread mCallbackThread = new CallbackThread(); + @NonNull private final CallbackThread mCallbackThread = new CallbackThread(); public SoundTriggerHalConcurrentCaptureHandler( @NonNull ISoundTriggerHal delegate, @@ -122,20 +128,28 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal @Override public void startRecognition(int modelHandle, int deviceHandle, int ioHandle, RecognitionConfig config) { - synchronized (mActiveModels) { - if (mCaptureState) { - throw new RecoverableException(Status.RESOURCE_CONTENTION); + synchronized (mStartStopLock) { + synchronized (mActiveModels) { + if (mCaptureState) { + throw new RecoverableException(Status.RESOURCE_CONTENTION); + } + mDelegate.startRecognition(modelHandle, deviceHandle, ioHandle, config); + mActiveModels.add(modelHandle); } - mDelegate.startRecognition(modelHandle, deviceHandle, ioHandle, config); - mActiveModels.add(modelHandle); } } @Override public void stopRecognition(int modelHandle) { - synchronized (mActiveModels) { - mDelegate.stopRecognition(modelHandle); - mActiveModels.remove(modelHandle); + synchronized (mStartStopLock) { + boolean wasActive; + synchronized (mActiveModels) { + wasActive = mActiveModels.remove(modelHandle); + } + if (wasActive) { + // Must be done outside of the lock, since it may trigger synchronous callbacks. + mDelegate.stopRecognition(modelHandle); + } } // Block until all previous events are delivered. Since this is potentially blocking on // upward calls, it must be done outside the lock. @@ -144,27 +158,38 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal @Override public void onCaptureStateChange(boolean active) { - synchronized (mActiveModels) { + synchronized (mStartStopLock) { if (active) { - // Abort all active models. This must be done as one transaction to the event - // thread, in order to be able to dedupe events before they are delivered. - try (SafeCloseable ignored = mCallbackThread.stallReader()) { - for (int modelHandle : mActiveModels) { - mDelegate.stopRecognition(modelHandle); - LoadedModel model = mLoadedModels.get(modelHandle); - // An abort event must be the last one for its model. - mCallbackThread.pushWithDedupe(modelHandle, true, - () -> notifyAbort(modelHandle, model)); - } - } + abortAllActiveModels(); } else { - mGlobalCallback.onResourcesAvailable(); + if (mGlobalCallback != null) { + mGlobalCallback.onResourcesAvailable(); + } } - mCaptureState = active; } } + private void abortAllActiveModels() { + while (true) { + int toStop; + synchronized (mActiveModels) { + Iterator<Integer> iterator = mActiveModels.iterator(); + if (!iterator.hasNext()) { + return; + } + toStop = iterator.next(); + mActiveModels.remove(toStop); + } + // Invoke stop outside of the lock. + mDelegate.stopRecognition(toStop); + + LoadedModel model = mLoadedModels.get(toStop); + // Queue an abort event (no need to flush). + mCallbackThread.push(() -> notifyAbort(toStop, model)); + } + } + @Override public int loadSoundModel(SoundModel soundModel, ModelCallback callback) { int handle = mDelegate.loadSoundModel(soundModel, new CallbackWrapper(callback)); @@ -188,23 +213,13 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal @Override public void registerCallback(GlobalCallback callback) { - mGlobalCallback = new GlobalCallback() { - @Override - public void onResourcesAvailable() { - mCallbackThread.push(callback::onResourcesAvailable); - } - }; + mGlobalCallback = () -> mCallbackThread.push(callback::onResourcesAvailable); mDelegate.registerCallback(mGlobalCallback); } @Override public void linkToDeath(IBinder.DeathRecipient recipient) { - IBinder.DeathRecipient wrapper = new IBinder.DeathRecipient() { - @Override - public void binderDied() { - mCallbackThread.push(() -> recipient.binderDied()); - } - }; + IBinder.DeathRecipient wrapper = () -> mCallbackThread.push(recipient::binderDied); mDelegate.linkToDeath(wrapper); mDeathRecipientMap.put(recipient, wrapper); } @@ -215,7 +230,7 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal } private class CallbackWrapper implements ISoundTriggerHal.ModelCallback { - private final @NonNull ISoundTriggerHal.ModelCallback mDelegateCallback; + @NonNull private final ISoundTriggerHal.ModelCallback mDelegateCallback; private CallbackWrapper(@NonNull ModelCallback delegateCallback) { mDelegateCallback = delegateCallback; @@ -223,18 +238,36 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal @Override public void recognitionCallback(int modelHandle, RecognitionEvent event) { - // A recognition event must be the last one for its model, unless it is a forced one - // (those leave the model active). - mCallbackThread.pushWithDedupe(modelHandle, !event.recognitionStillActive, - () -> mDelegateCallback.recognitionCallback(modelHandle, event)); + synchronized (mActiveModels) { + if (!mActiveModels.contains(modelHandle)) { + // Discard the event. + return; + } + if (!event.recognitionStillActive) { + mActiveModels.remove(modelHandle); + } + // A recognition event must be the last one for its model, unless it indicates that + // recognition is still active. + mCallbackThread.push( + () -> mDelegateCallback.recognitionCallback(modelHandle, event)); + } } @Override public void phraseRecognitionCallback(int modelHandle, PhraseRecognitionEvent event) { - // A recognition event must be the last one for its model, unless it is a forced one - // (those leave the model active). - mCallbackThread.pushWithDedupe(modelHandle, !event.common.recognitionStillActive, - () -> mDelegateCallback.phraseRecognitionCallback(modelHandle, event)); + synchronized (mActiveModels) { + if (!mActiveModels.contains(modelHandle)) { + // Discard the event. + return; + } + if (!event.common.recognitionStillActive) { + mActiveModels.remove(modelHandle); + } + // A recognition event must be the last one for its model, unless it indicates that + // recognition is still active. + mCallbackThread.push( + () -> mDelegateCallback.phraseRecognitionCallback(modelHandle, event)); + } } @Override @@ -254,36 +287,12 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal * <ul> * <li>Events are processed on a separate thread than the thread that pushed them, in the order * they were pushed. - * <li>Events can be deduped upon entry to the queue. This is achieved as follows: - * <ul> - * <li>Temporarily stall the reader via {@link #stallReader()}. - * <li>Within this scope, push as many events as needed via - * {@link #pushWithDedupe(int, boolean, Runnable)}. - * If an event with the same model handle as the one being pushed is already in the queue - * and has been marked as "lastForModel", the new event will be discarded before entering - * the queue. - * <li>Finally, un-stall the reader by existing the scope. - * <li>Events that do not require deduping can be pushed via {@link #push(Runnable)}. - * </ul> * <li>Events can be flushed via {@link #flush()}. This will block until all events pushed prior * to this call have been fully processed. * </ul> */ private static class CallbackThread { - private static class Entry { - final boolean lastForModel; - final int modelHandle; - final Runnable runnable; - - private Entry(boolean lastForModel, int modelHandle, Runnable runnable) { - this.lastForModel = lastForModel; - this.modelHandle = modelHandle; - this.runnable = runnable; - } - } - - private boolean mStallReader = false; - private final Queue<Entry> mList = new LinkedList<>(); + private final Queue<Runnable> mList = new LinkedList<>(); private int mPushCount = 0; private int mProcessedCount = 0; @@ -312,23 +321,11 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal * @param runnable The runnable to push. */ void push(Runnable runnable) { - pushEntry(new Entry(false, 0, runnable), false); - } - - - /** - * Push a new runnable to the queue, with deduping. - * If an entry with the same model handle is already in the queue and was designated as - * last for model, this one will be discarded. - * - * @param modelHandle The model handle, used for deduping purposes. - * @param lastForModel If true, this entry will be considered the last one for this model - * and any subsequence calls for this handle (whether lastForModel or - * not) will be discarded while this entry is in the queue. - * @param runnable The runnable to push. - */ - void pushWithDedupe(int modelHandle, boolean lastForModel, Runnable runnable) { - pushEntry(new Entry(lastForModel, modelHandle, runnable), true); + synchronized (mList) { + mList.add(runnable); + mPushCount++; + mList.notifyAll(); + } } /** @@ -346,45 +343,15 @@ public class SoundTriggerHalConcurrentCaptureHandler implements ISoundTriggerHal } } - /** - * Creates a scope (using a try-with-resources block), within which events that are pushed - * remain queued and processed. This is useful in order to utilize deduping. - */ - SafeCloseable stallReader() { - synchronized (mList) { - mStallReader = true; - return () -> { - synchronized (mList) { - mStallReader = false; - mList.notifyAll(); - } - }; - } - } - - private void pushEntry(Entry entry, boolean dedupe) { - synchronized (mList) { - if (dedupe) { - for (Entry existing : mList) { - if (existing.lastForModel && existing.modelHandle == entry.modelHandle) { - return; - } - } - } - mList.add(entry); - mPushCount++; - mList.notifyAll(); - } - } - private Runnable pop() throws InterruptedException { synchronized (mList) { - while (mStallReader || mList.isEmpty()) { + while (mList.isEmpty()) { mList.wait(); } - return mList.remove().runnable; + return mList.remove(); } } + } /** Notify the client that recognition has been aborted. */ diff --git a/services/core/java/com/android/server/utils/WatchedArrayList.java b/services/core/java/com/android/server/utils/WatchedArrayList.java index bb0ba1329d86..6059f9675e34 100644 --- a/services/core/java/com/android/server/utils/WatchedArrayList.java +++ b/services/core/java/com/android/server/utils/WatchedArrayList.java @@ -273,6 +273,13 @@ public class WatchedArrayList<E> extends WatchableImpl } /** + * Return true if all the objects in the given collection are in this array list. + */ + public boolean containsAll(Collection<?> c) { + return mStorage.containsAll(c); + } + + /** * Ensure capacity. */ public void ensureCapacity(int min) { diff --git a/services/core/java/com/android/server/utils/WatchedSparseBooleanMatrix.java b/services/core/java/com/android/server/utils/WatchedSparseBooleanMatrix.java index 25ae00004b3e..c43e7f9babe6 100644 --- a/services/core/java/com/android/server/utils/WatchedSparseBooleanMatrix.java +++ b/services/core/java/com/android/server/utils/WatchedSparseBooleanMatrix.java @@ -18,6 +18,7 @@ package com.android.server.utils; import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; @@ -168,12 +169,19 @@ public class WatchedSparseBooleanMatrix extends WatchableImpl implements Snappab * A copy constructor that can be used for snapshotting. */ private WatchedSparseBooleanMatrix(WatchedSparseBooleanMatrix r) { - mOrder = r.mOrder; - mSize = r.mSize; - mKeys = r.mKeys.clone(); - mMap = r.mMap.clone(); - mInUse = r.mInUse.clone(); - mValues = r.mValues.clone(); + copyFrom(r); + } + + /** + * Copy from src to this. + */ + public void copyFrom(@NonNull WatchedSparseBooleanMatrix src) { + mOrder = src.mOrder; + mSize = src.mSize; + mKeys = src.mKeys.clone(); + mMap = src.mMap.clone(); + mInUse = src.mInUse.clone(); + mValues = src.mValues.clone(); } /** diff --git a/services/core/java/com/android/server/utils/WatchedSparseSetArray.java b/services/core/java/com/android/server/utils/WatchedSparseSetArray.java new file mode 100644 index 000000000000..05db12e49a13 --- /dev/null +++ b/services/core/java/com/android/server/utils/WatchedSparseSetArray.java @@ -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.server.utils; + +import android.annotation.NonNull; +import android.util.ArraySet; +import android.util.SparseSetArray; + + +/** + * A watched variant of SparseSetArray. Changes to the array are notified to + * registered {@link Watcher}s. + * @param <T> The element type, stored in the SparseSetArray. + */ +public class WatchedSparseSetArray<T> extends WatchableImpl implements Snappable { + // The storage + private final SparseSetArray mStorage; + + // A private convenience function + private void onChanged() { + dispatchChange(this); + } + + public WatchedSparseSetArray() { + mStorage = new SparseSetArray(); + } + + /** + * Creates a new WatchedSparseSetArray from an existing WatchedSparseSetArray and copy its data + */ + public WatchedSparseSetArray(@NonNull WatchedSparseSetArray<T> watchedSparseSetArray) { + mStorage = new SparseSetArray(watchedSparseSetArray.untrackedStorage()); + } + + /** + * Return the underlying storage. This breaks the wrapper but is necessary when + * passing the array to distant methods. + */ + public SparseSetArray<T> untrackedStorage() { + return mStorage; + } + + /** + * Add a value for key n. + * @return FALSE when the value already existed for the given key, TRUE otherwise. + */ + public boolean add(int n, T value) { + final boolean res = mStorage.add(n, value); + onChanged(); + return res; + } + + /** + * Removes all mappings from this SparseSetArray. + */ + public void clear() { + mStorage.clear(); + onChanged(); + } + + /** + * @return whether the value exists for the key n. + */ + public boolean contains(int n, T value) { + return mStorage.contains(n, value); + } + + /** + * @return the set of items of key n + */ + public ArraySet<T> get(int n) { + return mStorage.get(n); + } + + /** + * Remove a value for key n. + * @return TRUE when the value existed for the given key and removed, FALSE otherwise. + */ + public boolean remove(int n, T value) { + if (mStorage.remove(n, value)) { + onChanged(); + return true; + } + return false; + } + + /** + * Remove all values for key n. + */ + public void remove(int n) { + mStorage.remove(n); + onChanged(); + } + + /** + * Return the size of the SparseSetArray. + */ + public int size() { + return mStorage.size(); + } + + /** + * Return the key stored at the given index. + */ + public int keyAt(int index) { + return mStorage.keyAt(index); + } + + /** + * Return the size of the array at the given index. + */ + public int sizeAt(int index) { + return mStorage.sizeAt(index); + } + + /** + * Return the value in the SetArray at the given key index and value index. + */ + public T valueAt(int intIndex, int valueIndex) { + return (T) mStorage.valueAt(intIndex, valueIndex); + } + + @NonNull + @Override + public Object snapshot() { + WatchedSparseSetArray l = new WatchedSparseSetArray(this); + l.seal(); + return l; + } + + /** + * Make <this> a snapshot of the argument. Note that <this> is immutable when the + * method returns. <this> must be empty when the function is called. + * @param r The source array, which is copied into <this> + */ + public void snapshot(@NonNull WatchedSparseSetArray<T> r) { + snapshot(this, r); + } + + /** + * Make the destination a copy of the source. If the element is a subclass of Snapper then the + * copy contains snapshots of the elements. Otherwise the copy contains references to the + * elements. The destination must be initially empty. Upon return, the destination is + * immutable. + * @param dst The destination array. It must be empty. + * @param src The source array. It is not modified. + */ + public static void snapshot(@NonNull WatchedSparseSetArray dst, + @NonNull WatchedSparseSetArray src) { + if (dst.size() != 0) { + throw new IllegalArgumentException("snapshot destination is not empty"); + } + final int arraySize = src.size(); + for (int i = 0; i < arraySize; i++) { + final ArraySet set = src.get(i); + final int setSize = set.size(); + for (int j = 0; j < setSize; j++) { + dst.add(src.keyAt(i), set.valueAt(j)); + } + } + dst.seal(); + } +} diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java index 8ecc51b3087c..3e364314e10f 100644 --- a/services/core/java/com/android/server/vibrator/Vibration.java +++ b/services/core/java/com/android/server/vibrator/Vibration.java @@ -66,6 +66,7 @@ final class Vibration { IGNORED_FOR_ONGOING, IGNORED_FOR_POWER, IGNORED_FOR_RINGER_MODE, + IGNORED_FOR_RINGTONE, IGNORED_FOR_SETTINGS, IGNORED_SUPERSEDED, } diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java index bf3298558cd6..d7341cb37685 100644 --- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java +++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java @@ -733,6 +733,12 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { + attrs); } break; + case IGNORED_FOR_RINGTONE: + if (DEBUG) { + Slog.d(TAG, "Ignoring incoming vibration in favor of ringtone vibration"); + } + break; + default: if (DEBUG) { Slog.d(TAG, "Vibration for uid=" + uid + " and with attrs=" + attrs @@ -809,6 +815,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { return Vibration.Status.IGNORED_FOR_ALARM; } + if (currentVibration.attrs.getUsage() == VibrationAttributes.USAGE_RINGTONE) { + return Vibration.Status.IGNORED_FOR_RINGTONE; + } + if (currentVibration.isRepeating()) { return Vibration.Status.IGNORED_FOR_ONGOING; } diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 003268b33cdc..f6396556ae22 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -195,7 +195,6 @@ class ActivityStarter { private TaskFragment mInTaskFragment; @VisibleForTesting boolean mAddingToTask; - private Task mReuseTask; private ActivityInfo mNewTaskInfo; private Intent mNewTaskIntent; @@ -204,6 +203,7 @@ class ActivityStarter { // The task that the last activity was started into. We currently reset the actual start // activity's task and as a result may not have a reference to the task in all cases private Task mTargetTask; + private boolean mIsTaskCleared; private boolean mMovedToFront; private boolean mNoAnimation; private boolean mAvoidMoveToFront; @@ -597,7 +597,6 @@ class ActivityStarter { mInTask = starter.mInTask; mInTaskFragment = starter.mInTaskFragment; mAddingToTask = starter.mAddingToTask; - mReuseTask = starter.mReuseTask; mNewTaskInfo = starter.mNewTaskInfo; mNewTaskIntent = starter.mNewTaskIntent; @@ -605,6 +604,7 @@ class ActivityStarter { mTargetTask = starter.mTargetTask; mTargetRootTask = starter.mTargetRootTask; + mIsTaskCleared = starter.mIsTaskCleared; mMovedToFront = starter.mMovedToFront; mNoAnimation = starter.mNoAnimation; mAvoidMoveToFront = starter.mAvoidMoveToFront; @@ -1568,10 +1568,7 @@ class ActivityStarter { return; } - final int clearTaskFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK; - boolean clearedTask = (mLaunchFlags & clearTaskFlags) == clearTaskFlags - && mReuseTask != null; - if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP || clearedTask) { + if (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP) { // The activity was already running so it wasn't started, but either brought to the // front or the new intent was delivered to it since it was already in front. Notify // anyone interested in this piece of information. @@ -1581,7 +1578,7 @@ class ActivityStarter { final ActivityRecord top = targetTask.getTopNonFinishingActivity(); final boolean visible = top != null && top.isVisible(); mService.getTaskChangeNotificationController().notifyActivityRestartAttempt( - targetTask.getTaskInfo(), homeTaskVisible, clearedTask, visible); + targetTask.getTaskInfo(), homeTaskVisible, mIsTaskCleared, visible); } if (ActivityManager.isStartResultSuccessful(result)) { @@ -1927,6 +1924,7 @@ class ActivityStarter { return START_SUCCESS; } + /** Returns the leaf task where the target activity may be placed. */ private Task computeTargetTask() { if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { @@ -1935,6 +1933,12 @@ class ActivityStarter { } else if (mSourceRecord != null) { return mSourceRecord.getTask(); } else if (mInTask != null) { + // The task is specified from AppTaskImpl, so it may not be attached yet. + if (!mInTask.isAttached()) { + // Attach the task to display area. Ignore the returned root task (though usually + // they are the same) because "target task" should be leaf task. + getOrCreateRootTask(mStartActivity, mLaunchFlags, mInTask, mOptions); + } return mInTask; } else { final Task rootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, null /* task */, @@ -2225,13 +2229,12 @@ class ActivityStarter { // activity. Well that should not be too hard... // Note: we must persist the {@link Task} first as intentActivity could be // removed from calling performClearTaskLocked (For example, if it is being brought out - // of history or if it is finished immediately), thus disassociating the task. Also note - // that mReuseTask is reset as a result of {@link Task#performClearTaskLocked} - // launching another activity. Keep the task-overlay activity because the targetTask - // will be reused to launch new activity. + // of history or if it is finished immediately), thus disassociating the task. Keep the + // task-overlay activity because the targetTask will be reused to launch new activity. targetTask.performClearTaskForReuse(true /* excludingTaskOverlay*/); targetTask.setIntent(mStartActivity); mAddingToTask = true; + mIsTaskCleared = true; } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0 || isDocumentLaunchesIntoExisting(mLaunchFlags) || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK, @@ -2344,7 +2347,6 @@ class ActivityStarter { mInTask = null; mInTaskFragment = null; mAddingToTask = false; - mReuseTask = null; mNewTaskInfo = null; mNewTaskIntent = null; @@ -2352,6 +2354,7 @@ class ActivityStarter { mTargetRootTask = null; mTargetTask = null; + mIsTaskCleared = false; mMovedToFront = false; mNoAnimation = false; mAvoidMoveToFront = false; @@ -2569,8 +2572,6 @@ class ActivityStarter { } else { mAddingToTask = true; } - - mReuseTask = mInTask; } else { mInTask = null; // Launch ResolverActivity in the source task, so that it stays in the task bounds @@ -2843,7 +2844,7 @@ class ActivityStarter { mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession, mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions); task.mTransitionController.collectExistenceChange(task); - addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask"); + addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask"); ProtoLog.v(WM_DEBUG_TASKS, "Starting new activity %s in new task %s", mStartActivity, mStartActivity.getTask()); @@ -2953,11 +2954,6 @@ class ActivityStarter { private Task getOrCreateRootTask(ActivityRecord r, int launchFlags, Task task, ActivityOptions aOptions) { - // We are reusing a task, keep the root task! - if (mReuseTask != null) { - return mReuseTask.getRootTask(); - } - final boolean onTop = (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind; final Task sourceTask = mSourceRecord != null ? mSourceRecord.getTask() : null; diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index eb5ca9c2f43b..95de040551b1 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -897,6 +897,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { proc.getThread(), r.token); final boolean isTransitionForward = r.isTransitionForward(); + final IBinder fragmentToken = r.getTaskFragment().getFragmentToken(); clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), System.identityHashCode(r), r.info, // TODO: Have this take the merged configuration instead of separate global @@ -907,7 +908,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(), results, newIntents, r.takeOptions(), isTransitionForward, proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController, - r.shareableActivityToken, r.getLaunchedFromBubble())); + r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken)); // Set desired final state. final ActivityLifecycleItem lifecycleItem; diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java index 22a2c41ca5f3..6e46fa6b67d0 100644 --- a/services/core/java/com/android/server/wm/AppTaskImpl.java +++ b/services/core/java/com/android/server/wm/AppTaskImpl.java @@ -26,6 +26,8 @@ import android.content.Intent; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; +import android.os.Parcel; +import android.os.RemoteException; import android.os.UserHandle; /** @@ -54,6 +56,16 @@ class AppTaskImpl extends IAppTask.Stub { } @Override + public boolean onTransact(int code, Parcel data, Parcel reply, int flags) + throws RemoteException { + try { + return super.onTransact(code, data, reply, flags); + } catch (RuntimeException e) { + throw ActivityTaskManagerService.logAndRethrowRuntimeExceptionOnTransact(TAG, e); + } + } + + @Override public void finishAndRemoveTask() { checkCaller(); diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java index ef0b7374f79e..66c625e13f78 100644 --- a/services/core/java/com/android/server/wm/BackNavigationController.java +++ b/services/core/java/com/android/server/wm/BackNavigationController.java @@ -47,12 +47,6 @@ import com.android.server.LocalServices; class BackNavigationController { private static final String TAG = "BackNavigationController"; - // By default, enable new back dispatching without any animations. - private static final int BACK_PREDICTABILITY_PROP = - SystemProperties.getInt("persist.debug.back_predictability", 1); - private static final int ANIMATIONS_MASK = 1 << 1; - private static final int SCREENSHOT_MASK = 1 << 2; - @Nullable private TaskSnapshotController mTaskSnapshotController; @@ -60,15 +54,15 @@ class BackNavigationController { * Returns true if the back predictability feature is enabled */ static boolean isEnabled() { - return BACK_PREDICTABILITY_PROP > 0; + return SystemProperties.getInt("persist.wm.debug.predictive_back", 1) != 0; } static boolean isScreenshotEnabled() { - return (BACK_PREDICTABILITY_PROP & SCREENSHOT_MASK) != 0; + return SystemProperties.getInt("persist.wm.debug.predictive_back_screenshot", 0) != 0; } private static boolean isAnimationEnabled() { - return (BACK_PREDICTABILITY_PROP & ANIMATIONS_MASK) != 0; + return SystemProperties.getInt("persist.wm.debug.predictive_back_anim", 0) != 0; } /** diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 81560d4f8676..466075702409 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1992,7 +1992,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp scheduleAnimation(); forAllWindows(w -> { - if (w.mHasSurface && !rotateSeamlessly) { + if (!w.mHasSurface) return; + if (!rotateSeamlessly) { ProtoLog.v(WM_DEBUG_ORIENTATION, "Set mOrientationChanging of %s", w); w.setOrientationChanging(true); } @@ -4047,12 +4048,20 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp @VisibleForTesting void setImeInputTarget(InputTarget target) { mImeInputTarget = target; - boolean canScreenshot = mImeInputTarget == null || mImeInputTarget.canScreenshotIme(); - if (mImeWindowsContainer.setCanScreenshot(canScreenshot)) { + if (refreshImeSecureFlag(getPendingTransaction())) { mWmService.requestTraversal(); } } + /** + * Re-check the IME target's SECURE flag since it's possible to have changed after the target + * was set. + */ + boolean refreshImeSecureFlag(Transaction t) { + boolean canScreenshot = mImeInputTarget == null || mImeInputTarget.canScreenshotIme(); + return mImeWindowsContainer.setCanScreenshot(t, canScreenshot); + } + @VisibleForTesting void setImeControlTarget(InsetsControlTarget target) { mImeControlTarget = target; diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java index 8d1425d17d47..67dd89ee295c 100644 --- a/services/core/java/com/android/server/wm/InputManagerCallback.java +++ b/services/core/java/com/android/server/wm/InputManagerCallback.java @@ -29,6 +29,7 @@ import android.graphics.PointF; import android.os.Debug; import android.os.IBinder; import android.util.Slog; +import android.view.Display; import android.view.InputApplicationHandle; import android.view.KeyEvent; import android.view.SurfaceControl; @@ -194,6 +195,9 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal int firstExternalDisplayId = DEFAULT_DISPLAY; for (int i = mService.mRoot.mChildren.size() - 1; i >= 0; --i) { final DisplayContent displayContent = mService.mRoot.mChildren.get(i); + if (displayContent.getDisplayInfo().state == Display.STATE_OFF) { + continue; + } // Heuristic solution here. Currently when "Freeform windows" developer option is // enabled we automatically put secondary displays in freeform mode and emulating // "desktop mode". It also makes sense to show the pointer on the same display. diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 00f7e6362be9..65062e576d55 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -249,6 +249,8 @@ final class InputMonitor { inputWindowHandle.setPaused(w.mActivityRecord != null && w.mActivityRecord.paused); inputWindowHandle.setWindowToken(w.mClient); + inputWindowHandle.setName(w.getName()); + // Update layout params flags to force the window to be not touch modal. We do this to // restrict the window's touchable region to the task even if it requests touches outside // its window bounds. An example is a dialog in primary split should get touches outside its diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java index 0038c716fee7..c162e8ecadfc 100644 --- a/services/core/java/com/android/server/wm/LetterboxUiController.java +++ b/services/core/java/com/android/server/wm/LetterboxUiController.java @@ -175,7 +175,7 @@ final class LetterboxUiController { final Rect spaceToFill = transformedBounds != null ? transformedBounds : mActivityRecord.inMultiWindowMode() - ? mActivityRecord.getRootTask().getBounds() + ? mActivityRecord.getTask().getBounds() : mActivityRecord.getRootTask().getParent().getBounds(); mLetterbox.layout(spaceToFill, w.getFrame(), mTmpPoint); } else if (mLetterbox != null) { diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java index 65dca86d0259..83be73a47eb4 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java @@ -176,13 +176,24 @@ class SurfaceAnimationRunner { t.addTransactionCommittedListener(Runnable::run, () -> { final WindowAnimationSpec animationSpec = a.asWindowAnimationSpec(); + final Transaction edgeExtensionCreationTransaction = new Transaction(); edgeExtendWindow(animationLeash, animationSpec.getRootTaskBounds(), animationSpec.getAnimation(), - mFrameTransaction); + edgeExtensionCreationTransaction); synchronized (mLock) { // only run if animation is not yet canceled by this point if (mPreProcessingAnimations.get(animationLeash) == runningAnim) { + // In the case the animation is cancelled, edge extensions are removed + // onAnimationLeashLost which is called before onAnimationCancelled. + // So we need to check if the edge extensions have already been removed + // or not, and if so we don't want to apply the transaction. + synchronized (mEdgeExtensionLock) { + if (!mEdgeExtensions.isEmpty()) { + edgeExtensionCreationTransaction.apply(); + } + } + mPreProcessingAnimations.remove(animationLeash); mPendingAnimations.put(animationLeash, runningAnim); if (!mAnimationStartDeferred) { diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index 3a458fdc75bb..900963e29bd6 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -2262,7 +2262,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { mFragmentToken, mRemoteToken.toWindowContainerToken(), getConfiguration(), - getChildCount() == 0, + runningActivityCount[0] == 0, runningActivityCount[0], isVisible(), childActivities, diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 214524c2f42c..2900a5df6198 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -3782,11 +3782,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return INVALID_WINDOW_TYPE; } - boolean setCanScreenshot(boolean canScreenshot) { + boolean setCanScreenshot(Transaction t, boolean canScreenshot) { if (mSurfaceControl == null) { return false; } - getPendingTransaction().setSecure(mSurfaceControl, !canScreenshot); + t.setSecure(mSurfaceControl, !canScreenshot); return true; } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 8546e8002602..237982220a18 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2606,11 +2606,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return; } + // Remove immediately if there is display transition because the animation is + // usually unnoticeable (e.g. covered by rotation animation) and the animation + // bounds could be inconsistent, such as depending on when the window applies + // its draw transaction with new rotation. + final boolean allowExitAnimation = !getDisplayContent().inTransition(); + if (wasVisible) { final int transit = (!startingWindow) ? TRANSIT_EXIT : TRANSIT_PREVIEW_DONE; // Try starting an animation. - if (mWinAnimator.applyAnimationLocked(transit, false)) { + if (allowExitAnimation && mWinAnimator.applyAnimationLocked(transit, false)) { ProtoLog.v(WM_DEBUG_ANIM, "Set animatingExit: reason=remove/applyAnimation win=%s", this); mAnimatingExit = true; @@ -2624,7 +2630,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mWmService.mAccessibilityController.onWindowTransition(this, transit); } } - final boolean isAnimating = mAnimatingExit || isExitAnimationRunningSelfOrParent(); + final boolean isAnimating = allowExitAnimation + && (mAnimatingExit || isExitAnimationRunningSelfOrParent()); final boolean lastWindowIsStartingWindow = startingWindow && mActivityRecord != null && mActivityRecord.isLastWindow(this); // We delay the removal of a window if it has a showing surface that can be used to run @@ -3602,6 +3609,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mAnimatingExit = false; ProtoLog.d(WM_DEBUG_ANIM, "Clear animatingExit: reason=destroySurface win=%s", this); + // Clear the flag so the buffer requested for the next new surface won't be dropped by + // mistaking the surface size needs to update. + mReportOrientationChanged = false; + if (useBLASTSync()) { immediatelyNotifyBlastSync(); } @@ -5284,12 +5295,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (mControllableInsetProvider != null) { return; } - if (getDisplayContent().inTransition()) { - // Skip because the animation is usually unnoticeable (e.g. covered by rotation - // animation) and the animation bounds could be inconsistent, such as depending - // on when the window applies its draw transaction with new rotation. - return; - } final DisplayInfo displayInfo = getDisplayInfo(); anim.initialize(mWindowFrames.mFrame.width(), mWindowFrames.mFrame.height(), @@ -6125,14 +6130,21 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP applyHere = true; } - for (int i = mDrawHandlers.size() - 1; i >= 0; i--) { - DrawHandler h = mDrawHandlers.get(i); + final List<DrawHandler> handlersToRemove = new ArrayList<>(); + // Iterate forwards to ensure we process in the same order + // we added. + for (int i = 0; i < mDrawHandlers.size(); i++) { + final DrawHandler h = mDrawHandlers.get(i); if (h.mSeqId <= seqId) { h.mConsumer.accept(t); - mDrawHandlers.remove(h); + handlersToRemove.add(h); hadHandlers = true; } } + for (int i = 0; i < handlersToRemove.size(); i++) { + final DrawHandler h = handlersToRemove.get(i); + mDrawHandlers.remove(h); + } if (hadHandlers) { mWmService.mH.removeMessages(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this); diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index c2414e72abbd..5f43800bd9d5 100644 --- a/services/core/java/com/android/server/wm/WindowSurfaceController.java +++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java @@ -217,6 +217,11 @@ class WindowSurfaceController { mService.openSurfaceTransaction(); try { getGlobalTransaction().setSecure(mSurfaceControl, isSecure); + + final DisplayContent dc = mAnimator.mWin.mDisplayContent; + if (dc != null) { + dc.refreshImeSecureFlag(getGlobalTransaction()); + } } finally { mService.closeSurfaceTransaction("setSecure"); if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setSecureLocked"); diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 17016a6eb314..fa5e450c687a 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -130,6 +130,11 @@ static struct { static struct { jclass clazz; + jfieldID mPtr; +} gNativeInputManagerServiceImpl; + +static struct { + jclass clazz; } gInputDeviceClassInfo; static struct { @@ -259,17 +264,16 @@ public: void setDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray); - base::Result<std::unique_ptr<InputChannel>> createInputChannel(JNIEnv* env, - const std::string& name); - base::Result<std::unique_ptr<InputChannel>> createInputMonitor(JNIEnv* env, int32_t displayId, + base::Result<std::unique_ptr<InputChannel>> createInputChannel(const std::string& name); + base::Result<std::unique_ptr<InputChannel>> createInputMonitor(int32_t displayId, const std::string& name, int32_t pid); - status_t removeInputChannel(JNIEnv* env, const sp<IBinder>& connectionToken); + status_t removeInputChannel(const sp<IBinder>& connectionToken); status_t pilferPointers(const sp<IBinder>& token); void displayRemoved(JNIEnv* env, int32_t displayId); void setFocusedApplication(JNIEnv* env, int32_t displayId, jobject applicationHandleObj); - void setFocusedDisplay(JNIEnv* env, int32_t displayId); + void setFocusedDisplay(int32_t displayId); void setInputDispatchMode(bool enabled, bool frozen); void setSystemUiLightsOut(bool lightsOut); void setPointerSpeed(int32_t speed); @@ -510,19 +514,18 @@ void NativeInputManager::setDisplayViewports(JNIEnv* env, jobjectArray viewportO } base::Result<std::unique_ptr<InputChannel>> NativeInputManager::createInputChannel( - JNIEnv* /* env */, const std::string& name) { + const std::string& name) { ATRACE_CALL(); return mInputManager->getDispatcher().createInputChannel(name); } base::Result<std::unique_ptr<InputChannel>> NativeInputManager::createInputMonitor( - JNIEnv* /* env */, int32_t displayId, const std::string& name, int32_t pid) { + int32_t displayId, const std::string& name, int32_t pid) { ATRACE_CALL(); return mInputManager->getDispatcher().createInputMonitor(displayId, name, pid); } -status_t NativeInputManager::removeInputChannel(JNIEnv* /* env */, - const sp<IBinder>& connectionToken) { +status_t NativeInputManager::removeInputChannel(const sp<IBinder>& connectionToken) { ATRACE_CALL(); return mInputManager->getDispatcher().removeInputChannel(connectionToken); } @@ -1000,7 +1003,7 @@ void NativeInputManager::setFocusedApplication(JNIEnv* env, int32_t displayId, mInputManager->getDispatcher().setFocusedApplication(displayId, applicationHandle); } -void NativeInputManager::setFocusedDisplay(JNIEnv* env, int32_t displayId) { +void NativeInputManager::setFocusedDisplay(int32_t displayId) { mInputManager->getDispatcher().setFocusedDisplay(displayId); } @@ -1490,6 +1493,11 @@ void NativeInputManager::notifyPointerDisplayIdChanged() { // ---------------------------------------------------------------------------- +static NativeInputManager* getNativeInputManager(JNIEnv* env, jobject clazz) { + return reinterpret_cast<NativeInputManager*>( + env->GetLongField(clazz, gNativeInputManagerServiceImpl.mPtr)); +} + static jlong nativeInit(JNIEnv* env, jclass /* clazz */, jobject serviceObj, jobject contextObj, jobject messageQueueObj) { sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); @@ -1504,8 +1512,8 @@ static jlong nativeInit(JNIEnv* env, jclass /* clazz */, return reinterpret_cast<jlong>(im); } -static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeStart(JNIEnv* env, jobject nativeImplObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); status_t result = im->getInputManager()->start(); if (result) { @@ -1513,39 +1521,39 @@ static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) { } } -static void nativeSetDisplayViewports(JNIEnv* env, jclass /* clazz */, jlong ptr, - jobjectArray viewportObjArray) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetDisplayViewports(JNIEnv* env, jobject nativeImplObj, + jobjectArray viewportObjArray) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->setDisplayViewports(env, viewportObjArray); } -static jint nativeGetScanCodeState(JNIEnv* /* env */, jclass /* clazz */, - jlong ptr, jint deviceId, jint sourceMask, jint scanCode) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jint nativeGetScanCodeState(JNIEnv* env, jobject nativeImplObj, jint deviceId, + jint sourceMask, jint scanCode) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); return (jint)im->getInputManager()->getReader().getScanCodeState(deviceId, uint32_t(sourceMask), scanCode); } -static jint nativeGetKeyCodeState(JNIEnv* /* env */, jclass /* clazz */, - jlong ptr, jint deviceId, jint sourceMask, jint keyCode) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jint nativeGetKeyCodeState(JNIEnv* env, jobject nativeImplObj, jint deviceId, + jint sourceMask, jint keyCode) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); return (jint)im->getInputManager()->getReader().getKeyCodeState(deviceId, uint32_t(sourceMask), keyCode); } -static jint nativeGetSwitchState(JNIEnv* /* env */, jclass /* clazz */, - jlong ptr, jint deviceId, jint sourceMask, jint sw) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jint nativeGetSwitchState(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint sourceMask, + jint sw) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); return (jint)im->getInputManager()->getReader().getSwitchState(deviceId, uint32_t(sourceMask), sw); } -static jboolean nativeHasKeys(JNIEnv* env, jclass /* clazz */, - jlong ptr, jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jboolean nativeHasKeys(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint sourceMask, + jintArray keyCodes, jbooleanArray outFlags) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); int32_t* codes = env->GetIntArrayElements(keyCodes, nullptr); uint8_t* flags = env->GetBooleanArrayElements(outFlags, nullptr); @@ -1567,9 +1575,9 @@ static jboolean nativeHasKeys(JNIEnv* env, jclass /* clazz */, return result; } -static jint nativeGetKeyCodeForKeyLocation(JNIEnv* env, jclass /* clazz */, jlong ptr, - jint deviceId, jint locationKeyCode) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jint nativeGetKeyCodeForKeyLocation(JNIEnv* env, jobject nativeImplObj, jint deviceId, + jint locationKeyCode) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); return (jint)im->getInputManager()->getReader().getKeyCodeForKeyLocation(deviceId, locationKeyCode); } @@ -1582,17 +1590,16 @@ static void handleInputChannelDisposed(JNIEnv* env, jobject /* inputChannelObj * ALOGW("Input channel object '%s' was disposed without first being removed with " "the input manager!", inputChannel->getName().c_str()); - im->removeInputChannel(env, inputChannel->getConnectionToken()); + im->removeInputChannel(inputChannel->getConnectionToken()); } -static jobject nativeCreateInputChannel(JNIEnv* env, jclass /* clazz */, jlong ptr, - jstring nameObj) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jobject nativeCreateInputChannel(JNIEnv* env, jobject nativeImplObj, jstring nameObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); ScopedUtfChars nameChars(env, nameObj); std::string name = nameChars.c_str(); - base::Result<std::unique_ptr<InputChannel>> inputChannel = im->createInputChannel(env, name); + base::Result<std::unique_ptr<InputChannel>> inputChannel = im->createInputChannel(name); if (!inputChannel.ok()) { std::string message = inputChannel.error().message(); @@ -1612,9 +1619,9 @@ static jobject nativeCreateInputChannel(JNIEnv* env, jclass /* clazz */, jlong p return inputChannelObj; } -static jobject nativeCreateInputMonitor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint displayId, +static jobject nativeCreateInputMonitor(JNIEnv* env, jobject nativeImplObj, jint displayId, jstring nameObj, jint pid) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); if (displayId == ADISPLAY_ID_NONE) { std::string message = "InputChannel used as a monitor must be associated with a display"; @@ -1626,7 +1633,7 @@ static jobject nativeCreateInputMonitor(JNIEnv* env, jclass /* clazz */, jlong p std::string name = nameChars.c_str(); base::Result<std::unique_ptr<InputChannel>> inputChannel = - im->createInputMonitor(env, displayId, name, pid); + im->createInputMonitor(displayId, name, pid); if (!inputChannel.ok()) { std::string message = inputChannel.error().message(); @@ -1643,11 +1650,11 @@ static jobject nativeCreateInputMonitor(JNIEnv* env, jclass /* clazz */, jlong p return inputChannelObj; } -static void nativeRemoveInputChannel(JNIEnv* env, jclass /* clazz */, jlong ptr, jobject tokenObj) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeRemoveInputChannel(JNIEnv* env, jobject nativeImplObj, jobject tokenObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); sp<IBinder> token = ibinderForJavaObject(env, tokenObj); - status_t status = im->removeInputChannel(env, token); + status_t status = im->removeInputChannel(token); if (status && status != BAD_VALUE) { // ignore already removed channel std::string message; message += StringPrintf("Failed to remove input channel. status=%d", status); @@ -1655,47 +1662,44 @@ static void nativeRemoveInputChannel(JNIEnv* env, jclass /* clazz */, jlong ptr, } } -static void nativePilferPointers(JNIEnv* env, jclass /* clazz */, jlong ptr, jobject tokenObj) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativePilferPointers(JNIEnv* env, jobject nativeImplObj, jobject tokenObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); sp<IBinder> token = ibinderForJavaObject(env, tokenObj); im->pilferPointers(token); } -static void nativeSetInputFilterEnabled(JNIEnv* /* env */, jclass /* clazz */, - jlong ptr, jboolean enabled) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetInputFilterEnabled(JNIEnv* env, jobject nativeImplObj, jboolean enabled) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getDispatcher().setInputFilterEnabled(enabled); } -static jboolean nativeSetInTouchMode(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, - jboolean inTouchMode, jint pid, jint uid, - jboolean hasPermission) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jboolean nativeSetInTouchMode(JNIEnv* env, jobject nativeImplObj, jboolean inTouchMode, + jint pid, jint uid, jboolean hasPermission) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); return im->getInputManager()->getDispatcher().setInTouchMode(inTouchMode, pid, uid, hasPermission); } -static void nativeSetMaximumObscuringOpacityForTouch(JNIEnv* /* env */, jclass /* clazz */, - jlong ptr, jfloat opacity) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetMaximumObscuringOpacityForTouch(JNIEnv* env, jobject nativeImplObj, + jfloat opacity) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getDispatcher().setMaximumObscuringOpacityForTouch(opacity); } -static void nativeSetBlockUntrustedTouchesMode(JNIEnv* env, jclass /* clazz */, jlong ptr, - jint mode) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetBlockUntrustedTouchesMode(JNIEnv* env, jobject nativeImplObj, jint mode) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getDispatcher().setBlockUntrustedTouchesMode( static_cast<BlockUntrustedTouchesMode>(mode)); } -static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */, jlong ptr, - jobject inputEventObj, jboolean injectIntoUid, jint uid, - jint syncMode, jint timeoutMillis, jint policyFlags) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jint nativeInjectInputEvent(JNIEnv* env, jobject nativeImplObj, jobject inputEventObj, + jboolean injectIntoUid, jint uid, jint syncMode, + jint timeoutMillis, jint policyFlags) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); const std::optional<int32_t> targetUid = injectIntoUid ? std::make_optional(uid) : std::nullopt; // static_cast is safe because the value was already checked at the Java layer @@ -1735,9 +1739,8 @@ static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */, jlong ptr, } } -static jobject nativeVerifyInputEvent(JNIEnv* env, jclass /* clazz */, jlong ptr, - jobject inputEventObj) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jobject nativeVerifyInputEvent(JNIEnv* env, jobject nativeImplObj, jobject inputEventObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) { KeyEvent keyEvent; @@ -1778,56 +1781,53 @@ static jobject nativeVerifyInputEvent(JNIEnv* env, jclass /* clazz */, jlong ptr } } -static void nativeToggleCapsLock(JNIEnv* env, jclass /* clazz */, - jlong ptr, jint deviceId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeToggleCapsLock(JNIEnv* env, jobject nativeImplObj, jint deviceId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getReader().toggleCapsLockState(deviceId); } -static void nativeDisplayRemoved(JNIEnv* env, jclass /* clazz */, jlong ptr, jint displayId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeDisplayRemoved(JNIEnv* env, jobject nativeImplObj, jint displayId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->displayRemoved(env, displayId); } -static void nativeSetFocusedApplication(JNIEnv* env, jclass /* clazz */, - jlong ptr, jint displayId, jobject applicationHandleObj) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetFocusedApplication(JNIEnv* env, jobject nativeImplObj, jint displayId, + jobject applicationHandleObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->setFocusedApplication(env, displayId, applicationHandleObj); } -static void nativeSetFocusedDisplay(JNIEnv* env, jclass /* clazz */, - jlong ptr, jint displayId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetFocusedDisplay(JNIEnv* env, jobject nativeImplObj, jint displayId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); - im->setFocusedDisplay(env, displayId); + im->setFocusedDisplay(displayId); } -static void nativeRequestPointerCapture(JNIEnv* env, jclass /* clazz */, jlong ptr, - jobject tokenObj, jboolean enabled) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeRequestPointerCapture(JNIEnv* env, jobject nativeImplObj, jobject tokenObj, + jboolean enabled) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); sp<IBinder> windowToken = ibinderForJavaObject(env, tokenObj); im->requestPointerCapture(windowToken, enabled); } -static void nativeSetInputDispatchMode(JNIEnv* /* env */, - jclass /* clazz */, jlong ptr, jboolean enabled, jboolean frozen) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetInputDispatchMode(JNIEnv* env, jobject nativeImplObj, jboolean enabled, + jboolean frozen) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->setInputDispatchMode(enabled, frozen); } -static void nativeSetSystemUiLightsOut(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, - jboolean lightsOut) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetSystemUiLightsOut(JNIEnv* env, jobject nativeImplObj, jboolean lightsOut) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->setSystemUiLightsOut(lightsOut); } -static jboolean nativeTransferTouchFocus(JNIEnv* env, jclass /* clazz */, jlong ptr, +static jboolean nativeTransferTouchFocus(JNIEnv* env, jobject nativeImplObj, jobject fromChannelTokenObj, jobject toChannelTokenObj, jboolean isDragDrop) { if (fromChannelTokenObj == nullptr || toChannelTokenObj == nullptr) { @@ -1837,7 +1837,7 @@ static jboolean nativeTransferTouchFocus(JNIEnv* env, jclass /* clazz */, jlong sp<IBinder> fromChannelToken = ibinderForJavaObject(env, fromChannelTokenObj); sp<IBinder> toChannelToken = ibinderForJavaObject(env, toChannelTokenObj); - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); if (im->getInputManager()->getDispatcher().transferTouchFocus(fromChannelToken, toChannelToken, isDragDrop)) { return JNI_TRUE; @@ -1846,11 +1846,11 @@ static jboolean nativeTransferTouchFocus(JNIEnv* env, jclass /* clazz */, jlong } } -static jboolean nativeTransferTouch(JNIEnv* env, jclass /* clazz */, jlong ptr, +static jboolean nativeTransferTouch(JNIEnv* env, jobject nativeImplObj, jobject destChannelTokenObj) { sp<IBinder> destChannelToken = ibinderForJavaObject(env, destChannelTokenObj); - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); if (im->getInputManager()->getDispatcher().transferTouch(destChannelToken)) { return JNI_TRUE; } else { @@ -1858,42 +1858,39 @@ static jboolean nativeTransferTouch(JNIEnv* env, jclass /* clazz */, jlong ptr, } } -static void nativeSetPointerSpeed(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint speed) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetPointerSpeed(JNIEnv* env, jobject nativeImplObj, jint speed) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->setPointerSpeed(speed); } -static void nativeSetPointerAcceleration(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, - jfloat acceleration) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetPointerAcceleration(JNIEnv* env, jobject nativeImplObj, jfloat acceleration) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->setPointerAcceleration(acceleration); } -static void nativeSetShowTouches(JNIEnv* /* env */, - jclass /* clazz */, jlong ptr, jboolean enabled) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetShowTouches(JNIEnv* env, jobject nativeImplObj, jboolean enabled) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->setShowTouches(enabled); } -static void nativeSetInteractive(JNIEnv* env, - jclass clazz, jlong ptr, jboolean interactive) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetInteractive(JNIEnv* env, jobject nativeImplObj, jboolean interactive) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->setInteractive(interactive); } -static void nativeReloadCalibration(JNIEnv* env, jclass clazz, jlong ptr) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeReloadCalibration(JNIEnv* env, jobject nativeImplObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->reloadCalibration(); } -static void nativeVibrate(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId, - jlongArray patternObj, jintArray amplitudesObj, jint repeat, jint token) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeVibrate(JNIEnv* env, jobject nativeImplObj, jint deviceId, jlongArray patternObj, + jintArray amplitudesObj, jint repeat, jint token) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); size_t patternSize = env->GetArrayLength(patternObj); if (patternSize > MAX_VIBRATE_PATTERN_SIZE) { @@ -1926,10 +1923,10 @@ static void nativeVibrate(JNIEnv* env, jclass /* clazz */, jlong ptr, jint devic im->getInputManager()->getReader().vibrate(deviceId, sequence, repeat, token); } -static void nativeVibrateCombined(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId, +static void nativeVibrateCombined(JNIEnv* env, jobject nativeImplObj, jint deviceId, jlongArray patternObj, jobject amplitudesObj, jint repeat, jint token) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); size_t patternSize = env->GetArrayLength(patternObj); @@ -1976,21 +1973,20 @@ static void nativeVibrateCombined(JNIEnv* env, jclass /* clazz */, jlong ptr, ji im->getInputManager()->getReader().vibrate(deviceId, sequence, repeat, token); } -static void nativeCancelVibrate(JNIEnv* /* env */, - jclass /* clazz */, jlong ptr, jint deviceId, jint token) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeCancelVibrate(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint token) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getReader().cancelVibrate(deviceId, token); } -static bool nativeIsVibrating(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint deviceId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static bool nativeIsVibrating(JNIEnv* env, jobject nativeImplObj, jint deviceId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); return im->getInputManager()->getReader().isVibrating(deviceId); } -static jintArray nativeGetVibratorIds(JNIEnv* env, jclass clazz, jlong ptr, jint deviceId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jintArray nativeGetVibratorIds(JNIEnv* env, jobject nativeImplObj, jint deviceId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); std::vector<int32_t> vibrators = im->getInputManager()->getReader().getVibratorIds(deviceId); jintArray vibIdArray = env->NewIntArray(vibrators.size()); @@ -2000,8 +1996,8 @@ static jintArray nativeGetVibratorIds(JNIEnv* env, jclass clazz, jlong ptr, jint return vibIdArray; } -static jobject nativeGetLights(JNIEnv* env, jclass clazz, jlong ptr, jint deviceId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jobject nativeGetLights(JNIEnv* env, jobject nativeImplObj, jint deviceId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); jobject jLights = env->NewObject(gArrayListClassInfo.clazz, gArrayListClassInfo.constructor); std::vector<InputDeviceLightInfo> lights = @@ -2045,9 +2041,9 @@ static jobject nativeGetLights(JNIEnv* env, jclass clazz, jlong ptr, jint device return jLights; } -static jint nativeGetLightPlayerId(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId, +static jint nativeGetLightPlayerId(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint lightId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); std::optional<int32_t> ret = im->getInputManager()->getReader().getLightPlayerId(deviceId, lightId); @@ -2055,54 +2051,51 @@ static jint nativeGetLightPlayerId(JNIEnv* env, jclass /* clazz */, jlong ptr, j return static_cast<jint>(ret.value_or(0)); } -static jint nativeGetLightColor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId, - jint lightId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jint nativeGetLightColor(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint lightId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); std::optional<int32_t> ret = im->getInputManager()->getReader().getLightColor(deviceId, lightId); return static_cast<jint>(ret.value_or(0)); } -static void nativeSetLightPlayerId(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId, - jint lightId, jint playerId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetLightPlayerId(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint lightId, + jint playerId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getReader().setLightPlayerId(deviceId, lightId, playerId); } -static void nativeSetLightColor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId, - jint lightId, jint color) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetLightColor(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint lightId, + jint color) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getReader().setLightColor(deviceId, lightId, color); } -static jint nativeGetBatteryCapacity(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jint nativeGetBatteryCapacity(JNIEnv* env, jobject nativeImplObj, jint deviceId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); std::optional<int32_t> ret = im->getInputManager()->getReader().getBatteryCapacity(deviceId); return static_cast<jint>(ret.value_or(android::os::IInputConstants::INVALID_BATTERY_CAPACITY)); } -static jint nativeGetBatteryStatus(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jint nativeGetBatteryStatus(JNIEnv* env, jobject nativeImplObj, jint deviceId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); std::optional<int32_t> ret = im->getInputManager()->getReader().getBatteryStatus(deviceId); return static_cast<jint>(ret.value_or(BATTERY_STATUS_UNKNOWN)); } -static void nativeReloadKeyboardLayouts(JNIEnv* /* env */, - jclass /* clazz */, jlong ptr) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeReloadKeyboardLayouts(JNIEnv* env, jobject nativeImplObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getReader().requestRefreshConfiguration( InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS); } -static void nativeReloadDeviceAliases(JNIEnv* /* env */, - jclass /* clazz */, jlong ptr) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeReloadDeviceAliases(JNIEnv* env, jobject nativeImplObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getReader().requestRefreshConfiguration( InputReaderConfiguration::CHANGE_DEVICE_ALIAS); @@ -2117,58 +2110,54 @@ static std::string dumpInputProperties() { return out; } -static jstring nativeDump(JNIEnv* env, jclass /* clazz */, jlong ptr) { +static jstring nativeDump(JNIEnv* env, jobject nativeImplObj) { std::string dump = dumpInputProperties(); - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->dump(dump); return env->NewStringUTF(dump.c_str()); } -static void nativeMonitor(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeMonitor(JNIEnv* env, jobject nativeImplObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getReader().monitor(); im->getInputManager()->getDispatcher().monitor(); } -static jboolean nativeIsInputDeviceEnabled(JNIEnv* env /* env */, - jclass /* clazz */, jlong ptr, jint deviceId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jboolean nativeIsInputDeviceEnabled(JNIEnv* env, jobject nativeImplObj, jint deviceId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); return im->getInputManager()->getReader().isInputDeviceEnabled(deviceId); } -static void nativeEnableInputDevice(JNIEnv* /* env */, - jclass /* clazz */, jlong ptr, jint deviceId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeEnableInputDevice(JNIEnv* env, jobject nativeImplObj, jint deviceId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->setInputDeviceEnabled(deviceId, true); } -static void nativeDisableInputDevice(JNIEnv* /* env */, - jclass /* clazz */, jlong ptr, jint deviceId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeDisableInputDevice(JNIEnv* env, jobject nativeImplObj, jint deviceId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->setInputDeviceEnabled(deviceId, false); } -static void nativeSetPointerIconType(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint iconId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetPointerIconType(JNIEnv* env, jobject nativeImplObj, jint iconId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->setPointerIconType(iconId); } -static void nativeReloadPointerIcons(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeReloadPointerIcons(JNIEnv* env, jobject nativeImplObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->reloadPointerIcons(); } -static void nativeSetCustomPointerIcon(JNIEnv* env, jclass /* clazz */, - jlong ptr, jobject iconObj) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetCustomPointerIcon(JNIEnv* env, jobject nativeImplObj, jobject iconObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); PointerIcon pointerIcon; status_t result = android_view_PointerIcon_getLoadedIcon(env, iconObj, &pointerIcon); @@ -2182,40 +2171,38 @@ static void nativeSetCustomPointerIcon(JNIEnv* env, jclass /* clazz */, im->setCustomPointerIcon(spriteIcon); } -static jboolean nativeCanDispatchToDisplay(JNIEnv* env, jclass /* clazz */, jlong ptr, - jint deviceId, jint displayId) { - - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jboolean nativeCanDispatchToDisplay(JNIEnv* env, jobject nativeImplObj, jint deviceId, + jint displayId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); return im->getInputManager()->getReader().canDispatchToDisplay(deviceId, displayId); } -static void nativeNotifyPortAssociationsChanged(JNIEnv* env, jclass /* clazz */, jlong ptr) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeNotifyPortAssociationsChanged(JNIEnv* env, jobject nativeImplObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getReader().requestRefreshConfiguration( InputReaderConfiguration::CHANGE_DISPLAY_INFO); } -static void nativeNotifyPointerDisplayIdChanged(JNIEnv* env, jclass /* clazz */, jlong ptr) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeNotifyPointerDisplayIdChanged(JNIEnv* env, jobject nativeImplObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->notifyPointerDisplayIdChanged(); } -static void nativeSetDisplayEligibilityForPointerCapture(JNIEnv* env, jclass /* clazz */, jlong ptr, +static void nativeSetDisplayEligibilityForPointerCapture(JNIEnv* env, jobject nativeImplObj, jint displayId, jboolean isEligible) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getDispatcher().setDisplayEligibilityForPointerCapture(displayId, isEligible); } -static void nativeChangeUniqueIdAssociation(JNIEnv* env, jclass /* clazz */, jlong ptr) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeChangeUniqueIdAssociation(JNIEnv* env, jobject nativeImplObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getReader().requestRefreshConfiguration( InputReaderConfiguration::CHANGE_DISPLAY_INFO); } -static void nativeSetMotionClassifierEnabled(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, - jboolean enabled) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeSetMotionClassifierEnabled(JNIEnv* env, jobject nativeImplObj, jboolean enabled) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->setMotionClassifierEnabled(enabled); } @@ -2251,8 +2238,8 @@ static jobject createInputSensorInfo(JNIEnv* env, jstring name, jstring vendor, return sensorInfo; } -static jobjectArray nativeGetSensorList(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static jobjectArray nativeGetSensorList(JNIEnv* env, jobject nativeImplObj, jint deviceId) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); std::vector<InputDeviceSensorInfo> sensors = im->getInputManager()->getReader().getSensors(deviceId); @@ -2281,10 +2268,10 @@ static jobjectArray nativeGetSensorList(JNIEnv* env, jclass /* clazz */, jlong p return arr; } -static jboolean nativeEnableSensor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId, +static jboolean nativeEnableSensor(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint sensorType, jint samplingPeriodUs, jint maxBatchReportLatencyUs) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); return im->getInputManager() ->getReader() @@ -2293,18 +2280,18 @@ static jboolean nativeEnableSensor(JNIEnv* env, jclass /* clazz */, jlong ptr, j std::chrono::microseconds(maxBatchReportLatencyUs)); } -static void nativeDisableSensor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId, +static void nativeDisableSensor(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint sensorType) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getReader().disableSensor(deviceId, static_cast<InputDeviceSensorType>( sensorType)); } -static jboolean nativeFlushSensor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId, +static jboolean nativeFlushSensor(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint sensorType) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getReader().flushSensor(deviceId, static_cast<InputDeviceSensorType>(sensorType)); @@ -2313,8 +2300,8 @@ static jboolean nativeFlushSensor(JNIEnv* env, jclass /* clazz */, jlong ptr, ji sensorType)); } -static void nativeCancelCurrentTouch(JNIEnv* env, jclass /* clazz */, jlong ptr) { - NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); +static void nativeCancelCurrentTouch(JNIEnv* env, jobject nativeImplObj) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getDispatcher().cancelCurrentTouch(); } @@ -2322,87 +2309,84 @@ static void nativeCancelCurrentTouch(JNIEnv* env, jclass /* clazz */, jlong ptr) static const JNINativeMethod gInputManagerMethods[] = { /* name, signature, funcPtr */ - {"nativeInit", + {"init", "(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/" "MessageQueue;)J", (void*)nativeInit}, - {"nativeStart", "(J)V", (void*)nativeStart}, - {"nativeSetDisplayViewports", "(J[Landroid/hardware/display/DisplayViewport;)V", + {"start", "()V", (void*)nativeStart}, + {"setDisplayViewports", "([Landroid/hardware/display/DisplayViewport;)V", (void*)nativeSetDisplayViewports}, - {"nativeGetScanCodeState", "(JIII)I", (void*)nativeGetScanCodeState}, - {"nativeGetKeyCodeState", "(JIII)I", (void*)nativeGetKeyCodeState}, - {"nativeGetSwitchState", "(JIII)I", (void*)nativeGetSwitchState}, - {"nativeHasKeys", "(JII[I[Z)Z", (void*)nativeHasKeys}, - {"nativeGetKeyCodeForKeyLocation", "(JII)I", (void*)nativeGetKeyCodeForKeyLocation}, - {"nativeCreateInputChannel", "(JLjava/lang/String;)Landroid/view/InputChannel;", + {"getScanCodeState", "(III)I", (void*)nativeGetScanCodeState}, + {"getKeyCodeState", "(III)I", (void*)nativeGetKeyCodeState}, + {"getSwitchState", "(III)I", (void*)nativeGetSwitchState}, + {"hasKeys", "(II[I[Z)Z", (void*)nativeHasKeys}, + {"getKeyCodeForKeyLocation", "(II)I", (void*)nativeGetKeyCodeForKeyLocation}, + {"createInputChannel", "(Ljava/lang/String;)Landroid/view/InputChannel;", (void*)nativeCreateInputChannel}, - {"nativeCreateInputMonitor", "(JILjava/lang/String;I)Landroid/view/InputChannel;", + {"createInputMonitor", "(ILjava/lang/String;I)Landroid/view/InputChannel;", (void*)nativeCreateInputMonitor}, - {"nativeRemoveInputChannel", "(JLandroid/os/IBinder;)V", (void*)nativeRemoveInputChannel}, - {"nativePilferPointers", "(JLandroid/os/IBinder;)V", (void*)nativePilferPointers}, - {"nativeSetInputFilterEnabled", "(JZ)V", (void*)nativeSetInputFilterEnabled}, - {"nativeSetInTouchMode", "(JZIIZ)Z", (void*)nativeSetInTouchMode}, - {"nativeSetMaximumObscuringOpacityForTouch", "(JF)V", + {"removeInputChannel", "(Landroid/os/IBinder;)V", (void*)nativeRemoveInputChannel}, + {"pilferPointers", "(Landroid/os/IBinder;)V", (void*)nativePilferPointers}, + {"setInputFilterEnabled", "(Z)V", (void*)nativeSetInputFilterEnabled}, + {"setInTouchMode", "(ZIIZ)Z", (void*)nativeSetInTouchMode}, + {"setMaximumObscuringOpacityForTouch", "(F)V", (void*)nativeSetMaximumObscuringOpacityForTouch}, - {"nativeSetBlockUntrustedTouchesMode", "(JI)V", (void*)nativeSetBlockUntrustedTouchesMode}, - {"nativeInjectInputEvent", "(JLandroid/view/InputEvent;ZIIII)I", - (void*)nativeInjectInputEvent}, - {"nativeVerifyInputEvent", "(JLandroid/view/InputEvent;)Landroid/view/VerifiedInputEvent;", + {"setBlockUntrustedTouchesMode", "(I)V", (void*)nativeSetBlockUntrustedTouchesMode}, + {"injectInputEvent", "(Landroid/view/InputEvent;ZIIII)I", (void*)nativeInjectInputEvent}, + {"verifyInputEvent", "(Landroid/view/InputEvent;)Landroid/view/VerifiedInputEvent;", (void*)nativeVerifyInputEvent}, - {"nativeToggleCapsLock", "(JI)V", (void*)nativeToggleCapsLock}, - {"nativeDisplayRemoved", "(JI)V", (void*)nativeDisplayRemoved}, - {"nativeSetFocusedApplication", "(JILandroid/view/InputApplicationHandle;)V", + {"toggleCapsLock", "(I)V", (void*)nativeToggleCapsLock}, + {"displayRemoved", "(I)V", (void*)nativeDisplayRemoved}, + {"setFocusedApplication", "(ILandroid/view/InputApplicationHandle;)V", (void*)nativeSetFocusedApplication}, - {"nativeSetFocusedDisplay", "(JI)V", (void*)nativeSetFocusedDisplay}, - {"nativeRequestPointerCapture", "(JLandroid/os/IBinder;Z)V", - (void*)nativeRequestPointerCapture}, - {"nativeSetInputDispatchMode", "(JZZ)V", (void*)nativeSetInputDispatchMode}, - {"nativeSetSystemUiLightsOut", "(JZ)V", (void*)nativeSetSystemUiLightsOut}, - {"nativeTransferTouchFocus", "(JLandroid/os/IBinder;Landroid/os/IBinder;Z)Z", + {"setFocusedDisplay", "(I)V", (void*)nativeSetFocusedDisplay}, + {"requestPointerCapture", "(Landroid/os/IBinder;Z)V", (void*)nativeRequestPointerCapture}, + {"setInputDispatchMode", "(ZZ)V", (void*)nativeSetInputDispatchMode}, + {"setSystemUiLightsOut", "(Z)V", (void*)nativeSetSystemUiLightsOut}, + {"transferTouchFocus", "(Landroid/os/IBinder;Landroid/os/IBinder;Z)Z", (void*)nativeTransferTouchFocus}, - {"nativeTransferTouch", "(JLandroid/os/IBinder;)Z", (void*)nativeTransferTouch}, - {"nativeSetPointerSpeed", "(JI)V", (void*)nativeSetPointerSpeed}, - {"nativeSetPointerAcceleration", "(JF)V", (void*)nativeSetPointerAcceleration}, - {"nativeSetShowTouches", "(JZ)V", (void*)nativeSetShowTouches}, - {"nativeSetInteractive", "(JZ)V", (void*)nativeSetInteractive}, - {"nativeReloadCalibration", "(J)V", (void*)nativeReloadCalibration}, - {"nativeVibrate", "(JI[J[III)V", (void*)nativeVibrate}, - {"nativeVibrateCombined", "(JI[JLandroid/util/SparseArray;II)V", - (void*)nativeVibrateCombined}, - {"nativeCancelVibrate", "(JII)V", (void*)nativeCancelVibrate}, - {"nativeIsVibrating", "(JI)Z", (void*)nativeIsVibrating}, - {"nativeGetVibratorIds", "(JI)[I", (void*)nativeGetVibratorIds}, - {"nativeGetLights", "(JI)Ljava/util/List;", (void*)nativeGetLights}, - {"nativeGetLightPlayerId", "(JII)I", (void*)nativeGetLightPlayerId}, - {"nativeGetLightColor", "(JII)I", (void*)nativeGetLightColor}, - {"nativeSetLightPlayerId", "(JIII)V", (void*)nativeSetLightPlayerId}, - {"nativeSetLightColor", "(JIII)V", (void*)nativeSetLightColor}, - {"nativeGetBatteryCapacity", "(JI)I", (void*)nativeGetBatteryCapacity}, - {"nativeGetBatteryStatus", "(JI)I", (void*)nativeGetBatteryStatus}, - {"nativeReloadKeyboardLayouts", "(J)V", (void*)nativeReloadKeyboardLayouts}, - {"nativeReloadDeviceAliases", "(J)V", (void*)nativeReloadDeviceAliases}, - {"nativeDump", "(J)Ljava/lang/String;", (void*)nativeDump}, - {"nativeMonitor", "(J)V", (void*)nativeMonitor}, - {"nativeIsInputDeviceEnabled", "(JI)Z", (void*)nativeIsInputDeviceEnabled}, - {"nativeEnableInputDevice", "(JI)V", (void*)nativeEnableInputDevice}, - {"nativeDisableInputDevice", "(JI)V", (void*)nativeDisableInputDevice}, - {"nativeSetPointerIconType", "(JI)V", (void*)nativeSetPointerIconType}, - {"nativeReloadPointerIcons", "(J)V", (void*)nativeReloadPointerIcons}, - {"nativeSetCustomPointerIcon", "(JLandroid/view/PointerIcon;)V", + {"transferTouch", "(Landroid/os/IBinder;)Z", (void*)nativeTransferTouch}, + {"setPointerSpeed", "(I)V", (void*)nativeSetPointerSpeed}, + {"setPointerAcceleration", "(F)V", (void*)nativeSetPointerAcceleration}, + {"setShowTouches", "(Z)V", (void*)nativeSetShowTouches}, + {"setInteractive", "(Z)V", (void*)nativeSetInteractive}, + {"reloadCalibration", "()V", (void*)nativeReloadCalibration}, + {"vibrate", "(I[J[III)V", (void*)nativeVibrate}, + {"vibrateCombined", "(I[JLandroid/util/SparseArray;II)V", (void*)nativeVibrateCombined}, + {"cancelVibrate", "(II)V", (void*)nativeCancelVibrate}, + {"isVibrating", "(I)Z", (void*)nativeIsVibrating}, + {"getVibratorIds", "(I)[I", (void*)nativeGetVibratorIds}, + {"getLights", "(I)Ljava/util/List;", (void*)nativeGetLights}, + {"getLightPlayerId", "(II)I", (void*)nativeGetLightPlayerId}, + {"getLightColor", "(II)I", (void*)nativeGetLightColor}, + {"setLightPlayerId", "(III)V", (void*)nativeSetLightPlayerId}, + {"setLightColor", "(III)V", (void*)nativeSetLightColor}, + {"getBatteryCapacity", "(I)I", (void*)nativeGetBatteryCapacity}, + {"getBatteryStatus", "(I)I", (void*)nativeGetBatteryStatus}, + {"reloadKeyboardLayouts", "()V", (void*)nativeReloadKeyboardLayouts}, + {"reloadDeviceAliases", "()V", (void*)nativeReloadDeviceAliases}, + {"dump", "()Ljava/lang/String;", (void*)nativeDump}, + {"monitor", "()V", (void*)nativeMonitor}, + {"isInputDeviceEnabled", "(I)Z", (void*)nativeIsInputDeviceEnabled}, + {"enableInputDevice", "(I)V", (void*)nativeEnableInputDevice}, + {"disableInputDevice", "(I)V", (void*)nativeDisableInputDevice}, + {"setPointerIconType", "(I)V", (void*)nativeSetPointerIconType}, + {"reloadPointerIcons", "()V", (void*)nativeReloadPointerIcons}, + {"setCustomPointerIcon", "(Landroid/view/PointerIcon;)V", (void*)nativeSetCustomPointerIcon}, - {"nativeCanDispatchToDisplay", "(JII)Z", (void*)nativeCanDispatchToDisplay}, - {"nativeNotifyPortAssociationsChanged", "(J)V", (void*)nativeNotifyPortAssociationsChanged}, - {"nativeChangeUniqueIdAssociation", "(J)V", (void*)nativeChangeUniqueIdAssociation}, - {"nativeNotifyPointerDisplayIdChanged", "(J)V", (void*)nativeNotifyPointerDisplayIdChanged}, - {"nativeSetDisplayEligibilityForPointerCapture", "(JIZ)V", + {"canDispatchToDisplay", "(II)Z", (void*)nativeCanDispatchToDisplay}, + {"notifyPortAssociationsChanged", "()V", (void*)nativeNotifyPortAssociationsChanged}, + {"changeUniqueIdAssociation", "()V", (void*)nativeChangeUniqueIdAssociation}, + {"notifyPointerDisplayIdChanged", "()V", (void*)nativeNotifyPointerDisplayIdChanged}, + {"setDisplayEligibilityForPointerCapture", "(IZ)V", (void*)nativeSetDisplayEligibilityForPointerCapture}, - {"nativeSetMotionClassifierEnabled", "(JZ)V", (void*)nativeSetMotionClassifierEnabled}, - {"nativeGetSensorList", "(JI)[Landroid/hardware/input/InputSensorInfo;", + {"setMotionClassifierEnabled", "(Z)V", (void*)nativeSetMotionClassifierEnabled}, + {"getSensorList", "(I)[Landroid/hardware/input/InputSensorInfo;", (void*)nativeGetSensorList}, - {"nativeEnableSensor", "(JIIII)Z", (void*)nativeEnableSensor}, - {"nativeDisableSensor", "(JII)V", (void*)nativeDisableSensor}, - {"nativeFlushSensor", "(JII)Z", (void*)nativeFlushSensor}, - {"nativeCancelCurrentTouch", "(J)V", (void*)nativeCancelCurrentTouch}, + {"enableSensor", "(IIII)Z", (void*)nativeEnableSensor}, + {"disableSensor", "(II)V", (void*)nativeDisableSensor}, + {"flushSensor", "(II)Z", (void*)nativeFlushSensor}, + {"cancelCurrentTouch", "()V", (void*)nativeCancelCurrentTouch}, }; #define FIND_CLASS(var, className) \ @@ -2422,11 +2406,21 @@ static const JNINativeMethod gInputManagerMethods[] = { LOG_FATAL_IF(! (var), "Unable to find field " fieldName); int register_android_server_InputManager(JNIEnv* env) { - int res = jniRegisterNativeMethods(env, "com/android/server/input/InputManagerService", - gInputManagerMethods, NELEM(gInputManagerMethods)); - (void) res; // Faked use when LOG_NDEBUG. + int res = jniRegisterNativeMethods(env, + "com/android/server/input/" + "NativeInputManagerService$NativeImpl", + gInputManagerMethods, NELEM(gInputManagerMethods)); + (void)res; // Faked use when LOG_NDEBUG. LOG_FATAL_IF(res < 0, "Unable to register native methods."); + FIND_CLASS(gNativeInputManagerServiceImpl.clazz, + "com/android/server/input/" + "NativeInputManagerService$NativeImpl"); + gNativeInputManagerServiceImpl.clazz = + jclass(env->NewGlobalRef(gNativeInputManagerServiceImpl.clazz)); + gNativeInputManagerServiceImpl.mPtr = + env->GetFieldID(gNativeInputManagerServiceImpl.clazz, "mPtr", "J"); + // Callbacks jclass clazz; diff --git a/services/devicepolicy/TEST_MAPPING b/services/devicepolicy/TEST_MAPPING index 3d86cf30f38e..72bba11c5366 100644 --- a/services/devicepolicy/TEST_MAPPING +++ b/services/devicepolicy/TEST_MAPPING @@ -16,5 +16,15 @@ { "name": "CtsDevicePolicyManagerTestCases" } + ], + "presubmit": [ + { + "name": "CtsDevicePolicyManagerTestCases", + "options": [ + { + "include-filter": "com.android.cts.devicepolicy.ManagedProfileTest#testParentProfileApiDisabled" + } + ] + } ] } diff --git a/services/people/java/com/android/server/people/data/DataManager.java b/services/people/java/com/android/server/people/data/DataManager.java index e6fd9164d96b..d305fc5d7dc4 100644 --- a/services/people/java/com/android/server/people/data/DataManager.java +++ b/services/people/java/com/android/server/people/data/DataManager.java @@ -618,10 +618,17 @@ public class DataManager { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED); intentFilter.addAction(SmsApplication.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL); - BroadcastReceiver broadcastReceiver = new PerUserBroadcastReceiver(userId); - mBroadcastReceivers.put(userId, broadcastReceiver); - mContext.registerReceiverAsUser( - broadcastReceiver, UserHandle.of(userId), intentFilter, null, null); + + if (mBroadcastReceivers.get(userId) == null) { + BroadcastReceiver broadcastReceiver = new PerUserBroadcastReceiver(userId); + mBroadcastReceivers.put(userId, broadcastReceiver); + mContext.registerReceiverAsUser( + broadcastReceiver, UserHandle.of(userId), intentFilter, null, null); + } else { + // Stopped was not called on this user before setup is called again. This + // could happen during consecutive rapid user switching. + if (DEBUG) Log.d(TAG, "PerUserBroadcastReceiver was registered for: " + userId); + } ContentObserver contactsContentObserver = new ContactsContentObserver( BackgroundThread.getHandler()); @@ -639,9 +646,15 @@ public class DataManager { // Should never occur for local calls. } - PackageMonitor packageMonitor = new PerUserPackageMonitor(); - packageMonitor.register(mContext, null, UserHandle.of(userId), true); - mPackageMonitors.put(userId, packageMonitor); + if (mPackageMonitors.get(userId) == null) { + PackageMonitor packageMonitor = new PerUserPackageMonitor(); + packageMonitor.register(mContext, null, UserHandle.of(userId), true); + mPackageMonitors.put(userId, packageMonitor); + } else { + // Stopped was not called on this user before setup is called again. This + // could happen during consecutive rapid user switching. + if (DEBUG) Log.d(TAG, "PerUserPackageMonitor was registered for: " + userId); + } if (userId == UserHandle.USER_SYSTEM) { // The call log and MMS/SMS messages are shared across user profiles. So only need diff --git a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt index 7017440a86bb..7b152247eb9c 100644 --- a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt +++ b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt @@ -34,7 +34,6 @@ import com.android.server.pm.test.override.PackageManagerComponentLabelIconOverr import com.android.server.testutils.TestHandler import com.android.server.testutils.mock import com.android.server.testutils.mockThrowOnUnmocked -import com.android.server.testutils.spy import com.android.server.testutils.whenever import com.android.server.wm.ActivityTaskManagerInternal import com.google.common.truth.Truth.assertThat @@ -46,13 +45,9 @@ import org.junit.runner.RunWith import org.junit.runners.Parameterized import org.mockito.Mockito.any import org.mockito.Mockito.anyInt -import org.mockito.Mockito.clearInvocations -import org.mockito.Mockito.doAnswer import org.mockito.Mockito.doReturn import org.mockito.Mockito.intThat -import org.mockito.Mockito.never import org.mockito.Mockito.same -import org.mockito.Mockito.verify import org.testng.Assert.assertThrows import java.io.File import java.util.UUID @@ -365,7 +360,7 @@ class PackageManagerComponentLabelIconOverrideTest { val mockActivityTaskManager: ActivityTaskManagerInternal = mockThrowOnUnmocked { whenever(this.isCallerRecents(anyInt())) { false } } - val mockAppsFilter: AppsFilter = mockThrowOnUnmocked { + val mockAppsFilter: AppsFilterImpl = mockThrowOnUnmocked { whenever(this.shouldFilterApplication(anyInt(), any<PackageSetting>(), any<PackageSetting>(), anyInt())) { false } whenever(this.snapshot()) { this@mockThrowOnUnmocked } diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java index c9523ec16b8f..529def3697cd 100644 --- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java @@ -27,6 +27,7 @@ import static android.app.AlarmManager.FLAG_STANDALONE; import static android.app.AlarmManager.FLAG_WAKE_FROM_IDLE; import static android.app.AlarmManager.RTC; import static android.app.AlarmManager.RTC_WAKEUP; +import static android.app.AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT; import static android.app.AlarmManager.WINDOW_EXACT; import static android.app.AlarmManager.WINDOW_HEURISTIC; import static android.app.AppOpsManager.MODE_ALLOWED; @@ -122,6 +123,7 @@ import android.app.IAlarmListener; import android.app.IAlarmManager; import android.app.PendingIntent; import android.app.compat.CompatChanges; +import android.app.role.RoleManager; import android.app.usage.UsageStatsManagerInternal; import android.content.ContentResolver; import android.content.Context; @@ -184,6 +186,7 @@ import org.mockito.quality.Strictness; import org.mockito.stubbing.Answer; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -232,6 +235,8 @@ public class AlarmManagerServiceTest { @Mock private PackageManagerInternal mPackageManagerInternal; @Mock + private RoleManager mRoleManager; + @Mock private AppStateTrackerImpl mAppStateTracker; @Mock private AlarmManagerService.ClockReceiver mClockReceiver; @@ -457,6 +462,7 @@ public class AlarmManagerServiceTest { when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager); when(mMockContext.getSystemService(BatteryManager.class)).thenReturn(mBatteryManager); + when(mMockContext.getSystemService(RoleManager.class)).thenReturn(mRoleManager); registerAppIds(new String[]{TEST_CALLING_PACKAGE}, new Integer[]{UserHandle.getAppId(TEST_CALLING_UID)}); @@ -3191,6 +3197,70 @@ public class AlarmManagerServiceTest { } @Test + public void isScheduleExactAlarmAllowedByDefault() { + final String package1 = "priv"; + final String package2 = "signed"; + final String package3 = "normal"; + final String package4 = "wellbeing"; + final int uid1 = 1294; + final int uid2 = 8321; + final int uid3 = 3412; + final int uid4 = 4591; + + when(mPackageManagerInternal.isUidPrivileged(uid1)).thenReturn(true); + when(mPackageManagerInternal.isUidPrivileged(uid2)).thenReturn(false); + when(mPackageManagerInternal.isUidPrivileged(uid3)).thenReturn(false); + when(mPackageManagerInternal.isUidPrivileged(uid4)).thenReturn(false); + + when(mPackageManagerInternal.isPlatformSigned(package1)).thenReturn(false); + when(mPackageManagerInternal.isPlatformSigned(package2)).thenReturn(true); + when(mPackageManagerInternal.isPlatformSigned(package3)).thenReturn(false); + when(mPackageManagerInternal.isPlatformSigned(package4)).thenReturn(false); + + when(mRoleManager.getRoleHolders(RoleManager.ROLE_SYSTEM_WELLBEING)).thenReturn( + Arrays.asList(package4)); + + mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true); + mService.mConstants.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = false; + mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[] { + package1, + package3, + }); + + // Deny listed packages will be false. + assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package1, uid1)); + assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package2, uid2)); + assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package3, uid3)); + assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package4, uid4)); + + mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, false); + mService.mConstants.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = true; + mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[] { + package1, + package3, + }); + + // Same as above, deny listed packages will be false. + assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package1, uid1)); + assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package2, uid2)); + assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package3, uid3)); + assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package4, uid4)); + + mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true); + mService.mConstants.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = true; + mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[] { + package1, + package3, + }); + + // Deny list doesn't matter now, only exemptions should be true. + assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package1, uid1)); + assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package2, uid2)); + assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package3, uid3)); + assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package4, uid4)); + } + + @Test public void alarmScheduledAtomPushed() { for (int i = 0; i < 10; i++) { final PendingIntent pi = getNewMockPendingIntent(); diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java index 9a4f8e261124..43ba39adcb85 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java @@ -2164,6 +2164,49 @@ public class QuotaControllerTest { } } + @Test + public void testIsWithinEJQuotaLocked_TempAllowlisting_Restricted() { + setDischarging(); + JobStatus js = createExpeditedJobStatus("testIsWithinEJQuotaLocked_TempAllowlisting_Restricted", 1); + setStandbyBucket(RESTRICTED_INDEX, js); + setDeviceConfigLong(QcConstants.KEY_EJ_LIMIT_FREQUENT_MS, 10 * MINUTE_IN_MILLIS); + final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession(now - (HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), true); + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession(now - (30 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), true); + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession(now - (5 * MINUTE_IN_MILLIS), 4 * MINUTE_IN_MILLIS, 5), true); + synchronized (mQuotaController.mLock) { + assertFalse(mQuotaController.isWithinEJQuotaLocked(js)); + } + + setProcessState(ActivityManager.PROCESS_STATE_RECEIVER); + final long gracePeriodMs = 15 * SECOND_IN_MILLIS; + setDeviceConfigLong(QcConstants.KEY_EJ_GRACE_PERIOD_TEMP_ALLOWLIST_MS, gracePeriodMs); + Handler handler = mQuotaController.getHandler(); + spyOn(handler); + + // The temp allowlist should not enable RESTRICTED apps' to schedule & start EJs if they're + // out of quota. + mTempAllowlistListener.onAppAdded(mSourceUid); + synchronized (mQuotaController.mLock) { + assertFalse(mQuotaController.isWithinEJQuotaLocked(js)); + } + advanceElapsedClock(10 * SECOND_IN_MILLIS); + mTempAllowlistListener.onAppRemoved(mSourceUid); + advanceElapsedClock(10 * SECOND_IN_MILLIS); + // Still in grace period + synchronized (mQuotaController.mLock) { + assertFalse(mQuotaController.isWithinEJQuotaLocked(js)); + } + advanceElapsedClock(6 * SECOND_IN_MILLIS); + // Out of grace period. + synchronized (mQuotaController.mLock) { + assertFalse(mQuotaController.isWithinEJQuotaLocked(js)); + } + } + /** * Tests that Timers properly track sessions when an app becomes top and is closed. */ @@ -5559,6 +5602,111 @@ public class QuotaControllerTest { mQuotaController.getEJTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); } + @Test + public void testEJTimerTracking_TempAllowlisting_Restricted() { + setDischarging(); + setProcessState(ActivityManager.PROCESS_STATE_RECEIVER); + final long gracePeriodMs = 15 * SECOND_IN_MILLIS; + setDeviceConfigLong(QcConstants.KEY_EJ_GRACE_PERIOD_TEMP_ALLOWLIST_MS, gracePeriodMs); + Handler handler = mQuotaController.getHandler(); + spyOn(handler); + + JobStatus job = createExpeditedJobStatus("testEJTimerTracking_TempAllowlisting_Restricted", 1); + setStandbyBucket(RESTRICTED_INDEX, job); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(job, null); + } + assertNull(mQuotaController.getEJTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); + List<TimingSession> expected = new ArrayList<>(); + + long start = JobSchedulerService.sElapsedRealtimeClock.millis(); + synchronized (mQuotaController.mLock) { + mQuotaController.prepareForExecutionLocked(job); + } + advanceElapsedClock(10 * SECOND_IN_MILLIS); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(job, job, true); + } + expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1)); + assertEquals(expected, + mQuotaController.getEJTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); + + advanceElapsedClock(SECOND_IN_MILLIS); + + // Job starts after app is added to temp allowlist and stops before removal. + start = JobSchedulerService.sElapsedRealtimeClock.millis(); + mTempAllowlistListener.onAppAdded(mSourceUid); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(job, null); + mQuotaController.prepareForExecutionLocked(job); + } + advanceElapsedClock(10 * SECOND_IN_MILLIS); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(job, null, false); + } + expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1)); + assertEquals(expected, + mQuotaController.getEJTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); + + // Job starts after app is added to temp allowlist and stops after removal, + // before grace period ends. + start = JobSchedulerService.sElapsedRealtimeClock.millis(); + mTempAllowlistListener.onAppAdded(mSourceUid); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(job, null); + mQuotaController.prepareForExecutionLocked(job); + } + advanceElapsedClock(10 * SECOND_IN_MILLIS); + mTempAllowlistListener.onAppRemoved(mSourceUid); + long elapsedGracePeriodMs = 2 * SECOND_IN_MILLIS; + advanceElapsedClock(elapsedGracePeriodMs); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(job, null, false); + } + expected.add(createTimingSession(start, 12 * SECOND_IN_MILLIS, 1)); + assertEquals(expected, + mQuotaController.getEJTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); + + advanceElapsedClock(SECOND_IN_MILLIS); + elapsedGracePeriodMs += SECOND_IN_MILLIS; + + // Job starts during grace period and ends after grace period ends + start = JobSchedulerService.sElapsedRealtimeClock.millis(); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(job, null); + mQuotaController.prepareForExecutionLocked(job); + } + final long remainingGracePeriod = gracePeriodMs - elapsedGracePeriodMs; + advanceElapsedClock(remainingGracePeriod); + // Wait for handler to update Timer + // Can't directly evaluate the message because for some reason, the captured message returns + // the wrong 'what' even though the correct message goes to the handler and the correct + // path executes. + verify(handler, timeout(gracePeriodMs + 5 * SECOND_IN_MILLIS)).handleMessage(any()); + advanceElapsedClock(10 * SECOND_IN_MILLIS); + expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS + remainingGracePeriod, 1)); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(job, job, true); + } + assertEquals(expected, + mQuotaController.getEJTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); + + // Job starts and runs completely after temp allowlist grace period. + advanceElapsedClock(10 * SECOND_IN_MILLIS); + start = JobSchedulerService.sElapsedRealtimeClock.millis(); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStartTrackingJobLocked(job, null); + mQuotaController.prepareForExecutionLocked(job); + } + advanceElapsedClock(10 * SECOND_IN_MILLIS); + synchronized (mQuotaController.mLock) { + mQuotaController.maybeStopTrackingJobLocked(job, job, true); + } + expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1)); + assertEquals(expected, + mQuotaController.getEJTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE)); + } + /** * Tests that Timers properly track sessions when TOP state and temp allowlisting overlaps. */ diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt index 0567f58b1bbe..353c8e22cceb 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt +++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt @@ -194,7 +194,7 @@ class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) { val packageParser: PackageParser2 = mock() val keySetManagerService: KeySetManagerService = mock() val packageAbiHelper: PackageAbiHelper = mock() - val appsFilter: AppsFilter = mock { + val appsFilter: AppsFilterImpl = mock { whenever(snapshot()) { this@mock } } val dexManager: DexManager = mock() diff --git a/services/tests/servicestests/res/xml/test_account_type1_authenticator.xml b/services/tests/servicestests/res/xml/test_account_type1_authenticator.xml index 0c531de1827e..a4558acdc274 100644 --- a/services/tests/servicestests/res/xml/test_account_type1_authenticator.xml +++ b/services/tests/servicestests/res/xml/test_account_type1_authenticator.xml @@ -18,4 +18,5 @@ android:accountType="@string/test_account_type1" android:icon="@drawable/icon1" android:smallIcon="@drawable/icon1" + android:customTokens="true" android:label="@string/test_account_type1_authenticator_label" /> diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java index 3c2fbd9ccf7d..863dcb64b885 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java @@ -18,8 +18,11 @@ package com.android.server.accessibility; import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_FULLSCREEN; import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_WINDOW; +import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN; +import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -255,6 +258,20 @@ public class MagnificationProcessorTest { } @Test + public void getCurrentMode_changeOtherDisplayMode_returnDefaultModeOnDefaultDisplay() { + final int otherDisplayId = TEST_DISPLAY + 1; + setMagnificationActivated(otherDisplayId, MAGNIFICATION_MODE_WINDOW); + + int currentMode = mMagnificationProcessor.getControllingMode(TEST_DISPLAY); + + assertFalse(mMockMagnificationController.isActivated(TEST_DISPLAY, + ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN)); + assertFalse(mMockMagnificationController.isActivated(TEST_DISPLAY, + ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW)); + assertEquals(MAGNIFICATION_MODE_FULLSCREEN, currentMode); + } + + @Test public void resetFullscreenMagnification_fullscreenMagnificationActivated() { setMagnificationActivated(TEST_DISPLAY, MAGNIFICATION_MODE_FULLSCREEN); diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java index cc6d7611b4a1..ca22f80a7189 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java @@ -555,7 +555,22 @@ public class MagnificationControllerTest { } @Test - public void onRectangleOnScreenRequested_NoneIsActivated_noneDispatchEvent() { + public void onRectangleOnScreenRequested_noneIsActivated_noneDispatchEvent() { + UiChangesForAccessibilityCallbacks callbacks = getUiChangesForAccessibilityCallbacks(); + + callbacks.onRectangleOnScreenRequested(TEST_DISPLAY, + TEST_RECT.left, TEST_RECT.top, TEST_RECT.right, TEST_RECT.bottom); + + verify(mScreenMagnificationController, never()).onRectangleOnScreenRequested( + eq(TEST_DISPLAY), anyInt(), anyInt(), anyInt(), anyInt()); + verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(), + anyInt(), anyInt(), anyInt(), anyInt()); + } + + @Test + public void onRectangleOnScreenRequested_otherDisplayIsActivated_noneEventOnDefaultDisplay() { + mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY + 1, + true); UiChangesForAccessibilityCallbacks callbacks = getUiChangesForAccessibilityCallbacks(); callbacks.onRectangleOnScreenRequested(TEST_DISPLAY, @@ -579,6 +594,41 @@ public class MagnificationControllerTest { } @Test + public void getLastActivatedMode_switchMode_returnExpectedLastActivatedMode() + throws RemoteException { + activateMagnifier(MODE_WINDOW, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y); + + final int lastActivatedMode = mMagnificationController + .getLastMagnificationActivatedMode(TEST_DISPLAY); + + assertEquals(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW, lastActivatedMode); + } + + @Test + public void getLastActivatedMode_switchModeAtOtherDisplay_returnExpectedLastActivatedMode() + throws RemoteException { + activateMagnifier(TEST_DISPLAY, MODE_WINDOW, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y); + activateMagnifier(TEST_DISPLAY + 1, MODE_FULLSCREEN, MAGNIFIED_CENTER_X, + MAGNIFIED_CENTER_Y); + + final int lastActivatedMode = mMagnificationController + .getLastMagnificationActivatedMode(TEST_DISPLAY); + + assertEquals(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW, lastActivatedMode); + } + + @Test + public void getLastActivatedMode_otherDisplayIsActivated_defaultModeOnDefaultDisplay() + throws RemoteException { + activateMagnifier(TEST_DISPLAY + 1, MODE_WINDOW, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y); + + int lastActivatedMode = mMagnificationController + .getLastMagnificationActivatedMode(TEST_DISPLAY); + + assertEquals(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN, lastActivatedMode); + } + + @Test public void onFullScreenMagnificationActivationState_fullScreenEnabled_logFullScreenDuration() { MagnificationController spyController = spy(mMagnificationController); spyController.onFullScreenMagnificationActivationState(TEST_DISPLAY, true); @@ -818,17 +868,22 @@ public class MagnificationControllerTest { } private void activateMagnifier(int mode, float centerX, float centerY) throws RemoteException { + activateMagnifier(TEST_DISPLAY, mode, centerX, centerY); + } + + private void activateMagnifier(int displayId, int mode, float centerX, float centerY) + throws RemoteException { final boolean windowMagnifying = mWindowMagnificationManager.isWindowMagnifierEnabled( - TEST_DISPLAY); + displayId); if (windowMagnifying) { - mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false); + mWindowMagnificationManager.disableWindowMagnification(displayId, false); mMockConnection.invokeCallbacks(); } if (mode == MODE_FULLSCREEN) { - mScreenMagnificationController.setScaleAndCenter(TEST_DISPLAY, DEFAULT_SCALE, centerX, + mScreenMagnificationController.setScaleAndCenter(displayId, DEFAULT_SCALE, centerX, centerY, true, AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID); } else { - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, DEFAULT_SCALE, + mWindowMagnificationManager.enableWindowMagnification(displayId, DEFAULT_SCALE, centerX, centerY, null, TEST_SERVICE_ID); mMockConnection.invokeCallbacks(); } diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java index 997a138cf58f..d5c5745d6680 100644 --- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java @@ -26,9 +26,11 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.never; import static org.mockito.Mockito.nullable; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.accounts.AbstractAccountAuthenticator; import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.AccountManagerInternal; @@ -1698,13 +1700,14 @@ public class AccountManagerServiceTest extends AndroidTestCase { final CountDownLatch latch = new CountDownLatch(1); Response response = new Response(latch, mMockAccountManagerResponse); + long expiryEpochTimeInMillis = System.currentTimeMillis() + ONE_DAY_IN_MILLISECOND; mAms.getAuthToken( response, // response AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "authTokenType", // authTokenType true, // notifyOnAuthFailure false, // expectActivityLaunch - createGetAuthTokenOptions()); + createGetAuthTokenOptionsWithExpiry(expiryEpochTimeInMillis)); waitForLatch(latch); verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture()); @@ -1715,6 +1718,58 @@ public class AccountManagerServiceTest extends AndroidTestCase { AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS); assertEquals(result.getString(AccountManager.KEY_ACCOUNT_TYPE), AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1); + assertEquals(result.getLong(AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY), + expiryEpochTimeInMillis); + } + + @SmallTest + public void testGetAuthTokenCachedSuccess() throws Exception { + unlockSystemUser(); + when(mMockContext.createPackageContextAsUser( + anyString(), anyInt(), any(UserHandle.class))).thenReturn(mMockContext); + when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager); + String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE}; + when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list); + + final CountDownLatch latch = new CountDownLatch(1); + Response response = new Response(latch, mMockAccountManagerResponse); + long expiryEpochTimeInMillis = System.currentTimeMillis() + ONE_DAY_IN_MILLISECOND; + mAms.getAuthToken( + response, // response + AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, + "authTokenType", // authTokenType + true, // notifyOnAuthFailure + false, // expectActivityLaunch + createGetAuthTokenOptionsWithExpiry(expiryEpochTimeInMillis)); + waitForLatch(latch); + + // Make call for cached token. + mAms.getAuthToken( + response, // response + AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, + "authTokenType", // authTokenType + true, // notifyOnAuthFailure + false, // expectActivityLaunch + createGetAuthTokenOptionsWithExpiry(expiryEpochTimeInMillis + 10)); + waitForLatch(latch); + + verify(mMockAccountManagerResponse, times(2)).onResult(mBundleCaptor.capture()); + List<Bundle> result = mBundleCaptor.getAllValues(); + assertGetTokenResponse(result.get(0), expiryEpochTimeInMillis); + // cached token was returned with the same expiration time as first token. + assertGetTokenResponse(result.get(1), expiryEpochTimeInMillis); + } + + private void assertGetTokenResponse(Bundle result, long expiryEpochTimeInMillis) { + assertEquals(result.getString(AccountManager.KEY_AUTHTOKEN), + AccountManagerServiceTestFixtures.AUTH_TOKEN); + assertEquals(result.getString(AccountManager.KEY_ACCOUNT_NAME), + AccountManagerServiceTestFixtures.ACCOUNT_NAME_SUCCESS); + assertEquals(result.getString(AccountManager.KEY_ACCOUNT_TYPE), + AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1); + assertEquals(result.getLong(AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY), + expiryEpochTimeInMillis); + } @SmallTest @@ -3241,11 +3296,16 @@ public class AccountManagerServiceTest extends AndroidTestCase { } private Bundle createGetAuthTokenOptions() { + return createGetAuthTokenOptionsWithExpiry( + System.currentTimeMillis() + ONE_DAY_IN_MILLISECOND); + } + + private Bundle createGetAuthTokenOptionsWithExpiry(long expiryEpochTimeInMillis) { Bundle options = new Bundle(); options.putString(AccountManager.KEY_ANDROID_PACKAGE_NAME, AccountManagerServiceTestFixtures.CALLER_PACKAGE); options.putLong(AccountManagerServiceTestFixtures.KEY_TOKEN_EXPIRY, - System.currentTimeMillis() + ONE_DAY_IN_MILLISECOND); + expiryEpochTimeInMillis); return options; } diff --git a/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java b/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java new file mode 100644 index 000000000000..00f4c3908f26 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.am; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.os.SystemClock; + +import org.junit.Before; +import org.junit.Test; + +/** + * Test class for {@link DropboxRateLimiter}. + * + * Build/Install/Run: + * atest DropboxRateLimiterTest + */ +public class DropboxRateLimiterTest { + private DropboxRateLimiter mRateLimiter; + private TestClock mClock; + + @Before + public void setUp() { + mClock = new TestClock(); + mRateLimiter = new DropboxRateLimiter(mClock); + } + + @Test + public void testMultipleProcesses() { + // The first 5 entries should not be rate limited. + assertFalse(mRateLimiter.shouldRateLimit("tag", "process")); + assertFalse(mRateLimiter.shouldRateLimit("tag", "process")); + assertFalse(mRateLimiter.shouldRateLimit("tag", "process")); + assertFalse(mRateLimiter.shouldRateLimit("tag", "process")); + assertFalse(mRateLimiter.shouldRateLimit("tag", "process")); + // Different processes and tags should not get rate limited either. + assertFalse(mRateLimiter.shouldRateLimit("tag", "process2")); + assertFalse(mRateLimiter.shouldRateLimit("tag2", "process")); + // The 6th entry of the same process should be rate limited. + assertTrue(mRateLimiter.shouldRateLimit("tag", "process")); + } + + @Test + public void testBufferClearing() throws Exception { + // The first 5 entries should not be rate limited. + assertFalse(mRateLimiter.shouldRateLimit("tag", "process")); + assertFalse(mRateLimiter.shouldRateLimit("tag", "process")); + assertFalse(mRateLimiter.shouldRateLimit("tag", "process")); + assertFalse(mRateLimiter.shouldRateLimit("tag", "process")); + assertFalse(mRateLimiter.shouldRateLimit("tag", "process")); + // The 6th entry of the same process should be rate limited. + assertTrue(mRateLimiter.shouldRateLimit("tag", "process")); + + // After 11 seconds there should be nothing left in the buffer and the same type of entry + // should not get rate limited anymore. + mClock.setOffsetMillis(11000); + + assertFalse(mRateLimiter.shouldRateLimit("tag", "process")); + } + + private static class TestClock implements DropboxRateLimiter.Clock { + long mOffsetMillis = 0L; + + public long uptimeMillis() { + return mOffsetMillis + SystemClock.uptimeMillis(); + } + + public void setOffsetMillis(long millis) { + mOffsetMillis = millis; + } + } +} diff --git a/services/tests/servicestests/src/com/android/server/backup/transport/BackupTransportClientTest.java b/services/tests/servicestests/src/com/android/server/backup/transport/BackupTransportClientTest.java index b154d6f6db0c..1171518130cc 100644 --- a/services/tests/servicestests/src/com/android/server/backup/transport/BackupTransportClientTest.java +++ b/services/tests/servicestests/src/com/android/server/backup/transport/BackupTransportClientTest.java @@ -110,10 +110,7 @@ public class BackupTransportClientTest { Thread thread = new Thread(() -> { try { - /*String name =*/ client.transportDirName(); - fail("transportDirName should be cancelled"); - } catch (CancellationException ex) { - // This is expected. + assertThat(client.transportDirName()).isNull(); } catch (Exception ex) { fail("unexpected Exception: " + ex.getClass().getCanonicalName()); } @@ -189,7 +186,7 @@ public class BackupTransportClientTest { } @Test - public void testFinishBackup_canceledBeforeCompletion_throwsException() throws Exception { + public void testFinishBackup_canceledBeforeCompletion_returnsError() throws Exception { TestCallbacksFakeTransportBinder binder = new TestCallbacksFakeTransportBinder(); BackupTransportClient client = new BackupTransportClient(binder); diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java index 33ea7108a705..b9ae6702c37e 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java @@ -25,6 +25,8 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; + import static junit.framework.Assert.assertEquals; import static org.mockito.ArgumentMatchers.anyInt; @@ -48,6 +50,7 @@ import android.os.Looper; import android.os.Process; import android.os.ResultReceiver; import android.os.ShellCallback; +import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import androidx.test.InstrumentationRegistry; @@ -370,6 +373,19 @@ public class LockSettingsShellCommandTest { mUserId); } + @Test + public void testRequireStrongAuth_STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN() throws Exception { + when(mLockPatternUtils.isSecure(mUserId)).thenReturn(true); + + assertEquals(0, mCommand.exec(new Binder(), in, out, err, + new String[] { "require-strong-auth", "STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN"}, + mShellCallback, mResultReceiver)); + + verify(mLockPatternUtils).requireStrongAuth( + STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN, + UserHandle.USER_ALL); + } + private List<LockPatternView.Cell> stringToPattern(String str) { return LockPatternUtils.byteArrayToPattern(str.getBytes()); } diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java index b72b8d2ec6e8..d8f4349b95bf 100644 --- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java @@ -77,7 +77,7 @@ import java.util.concurrent.Executor; @Presubmit @RunWith(JUnit4.class) -public class AppsFilterTest { +public class AppsFilterImplTest { private static final int DUMMY_CALLING_APPID = 10345; private static final int DUMMY_TARGET_APPID = 10556; @@ -98,9 +98,9 @@ public class AppsFilterTest { } @Mock - AppsFilter.FeatureConfig mFeatureConfigMock; + AppsFilterImpl.FeatureConfig mFeatureConfigMock; @Mock - AppsFilter.StateProvider mStateProvider; + AppsFilterImpl.StateProvider mStateProvider; @Mock Executor mMockExecutor; @Mock @@ -204,11 +204,11 @@ public class AppsFilterTest { MockitoAnnotations.initMocks(this); doAnswer(invocation -> { - ((AppsFilter.StateProvider.CurrentStateCallback) invocation.getArgument(0)) + ((AppsFilterImpl.StateProvider.CurrentStateCallback) invocation.getArgument(0)) .currentState(mExisting, USER_INFO_LIST); return new Object(); }).when(mStateProvider) - .runWithState(any(AppsFilter.StateProvider.CurrentStateCallback.class)); + .runWithState(any(AppsFilterImpl.StateProvider.CurrentStateCallback.class)); doAnswer(invocation -> { ((Runnable) invocation.getArgument(0)).run(); @@ -218,14 +218,14 @@ public class AppsFilterTest { when(mFeatureConfigMock.isGloballyEnabled()).thenReturn(true); when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))).thenAnswer( (Answer<Boolean>) invocation -> - ((AndroidPackage)invocation.getArgument(SYSTEM_USER)).getTargetSdkVersion() + ((AndroidPackage) invocation.getArgument(SYSTEM_USER)).getTargetSdkVersion() >= Build.VERSION_CODES.R); } @Test public void testSystemReadyPropogates() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -236,8 +236,8 @@ public class AppsFilterTest { @Test public void testQueriesAction_FilterMatches() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -259,8 +259,8 @@ public class AppsFilterTest { } @Test public void testQueriesProtectedAction_FilterDoesNotMatch() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -308,8 +308,8 @@ public class AppsFilterTest { @Test public void testQueriesProvider_FilterMatches() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -333,8 +333,8 @@ public class AppsFilterTest { @Test public void testOnUserUpdated_FilterMatches() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); @@ -356,11 +356,11 @@ public class AppsFilterTest { // adds new user doAnswer(invocation -> { - ((AppsFilter.StateProvider.CurrentStateCallback) invocation.getArgument(0)) + ((AppsFilterImpl.StateProvider.CurrentStateCallback) invocation.getArgument(0)) .currentState(mExisting, USER_INFO_LIST_WITH_ADDED); return new Object(); }).when(mStateProvider) - .runWithState(any(AppsFilter.StateProvider.CurrentStateCallback.class)); + .runWithState(any(AppsFilterImpl.StateProvider.CurrentStateCallback.class)); appsFilter.onUserCreated(ADDED_USER); for (int subjectUserId : USER_ARRAY_WITH_ADDED) { @@ -373,11 +373,11 @@ public class AppsFilterTest { // delete user doAnswer(invocation -> { - ((AppsFilter.StateProvider.CurrentStateCallback) invocation.getArgument(0)) + ((AppsFilterImpl.StateProvider.CurrentStateCallback) invocation.getArgument(0)) .currentState(mExisting, USER_INFO_LIST); return new Object(); }).when(mStateProvider) - .runWithState(any(AppsFilter.StateProvider.CurrentStateCallback.class)); + .runWithState(any(AppsFilterImpl.StateProvider.CurrentStateCallback.class)); appsFilter.onUserDeleted(ADDED_USER); for (int subjectUserId : USER_ARRAY) { @@ -391,8 +391,8 @@ public class AppsFilterTest { @Test public void testQueriesDifferentProvider_Filters() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -416,8 +416,8 @@ public class AppsFilterTest { @Test public void testQueriesProviderWithSemiColon_FilterMatches() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -435,8 +435,8 @@ public class AppsFilterTest { @Test public void testQueriesAction_NoMatchingAction_Filters() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -452,8 +452,8 @@ public class AppsFilterTest { @Test public void testQueriesAction_NoMatchingActionFilterLowSdk_DoesntFilter() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -473,8 +473,8 @@ public class AppsFilterTest { @Test public void testNoQueries_Filters() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -490,7 +490,7 @@ public class AppsFilterTest { @Test public void testNoUsesLibrary_Filters() throws Exception { - final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, + final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, mMockExecutor, mMockPmInternal); @@ -516,7 +516,7 @@ public class AppsFilterTest { @Test public void testUsesLibrary_DoesntFilter() throws Exception { - final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, + final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, mMockExecutor, mMockPmInternal); @@ -543,7 +543,7 @@ public class AppsFilterTest { @Test public void testUsesOptionalLibrary_DoesntFilter() throws Exception { - final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, + final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, mMockExecutor, mMockPmInternal); @@ -570,7 +570,7 @@ public class AppsFilterTest { @Test public void testUsesLibrary_ShareUid_DoesntFilter() throws Exception { - final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock, + final AppsFilterImpl appsFilter = new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null, mMockExecutor, mMockPmInternal); @@ -602,8 +602,8 @@ public class AppsFilterTest { @Test public void testForceQueryable_SystemDoesntFilter() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -621,8 +621,8 @@ public class AppsFilterTest { @Test public void testForceQueryable_NonSystemFilters() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -638,9 +638,10 @@ public class AppsFilterTest { @Test public void testForceQueryableByDevice_SystemCaller_DoesntFilter() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"}, - false, null, mMockExecutor, mMockPmInternal); + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, + new String[]{"com.some.package"}, false, null, + mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -657,8 +658,8 @@ public class AppsFilterTest { @Test public void testSystemSignedTarget_DoesntFilter() throws CertificateException { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); appsFilter.onSystemReady(); @@ -686,9 +687,10 @@ public class AppsFilterTest { @Test public void testForceQueryableByDevice_NonSystemCaller_Filters() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{"com.some.package"}, - false, null, mMockExecutor, mMockPmInternal); + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, + new String[]{"com.some.package"}, false, null, + mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -704,8 +706,8 @@ public class AppsFilterTest { @Test public void testSystemQueryable_DoesntFilter() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, true /* system force queryable */, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); @@ -723,8 +725,8 @@ public class AppsFilterTest { @Test public void testQueriesPackage_DoesntFilter() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -742,8 +744,8 @@ public class AppsFilterTest { public void testNoQueries_FeatureOff_DoesntFilter() throws Exception { when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class))) .thenReturn(false); - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -759,8 +761,8 @@ public class AppsFilterTest { @Test public void testSystemUid_DoesntFilter() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -775,8 +777,8 @@ public class AppsFilterTest { @Test public void testSystemUidSecondaryUser_DoesntFilter() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -792,8 +794,8 @@ public class AppsFilterTest { @Test public void testNonSystemUid_NoCallingSetting_Filters() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -807,8 +809,8 @@ public class AppsFilterTest { @Test public void testNoTargetPackage_filters() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -838,7 +840,7 @@ public class AppsFilterTest { .setOverlayTargetOverlayableName("overlayableName"); ParsingPackage actor = pkg("com.some.package.actor"); - final AppsFilter appsFilter = new AppsFilter( + final AppsFilterImpl appsFilter = new AppsFilterImpl( mStateProvider, mFeatureConfigMock, new String[]{}, @@ -933,7 +935,7 @@ public class AppsFilterTest { when(mMockPmInternal.getSharedUserPackages(any(Integer.class))).thenReturn( actorSharedSettingPackages ); - final AppsFilter appsFilter = new AppsFilter( + final AppsFilterImpl appsFilter = new AppsFilterImpl( mStateProvider, mFeatureConfigMock, new String[]{}, @@ -985,8 +987,8 @@ public class AppsFilterTest { @Test public void testInitiatingApp_DoesntFilter() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -1003,8 +1005,8 @@ public class AppsFilterTest { @Test public void testUninstalledInitiatingApp_Filters() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -1021,8 +1023,8 @@ public class AppsFilterTest { @Test public void testOriginatingApp_Filters() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -1046,8 +1048,8 @@ public class AppsFilterTest { @Test public void testInstallingApp_DoesntFilter() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -1071,8 +1073,8 @@ public class AppsFilterTest { @Test public void testInstrumentation_DoesntFilter() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -1100,8 +1102,8 @@ public class AppsFilterTest { @Test public void testWhoCanSee() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -1173,8 +1175,8 @@ public class AppsFilterTest { @Test public void testOnChangeReport() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); final WatchableTester watcher = new WatchableTester(appsFilter, "onChange"); watcher.register(); @@ -1246,8 +1248,8 @@ public class AppsFilterTest { @Test public void testOnChangeReportedFilter() throws Exception { - final AppsFilter appsFilter = - new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, mMockExecutor, mMockPmInternal); simulateAddBasicAndroid(appsFilter); appsFilter.onSystemReady(); @@ -1270,6 +1272,53 @@ public class AppsFilterTest { watcher.verifyNoChangeReported("shouldFilterApplication"); } + @Test + public void testAppsFilterRead() throws Exception { + final AppsFilterImpl appsFilter = + new AppsFilterImpl(mStateProvider, mFeatureConfigMock, new String[]{}, false, null, + mMockExecutor, mMockPmInternal); + simulateAddBasicAndroid(appsFilter); + appsFilter.onSystemReady(); + + PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"), + DUMMY_TARGET_APPID); + PackageSetting instrumentation = simulateAddPackage(appsFilter, + pkgWithInstrumentation("com.some.other.package", "com.some.package"), + DUMMY_CALLING_APPID); + + final int hasProviderAppId = Process.FIRST_APPLICATION_UID + 1; + final int queriesProviderAppId = Process.FIRST_APPLICATION_UID + 2; + PackageSetting queriesProvider = simulateAddPackage(appsFilter, + pkgQueriesProvider("com.yet.some.other.package", "com.some.authority"), + queriesProviderAppId); + appsFilter.grantImplicitAccess( + hasProviderAppId, queriesProviderAppId, false /* retainOnUpdate */); + + AppsFilterSnapshot snapshot = appsFilter.snapshot(); + assertFalse( + snapshot.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target, + SYSTEM_USER)); + assertFalse( + snapshot.shouldFilterApplication(DUMMY_TARGET_APPID, target, instrumentation, + SYSTEM_USER)); + + SparseArray<int[]> queriesProviderFilter = + snapshot.getVisibilityAllowList(queriesProvider, USER_ARRAY, mExisting); + assertThat(toList(queriesProviderFilter.get(SYSTEM_USER)), contains(queriesProviderAppId)); + assertTrue(snapshot.canQueryPackage(instrumentation.getPkg(), + target.getPackageName())); + + // New changes don't affect the snapshot + appsFilter.removePackage(target, false); + assertTrue( + appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target, + SYSTEM_USER)); + assertFalse( + snapshot.shouldFilterApplication(DUMMY_CALLING_APPID, instrumentation, target, + SYSTEM_USER)); + + } + private List<Integer> toList(int[] array) { ArrayList<Integer> ret = new ArrayList<>(array.length); for (int i = 0; i < array.length; i++) { @@ -1282,7 +1331,7 @@ public class AppsFilterTest { PackageSettingBuilder withBuilder(PackageSettingBuilder builder); } - private void simulateAddBasicAndroid(AppsFilter appsFilter) throws Exception { + private void simulateAddBasicAndroid(AppsFilterImpl appsFilter) throws Exception { final Signature frameworkSignature = Mockito.mock(Signature.class); final SigningDetails frameworkSigningDetails = new SigningDetails(new Signature[]{frameworkSignature}, 1); @@ -1291,17 +1340,17 @@ public class AppsFilterTest { b -> b.setSigningDetails(frameworkSigningDetails)); } - private PackageSetting simulateAddPackage(AppsFilter filter, + private PackageSetting simulateAddPackage(AppsFilterImpl filter, ParsingPackage newPkgBuilder, int appId) { return simulateAddPackage(filter, newPkgBuilder, appId, null /*settingBuilder*/); } - private PackageSetting simulateAddPackage(AppsFilter filter, + private PackageSetting simulateAddPackage(AppsFilterImpl filter, ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action) { return simulateAddPackage(filter, newPkgBuilder, appId, action, null /*sharedUserSetting*/); } - private PackageSetting simulateAddPackage(AppsFilter filter, + private PackageSetting simulateAddPackage(AppsFilterImpl filter, ParsingPackage newPkgBuilder, int appId, @Nullable WithSettingBuilder action, @Nullable SharedUserSetting sharedUserSetting) { final PackageSetting setting = @@ -1324,7 +1373,7 @@ public class AppsFilterTest { return setting; } - private void simulateAddPackage(PackageSetting setting, AppsFilter filter, + private void simulateAddPackage(PackageSetting setting, AppsFilterImpl filter, @Nullable SharedUserSetting sharedUserSetting) { mExisting.put(setting.getPackageName(), setting); if (sharedUserSetting != null) { diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/library/ApexSharedLibraryUpdaterTest.java b/services/tests/servicestests/src/com/android/server/pm/parsing/library/ApexSharedLibraryUpdaterTest.java index 1d9ea4b6028c..0b144dc7ee3a 100644 --- a/services/tests/servicestests/src/com/android/server/pm/parsing/library/ApexSharedLibraryUpdaterTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/parsing/library/ApexSharedLibraryUpdaterTest.java @@ -41,6 +41,8 @@ import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class ApexSharedLibraryUpdaterTest extends PackageSharedLibraryUpdaterTest { + private static final String SDK_INT_PLUS_ONE = "" + (Build.VERSION.SDK_INT + 1); + private static final String SDK_INT_PLUS_TWO = "" + (Build.VERSION.SDK_INT + 2); private final ArrayMap<String, SystemConfig.SharedLibraryEntry> mSharedLibraries = new ArrayMap<>(8); @@ -51,14 +53,19 @@ public class ApexSharedLibraryUpdaterTest extends PackageSharedLibraryUpdaterTes private void installSharedLibraries() throws Exception { mSharedLibraries.clear(); - insertLibrary("foo", 0, 0); - insertLibrary("fooBcpSince30", 30, 0); - insertLibrary("fooBcpBefore30", 0, 30); - insertLibrary("fooFromFuture", Build.VERSION.SDK_INT + 2, 0); + insertLibrary("foo", null, null); + insertLibrary("fooBcpSince30", "30", null); + insertLibrary("fooBcpBefore30", null, "30"); + // simulate libraries being added to the BCP in a future release + insertLibrary("fooSinceFuture", SDK_INT_PLUS_ONE, null); + insertLibrary("fooSinceFutureCodename", "Z", null); + // simulate libraries being removed from the BCP in a future release + insertLibrary("fooBcpBeforeFuture", null, SDK_INT_PLUS_ONE); + insertLibrary("fooBcpBeforeFutureCodename", null, "Z"); } - private void insertLibrary(String libraryName, int onBootclasspathSince, - int onBootclasspathBefore) { + private void insertLibrary(String libraryName, String onBootclasspathSince, + String onBootclasspathBefore) { mSharedLibraries.put(libraryName, new SystemConfig.SharedLibraryEntry( libraryName, "foo.jar", @@ -112,7 +119,7 @@ public class ApexSharedLibraryUpdaterTest extends PackageSharedLibraryUpdaterTes } @Test - public void testBcpSince11kNotAppliedWithoutLibrary() { + public void testBcpSinceFutureNotAppliedWithoutLibrary() { ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) .setTargetSdkVersion(Build.VERSION_CODES.R) .hideAsParsed()); @@ -128,15 +135,17 @@ public class ApexSharedLibraryUpdaterTest extends PackageSharedLibraryUpdaterTes } @Test - public void testBcpSince11kNotAppliedWithLibrary() { + public void testBcpSinceFutureNotAppliedWithLibrary() { ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) .setTargetSdkVersion(Build.VERSION_CODES.R) - .addUsesLibrary("fooFromFuture") + .addUsesLibrary("fooSinceFuture") + .addUsesLibrary("fooSinceFutureCodename") .hideAsParsed()); AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) .setTargetSdkVersion(Build.VERSION_CODES.R) - .addUsesLibrary("fooFromFuture") + .addUsesLibrary("fooSinceFuture") + .addUsesLibrary("fooSinceFutureCodename") .hideAsParsed()) .hideAsFinal(); @@ -183,7 +192,7 @@ public class ApexSharedLibraryUpdaterTest extends PackageSharedLibraryUpdaterTes */ @Test public void testBcpRemovedThenAddedPast() { - insertLibrary("fooBcpRemovedThenAdded", 30, 28); + insertLibrary("fooBcpRemovedThenAdded", "30", "28"); ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) .setTargetSdkVersion(Build.VERSION_CODES.N) @@ -207,7 +216,8 @@ public class ApexSharedLibraryUpdaterTest extends PackageSharedLibraryUpdaterTes */ @Test public void testBcpRemovedThenAddedMiddle_targetQ() { - insertLibrary("fooBcpRemovedThenAdded", Build.VERSION.SDK_INT + 1, 30); + insertLibrary("fooBcpRemovedThenAdded", SDK_INT_PLUS_ONE, "30"); + insertLibrary("fooBcpRemovedThenAddedCodename", "Z", "30"); ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) .setTargetSdkVersion(Build.VERSION_CODES.Q) @@ -217,6 +227,7 @@ public class ApexSharedLibraryUpdaterTest extends PackageSharedLibraryUpdaterTes .setTargetSdkVersion(Build.VERSION_CODES.Q) .addUsesLibrary("fooBcpRemovedThenAdded") .addUsesLibrary("fooBcpBefore30") + .addUsesLibrary("fooBcpRemovedThenAddedCodename") .hideAsParsed()) .hideAsFinal(); @@ -232,7 +243,8 @@ public class ApexSharedLibraryUpdaterTest extends PackageSharedLibraryUpdaterTes */ @Test public void testBcpRemovedThenAddedMiddle_targetR() { - insertLibrary("fooBcpRemovedThenAdded", Build.VERSION.SDK_INT + 1, 30); + insertLibrary("fooBcpRemovedThenAdded", SDK_INT_PLUS_ONE, "30"); + insertLibrary("fooBcpRemovedThenAddedCodename", "Z", "30"); ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) .setTargetSdkVersion(Build.VERSION_CODES.R) @@ -256,7 +268,8 @@ public class ApexSharedLibraryUpdaterTest extends PackageSharedLibraryUpdaterTes */ @Test public void testBcpRemovedThenAddedMiddle_targetR_usingLib() { - insertLibrary("fooBcpRemovedThenAdded", Build.VERSION.SDK_INT + 1, 30); + insertLibrary("fooBcpRemovedThenAdded", SDK_INT_PLUS_ONE, "30"); + insertLibrary("fooBcpRemovedThenAddedCodename", "Z", "30"); ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) .setTargetSdkVersion(Build.VERSION_CODES.R) @@ -274,6 +287,82 @@ public class ApexSharedLibraryUpdaterTest extends PackageSharedLibraryUpdaterTes checkBackwardsCompatibility(before, after); } + /** + * Test a library that was first removed from the BCP [to a mainline module] and later was + * moved back to the BCP via a mainline module update. Both things happening in future SDKs. + */ + @Test + public void testBcpRemovedThenAddedFuture() { + insertLibrary("fooBcpRemovedThenAdded", SDK_INT_PLUS_TWO, SDK_INT_PLUS_ONE); + ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) + .setTargetSdkVersion(Build.VERSION_CODES.R) + .hideAsParsed()); + + AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) + .setTargetSdkVersion(Build.VERSION_CODES.R) + .hideAsParsed()) + .hideAsFinal(); + + // in this example, we are at the point where the library is still in the BCP + checkBackwardsCompatibility(before, after); + } + + /** + * Test a library that was first removed from the BCP [to a mainline module] and later was + * moved back to the BCP via a mainline module update. Both things happening in future SDKs. + */ + @Test + public void testBcpRemovedThenAddedFuture_usingLib() { + insertLibrary("fooBcpRemovedThenAdded", SDK_INT_PLUS_TWO, SDK_INT_PLUS_ONE); + + ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) + .setTargetSdkVersion(Integer.parseInt(SDK_INT_PLUS_ONE)) + .addUsesLibrary("fooBcpRemovedThenAdded") + .hideAsParsed()); + + AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) + .setTargetSdkVersion(Integer.parseInt(SDK_INT_PLUS_ONE)) + .hideAsParsed()) + .hideAsFinal(); + + // in this example, we are at the point where the library was removed from the BCP + checkBackwardsCompatibility(before, after); + } + + @Test + public void testBcpBeforeFuture() { + ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) + .setTargetSdkVersion(Build.VERSION_CODES.R) + .addUsesLibrary("fooBcpBeforeFuture") + .addUsesLibrary("fooBcpBeforeFutureCodename") + .hideAsParsed()); + + AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) + .setTargetSdkVersion(Build.VERSION_CODES.R) + .hideAsParsed()) + .hideAsFinal(); + + // in this example, we are at the point where the library was removed from the BCP + checkBackwardsCompatibility(before, after); + } + + @Test + public void testBcpBeforeFuture_futureTargetSdk() { + ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) + .setTargetSdkVersion(Integer.parseInt(SDK_INT_PLUS_ONE)) + .addUsesLibrary("fooBcpBeforeFuture") + .addUsesLibrary("fooBcpBeforeFutureCodename") + .hideAsParsed()); + + AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME) + .setTargetSdkVersion(Integer.parseInt(SDK_INT_PLUS_ONE)) + .hideAsParsed()) + .hideAsFinal(); + + // in this example, we are at the point where the library was removed from the BCP + checkBackwardsCompatibility(before, after); + } + private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) { checkBackwardsCompatibility(before, after, () -> new ApexSharedLibraryUpdater(mSharedLibraries)); diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java index 6bdd88c6a712..2d0755d00ba8 100644 --- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java +++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java @@ -20,18 +20,15 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; -import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atMost; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @@ -56,32 +53,20 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.mockito.ArgumentCaptor; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.atomic.AtomicReference; @RunWith(Parameterized.class) public class SoundHw2CompatTest { - @Parameterized.Parameter(0) public String mVersion; - @Parameterized.Parameter(1) public boolean mSupportConcurrentCapture; + @Parameterized.Parameter public String mVersion; private final Runnable mRebootRunnable = mock(Runnable.class); private ISoundTriggerHal mCanonical; - private CaptureStateNotifier mCaptureStateNotifier; private android.hardware.soundtrigger.V2_0.ISoundTriggerHw mHalDriver; // We run the test once for every version of the underlying driver. - @Parameterized.Parameters(name = "{0}, concurrent={1}") - public static Iterable<Object[]> data() { - List<Object[]> result = new LinkedList<>(); - - for (String version : new String[]{"V2_0", "V2_1", "V2_2", "V2_3",}) { - for (boolean concurrentCapture : new boolean[]{false, true}) { - result.add(new Object[]{version, concurrentCapture}); - } - } - - return result; + @Parameterized.Parameters + public static Object[] data() { + return new String[]{"V2_0", "V2_1", "V2_2", "V2_3"}; } @Before @@ -139,7 +124,7 @@ public class SoundHw2CompatTest { when(mHalDriver.asBinder()).thenReturn(binder); android.hardware.soundtrigger.V2_3.Properties halProperties = - TestUtil.createDefaultProperties_2_3(mSupportConcurrentCapture); + TestUtil.createDefaultProperties_2_3(); doAnswer(invocation -> { ((android.hardware.soundtrigger.V2_0.ISoundTriggerHw.getPropertiesCallback) invocation.getArgument( 0)).onValues(0, halProperties.base); @@ -156,10 +141,7 @@ public class SoundHw2CompatTest { }).when(driver).getProperties_2_3(any()); } - mCaptureStateNotifier = spy(new CaptureStateNotifier()); - - mCanonical = SoundTriggerHw2Compat.create(mHalDriver, mRebootRunnable, - mCaptureStateNotifier); + mCanonical = SoundTriggerHw2Compat.create(mHalDriver, mRebootRunnable, null); // During initialization any method can be called, but after we're starting to enforce that // no additional methods are called. @@ -171,7 +153,6 @@ public class SoundHw2CompatTest { mCanonical.detach(); verifyNoMoreInteractions(mHalDriver); verifyNoMoreInteractions(mRebootRunnable); - mCaptureStateNotifier.verifyNoMoreListeners(); } @Test @@ -194,12 +175,12 @@ public class SoundHw2CompatTest { // It is OK for the SUT to cache the properties, so the underlying method doesn't // need to be called every single time. verify(driver, atMost(1)).getProperties_2_3(any()); - TestUtil.validateDefaultProperties(properties, mSupportConcurrentCapture); + TestUtil.validateDefaultProperties(properties); } else { // It is OK for the SUT to cache the properties, so the underlying method doesn't // need to be called every single time. verify(mHalDriver, atMost(1)).getProperties(any()); - TestUtil.validateDefaultProperties(properties, mSupportConcurrentCapture, 0, ""); + TestUtil.validateDefaultProperties(properties, 0, ""); } } @@ -291,7 +272,7 @@ public class SoundHw2CompatTest { ISoundTriggerHal.ModelCallback canonicalCallback = mock( ISoundTriggerHal.ModelCallback.class); - final int maxModels = TestUtil.createDefaultProperties_2_0(false).maxSoundModels; + final int maxModels = TestUtil.createDefaultProperties_2_0().maxSoundModels; int[] modelHandles = new int[maxModels]; // Load as many models as we're allowed. @@ -318,7 +299,7 @@ public class SoundHw2CompatTest { verify(globalCallback).onResourcesAvailable(); } - private int loadPhraseModel_2_0(ISoundTriggerHal.ModelCallback canonicalCallback) + private void loadPhraseModel_2_0(ISoundTriggerHal.ModelCallback canonicalCallback) throws Exception { final int handle = 29; ArgumentCaptor<android.hardware.soundtrigger.V2_0.ISoundTriggerHw.PhraseSoundModel> @@ -345,10 +326,9 @@ public class SoundHw2CompatTest { TestUtil.validatePhraseSoundModel_2_0(modelCaptor.getValue()); validateCallback_2_0(callbackCaptor.getValue(), canonicalCallback); - return handle; } - private int loadPhraseModel_2_1(ISoundTriggerHal.ModelCallback canonicalCallback) + private void loadPhraseModel_2_1(ISoundTriggerHal.ModelCallback canonicalCallback) throws Exception { final android.hardware.soundtrigger.V2_1.ISoundTriggerHw driver_2_1 = (android.hardware.soundtrigger.V2_1.ISoundTriggerHw) mHalDriver; @@ -380,14 +360,13 @@ public class SoundHw2CompatTest { TestUtil.validatePhraseSoundModel_2_1(model.get()); validateCallback_2_1(callbackCaptor.getValue(), canonicalCallback); - return handle; } - public int loadPhraseModel(ISoundTriggerHal.ModelCallback canonicalCallback) throws Exception { + public void loadPhraseModel(ISoundTriggerHal.ModelCallback canonicalCallback) throws Exception { if (mHalDriver instanceof android.hardware.soundtrigger.V2_1.ISoundTriggerHw) { - return loadPhraseModel_2_1(canonicalCallback); + loadPhraseModel_2_1(canonicalCallback); } else { - return loadPhraseModel_2_0(canonicalCallback); + loadPhraseModel_2_0(canonicalCallback); } } @@ -484,80 +463,6 @@ public class SoundHw2CompatTest { } @Test - public void testConcurrentCaptureAbort() throws Exception { - assumeFalse(mSupportConcurrentCapture); - verify(mCaptureStateNotifier, atLeast(1)).registerListener(any()); - - // Register global callback. - ISoundTriggerHal.GlobalCallback globalCallback = mock( - ISoundTriggerHal.GlobalCallback.class); - mCanonical.registerCallback(globalCallback); - - // Load. - ISoundTriggerHal.ModelCallback canonicalCallback = mock( - ISoundTriggerHal.ModelCallback.class); - final int handle = loadGenericModel(canonicalCallback); - - // Then start. - startRecognition(handle, canonicalCallback); - - // Now activate external capture. - mCaptureStateNotifier.setState(true); - - // Expect hardware to have been stopped. - verify(mHalDriver).stopRecognition(handle); - - // Expect an abort event (async). - ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass( - RecognitionEvent.class); - mCanonical.flushCallbacks(); - verify(canonicalCallback).recognitionCallback(eq(handle), eventCaptor.capture()); - assertEquals(RecognitionStatus.ABORTED, eventCaptor.getValue().status); - - // Deactivate external capture. - mCaptureStateNotifier.setState(false); - - // Expect a onResourcesAvailable(). - mCanonical.flushCallbacks(); - verify(globalCallback).onResourcesAvailable(); - } - - @Test - public void testConcurrentCaptureReject() throws Exception { - assumeFalse(mSupportConcurrentCapture); - verify(mCaptureStateNotifier, atLeast(1)).registerListener(any()); - - // Register global callback. - ISoundTriggerHal.GlobalCallback globalCallback = mock( - ISoundTriggerHal.GlobalCallback.class); - mCanonical.registerCallback(globalCallback); - - // Load (this registers the callback). - ISoundTriggerHal.ModelCallback canonicalCallback = mock( - ISoundTriggerHal.ModelCallback.class); - final int handle = loadGenericModel(canonicalCallback); - - // Report external capture active. - mCaptureStateNotifier.setState(true); - - // Then start. - RecognitionConfig config = TestUtil.createRecognitionConfig(); - try { - mCanonical.startRecognition(handle, 203, 204, config); - fail("Expected an exception"); - } catch (RecoverableException e) { - assertEquals(Status.RESOURCE_CONTENTION, e.errorCode); - } - - // Deactivate external capture. - mCaptureStateNotifier.setState(false); - - // Expect a onResourcesAvailable(). - mCanonical.flushCallbacks(); - verify(globalCallback).onResourcesAvailable(); - } - - @Test public void testStopRecognition() throws Exception { mCanonical.stopRecognition(17); verify(mHalDriver).stopRecognition(17); @@ -675,7 +580,7 @@ public class SoundHw2CompatTest { } @Test - public void testGlobalCallback() throws Exception { + public void testGlobalCallback() { testGlobalCallback_2_0(); } @@ -803,29 +708,4 @@ public class SoundHw2CompatTest { verifyNoMoreInteractions(canonicalCallback); clearInvocations(canonicalCallback); } - - public static class CaptureStateNotifier implements ICaptureStateNotifier { - private final List<Listener> mListeners = new LinkedList<>(); - - @Override - public boolean registerListener(Listener listener) { - mListeners.add(listener); - return false; - } - - @Override - public void unregisterListener(Listener listener) { - mListeners.remove(listener); - } - - public void setState(boolean state) { - for (Listener listener : mListeners) { - listener.onCaptureStateChange(state); - } - } - - public void verifyNoMoreListeners() { - assertEquals(0, mListeners.size()); - } - } } diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandlerTest.java b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandlerTest.java new file mode 100644 index 000000000000..61989252d04d --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandlerTest.java @@ -0,0 +1,313 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.soundtrigger_middleware; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.atMost; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +import android.media.soundtrigger.RecognitionEvent; +import android.media.soundtrigger.RecognitionStatus; + +import androidx.annotation.NonNull; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.ArgumentCaptor; + +@RunWith(JUnit4.class) +public class SoundTriggerHalConcurrentCaptureHandlerTest { + private ISoundTriggerHal mUnderlying; + private CaptureStateNotifier mNotifier; + private ISoundTriggerHal.GlobalCallback mGlobalCallback; + private SoundTriggerHalConcurrentCaptureHandler mHandler; + + @Before + public void setUp() { + mNotifier = new CaptureStateNotifier(); + mUnderlying = mock(ISoundTriggerHal.class); + mGlobalCallback = mock(ISoundTriggerHal.GlobalCallback.class); + mHandler = new SoundTriggerHalConcurrentCaptureHandler(mUnderlying, mNotifier); + mHandler.registerCallback(mGlobalCallback); + } + + @Test + public void testBasic() throws Exception { + ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class); + int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback); + verify(mUnderlying).loadSoundModel(any(), any()); + + mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig()); + verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any()); + + mNotifier.setActive(true); + verify(mUnderlying).stopRecognition(handle); + ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass( + RecognitionEvent.class); + Thread.sleep(50); + verify(callback).recognitionCallback(eq(handle), eventCaptor.capture()); + RecognitionEvent event = eventCaptor.getValue(); + assertEquals(event.status, RecognitionStatus.ABORTED); + assertFalse(event.recognitionStillActive); + verifyZeroInteractions(mGlobalCallback); + clearInvocations(callback, mUnderlying); + + mNotifier.setActive(false); + Thread.sleep(50); + verify(mGlobalCallback).onResourcesAvailable(); + verifyNoMoreInteractions(callback, mUnderlying); + + mNotifier.setActive(true); + verifyNoMoreInteractions(callback, mUnderlying); + } + + @Test + public void testStopBeforeActive() throws Exception { + ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class); + int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback); + verify(mUnderlying).loadSoundModel(any(), any()); + + mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig()); + verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any()); + mHandler.stopRecognition(handle); + verify(mUnderlying).stopRecognition(handle); + clearInvocations(mUnderlying); + + mNotifier.setActive(true); + Thread.sleep(50); + verifyNoMoreInteractions(mUnderlying); + verifyNoMoreInteractions(callback); + } + + @Test + public void testStopAfterActive() { + ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class); + int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback); + verify(mUnderlying).loadSoundModel(any(), any()); + + mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig()); + verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any()); + + mNotifier.setActive(true); + verify(mUnderlying, times(1)).stopRecognition(handle); + mHandler.stopRecognition(handle); + verify(callback, times(1)).recognitionCallback(eq(handle), any()); + } + + @Test(timeout = 200) + public void testAbortWhileStop() { + ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class); + int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback); + ArgumentCaptor<ISoundTriggerHal.ModelCallback> modelCallbackCaptor = + ArgumentCaptor.forClass(ISoundTriggerHal.ModelCallback.class); + verify(mUnderlying).loadSoundModel(any(), modelCallbackCaptor.capture()); + ISoundTriggerHal.ModelCallback modelCallback = modelCallbackCaptor.getValue(); + + mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig()); + verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any()); + + doAnswer(invocation -> { + RecognitionEvent event = TestUtil.createRecognitionEvent(RecognitionStatus.ABORTED, + false); + // Call the callback from a different thread to detect deadlocks by preventing recursive + // locking from working. + runOnSeparateThread(() -> modelCallback.recognitionCallback(handle, event)); + return null; + }).when(mUnderlying).stopRecognition(handle); + mHandler.stopRecognition(handle); + verify(mUnderlying, times(1)).stopRecognition(handle); + + ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass( + RecognitionEvent.class); + verify(callback, atMost(1)).recognitionCallback(eq(handle), eventCaptor.capture()); + } + + @Test(timeout = 200) + public void testActiveWhileStop() { + ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class); + int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback); + ArgumentCaptor<ISoundTriggerHal.ModelCallback> modelCallbackCaptor = + ArgumentCaptor.forClass(ISoundTriggerHal.ModelCallback.class); + verify(mUnderlying).loadSoundModel(any(), modelCallbackCaptor.capture()); + ISoundTriggerHal.ModelCallback modelCallback = modelCallbackCaptor.getValue(); + + mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig()); + verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any()); + + doAnswer(invocation -> { + // The stop request causes a callback to be flushed. + RecognitionEvent event = TestUtil.createRecognitionEvent(RecognitionStatus.FORCED, + true); + // Call the callback from a different thread to detect deadlocks by preventing recursive + // locking from working. + runOnSeparateThread(() -> modelCallback.recognitionCallback(handle, event)); + // While the HAL is processing the stop request, capture state becomes active. + new Thread(() -> mNotifier.setActive(true)).start(); + Thread.sleep(50); + return null; + }).when(mUnderlying).stopRecognition(handle); + mHandler.stopRecognition(handle); + // We only expect one underlying invocation of stop(). + verify(mUnderlying, times(1)).stopRecognition(handle); + + // The callback shouldn't be invoked in this case. + verify(callback, never()).recognitionCallback(eq(handle), any()); + } + + @Test(timeout = 200) + public void testStopWhileActive() { + ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class); + int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback); + ArgumentCaptor<ISoundTriggerHal.ModelCallback> modelCallbackCaptor = + ArgumentCaptor.forClass(ISoundTriggerHal.ModelCallback.class); + verify(mUnderlying).loadSoundModel(any(), modelCallbackCaptor.capture()); + ISoundTriggerHal.ModelCallback modelCallback = modelCallbackCaptor.getValue(); + + mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig()); + verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any()); + + doAnswer(invocation -> { + // The stop request causes a callback to be flushed. + RecognitionEvent event = TestUtil.createRecognitionEvent(RecognitionStatus.FORCED, + true); + // Call the callback from a different thread to detect deadlocks by preventing recursive + // locking from working. + runOnSeparateThread(() -> modelCallback.recognitionCallback(handle, event)); + // While the HAL is processing the stop request, client requests stop. + new Thread(() -> mHandler.stopRecognition(handle)).start(); + Thread.sleep(50); + return null; + }).when(mUnderlying).stopRecognition(handle); + mNotifier.setActive(true); + // We only expect one underlying invocation of stop(). + verify(mUnderlying, times(1)).stopRecognition(handle); + verify(callback, atMost(1)).recognitionCallback(eq(handle), any()); + } + + @Test(timeout = 200) + public void testEventWhileActive() throws Exception { + ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class); + int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback); + ArgumentCaptor<ISoundTriggerHal.ModelCallback> modelCallbackCaptor = + ArgumentCaptor.forClass(ISoundTriggerHal.ModelCallback.class); + verify(mUnderlying).loadSoundModel(any(), modelCallbackCaptor.capture()); + ISoundTriggerHal.ModelCallback modelCallback = modelCallbackCaptor.getValue(); + + mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig()); + verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any()); + + doAnswer(invocation -> { + RecognitionEvent event = TestUtil.createRecognitionEvent(RecognitionStatus.SUCCESS, + false); + // Call the callback from a different thread to detect deadlocks by preventing recursive + // locking from working. + runOnSeparateThread(() -> modelCallback.recognitionCallback(handle, event)); + return null; + }).when(mUnderlying).stopRecognition(handle); + mNotifier.setActive(true); + verify(mUnderlying, times(1)).stopRecognition(handle); + Thread.sleep(50); + + ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass( + RecognitionEvent.class); + verify(callback, atMost(2)).recognitionCallback(eq(handle), eventCaptor.capture()); + RecognitionEvent lastEvent = eventCaptor.getValue(); + assertEquals(lastEvent.status, RecognitionStatus.ABORTED); + assertFalse(lastEvent.recognitionStillActive); + } + + + @Test(timeout = 200) + public void testNonFinalEventWhileActive() throws Exception { + ISoundTriggerHal.ModelCallback callback = mock(ISoundTriggerHal.ModelCallback.class); + int handle = mHandler.loadSoundModel(TestUtil.createGenericSoundModel(), callback); + ArgumentCaptor<ISoundTriggerHal.ModelCallback> modelCallbackCaptor = + ArgumentCaptor.forClass(ISoundTriggerHal.ModelCallback.class); + verify(mUnderlying).loadSoundModel(any(), modelCallbackCaptor.capture()); + ISoundTriggerHal.ModelCallback modelCallback = modelCallbackCaptor.getValue(); + + mHandler.startRecognition(handle, 101, 102, TestUtil.createRecognitionConfig()); + verify(mUnderlying).startRecognition(eq(handle), eq(101), eq(102), any()); + + doAnswer(invocation -> { + RecognitionEvent event = TestUtil.createRecognitionEvent(RecognitionStatus.FORCED, + true); + // Call the callback from a different thread to detect deadlocks by preventing recursive + // locking from working. + runOnSeparateThread(() -> modelCallback.recognitionCallback(handle, event)); + + return null; + }).when(mUnderlying).stopRecognition(handle); + mNotifier.setActive(true); + verify(mUnderlying, times(1)).stopRecognition(handle); + + Thread.sleep(50); + ArgumentCaptor<RecognitionEvent> eventCaptor = ArgumentCaptor.forClass( + RecognitionEvent.class); + verify(callback, atMost(2)).recognitionCallback(eq(handle), eventCaptor.capture()); + RecognitionEvent lastEvent = eventCaptor.getValue(); + assertEquals(lastEvent.status, RecognitionStatus.ABORTED); + assertFalse(lastEvent.recognitionStillActive); + } + + private static void runOnSeparateThread(Runnable runnable) { + Thread thread = new Thread(runnable); + thread.start(); + try { + thread.join(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + private static class CaptureStateNotifier implements ICaptureStateNotifier { + boolean mActive = false; + Listener mListener; + + @Override + public boolean registerListener(@NonNull Listener listener) { + mListener = listener; + return mActive; + } + + @Override + public void unregisterListener(@NonNull Listener listener) { + mListener = null; + } + + public void setActive(boolean active) { + mActive = active; + if (mListener != null) { + // Call the callback from a different thread to detect deadlocks by preventing + // recursive locking from working. + runOnSeparateThread(() -> mListener.onCaptureStateChange(mActive)); + } + } + } +} diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareImplTest.java b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareImplTest.java index 0187e34cbc5f..3bebc94fe0ed 100644 --- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareImplTest.java +++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareImplTest.java @@ -134,7 +134,7 @@ public class SoundTriggerMiddlewareImplTest { public void setUp() throws Exception { clearInvocations(mHalDriver); clearInvocations(mAudioSessionProvider); - when(mHalDriver.getProperties()).thenReturn(TestUtil.createDefaultProperties(false)); + when(mHalDriver.getProperties()).thenReturn(TestUtil.createDefaultProperties()); mService = new SoundTriggerMiddlewareImpl(() -> mHalDriver, mAudioSessionProvider); } @@ -156,7 +156,7 @@ public class SoundTriggerMiddlewareImplTest { assertEquals(1, allDescriptors.length); Properties properties = allDescriptors[0].properties; - assertEquals(TestUtil.createDefaultProperties(false), properties); + assertEquals(TestUtil.createDefaultProperties(), properties); } @Test diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java index 30b4a59b32b1..39561f74d7ed 100644 --- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java +++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java @@ -162,8 +162,8 @@ class TestUtil { phrases.get(0).recognitionModes); } - static android.hardware.soundtrigger.V2_0.ISoundTriggerHw.Properties createDefaultProperties_2_0( - boolean supportConcurrentCapture) { + static android.hardware.soundtrigger.V2_0.ISoundTriggerHw.Properties + createDefaultProperties_2_0() { android.hardware.soundtrigger.V2_0.ISoundTriggerHw.Properties properties = new android.hardware.soundtrigger.V2_0.ISoundTriggerHw.Properties(); properties.implementor = "implementor"; @@ -185,17 +185,16 @@ class TestUtil { | android.hardware.soundtrigger.V2_0.RecognitionMode.GENERIC_TRIGGER; properties.captureTransition = true; properties.maxBufferMs = 321; - properties.concurrentCapture = supportConcurrentCapture; + properties.concurrentCapture = true; properties.triggerInEvent = true; properties.powerConsumptionMw = 432; return properties; } - static android.hardware.soundtrigger.V2_3.Properties createDefaultProperties_2_3( - boolean supportConcurrentCapture) { + static android.hardware.soundtrigger.V2_3.Properties createDefaultProperties_2_3() { android.hardware.soundtrigger.V2_3.Properties properties = new android.hardware.soundtrigger.V2_3.Properties(); - properties.base = createDefaultProperties_2_0(supportConcurrentCapture); + properties.base = createDefaultProperties_2_0(); properties.supportedModelArch = "supportedModelArch"; properties.audioCapabilities = android.hardware.soundtrigger.V2_3.AudioCapabilities.ECHO_CANCELLATION @@ -203,7 +202,7 @@ class TestUtil { return properties; } - static Properties createDefaultProperties(boolean supportConcurrentCapture) { + static Properties createDefaultProperties() { Properties properties = new Properties(); properties.implementor = "implementor"; properties.description = "description"; @@ -217,7 +216,7 @@ class TestUtil { | RecognitionMode.USER_AUTHENTICATION | RecognitionMode.GENERIC_TRIGGER; properties.captureTransition = true; properties.maxBufferMs = 321; - properties.concurrentCapture = supportConcurrentCapture; + properties.concurrentCapture = true; properties.triggerInEvent = true; properties.powerConsumptionMw = 432; properties.supportedModelArch = "supportedModelArch"; @@ -226,13 +225,13 @@ class TestUtil { return properties; } - static void validateDefaultProperties(Properties properties, boolean supportConcurrentCapture) { - validateDefaultProperties(properties, supportConcurrentCapture, + static void validateDefaultProperties(Properties properties) { + validateDefaultProperties(properties, AudioCapabilities.ECHO_CANCELLATION | AudioCapabilities.NOISE_SUPPRESSION, "supportedModelArch"); } - static void validateDefaultProperties(Properties properties, boolean supportConcurrentCapture, + static void validateDefaultProperties(Properties properties, @AudioCapabilities int audioCapabilities, @NonNull String supportedModelArch) { assertEquals("implementor", properties.implementor); assertEquals("description", properties.description); @@ -246,7 +245,7 @@ class TestUtil { properties.recognitionModes); assertTrue(properties.captureTransition); assertEquals(321, properties.maxBufferMs); - assertEquals(supportConcurrentCapture, properties.concurrentCapture); + assertEquals(true, properties.concurrentCapture); assertTrue(properties.triggerInEvent); assertEquals(432, properties.powerConsumptionMw); assertEquals(supportedModelArch, properties.supportedModelArch); diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java index bfdffc0e6567..20486b3e396d 100644 --- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java +++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java @@ -429,18 +429,40 @@ public class SystemConfigTest { public void readPermissions_allowLibs_parsesSimpleLibrary() throws IOException { String contents = "<permissions>\n" - + " <library \n" - + " name=\"foo\"\n" - + " file=\"" + mFooJar + "\"\n" - + " on-bootclasspath-before=\"10\"\n" - + " on-bootclasspath-since=\"20\"\n" - + " />\n\n" - + " </permissions>"; + + " <library \n" + + " name=\"foo\"\n" + + " file=\"" + mFooJar + "\"\n" + + " on-bootclasspath-before=\"10\"\n" + + " on-bootclasspath-since=\"20\"\n" + + " />\n\n" + + " </permissions>"; parseSharedLibraries(contents); assertFooIsOnlySharedLibrary(); SystemConfig.SharedLibraryEntry entry = mSysConfig.getSharedLibraries().get("foo"); - assertThat(entry.onBootclasspathBefore).isEqualTo(10); - assertThat(entry.onBootclasspathSince).isEqualTo(20); + assertThat(entry.onBootclasspathBefore).isEqualTo("10"); + assertThat(entry.onBootclasspathSince).isEqualTo("20"); + } + + /** + * Tests that readPermissions works correctly for a library with on-bootclasspath-before + * and on-bootclasspath-since that uses codenames. + */ + @Test + public void readPermissions_allowLibs_parsesSimpleLibraryWithCodenames() throws IOException { + String contents = + "<permissions>\n" + + " <library \n" + + " name=\"foo\"\n" + + " file=\"" + mFooJar + "\"\n" + + " on-bootclasspath-before=\"Q\"\n" + + " on-bootclasspath-since=\"W\"\n" + + " />\n\n" + + " </permissions>"; + parseSharedLibraries(contents); + assertFooIsOnlySharedLibrary(); + SystemConfig.SharedLibraryEntry entry = mSysConfig.getSharedLibraries().get("foo"); + assertThat(entry.onBootclasspathBefore).isEqualTo("Q"); + assertThat(entry.onBootclasspathSince).isEqualTo("W"); } /** @@ -461,8 +483,8 @@ public class SystemConfigTest { parseSharedLibraries(contents); assertFooIsOnlySharedLibrary(); SystemConfig.SharedLibraryEntry entry = mSysConfig.getSharedLibraries().get("foo"); - assertThat(entry.onBootclasspathBefore).isEqualTo(10); - assertThat(entry.onBootclasspathSince).isEqualTo(20); + assertThat(entry.onBootclasspathBefore).isEqualTo("10"); + assertThat(entry.onBootclasspathSince).isEqualTo("20"); } /** @@ -543,12 +565,20 @@ public class SystemConfigTest { */ @Test public void readPermissions_allowLibs_allowsCurrentMaxSdk() throws IOException { + // depending on whether this test is running before or after finalization, we need to + // pass a different parameter + String parameter; + if ("REL".equals(Build.VERSION.CODENAME)) { + parameter = "" + Build.VERSION.SDK_INT; + } else { + parameter = "ZZZ"; + } String contents = "<permissions>\n" + " <library \n" + " name=\"foo\"\n" + " file=\"" + mFooJar + "\"\n" - + " max-device-sdk=\"" + Build.VERSION.SDK_INT + "\"\n" + + " max-device-sdk=\"" + parameter + "\"\n" + " />\n\n" + " </permissions>"; parseSharedLibraries(contents); diff --git a/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java b/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java index 4ed4c236535f..37c95f735d89 100644 --- a/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java +++ b/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java @@ -17,6 +17,7 @@ package com.android.server.utils; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -860,6 +861,54 @@ public class WatcherTest { } } + @Test + public void testWatchedSparseSetArray() { + final String name = "WatchedSparseSetArray"; + WatchableTester tester; + + // Test WatchedSparseSetArray + WatchedSparseSetArray array = new WatchedSparseSetArray(); + tester = new WatchableTester(array, name); + tester.verify(0, "Initial array - no registration"); + array.add(INDEX_A, 1); + tester.verify(0, "Updates with no registration"); + tester.register(); + tester.verify(0, "Updates with no registration"); + array.add(INDEX_B, 2); + tester.verify(1, "Updates with registration"); + array.add(INDEX_B, 4); + array.add(INDEX_C, 5); + tester.verify(3, "Updates with registration"); + // Special methods + assertTrue(array.remove(INDEX_C, 5)); + tester.verify(4, "Removed 5 from key 3"); + array.remove(INDEX_B); + tester.verify(5, "Removed everything for key 2"); + + // Snapshot + { + WatchedSparseSetArray arraySnap = (WatchedSparseSetArray) array.snapshot(); + tester.verify(5, "Generate snapshot"); + // Verify that the snapshot is a proper copy of the source. + assertEquals("WatchedSparseSetArray snap same size", + array.size(), arraySnap.size()); + for (int i = 0; i < array.size(); i++) { + ArraySet set = array.get(array.keyAt(i)); + ArraySet setSnap = arraySnap.get(arraySnap.keyAt(i)); + assertNotNull(set); + assertTrue(set.equals(setSnap)); + } + array.add(INDEX_D, 9); + tester.verify(6, "Tick after snapshot"); + // Verify that the array is sealed + verifySealed(name, ()->arraySnap.add(INDEX_D, 10)); + assertTrue(!array.isSealed()); + assertTrue(arraySnap.isSealed()); + } + array.clear(); + tester.verify(7, "Cleared all entries"); + } + private static class IndexGenerator { private final int mSeed; private final Random mRandom; @@ -1084,6 +1133,18 @@ public class WatcherTest { assertEquals(a.equals(s), true); a.put(rowIndex, colIndex, !a.get(rowIndex, colIndex)); assertEquals(a.equals(s), false); + + // Verify copy-in/out + { + final String msg = name + " copy"; + WatchedSparseBooleanMatrix copy = new WatchedSparseBooleanMatrix(); + copy.copyFrom(matrix); + final int end = copy.size(); + assertTrue(msg + " size mismatch " + end + " " + matrix.size(), end == matrix.size()); + for (int i = 0; i < end; i++) { + assertEquals(copy.keyAt(i), keys[i]); + } + } } @Test diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java index f3d494d160f2..4fbf0065f78d 100644 --- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java @@ -602,10 +602,15 @@ public class VibratorManagerServiceTest { VibrationEffect.EFFECT_HEAVY_CLICK, VibrationEffect.EFFECT_DOUBLE_CLICK); VibratorManagerService service = createSystemReadyService(); mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE); + + // The haptic feedback should be ignored in low power, but not the ringtone. The end + // of the test asserts which actual effects ended up playing. vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_TICK), HAPTIC_FEEDBACK_ATTRS); vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), RINGTONE_ATTRS); assertTrue(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() == 1, service, TEST_TIMEOUT_MILLIS)); + // Allow the ringtone to complete, as the other vibrations won't cancel it. + assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); mRegisteredPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE); vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK), @@ -815,6 +820,29 @@ public class VibratorManagerServiceTest { } @Test + public void vibrate_withOngoingRingtoneVibration_ignoresEffect() throws Exception { + mockVibrators(1); + mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); + VibratorManagerService service = createSystemReadyService(); + + VibrationEffect alarmEffect = VibrationEffect.createWaveform( + new long[]{10_000, 10_000}, new int[]{128, 255}, -1); + vibrate(service, alarmEffect, new VibrationAttributes.Builder().setUsage( + VibrationAttributes.USAGE_RINGTONE).build()); + + // VibrationThread will start this vibration async, so wait before checking it started. + assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getAllEffectSegments().isEmpty(), + service, TEST_TIMEOUT_MILLIS)); + + vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), + HAPTIC_FEEDBACK_ATTRS); + + // Wait before checking it never played a second effect. + assertFalse(waitUntil(s -> mVibratorProviders.get(1).getAllEffectSegments().size() > 1, + service, /* timeout= */ 50)); + } + + @Test public void vibrate_withInputDevices_vibratesInputDevices() throws Exception { mockVibrators(1); mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index 9902e83c3648..908de34352c9 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -1139,18 +1139,8 @@ public class ActivityStarterTests extends WindowTestsBase { true /* createdByOrganizer */); sourceRecord.getTask().addChild(taskFragment, POSITION_TOP); - starter.startActivityInner( - /* r */targetRecord, - /* sourceRecord */ sourceRecord, - /* voiceSession */null, - /* voiceInteractor */ null, - /* startFlags */ 0, - /* doResume */true, - /* options */null, - /* inTask */null, - /* inTaskFragment */ taskFragment, - /* restrictedBgActivity */false, - /* intentGrants */null); + startActivityInner(starter, targetRecord, sourceRecord, null /* options */, + null /* inTask */, taskFragment); assertFalse(taskFragment.hasChild()); } @@ -1167,18 +1157,8 @@ public class ActivityStarterTests extends WindowTestsBase { taskFragment.setTaskFragmentOrganizer(mock(TaskFragmentOrganizerToken.class), SYSTEM_UID, "system_uid"); - starter.startActivityInner( - /* r */targetRecord, - /* sourceRecord */ sourceRecord, - /* voiceSession */null, - /* voiceInteractor */ null, - /* startFlags */ 0, - /* doResume */true, - /* options */null, - /* inTask */null, - /* inTaskFragment */ taskFragment, - /* restrictedBgActivity */false, - /* intentGrants */null); + startActivityInner(starter, targetRecord, sourceRecord, null /* options */, + null /* inTask */, taskFragment); assertTrue(taskFragment.hasChild()); } @@ -1195,18 +1175,8 @@ public class ActivityStarterTests extends WindowTestsBase { taskFragment.setTaskFragmentOrganizer(mock(TaskFragmentOrganizerToken.class), targetRecord.getUid(), "test_process_name"); - starter.startActivityInner( - /* r */targetRecord, - /* sourceRecord */ sourceRecord, - /* voiceSession */null, - /* voiceInteractor */ null, - /* startFlags */ 0, - /* doResume */true, - /* options */null, - /* inTask */null, - /* inTaskFragment */ taskFragment, - /* restrictedBgActivity */false, - /* intentGrants */null); + startActivityInner(starter, targetRecord, sourceRecord, null /* options */, + null /* inTask */, taskFragment); assertTrue(taskFragment.hasChild()); } @@ -1231,18 +1201,8 @@ public class ActivityStarterTests extends WindowTestsBase { doReturn(true).when(signingDetails).hasAncestorOrSelfWithDigest(any()); doReturn(signingDetails).when(androidPackage).getSigningDetails(); - starter.startActivityInner( - /* r */targetRecord, - /* sourceRecord */ sourceRecord, - /* voiceSession */null, - /* voiceInteractor */ null, - /* startFlags */ 0, - /* doResume */true, - /* options */null, - /* inTask */null, - /* inTaskFragment */ taskFragment, - /* restrictedBgActivity */false, - /* intentGrants */null); + startActivityInner(starter, targetRecord, sourceRecord, null /* options */, + null /* inTask */, taskFragment); assertTrue(taskFragment.hasChild()); } @@ -1258,23 +1218,30 @@ public class ActivityStarterTests extends WindowTestsBase { targetRecord.info.flags |= ActivityInfo.FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING; - starter.startActivityInner( - /* r */targetRecord, - /* sourceRecord */ sourceRecord, - /* voiceSession */null, - /* voiceInteractor */ null, - /* startFlags */ 0, - /* doResume */true, - /* options */null, - /* inTask */null, - /* inTaskFragment */ taskFragment, - /* restrictedBgActivity */false, - /* intentGrants */null); + startActivityInner(starter, targetRecord, sourceRecord, null /* options */, + null /* inTask */, taskFragment); assertTrue(taskFragment.hasChild()); } @Test + public void testStartActivityInner_inTask() { + final ActivityStarter starter = prepareStarter(0, false); + // Simulate an app uses AppTask to create a non-attached task, and then it requests to + // start activity in the task. + final Task inTask = new TaskBuilder(mSupervisor).setTaskDisplayArea(null).setTaskId(123) + .build(); + inTask.inRecents = true; + assertFalse(inTask.isAttached()); + final ActivityRecord target = new ActivityBuilder(mAtm).build(); + startActivityInner(starter, target, null /* source */, null /* options */, inTask, + null /* inTaskFragment */); + + assertTrue(inTask.isAttached()); + assertEquals(inTask, target.getTask()); + } + + @Test public void testLaunchCookie_newAndExistingTask() { final ActivityStarter starter = prepareStarter(0, false); @@ -1322,21 +1289,20 @@ public class ActivityStarterTests extends WindowTestsBase { // Start the target launch-into-pip activity from a source final ActivityRecord sourceRecord = new ActivityBuilder(mAtm).setCreateTask(true).build(); - starter.startActivityInner( - /* r */ targetRecord, - /* sourceRecord */ sourceRecord, - /* voiceSession */ null, - /* voiceInteractor */ null, - /* startFlags */ 0, - /* doResume */ true, - /* options */ opts, - /* inTask */ null, - /* inTaskFragment */ null, - /* restrictedBgActivity */ false, - /* intentGrants */ null); + startActivityInner(starter, targetRecord, sourceRecord, opts, + null /* inTask */, null /* inTaskFragment */); // Verify the ActivityRecord#getLaunchIntoPipHostActivity points to sourceRecord. assertThat(targetRecord.getLaunchIntoPipHostActivity()).isNotNull(); assertEquals(targetRecord.getLaunchIntoPipHostActivity(), sourceRecord); } + + private static void startActivityInner(ActivityStarter starter, ActivityRecord target, + ActivityRecord source, ActivityOptions options, Task inTask, + TaskFragment inTaskFragment) { + starter.startActivityInner(target, source, null /* voiceSession */, + null /* voiceInteractor */, 0 /* startFlags */, true /* doResume */, + options, inTask, inTaskFragment, false /* restrictedBgActivity */, + null /* intentGrants */); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index 605726c0e804..118f159bee7b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -1201,6 +1201,20 @@ public class DisplayContentTests extends WindowTestsBase { dc.computeImeControlTarget()); } + @UseTestDisplay(addWindows = W_INPUT_METHOD) + @Test + public void testImeSecureFlagGetUpdatedAfterImeInputTarget() { + // Verify IME window can get up-to-date secure flag update when the IME input target + // set before setCanScreenshot called. + final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); + SurfaceControl.Transaction t = mDisplayContent.mInputMethodWindow.getPendingTransaction(); + spyOn(t); + mDisplayContent.setImeInputTarget(app); + mDisplayContent.mInputMethodWindow.setCanScreenshot(t, false /* canScreenshot */); + + verify(t).setSecure(eq(mDisplayContent.mInputMethodWindow.mSurfaceControl), eq(true)); + } + @UseTestDisplay(addWindows = W_ACTIVITY) @Test public void testComputeImeControlTarget_notMatchParentBounds() throws Exception { diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerHelperTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java index f9689990c5e8..a82826006f17 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerHelperTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static android.app.ActivityManager.START_ABORTED; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; @@ -26,6 +27,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.mock; import android.app.WindowConfiguration; import android.content.ComponentName; @@ -45,13 +47,13 @@ import java.util.List; import java.util.Set; /** - * Tests for the {@link DisplayWindowPolicyControllerHelper} class. + * Tests for the {@link DisplayWindowPolicyController} class. * * Build/Install/Run: - * atest WmTests:DisplayWindowPolicyControllerHelperTests + * atest WmTests:DisplayWindowPolicyControllerTests */ @RunWith(WindowTestRunner.class) -public class DisplayWindowPolicyControllerHelperTests extends WindowTestsBase { +public class DisplayWindowPolicyControllerTests extends WindowTestsBase { private static final int TEST_USER_0_ID = 0; private static final int TEST_USER_1_ID = 10; @@ -152,8 +154,51 @@ public class DisplayWindowPolicyControllerHelperTests extends WindowTestsBase { assertTrue(mSecondaryDisplay.mDwpcHelper.isWindowingModeSupported(WINDOWING_MODE_PINNED)); } + @Test + public void testInterestedWindowFlags() { + final int fakeFlag1 = 0x00000010; + final int fakeFlag2 = 0x00000100; + final int fakeSystemFlag1 = 0x00000010; + final int fakeSystemFlag2 = 0x00000100; + + mDwpc.setInterestedWindowFlags(fakeFlag1, fakeSystemFlag1); + + assertTrue(mDwpc.isInterestedWindowFlags(fakeFlag1, fakeSystemFlag1)); + assertTrue(mDwpc.isInterestedWindowFlags(fakeFlag1, fakeSystemFlag2)); + assertTrue(mDwpc.isInterestedWindowFlags(fakeFlag2, fakeSystemFlag1)); + assertFalse(mDwpc.isInterestedWindowFlags(fakeFlag2, fakeSystemFlag2)); + } + + @Test + public void testCanContainActivities() { + ActivityStarter starter = new ActivityStarter(mock(ActivityStartController.class), mAtm, + mSupervisor, mock(ActivityStartInterceptor.class)); + final Task task = new TaskBuilder(mSupervisor).setDisplay(mSecondaryDisplay).build(); + final ActivityRecord sourceRecord = new ActivityBuilder(mAtm).setTask(task).build(); + final ActivityRecord disallowedRecord = + new ActivityBuilder(mAtm).setComponent(mDwpc.DISALLOWED_ACTIVITY).build(); + + int result = starter.startActivityInner( + disallowedRecord, + sourceRecord, + /* voiceSession */null, + /* voiceInteractor */ null, + /* startFlags */ 0, + /* doResume */true, + /* options */null, + /* inTask */null, + /* inTaskFragment */ null, + /* restrictedBgActivity */false, + /* intentGrants */null); + + assertEquals(result, START_ABORTED); + } + private class TestDisplayWindowPolicyController extends DisplayWindowPolicyController { + public ComponentName DISALLOWED_ACTIVITY = + new ComponentName("fake.package", "DisallowedActivity"); + ComponentName mTopActivity = null; int mTopActivityUid = UserHandle.USER_NULL; ArraySet<Integer> mRunningUids = new ArraySet<>(); @@ -161,7 +206,14 @@ public class DisplayWindowPolicyControllerHelperTests extends WindowTestsBase { @Override public boolean canContainActivities(@NonNull List<ActivityInfo> activities, @WindowConfiguration.WindowingMode int windowingMode) { - return false; + final int activityCount = activities.size(); + for (int i = 0; i < activityCount; i++) { + final ActivityInfo aInfo = activities.get(i); + if (aInfo.getComponentName().equals(DISALLOWED_ACTIVITY)) { + return false; + } + } + return true; } @Override diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java index c86f38d4264d..8d4a0176e3be 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java @@ -119,13 +119,6 @@ final class HotwordDetectionConnection { private static final Duration MAX_UPDATE_TIMEOUT_DURATION = Duration.ofMillis(MAX_UPDATE_TIMEOUT_MILLIS); private static final long RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS = 60 * 60 * 1000; // 1 hour - /** - * Time after which each HotwordDetectionService process is stopped and replaced by a new one. - * 0 indicates no restarts. - */ - private static final int RESTART_PERIOD_SECONDS = - DeviceConfig.getInt(DeviceConfig.NAMESPACE_VOICE_INTERACTION, - KEY_RESTART_PERIOD_IN_SECONDS, 0); private static final int MAX_ISOLATED_PROCESS_NUMBER = 10; // Hotword metrics @@ -150,6 +143,11 @@ final class HotwordDetectionConnection { private final @NonNull ServiceConnectionFactory mServiceConnectionFactory; private final IHotwordRecognitionStatusCallback mCallback; private final int mDetectorType; + /** + * Time after which each HotwordDetectionService process is stopped and replaced by a new one. + * 0 indicates no restarts. + */ + private final int mReStartPeriodSeconds; final Object mLock; final int mVoiceInteractionServiceUid; @@ -195,6 +193,8 @@ final class HotwordDetectionConnection { mUser = userId; mCallback = callback; mDetectorType = detectorType; + mReStartPeriodSeconds = DeviceConfig.getInt(DeviceConfig.NAMESPACE_VOICE_INTERACTION, + KEY_RESTART_PERIOD_IN_SECONDS, 0); final Intent intent = new Intent(HotwordDetectionService.SERVICE_INTERFACE); intent.setComponent(mDetectionComponentName); initAudioFlingerLocked(); @@ -206,11 +206,11 @@ final class HotwordDetectionConnection { mLastRestartInstant = Instant.now(); updateStateAfterProcessStart(options, sharedMemory); - if (RESTART_PERIOD_SECONDS <= 0) { + if (mReStartPeriodSeconds <= 0) { mCancellationTaskFuture = null; } else { - // TODO(volnov): we need to be smarter here, e.g. schedule it a bit more often, but wait - // until the current session is closed. + // TODO: we need to be smarter here, e.g. schedule it a bit more often, + // but wait until the current session is closed. mCancellationTaskFuture = mScheduledExecutorService.scheduleAtFixedRate(() -> { Slog.v(TAG, "Time to restart the process, TTL has passed"); synchronized (mLock) { @@ -218,7 +218,7 @@ final class HotwordDetectionConnection { HotwordMetricsLogger.writeServiceRestartEvent(mDetectorType, HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__SCHEDULE); } - }, RESTART_PERIOD_SECONDS, RESTART_PERIOD_SECONDS, TimeUnit.SECONDS); + }, mReStartPeriodSeconds, mReStartPeriodSeconds, TimeUnit.SECONDS); } } @@ -785,7 +785,7 @@ final class HotwordDetectionConnection { } public void dump(String prefix, PrintWriter pw) { - pw.print(prefix); pw.print("RESTART_PERIOD_SECONDS="); pw.println(RESTART_PERIOD_SECONDS); + pw.print(prefix); pw.print("mReStartPeriodSeconds="); pw.println(mReStartPeriodSeconds); pw.print(prefix); pw.print("mBound=" + mRemoteHotwordDetectionService.isBound()); pw.print(", mValidatingDspTrigger=" + mValidatingDspTrigger); diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 8d7fab4d101f..a2266fb3a929 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1959,6 +1959,13 @@ public class CarrierConfigManager { "nr_advanced_threshold_bandwidth_khz_int"; /** + * Boolean indicating if operator name should be shown in the status bar + * @hide + */ + public static final String KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL = + "show_operator_name_in_statusbar_bool"; + + /** * The string is used to filter redundant string from PLMN Network Name that's supplied by * specific carrier. * @@ -8913,6 +8920,7 @@ public class CarrierConfigManager { sDefaults.putStringArray(KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY, null); sDefaults.putBoolean(KEY_WORLD_MODE_ENABLED_BOOL, false); sDefaults.putString(KEY_CARRIER_SETTINGS_ACTIVITY_COMPONENT_NAME_STRING, ""); + sDefaults.putBoolean(KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, false); sDefaults.putBoolean(KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL, false); sDefaults.putBoolean(KEY_SHOW_DATA_CONNECTED_ROAMING_NOTIFICATION_BOOL, false); diff --git a/telephony/java/android/telephony/UiccCardInfo.java b/telephony/java/android/telephony/UiccCardInfo.java index 3843a6240b43..249f740c482b 100644 --- a/telephony/java/android/telephony/UiccCardInfo.java +++ b/telephony/java/android/telephony/UiccCardInfo.java @@ -21,6 +21,9 @@ import android.content.pm.PackageManager; import android.os.Parcel; import android.os.Parcelable; +import com.android.internal.telephony.util.TelephonyUtils; +import com.android.telephony.Rlog; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -227,7 +230,6 @@ public final class UiccCardInfo implements Parcelable { this.mIccIdAccessRestricted = iccIdAccessRestricted; } - @Override public boolean equals(Object obj) { if (this == obj) { @@ -261,7 +263,7 @@ public final class UiccCardInfo implements Parcelable { + ", mCardId=" + mCardId + ", mEid=" - + mEid + + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mEid) + ", mPhysicalSlotIndex=" + mPhysicalSlotIndex + ", mIsRemovable=" diff --git a/telephony/java/android/telephony/UiccSlotInfo.java b/telephony/java/android/telephony/UiccSlotInfo.java index 17ce45063d41..dd3639a9a7b9 100644 --- a/telephony/java/android/telephony/UiccSlotInfo.java +++ b/telephony/java/android/telephony/UiccSlotInfo.java @@ -279,7 +279,7 @@ public class UiccSlotInfo implements Parcelable { + ", mIsEuicc=" + mIsEuicc + ", mCardId=" - + mCardId + + SubscriptionInfo.givePrintableIccid(mCardId) + ", cardState=" + mCardStateInfo + ", mIsExtendedApduSupported=" diff --git a/tests/FlickerTests/OWNERS b/tests/FlickerTests/OWNERS index c1221e3940d2..d40ff5659708 100644 --- a/tests/FlickerTests/OWNERS +++ b/tests/FlickerTests/OWNERS @@ -1,4 +1,4 @@ -# Bug component: 909476 +# Bug component: 1157642 include /services/core/java/com/android/server/wm/OWNERS natanieljr@google.com pablogamito@google.com diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt new file mode 100644 index 000000000000..172c4330c3c6 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wm.flicker.helpers + +import android.app.Instrumentation +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.Until +import com.android.server.wm.flicker.testapp.ActivityOptions +import com.android.server.wm.traces.common.FlickerComponentName +import com.android.server.wm.traces.parser.toFlickerComponent +import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper + +class ImeEditorPopupDialogAppHelper @JvmOverloads constructor( + instr: Instrumentation, + private val rotation: Int, + private val imePackageName: String = IME_PACKAGE, + launcherName: String = ActivityOptions.EDITOR_POPUP_DIALOG_ACTIVITY_LAUNCHER_NAME, + component: FlickerComponentName = + ActivityOptions.EDITOR_POPUP_DIALOG_ACTIVITY_COMPONENT_NAME.toFlickerComponent() +) : ImeAppHelper(instr, launcherName, component) { + override fun openIME( + device: UiDevice, + wmHelper: WindowManagerStateHelper? + ) { + val editText = device.wait(Until.findObject(By.text("focused editText")), FIND_TIMEOUT) + + require(editText != null) { + "Text field not found, this usually happens when the device " + + "was left in an unknown state (e.g. in split screen)" + } + editText.click() + waitIMEShown(device, wmHelper) + } + + fun dismissDialog(wmHelper: WindowManagerStateHelper) { + val dismissButton = uiDevice.wait( + Until.findObject(By.text("Dismiss")), FIND_TIMEOUT) + + // Pressing back key to dismiss the dialog + if (dismissButton != null) { + dismissButton.click() + wmHelper.waitForAppTransitionIdle() + } + } +}
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt new file mode 100644 index 000000000000..bff099e2e7a1 --- /dev/null +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wm.flicker.ime + +import android.app.Instrumentation +import android.platform.test.annotations.Postsubmit +import android.view.Surface +import android.view.WindowManagerPolicyConstants +import androidx.test.filters.RequiresDevice +import androidx.test.platform.app.InstrumentationRegistry +import com.android.server.wm.flicker.FlickerBuilderProvider +import com.android.server.wm.flicker.FlickerTestParameterFactory +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.annotation.Group4 +import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.helpers.ImeEditorPopupDialogAppHelper +import com.android.server.wm.flicker.navBarWindowIsVisible +import com.android.server.wm.flicker.statusBarWindowIsVisible +import com.android.server.wm.flicker.traces.region.RegionSubject +import com.android.server.wm.traces.common.FlickerComponentName +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Group4 +class CloseImeEditorPopupDialogTest(private val testSpec: FlickerTestParameter) { + private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() + private val imeTestApp = ImeEditorPopupDialogAppHelper(instrumentation, testSpec.startRotation) + + @FlickerBuilderProvider + fun buildFlicker(): FlickerBuilder { + return FlickerBuilder(instrumentation).apply { + setup { + eachRun { + imeTestApp.launchViaIntent(wmHelper) + imeTestApp.openIME(device, wmHelper) + } + } + transitions { + imeTestApp.dismissDialog(wmHelper) + instrumentation.uiAutomation.syncInputTransactions() + } + teardown { + eachRun { + device.pressHome() + wmHelper.waitForHomeActivityVisible() + imeTestApp.exit() + } + } + } + } + + @Postsubmit + @Test + fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible() + + @Postsubmit + @Test + fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible() + + @Postsubmit + @Test + fun imeWindowBecameInvisible() = testSpec.imeWindowBecomesInvisible() + + @Postsubmit + @Test + fun imeLayerAndImeSnapshotVisibleOnScreen() { + testSpec.assertLayers { + this.isVisible(FlickerComponentName.IME) + .then() + .isVisible(FlickerComponentName.IME_SNAPSHOT) + .then() + .isInvisible(FlickerComponentName.IME) + } + } + + @Postsubmit + @Test + fun imeSnapshotAssociatedOnAppVisibleRegion() { + testSpec.assertLayers { + this.invoke("imeSnapshotAssociatedOnAppVisibleRegion") { + val imeSnapshotLayers = it.subjects.filter { + subject -> subject.name.contains( + FlickerComponentName.IME_SNAPSHOT.toLayerName()) && subject.isVisible + } + if (imeSnapshotLayers.isNotEmpty()) { + val visibleAreas = imeSnapshotLayers.mapNotNull { imeSnapshotLayer -> + imeSnapshotLayer.layer?.visibleRegion }.toTypedArray() + val imeVisibleRegion = RegionSubject.assertThat(visibleAreas, this, timestamp) + val appVisibleRegion = it.visibleRegion(imeTestApp.component) + if (imeVisibleRegion.region.isNotEmpty) { + imeVisibleRegion.coversAtMost(appVisibleRegion.region) + } + } + } + } + } + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): Collection<FlickerTestParameter> { + return FlickerTestParameterFactory.getInstance() + .getConfigNonRotationTests( + repetitions = 2, + supportedNavigationModes = listOf( + WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY, + WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY + ), + supportedRotations = listOf(Surface.ROTATION_0) + ) + } + } +}
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt index 7f4966375b98..1b60403ac354 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt @@ -79,7 +79,7 @@ class LaunchAppShowImeAndDialogThemeAppTest(private val testSpec: FlickerTestPar /** * Checks that [FlickerComponentName.IME] layer is visible at the end of the transition */ - @Presubmit + @FlakyTest(bugId = 227142436) @Test fun imeLayerExistsEnd() { testSpec.assertLayersEnd { diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt index 9c9dedc23ff9..4b8a8c80cd45 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest_ShellTransit.kt @@ -17,6 +17,7 @@ package com.android.server.wm.flicker.quickswitch import android.platform.test.annotations.RequiresDevice +import androidx.test.filters.FlakyTest import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.annotation.Group1 @@ -44,6 +45,7 @@ import org.junit.runners.Parameterized @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @Group1 +@FlakyTest(bugId = 228009808) open class QuickSwitchBetweenTwoAppsForwardTest_ShellTransit(testSpec: FlickerTestParameter) : QuickSwitchBetweenTwoAppsForwardTest(testSpec) { @Before diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml index 739fe020d555..7f513b21957f 100644 --- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml +++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml @@ -119,5 +119,16 @@ <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> + <activity android:name=".ImeEditorPopupDialogActivity" + android:taskAffinity="com.android.server.wm.flicker.testapp.ImeEditorPopupDialogActivity" + android:configChanges="orientation|screenSize" + android:theme="@style/CutoutShortEdges" + android:label="ImeEditorPopupDialogActivity" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> </application> </manifest> diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java index 3040a09f2345..18c95cf7bbff 100644 --- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java +++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java @@ -56,6 +56,7 @@ public class ActivityOptions { public static final ComponentName LAUNCH_NEW_TASK_ACTIVITY_COMPONENT_NAME = new ComponentName(FLICKER_APP_PACKAGE, FLICKER_APP_PACKAGE + ".LaunchNewTaskActivity"); + public static final String DIALOG_THEMED_ACTIVITY = "DialogThemedActivity"; public static final ComponentName DIALOG_THEMED_ACTIVITY_COMPONENT_NAME = new ComponentName(FLICKER_APP_PACKAGE, @@ -65,4 +66,10 @@ public class ActivityOptions { public static final ComponentName PORTRAIT_ONLY_ACTIVITY_COMPONENT_NAME = new ComponentName(FLICKER_APP_PACKAGE, FLICKER_APP_PACKAGE + ".PortraitOnlyActivity"); + + public static final String EDITOR_POPUP_DIALOG_ACTIVITY_LAUNCHER_NAME = + "ImeEditorPopupDialogActivity"; + public static final ComponentName EDITOR_POPUP_DIALOG_ACTIVITY_COMPONENT_NAME = + new ComponentName(FLICKER_APP_PACKAGE, + FLICKER_APP_PACKAGE + ".ImeEditorPopupDialogActivity"); } diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeEditorPopupDialogActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeEditorPopupDialogActivity.java new file mode 100644 index 000000000000..a8613f531e1c --- /dev/null +++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeEditorPopupDialogActivity.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wm.flicker.testapp; + +import android.app.Activity; +import android.app.AlertDialog; +import android.os.Bundle; +import android.view.WindowManager; +import android.widget.EditText; +import android.widget.LinearLayout; + +public class ImeEditorPopupDialogActivity extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + WindowManager.LayoutParams p = getWindow().getAttributes(); + p.layoutInDisplayCutoutMode = WindowManager.LayoutParams + .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; + getWindow().setAttributes(p); + LinearLayout layout = new LinearLayout(this); + layout.setOrientation(LinearLayout.VERTICAL); + setContentView(R.layout.activity_simple); + + final EditText editText = new EditText(this); + editText.setHint("focused editText"); + final AlertDialog dialog = new AlertDialog.Builder(this) + .setView(editText) + .setPositiveButton("Dismiss", (d, which) -> d.dismiss()) + .create(); + dialog.show(); + } +} diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp index bd0a4bc44e18..bfb32854a374 100644 --- a/tools/aapt2/Android.bp +++ b/tools/aapt2/Android.bp @@ -165,6 +165,7 @@ cc_library_host_static { ], proto: { export_proto_headers: true, + type: "full", }, defaults: ["aapt2_defaults"], } |