Merge "Use BatteryStats instead of BatteryStatsImpl in BatteryUsageStatsProvider" into sc-dev
diff --git a/Android.bp b/Android.bp
index ca014bc..da52c23 100644
--- a/Android.bp
+++ b/Android.bp
@@ -408,6 +408,7 @@
"core/java/android/annotation/MainThread.java",
"core/java/android/annotation/NonNull.java",
"core/java/android/annotation/Nullable.java",
+ "core/java/android/annotation/RequiresNoPermission.java",
"core/java/android/annotation/RequiresPermission.java",
"core/java/android/annotation/SdkConstant.java",
"core/java/android/annotation/StringDef.java",
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 175fb38..65b2511 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -22,7 +22,7 @@
strings_lint_hook = ${REPO_ROOT}/frameworks/base/tools/stringslint/stringslint_sha.sh ${PREUPLOAD_COMMIT}
-hidden_api_txt_checksorted_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
+hidden_api_txt_checksorted_hook = ${REPO_ROOT}/tools/platform-compat/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
hidden_api_txt_exclude_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/exclude.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 23dc720..bc3f131 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -96,6 +96,8 @@
],
api_levels_annotations_enabled: false,
filter_packages: packages_to_document,
+ defaults_visibility: ["//visibility:private"],
+ visibility: ["//frameworks/base/api"],
}
/////////////////////////////////////////////////////////////////////
@@ -352,6 +354,8 @@
tag: ".jar",
dest: "android-non-updatable.jar",
},
+ defaults_visibility: ["//visibility:private"],
+ visibility: ["//visibility:private"],
}
java_library_static {
@@ -405,6 +409,8 @@
system_modules: "none",
java_version: "1.8",
compile_dex: true,
+ defaults_visibility: ["//visibility:private"],
+ visibility: ["//visibility:public"],
}
java_defaults {
@@ -417,6 +423,7 @@
tag: ".jar",
dest: "android.jar",
},
+ defaults_visibility: ["//frameworks/base/services"],
}
java_library_static {
@@ -516,6 +523,7 @@
"metalava-manual",
],
args: priv_apps,
+ visibility: ["//visibility:private"],
}
java_library_static {
@@ -525,4 +533,5 @@
srcs: [
":hwbinder-stubs-docs",
],
+ visibility: ["//visibility:public"],
}
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java
index 5473690..d272507 100644
--- a/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java
+++ b/apct-tests/perftests/core/src/android/graphics/perftests/TypefaceSerializationPerfTest.java
@@ -20,6 +20,7 @@
import android.os.SharedMemory;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
+import android.util.ArrayMap;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
@@ -55,9 +56,10 @@
ByteBuffer buffer = memory.mapReadOnly().order(ByteOrder.BIG_ENDIAN);
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ ArrayMap<String, Typeface> out = new ArrayMap<>();
while (state.keepRunning()) {
buffer.position(0);
- Typeface.deserializeFontMap(buffer);
+ Typeface.deserializeFontMap(buffer, out);
}
}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java
index 35cea3e..6c62426 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java
@@ -26,6 +26,7 @@
import java.util.Collections;
import java.util.Map;
+import java.util.Objects;
/**
* Provides results for AppSearch batch operations which encompass multiple documents.
@@ -180,7 +181,7 @@
public Builder<KeyType, ValueType> setSuccess(
@NonNull KeyType key, @Nullable ValueType result) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- Preconditions.checkNotNull(key);
+ Objects.requireNonNull(key);
return setResult(key, AppSearchResult.newSuccessfulResult(result));
}
@@ -198,7 +199,7 @@
@AppSearchResult.ResultCode int resultCode,
@Nullable String errorMessage) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- Preconditions.checkNotNull(key);
+ Objects.requireNonNull(key);
return setResult(key, AppSearchResult.newFailedResult(resultCode, errorMessage));
}
@@ -214,8 +215,8 @@
public Builder<KeyType, ValueType> setResult(
@NonNull KeyType key, @NonNull AppSearchResult<ValueType> result) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
- Preconditions.checkNotNull(key);
- Preconditions.checkNotNull(result);
+ Objects.requireNonNull(key);
+ Objects.requireNonNull(result);
if (result.isSuccess()) {
mSuccesses.put(key, result.getResultValue());
mFailures.remove(key);
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
index 9776827..8af91b4 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
@@ -29,14 +29,16 @@
/**
* Provides access to the centralized AppSearch index maintained by the system.
*
- * <p>AppSearch is a search library for managing structured data featuring:
+ * <p>AppSearch is an offline, on-device search library for managing structured data featuring:
*
* <ul>
- * <li>A fully offline on-device solution
- * <li>A set of APIs for applications to index documents and retrieve them via full-text search
- * <li>APIs for applications to allow the System to display their content on system UI surfaces
- * <li>Similarly, APIs for applications to allow the System to share their content with other
- * specified applications.
+ * <li>APIs to index and retrieve data via full-text search.
+ * <li>An API for applications to explicitly grant read-access permission of their data to other
+ * applications.
+ * <b>See: {@link SetSchemaRequest.Builder#setSchemaTypeVisibilityForPackage}</b>
+ * <li>An API for applications to opt into or out of having their data displayed on System UI
+ * surfaces by the System-designated global querier.
+ * <b>See: {@link SetSchemaRequest.Builder#setSchemaTypeDisplayedBySystem}</b>
* </ul>
*
* <p>Applications create a database by opening an {@link AppSearchSession}.
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
index 4ae16aa..f6f5c98 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -54,7 +54,6 @@
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.appsearch.external.localstorage.AppSearchImpl;
@@ -75,7 +74,7 @@
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
-import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -94,7 +93,7 @@
// mutate requests will need to gain write lock and query requests need to gain read lock.
private static final Executor EXECUTOR = new ThreadPoolExecutor(/*corePoolSize=*/1,
Runtime.getRuntime().availableProcessors(), /*keepAliveTime*/ 60L, TimeUnit.SECONDS,
- new SynchronousQueue<Runnable>());
+ new LinkedBlockingQueue<>());
// Cache of unlocked user ids so we don't have to query UserManager service each time. The
// "locked" suffix refers to the fact that access to the field should be locked; unrelated to
@@ -181,10 +180,10 @@
int schemaVersion,
@UserIdInt int userId,
@NonNull IAppSearchResultCallback callback) {
- Preconditions.checkNotNull(packageName);
- Preconditions.checkNotNull(databaseName);
- Preconditions.checkNotNull(schemaBundles);
- Preconditions.checkNotNull(callback);
+ Objects.requireNonNull(packageName);
+ Objects.requireNonNull(databaseName);
+ Objects.requireNonNull(schemaBundles);
+ Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
EXECUTOR.execute(() -> {
@@ -230,9 +229,9 @@
@NonNull String databaseName,
@UserIdInt int userId,
@NonNull IAppSearchResultCallback callback) {
- Preconditions.checkNotNull(packageName);
- Preconditions.checkNotNull(databaseName);
- Preconditions.checkNotNull(callback);
+ Objects.requireNonNull(packageName);
+ Objects.requireNonNull(databaseName);
+ Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
EXECUTOR.execute(() -> {
@@ -257,9 +256,9 @@
@NonNull String databaseName,
@UserIdInt int userId,
@NonNull IAppSearchResultCallback callback) {
- Preconditions.checkNotNull(packageName);
- Preconditions.checkNotNull(databaseName);
- Preconditions.checkNotNull(callback);
+ Objects.requireNonNull(packageName);
+ Objects.requireNonNull(databaseName);
+ Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
EXECUTOR.execute(() -> {
@@ -285,10 +284,10 @@
@UserIdInt int userId,
@ElapsedRealtimeLong long binderCallStartTimeMillis,
@NonNull IAppSearchBatchResultCallback callback) {
- Preconditions.checkNotNull(packageName);
- Preconditions.checkNotNull(databaseName);
- Preconditions.checkNotNull(documentBundles);
- Preconditions.checkNotNull(callback);
+ Objects.requireNonNull(packageName);
+ Objects.requireNonNull(databaseName);
+ Objects.requireNonNull(documentBundles);
+ Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
EXECUTOR.execute(() -> {
@@ -359,11 +358,11 @@
@NonNull Map<String, List<String>> typePropertyPaths,
@UserIdInt int userId,
@NonNull IAppSearchBatchResultCallback callback) {
- Preconditions.checkNotNull(packageName);
- Preconditions.checkNotNull(databaseName);
- Preconditions.checkNotNull(namespace);
- Preconditions.checkNotNull(uris);
- Preconditions.checkNotNull(callback);
+ Objects.requireNonNull(packageName);
+ Objects.requireNonNull(databaseName);
+ Objects.requireNonNull(namespace);
+ Objects.requireNonNull(uris);
+ Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
EXECUTOR.execute(() -> {
@@ -404,11 +403,11 @@
@NonNull Bundle searchSpecBundle,
@UserIdInt int userId,
@NonNull IAppSearchResultCallback callback) {
- Preconditions.checkNotNull(packageName);
- Preconditions.checkNotNull(databaseName);
- Preconditions.checkNotNull(queryExpression);
- Preconditions.checkNotNull(searchSpecBundle);
- Preconditions.checkNotNull(callback);
+ Objects.requireNonNull(packageName);
+ Objects.requireNonNull(databaseName);
+ Objects.requireNonNull(queryExpression);
+ Objects.requireNonNull(searchSpecBundle);
+ Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
EXECUTOR.execute(() -> {
@@ -439,10 +438,10 @@
@NonNull Bundle searchSpecBundle,
@UserIdInt int userId,
@NonNull IAppSearchResultCallback callback) {
- Preconditions.checkNotNull(packageName);
- Preconditions.checkNotNull(queryExpression);
- Preconditions.checkNotNull(searchSpecBundle);
- Preconditions.checkNotNull(callback);
+ Objects.requireNonNull(packageName);
+ Objects.requireNonNull(queryExpression);
+ Objects.requireNonNull(searchSpecBundle);
+ Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
EXECUTOR.execute(() -> {
@@ -471,7 +470,7 @@
long nextPageToken,
@UserIdInt int userId,
@NonNull IAppSearchResultCallback callback) {
- Preconditions.checkNotNull(callback);
+ Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
// TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
@@ -644,10 +643,10 @@
@NonNull List<String> uris,
@UserIdInt int userId,
@NonNull IAppSearchBatchResultCallback callback) {
- Preconditions.checkNotNull(packageName);
- Preconditions.checkNotNull(databaseName);
- Preconditions.checkNotNull(uris);
- Preconditions.checkNotNull(callback);
+ Objects.requireNonNull(packageName);
+ Objects.requireNonNull(databaseName);
+ Objects.requireNonNull(uris);
+ Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
EXECUTOR.execute(() -> {
@@ -684,11 +683,11 @@
@NonNull Bundle searchSpecBundle,
@UserIdInt int userId,
@NonNull IAppSearchResultCallback callback) {
- Preconditions.checkNotNull(packageName);
- Preconditions.checkNotNull(databaseName);
- Preconditions.checkNotNull(queryExpression);
- Preconditions.checkNotNull(searchSpecBundle);
- Preconditions.checkNotNull(callback);
+ Objects.requireNonNull(packageName);
+ Objects.requireNonNull(databaseName);
+ Objects.requireNonNull(queryExpression);
+ Objects.requireNonNull(searchSpecBundle);
+ Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
EXECUTOR.execute(() -> {
@@ -717,9 +716,9 @@
@NonNull String databaseName,
@UserIdInt int userId,
@NonNull IAppSearchResultCallback callback) {
- Preconditions.checkNotNull(packageName);
- Preconditions.checkNotNull(databaseName);
- Preconditions.checkNotNull(callback);
+ Objects.requireNonNull(packageName);
+ Objects.requireNonNull(databaseName);
+ Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
EXECUTOR.execute(() -> {
@@ -757,7 +756,7 @@
@Override
public void initialize(@UserIdInt int userId, @NonNull IAppSearchResultCallback callback) {
- Preconditions.checkNotNull(callback);
+ Objects.requireNonNull(callback);
int callingUid = Binder.getCallingUid();
int callingUserId = handleIncomingUser(userId, callingUid);
EXECUTOR.execute(() -> {
@@ -788,7 +787,7 @@
}
private void verifyCallingPackage(int callingUid, @NonNull String callingPackage) {
- Preconditions.checkNotNull(callingPackage);
+ Objects.requireNonNull(callingPackage);
if (mPackageManagerInternal.getPackageUid(
callingPackage, /*flags=*/ 0, UserHandle.getUserId(callingUid))
!= callingUid) {
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java b/apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java
index c1b8294..4de52fb 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/VisibilityStore.java
@@ -35,7 +35,6 @@
import android.util.ArraySet;
import android.util.Log;
-import com.android.internal.util.Preconditions;
import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
import java.util.ArrayList;
@@ -43,6 +42,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
/**
@@ -333,9 +333,9 @@
@NonNull Set<String> schemasNotPlatformSurfaceable,
@NonNull Map<String, List<PackageIdentifier>> schemasPackageAccessible)
throws AppSearchException {
- Preconditions.checkNotNull(prefix);
- Preconditions.checkNotNull(schemasNotPlatformSurfaceable);
- Preconditions.checkNotNull(schemasPackageAccessible);
+ Objects.requireNonNull(prefix);
+ Objects.requireNonNull(schemasNotPlatformSurfaceable);
+ Objects.requireNonNull(schemasPackageAccessible);
// Persist the document
GenericDocument.Builder<?> visibilityDocument =
@@ -383,8 +383,8 @@
/** Checks whether {@code prefixedSchema} can be searched over by the {@code callerUid}. */
public boolean isSchemaSearchableByCaller(
@NonNull String prefix, @NonNull String prefixedSchema, int callerUid) {
- Preconditions.checkNotNull(prefix);
- Preconditions.checkNotNull(prefixedSchema);
+ Objects.requireNonNull(prefix);
+ Objects.requireNonNull(prefixedSchema);
// We compare appIds here rather than direct uids because the package's uid may change based
// on the user that's running.
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java b/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
index 1c04d99..731ab35 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java
@@ -29,7 +29,6 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FrameworkStatsLog;
-import com.android.internal.util.Preconditions;
import com.android.server.appsearch.external.localstorage.AppSearchLogger;
import com.android.server.appsearch.external.localstorage.stats.CallStats;
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
@@ -38,6 +37,7 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
+import java.util.Objects;
import java.util.Random;
/**
@@ -162,15 +162,15 @@
* Westworld constructor
*/
public PlatformLogger(@NonNull Context context, int userId, @NonNull Config config) {
- mContext = Preconditions.checkNotNull(context);
- mConfig = Preconditions.checkNotNull(config);
+ mContext = Objects.requireNonNull(context);
+ mConfig = Objects.requireNonNull(config);
mUserId = userId;
}
/** Logs {@link CallStats}. */
@Override
public void logStats(@NonNull CallStats stats) {
- Preconditions.checkNotNull(stats);
+ Objects.requireNonNull(stats);
synchronized (mLock) {
if (shouldLogForTypeLocked(stats.getCallType())) {
logStatsImplLocked(stats);
@@ -181,7 +181,7 @@
/** Logs {@link PutDocumentStats}. */
@Override
public void logStats(@NonNull PutDocumentStats stats) {
- Preconditions.checkNotNull(stats);
+ Objects.requireNonNull(stats);
synchronized (mLock) {
if (shouldLogForTypeLocked(CallStats.CALL_TYPE_PUT_DOCUMENT)) {
logStatsImplLocked(stats);
@@ -197,7 +197,7 @@
*/
public int removeCachedUidForPackage(@NonNull String packageName) {
// TODO(b/173532925) This needs to be called when we get PACKAGE_REMOVED intent
- Preconditions.checkNotNull(packageName);
+ Objects.requireNonNull(packageName);
synchronized (mLock) {
Integer uid = mPackageUidCacheLocked.remove(packageName);
return uid != null ? uid : Process.INVALID_UID;
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java
index f0de496..6193367 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java
@@ -40,11 +40,11 @@
import androidx.test.core.app.ApplicationProvider;
-import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -81,8 +81,8 @@
private AppSearchSessionShimImpl(
@NonNull AppSearchSession session, @NonNull ExecutorService executor) {
- mAppSearchSession = Preconditions.checkNotNull(session);
- mExecutor = Preconditions.checkNotNull(executor);
+ mAppSearchSession = Objects.requireNonNull(session);
+ mExecutor = Objects.requireNonNull(executor);
}
@Override
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/GlobalSearchSessionShimImpl.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/GlobalSearchSessionShimImpl.java
index 5042ce0..c35849d 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/GlobalSearchSessionShimImpl.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/GlobalSearchSessionShimImpl.java
@@ -30,11 +30,11 @@
import androidx.test.core.app.ApplicationProvider;
-import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
+import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -69,8 +69,8 @@
private GlobalSearchSessionShimImpl(
@NonNull GlobalSearchSession session, @NonNull ExecutorService executor) {
- mGlobalSearchSession = Preconditions.checkNotNull(session);
- mExecutor = Preconditions.checkNotNull(executor);
+ mGlobalSearchSession = Objects.requireNonNull(session);
+ mExecutor = Objects.requireNonNull(executor);
}
@NonNull
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/SearchResultsShimImpl.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/SearchResultsShimImpl.java
index 5f26e8c..72078f8 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/SearchResultsShimImpl.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/SearchResultsShimImpl.java
@@ -22,12 +22,12 @@
import android.app.appsearch.SearchResults;
import android.app.appsearch.SearchResultsShim;
-import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -40,8 +40,8 @@
private final SearchResults mSearchResults;
SearchResultsShimImpl(@NonNull SearchResults searchResults, @NonNull Executor executor) {
- mExecutor = Preconditions.checkNotNull(executor);
- mSearchResults = Preconditions.checkNotNull(searchResults);
+ mExecutor = Objects.requireNonNull(executor);
+ mSearchResults = Objects.requireNonNull(searchResults);
}
@NonNull
diff --git a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
index 44e87c3..93b6566 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
@@ -283,9 +283,10 @@
*/
public static final int REASON_PACKAGE_REPLACED = 311;
/**
- * LocationProviderManager.
+ * LocationProvider.
* @hide
*/
+ @SystemApi
public static final int REASON_LOCATION_PROVIDER = 312;
/**
* MediaButtonReceiver.
diff --git a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
index 29a5dee..4ce31e9 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
@@ -284,9 +284,10 @@
*/
public static final int REASON_PACKAGE_REPLACED = PowerExemptionManager.REASON_PACKAGE_REPLACED;
/**
- * LocationProviderManager.
+ * LocationProvider.
* @hide
*/
+ @SystemApi
public static final int REASON_LOCATION_PROVIDER =
PowerExemptionManager.REASON_LOCATION_PROVIDER;
/**
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 31da201..03d9a96 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -1684,17 +1684,13 @@
}
}
- if ((flags & AlarmManager.FLAG_IDLE_UNTIL) != 0) {
- // Do not support windows for idle-until alarms.
- windowLength = AlarmManager.WINDOW_EXACT;
- }
-
// Snap the window to reasonable limits.
if (windowLength > INTERVAL_DAY) {
Slog.w(TAG, "Window length " + windowLength
+ "ms suspiciously long; limiting to 1 day");
windowLength = INTERVAL_DAY;
- } else if (windowLength > 0 && windowLength < mConstants.MIN_WINDOW) {
+ } else if (windowLength > 0 && windowLength < mConstants.MIN_WINDOW
+ && (flags & FLAG_PRIORITIZE) == 0) {
if (CompatChanges.isChangeEnabled(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS,
callingPackage, UserHandle.getUserHandleForUid(callingUid))) {
Slog.w(TAG, "Window length " + windowLength + "ms too short; expanding to "
@@ -1741,7 +1737,7 @@
final long triggerElapsed = (nominalTrigger > minTrigger) ? nominalTrigger : minTrigger;
final long maxElapsed;
- if (windowLength == AlarmManager.WINDOW_EXACT) {
+ if (windowLength == 0) {
maxElapsed = triggerElapsed;
} else if (windowLength < 0) {
maxElapsed = maxTriggerTime(nowElapsed, triggerElapsed, interval);
@@ -2145,17 +2141,63 @@
+ " does not belong to the calling uid " + callingUid);
}
- final boolean allowWhileIdle = (flags & FLAG_ALLOW_WHILE_IDLE) != 0;
- final boolean exact = (windowLength == AlarmManager.WINDOW_EXACT);
+ // Repeating alarms must use PendingIntent, not direct listener
+ if (interval != 0 && directReceiver != null) {
+ throw new IllegalArgumentException("Repeating alarms cannot use AlarmReceivers");
+ }
- // make sure the caller is allowed to use the requested kind of alarm, and also
+ if (workSource != null) {
+ getContext().enforcePermission(
+ android.Manifest.permission.UPDATE_DEVICE_STATS,
+ Binder.getCallingPid(), callingUid, "AlarmManager.set");
+ }
+
+ if ((flags & AlarmManager.FLAG_IDLE_UNTIL) != 0) {
+ // Only the system can use FLAG_IDLE_UNTIL -- this is used to tell the alarm
+ // manager when to come out of idle mode, which is only for DeviceIdleController.
+ if (callingUid != Process.SYSTEM_UID) {
+ // TODO (b/169463012): Throw instead of tolerating this mistake.
+ flags &= ~AlarmManager.FLAG_IDLE_UNTIL;
+ } else {
+ // Do not support windows for idle-until alarms.
+ windowLength = 0;
+ }
+ }
+
+ // Remove flags reserved for the service, we will apply those later as appropriate.
+ flags &= ~(FLAG_WAKE_FROM_IDLE | FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED
+ | FLAG_ALLOW_WHILE_IDLE_COMPAT);
+
+ // If this alarm is for an alarm clock, then it must be exact and we will
+ // use it to wake early from idle if needed.
+ if (alarmClock != null) {
+ flags |= FLAG_WAKE_FROM_IDLE;
+ windowLength = 0;
+
+ // If the caller is a core system component or on the user's allowlist, and not calling
+ // to do work on behalf of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED.
+ // This means we will allow these alarms to go off as normal even while idle, with no
+ // timing restrictions.
+ } else if (workSource == null && (UserHandle.isCore(callingUid)
+ || UserHandle.isSameApp(callingUid, mSystemUiUid)
+ || ((mAppStateTracker != null)
+ && mAppStateTracker.isUidPowerSaveUserExempt(callingUid)))) {
+ flags |= FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
+ flags &= ~(FLAG_ALLOW_WHILE_IDLE | FLAG_PRIORITIZE);
+ }
+
+ final boolean allowWhileIdle = (flags & FLAG_ALLOW_WHILE_IDLE) != 0;
+ final boolean exact = (windowLength == 0);
+
+ // Make sure the caller is allowed to use the requested kind of alarm, and also
// decide what quota and broadcast options to use.
Bundle idleOptions = null;
if ((flags & FLAG_PRIORITIZE) != 0) {
getContext().enforcePermission(
Manifest.permission.SCHEDULE_PRIORITIZED_ALARM,
Binder.getCallingPid(), callingUid, "AlarmManager.setPrioritized");
- flags &= ~(FLAG_ALLOW_WHILE_IDLE | FLAG_ALLOW_WHILE_IDLE_COMPAT);
+ // The API doesn't allow using both together.
+ flags &= ~FLAG_ALLOW_WHILE_IDLE;
} else if (exact || allowWhileIdle) {
final boolean needsPermission;
boolean lowerQuota;
@@ -2193,55 +2235,11 @@
}
}
- // Repeating alarms must use PendingIntent, not direct listener
- if (interval != 0) {
- if (directReceiver != null) {
- throw new IllegalArgumentException(
- "Repeating alarms cannot use AlarmReceivers");
- }
- }
-
- if (workSource != null) {
- getContext().enforcePermission(
- android.Manifest.permission.UPDATE_DEVICE_STATS,
- Binder.getCallingPid(), callingUid, "AlarmManager.set");
- }
-
- // No incoming callers can request either WAKE_FROM_IDLE or
- // ALLOW_WHILE_IDLE_UNRESTRICTED -- we will apply those later as appropriate.
- flags &= ~(FLAG_WAKE_FROM_IDLE | FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED);
-
- // Only the system can use FLAG_IDLE_UNTIL -- this is used to tell the alarm
- // manager when to come out of idle mode, which is only for DeviceIdleController.
- if (callingUid != Process.SYSTEM_UID) {
- flags &= ~AlarmManager.FLAG_IDLE_UNTIL;
- }
-
// If this is an exact time alarm, then it can't be batched with other alarms.
- if (windowLength == AlarmManager.WINDOW_EXACT) {
+ if (exact) {
flags |= AlarmManager.FLAG_STANDALONE;
}
- // If this alarm is for an alarm clock, then it must be standalone and we will
- // use it to wake early from idle if needed.
- if (alarmClock != null) {
- flags |= FLAG_WAKE_FROM_IDLE | AlarmManager.FLAG_STANDALONE;
-
- // If the caller is a core system component or on the user's whitelist, and not calling
- // to do work on behalf of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED.
- // This means we will allow these alarms to go off as normal even while idle, with no
- // timing restrictions.
- } else if (workSource == null && (UserHandle.isCore(callingUid)
- || UserHandle.isSameApp(callingUid, mSystemUiUid)
- || ((mAppStateTracker != null)
- && mAppStateTracker.isUidPowerSaveUserExempt(callingUid)))) {
- flags |= FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
- flags &= ~FLAG_ALLOW_WHILE_IDLE;
- flags &= ~FLAG_ALLOW_WHILE_IDLE_COMPAT;
- flags &= ~FLAG_PRIORITIZE;
- idleOptions = null;
- }
-
setImpl(type, triggerAtTime, windowLength, interval, operation, directReceiver,
listenerTag, flags, workSource, alarmClock, callingUid, callingPackage,
idleOptions);
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/LazyAlarmStore.java b/apex/jobscheduler/service/java/com/android/server/alarm/LazyAlarmStore.java
index c37d2c3..9b1b066 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/LazyAlarmStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/LazyAlarmStore.java
@@ -16,7 +16,6 @@
package com.android.server.alarm;
-import static com.android.server.alarm.AlarmManagerService.TAG;
import static com.android.server.alarm.AlarmManagerService.dumpAlarmList;
import static com.android.server.alarm.AlarmManagerService.isTimeTickAlarm;
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
index 131783f..366e174 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -798,7 +798,8 @@
private void startJobLocked(@NonNull JobServiceContext worker, @NonNull JobStatus jobStatus,
@WorkType final int workType) {
final List<StateController> controllers = mService.mControllers;
- for (int ic = 0; ic < controllers.size(); ic++) {
+ final int numControllers = controllers.size();
+ for (int ic = 0; ic < numControllers; ic++) {
controllers.get(ic).prepareForExecutionLocked(jobStatus);
}
final PackageStats packageStats =
@@ -807,6 +808,9 @@
if (!worker.executeRunnableJob(jobStatus, workType)) {
Slog.e(TAG, "Error executing " + jobStatus);
mWorkCountTracker.onStagedJobFailed(workType);
+ for (int ic = 0; ic < numControllers; ic++) {
+ controllers.get(ic).unprepareFromExecutionLocked(jobStatus);
+ }
} else {
mRunningJobs.add(jobStatus);
mWorkCountTracker.onJobStarted(workType);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 667f5ab..1815661 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -2234,7 +2234,8 @@
}
/** Returns true if both the calling and source users for the job are started. */
- private boolean areUsersStartedLocked(final JobStatus job) {
+ @GuardedBy("mLock")
+ public boolean areUsersStartedLocked(final JobStatus job) {
boolean sourceStarted = ArrayUtils.contains(mStartedUsers, job.getSourceUserId());
if (job.getUserId() == job.getSourceUserId()) {
return sourceStarted;
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ComponentController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ComponentController.java
index 999c53f..12d9c7f 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ComponentController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ComponentController.java
@@ -34,6 +34,7 @@
import android.util.SparseArrayMap;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.annotations.GuardedBy;
import com.android.server.job.JobSchedulerService;
import java.util.Objects;
@@ -58,13 +59,28 @@
return;
}
switch (action) {
+ case Intent.ACTION_PACKAGE_ADDED:
+ if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+ // Only do this for app updates since new installs won't have any jobs
+ // scheduled.
+ final Uri uri = intent.getData();
+ final String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
+ if (pkg != null) {
+ final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+ final int userId = UserHandle.getUserId(pkgUid);
+ updateComponentStateForPackage(userId, pkg);
+ }
+ }
+ break;
case Intent.ACTION_PACKAGE_CHANGED:
final Uri uri = intent.getData();
final String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
final String[] changedComponents = intent.getStringArrayExtra(
Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
if (pkg != null && changedComponents != null && changedComponents.length > 0) {
- updateComponentStateForPackage(pkg);
+ final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+ final int userId = UserHandle.getUserId(pkgUid);
+ updateComponentStateForPackage(userId, pkg);
}
break;
case Intent.ACTION_USER_UNLOCKED:
@@ -86,6 +102,7 @@
super(service);
final IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addDataScheme("package");
mContext.registerReceiverAsUser(
@@ -99,6 +116,7 @@
}
@Override
+ @GuardedBy("mLock")
public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
updateComponentEnabledStateLocked(jobStatus);
}
@@ -108,30 +126,53 @@
boolean forUpdate) {
}
+ @Override
+ @GuardedBy("mLock")
+ public void onAppRemovedLocked(String packageName, int uid) {
+ clearComponentsForPackageLocked(UserHandle.getUserId(uid), packageName);
+ }
+
+ @Override
+ @GuardedBy("mLock")
+ public void onUserRemovedLocked(int userId) {
+ mServiceInfoCache.delete(userId);
+ }
+
@Nullable
- private ServiceInfo getServiceInfo(JobStatus jobStatus) {
+ @GuardedBy("mLock")
+ private ServiceInfo getServiceInfoLocked(JobStatus jobStatus) {
final ComponentName service = jobStatus.getServiceComponent();
final int userId = jobStatus.getUserId();
- ServiceInfo si = mServiceInfoCache.get(userId, service);
- if (si == null) {
- try {
- // createContextAsUser may potentially be expensive
- // TODO: cache user context or improve ContextImpl implementation if this becomes
- // a problem
- si = mContext.createContextAsUser(UserHandle.of(userId), 0)
- .getPackageManager()
- .getServiceInfo(service, PackageManager.MATCH_DIRECT_BOOT_AUTO);
- } catch (NameNotFoundException e) {
- Slog.e(TAG, "Job exists for non-existent package: " + service.getPackageName());
- return null;
- }
- mServiceInfoCache.add(userId, service, si);
+ if (mServiceInfoCache.contains(userId, service)) {
+ // Return whatever is in the cache, even if it's null. When something changes, we
+ // clear the cache.
+ return mServiceInfoCache.get(userId, service);
}
+
+ ServiceInfo si;
+ try {
+ // createContextAsUser may potentially be expensive
+ // TODO: cache user context or improve ContextImpl implementation if this becomes
+ // a problem
+ si = mContext.createContextAsUser(UserHandle.of(userId), 0)
+ .getPackageManager()
+ .getServiceInfo(service, PackageManager.MATCH_DIRECT_BOOT_AUTO);
+ } catch (NameNotFoundException e) {
+ if (mService.areUsersStartedLocked(jobStatus)) {
+ // User is fully unlocked but PM still says the package doesn't exist.
+ Slog.e(TAG, "Job exists for non-existent package: " + service.getPackageName());
+ }
+ // Write null to the cache so we don't keep querying PM.
+ si = null;
+ }
+ mServiceInfoCache.add(userId, service, si);
+
return si;
}
+ @GuardedBy("mLock")
private boolean updateComponentEnabledStateLocked(JobStatus jobStatus) {
- final ServiceInfo service = getServiceInfo(jobStatus);
+ final ServiceInfo service = getServiceInfoLocked(jobStatus);
if (DEBUG && service == null) {
Slog.v(TAG, jobStatus.toShortString() + " component not present");
@@ -141,20 +182,26 @@
return !Objects.equals(ogService, service);
}
- private void updateComponentStateForPackage(final String pkg) {
- synchronized (mLock) {
- for (int u = mServiceInfoCache.numMaps() - 1; u >= 0; --u) {
- final int userId = mServiceInfoCache.keyAt(u);
-
- for (int c = mServiceInfoCache.numElementsForKey(userId) - 1; c >= 0; --c) {
- final ComponentName cn = mServiceInfoCache.keyAt(u, c);
- if (cn.getPackageName().equals(pkg)) {
- mServiceInfoCache.delete(userId, cn);
- }
- }
+ @GuardedBy("mLock")
+ private void clearComponentsForPackageLocked(final int userId, final String pkg) {
+ final int uIdx = mServiceInfoCache.indexOfKey(userId);
+ for (int c = mServiceInfoCache.numElementsForKey(userId) - 1; c >= 0; --c) {
+ final ComponentName cn = mServiceInfoCache.keyAt(uIdx, c);
+ if (cn.getPackageName().equals(pkg)) {
+ mServiceInfoCache.delete(userId, cn);
}
- updateComponentStatesLocked(
- jobStatus -> jobStatus.getServiceComponent().getPackageName().equals(pkg));
+ }
+ }
+
+ private void updateComponentStateForPackage(final int userId, final String pkg) {
+ synchronized (mLock) {
+ clearComponentsForPackageLocked(userId, pkg);
+ updateComponentStatesLocked(jobStatus -> {
+ // Using user ID instead of source user ID because the service will run under the
+ // user ID, not source user ID.
+ return jobStatus.getUserId() == userId
+ && jobStatus.getServiceComponent().getPackageName().equals(pkg);
+ });
}
}
@@ -169,6 +216,7 @@
}
}
+ @GuardedBy("mLock")
private void updateComponentStatesLocked(@NonNull Predicate<JobStatus> filter) {
mComponentStateUpdateFunctor.reset();
mService.getJobStore().forEachJob(filter, mComponentStateUpdateFunctor);
@@ -178,24 +226,40 @@
}
final class ComponentStateUpdateFunctor implements Consumer<JobStatus> {
+ @GuardedBy("mLock")
boolean mChanged;
@Override
+ @GuardedBy("mLock")
public void accept(JobStatus jobStatus) {
mChanged |= updateComponentEnabledStateLocked(jobStatus);
}
+ @GuardedBy("mLock")
private void reset() {
mChanged = false;
}
}
@Override
+ @GuardedBy("mLock")
public void dumpControllerStateLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate) {
-
+ for (int u = 0; u < mServiceInfoCache.numMaps(); ++u) {
+ final int userId = mServiceInfoCache.keyAt(u);
+ for (int p = 0; p < mServiceInfoCache.numElementsForKey(userId); ++p) {
+ final ComponentName componentName = mServiceInfoCache.keyAt(u, p);
+ pw.print(userId);
+ pw.print("-");
+ pw.print(componentName);
+ pw.print(": ");
+ pw.print(mServiceInfoCache.valueAt(u, p));
+ pw.println();
+ }
+ }
}
@Override
+ @GuardedBy("mLock")
public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
Predicate<JobStatus> predicate) {
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
index 500735b..2bdf656 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
@@ -77,7 +77,7 @@
|| Log.isLoggable(TAG, Log.DEBUG);
// The networking stack has a hard limit so we can't make this configurable.
- private static final int MAX_NETWORK_CALLBACKS = 50;
+ private static final int MAX_NETWORK_CALLBACKS = 125;
/**
* Minimum amount of time that should have elapsed before we'll update a {@link UidStats}
* instance.
@@ -148,7 +148,8 @@
// 9. Enqueue time
// TODO: maybe consider number of jobs
// TODO: consider IMPORTANT_WHILE_FOREGROUND bit
- final int runningPriority = prioritizeExistenceOver(0, us1.numRunning, us2.numRunning);
+ final int runningPriority = prioritizeExistenceOver(0,
+ us1.runningJobs.size(), us2.runningJobs.size());
if (runningPriority != 0) {
return runningPriority;
}
@@ -256,7 +257,18 @@
if (jobStatus.hasConnectivityConstraint()) {
final UidStats uidStats =
getUidStats(jobStatus.getSourceUid(), jobStatus.getSourcePackageName(), true);
- uidStats.numRunning++;
+ uidStats.runningJobs.add(jobStatus);
+ }
+ }
+
+ @GuardedBy("mLock")
+ @Override
+ public void unprepareFromExecutionLocked(JobStatus jobStatus) {
+ if (jobStatus.hasConnectivityConstraint()) {
+ final UidStats uidStats =
+ getUidStats(jobStatus.getSourceUid(), jobStatus.getSourcePackageName(), true);
+ uidStats.runningJobs.remove(jobStatus);
+ postAdjustCallbacks();
}
}
@@ -272,12 +284,7 @@
final UidStats uidStats =
getUidStats(jobStatus.getSourceUid(), jobStatus.getSourcePackageName(), true);
uidStats.numReadyWithConnectivity--;
- if (jobStatus.madeActive != 0) {
- // numRunning would be 0 if the UidStats object didn't exist before this method
- // was called. getUidStats() handles logging, so just make sure we don't save a
- // negative value.
- uidStats.numRunning = Math.max(0, uidStats.numRunning - 1);
- }
+ uidStats.runningJobs.remove(jobStatus);
maybeRevokeStandbyExceptionLocked(jobStatus);
postAdjustCallbacks();
}
@@ -1151,7 +1158,7 @@
private static class UidStats {
public final int uid;
public int basePriority;
- public int numRunning;
+ public final ArraySet<JobStatus> runningJobs = new ArraySet<>();
public int numReadyWithConnectivity;
public int numRequestedNetworkAvailable;
public int numEJs;
@@ -1168,7 +1175,7 @@
pw.print("UidStats{");
pw.print("uid", uid);
pw.print("pri", basePriority);
- pw.print("#run", numRunning);
+ pw.print("#run", runningJobs.size());
pw.print("#readyWithConn", numReadyWithConnectivity);
pw.print("#netAvail", numRequestedNetworkAvailable);
pw.print("#EJs", numEJs);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ContentObserverController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ContentObserverController.java
index 8b0da34..e64233f 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ContentObserverController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ContentObserverController.java
@@ -136,6 +136,29 @@
}
@Override
+ public void unprepareFromExecutionLocked(JobStatus taskStatus) {
+ if (taskStatus.hasContentTriggerConstraint()) {
+ if (taskStatus.contentObserverJobInstance != null) {
+ if (taskStatus.contentObserverJobInstance.mChangedUris == null) {
+ taskStatus.contentObserverJobInstance.mChangedUris = taskStatus.changedUris;
+ } else {
+ taskStatus.contentObserverJobInstance.mChangedUris
+ .addAll(taskStatus.changedUris);
+ }
+ if (taskStatus.contentObserverJobInstance.mChangedAuthorities == null) {
+ taskStatus.contentObserverJobInstance.mChangedAuthorities =
+ taskStatus.changedAuthorities;
+ } else {
+ taskStatus.contentObserverJobInstance.mChangedAuthorities
+ .addAll(taskStatus.changedAuthorities);
+ }
+ taskStatus.changedUris = null;
+ taskStatus.changedAuthorities = null;
+ }
+ }
+ }
+
+ @Override
public void maybeStopTrackingJobLocked(JobStatus taskStatus, JobStatus incomingJob,
boolean forUpdate) {
if (taskStatus.clearTrackingController(JobStatus.TRACKING_CONTENT)) {
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 d4ce437..aace645 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
@@ -34,7 +34,6 @@
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AlarmManager;
-import android.app.AppGlobals;
import android.app.IUidObserver;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManagerInternal;
@@ -677,27 +676,30 @@
}
@Override
- public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
- boolean forUpdate) {
- if (jobStatus.clearTrackingController(JobStatus.TRACKING_QUOTA)) {
- Timer timer = mPkgTimers.get(jobStatus.getSourceUserId(),
- jobStatus.getSourcePackageName());
+ public void unprepareFromExecutionLocked(JobStatus jobStatus) {
+ Timer timer = mPkgTimers.get(jobStatus.getSourceUserId(), jobStatus.getSourcePackageName());
+ if (timer != null) {
+ timer.stopTrackingJob(jobStatus);
+ }
+ if (jobStatus.isRequestedExpeditedJob()) {
+ timer = mEJPkgTimers.get(jobStatus.getSourceUserId(), jobStatus.getSourcePackageName());
if (timer != null) {
timer.stopTrackingJob(jobStatus);
}
- if (jobStatus.isRequestedExpeditedJob()) {
- timer = mEJPkgTimers.get(jobStatus.getSourceUserId(),
- jobStatus.getSourcePackageName());
- if (timer != null) {
- timer.stopTrackingJob(jobStatus);
- }
- }
+ }
+ mTopStartedJobs.remove(jobStatus);
+ }
+
+ @Override
+ public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
+ boolean forUpdate) {
+ if (jobStatus.clearTrackingController(JobStatus.TRACKING_QUOTA)) {
+ unprepareFromExecutionLocked(jobStatus);
ArraySet<JobStatus> jobs = mTrackedJobs.get(jobStatus.getSourceUserId(),
jobStatus.getSourcePackageName());
if (jobs != null) {
jobs.remove(jobStatus);
}
- mTopStartedJobs.remove(jobStatus);
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java
index 334876f..f0fc3b0 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java
@@ -76,6 +76,12 @@
}
/**
+ * Optionally implement logic here for when a job that was about to be executed failed to start.
+ */
+ public void unprepareFromExecutionLocked(JobStatus jobStatus) {
+ }
+
+ /**
* Remove task - this will happen if the task is cancelled, completed, etc.
*/
public abstract void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
diff --git a/apex/jobscheduler/service/jni/Android.bp b/apex/jobscheduler/service/jni/Android.bp
index c630217..333da74 100644
--- a/apex/jobscheduler/service/jni/Android.bp
+++ b/apex/jobscheduler/service/jni/Android.bp
@@ -24,21 +24,10 @@
],
shared_libs: [
- "libnativehelper",
- "liblog",
- "libbase",
+ "libnativehelper",
+ "liblog",
+ "libbase",
],
-
- product_variables: {
- arc: {
- exclude_srcs: [
- "com_android_server_alarm_AlarmManagerService.cpp",
- ],
- srcs: [
- ":arctimersrcs",
- ],
- }
- },
}
filegroup {
diff --git a/apex/media/framework/api/current.txt b/apex/media/framework/api/current.txt
index bebf019..b7d7ed8 100644
--- a/apex/media/framework/api/current.txt
+++ b/apex/media/framework/api/current.txt
@@ -10,7 +10,6 @@
method @NonNull public java.util.List<java.lang.String> getUnsupportedVideoMimeTypes();
method public boolean isFormatSpecified(@NonNull String);
method public boolean isHdrTypeSupported(@NonNull String);
- method public boolean isSlowMotionSupported();
method public boolean isVideoMimeTypeSupported(@NonNull String);
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.media.ApplicationMediaCapabilities> CREATOR;
diff --git a/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java b/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java
index 3f30d3e..97fa0ec 100644
--- a/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java
+++ b/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java
@@ -242,7 +242,7 @@
}
};
- /*
+ /**
* Query the video codec mime types supported by the application.
* @return List of supported video codec mime types. The list will be empty if there are none.
*/
@@ -251,7 +251,7 @@
return new ArrayList<>(mSupportedVideoMimeTypes);
}
- /*
+ /**
* Query the video codec mime types that are not supported by the application.
* @return List of unsupported video codec mime types. The list will be empty if there are none.
*/
@@ -260,7 +260,7 @@
return new ArrayList<>(mUnsupportedVideoMimeTypes);
}
- /*
+ /**
* Query all hdr types that are supported by the application.
* @return List of supported hdr types. The list will be empty if there are none.
*/
@@ -269,7 +269,7 @@
return new ArrayList<>(mSupportedHdrTypes);
}
- /*
+ /**
* Query all hdr types that are not supported by the application.
* @return List of unsupported hdr types. The list will be empty if there are none.
*/
@@ -278,7 +278,7 @@
return new ArrayList<>(mUnsupportedHdrTypes);
}
- /*
+ /**
* Whether handling of slow-motion video is supported
* @hide
*/
diff --git a/core/api/current.txt b/core/api/current.txt
index 0420714..9e87a93 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -9607,12 +9607,12 @@
}
public final class BluetoothLeAdvertiser {
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_CONNECT}) public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_CONNECT}) public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_CONNECT}) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_CONNECT}) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_CONNECT}) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_CONNECT}) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void stopAdvertising(android.bluetooth.le.AdvertiseCallback);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void stopAdvertisingSet(android.bluetooth.le.AdvertisingSetCallback);
}
@@ -12086,13 +12086,6 @@
field public static final String ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED = "android.content.pm.action.CAN_INTERACT_ACROSS_PROFILES_CHANGED";
}
- public class DataLoaderParams {
- method @NonNull public static final android.content.pm.DataLoaderParams forStreaming(@NonNull android.content.ComponentName, @NonNull String);
- method @NonNull public final String getArguments();
- method @NonNull public final android.content.ComponentName getComponentName();
- method @NonNull public final int getType();
- }
-
public final class FeatureGroupInfo implements android.os.Parcelable {
ctor public FeatureGroupInfo();
ctor public FeatureGroupInfo(android.content.pm.FeatureGroupInfo);
@@ -12127,14 +12120,6 @@
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.InstallSourceInfo> CREATOR;
}
- public final class InstallationFile {
- method public long getLengthBytes();
- method public int getLocation();
- method @Nullable public byte[] getMetadata();
- method @NonNull public String getName();
- method @Nullable public byte[] getSignature();
- }
-
public class InstrumentationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
ctor public InstrumentationInfo();
ctor public InstrumentationInfo(android.content.pm.InstrumentationInfo);
@@ -12331,9 +12316,6 @@
field public static final String ACTION_SESSION_COMMITTED = "android.content.pm.action.SESSION_COMMITTED";
field public static final String ACTION_SESSION_DETAILS = "android.content.pm.action.SESSION_DETAILS";
field public static final String ACTION_SESSION_UPDATED = "android.content.pm.action.SESSION_UPDATED";
- field public static final int DATA_LOADER_TYPE_NONE = 0; // 0x0
- field public static final int DATA_LOADER_TYPE_STREAMING = 1; // 0x1
- field public static final String EXTRA_DATA_LOADER_TYPE = "android.content.pm.extra.DATA_LOADER_TYPE";
field public static final String EXTRA_OTHER_PACKAGE_NAME = "android.content.pm.extra.OTHER_PACKAGE_NAME";
field public static final String EXTRA_PACKAGE_NAME = "android.content.pm.extra.PACKAGE_NAME";
field public static final String EXTRA_SESSION = "android.content.pm.extra.SESSION";
@@ -12341,9 +12323,6 @@
field public static final String EXTRA_STATUS = "android.content.pm.extra.STATUS";
field public static final String EXTRA_STATUS_MESSAGE = "android.content.pm.extra.STATUS_MESSAGE";
field public static final String EXTRA_STORAGE_PATH = "android.content.pm.extra.STORAGE_PATH";
- field public static final int LOCATION_DATA_APP = 0; // 0x0
- field public static final int LOCATION_MEDIA_DATA = 2; // 0x2
- field public static final int LOCATION_MEDIA_OBB = 1; // 0x1
field public static final int STATUS_FAILURE = 1; // 0x1
field public static final int STATUS_FAILURE_ABORTED = 3; // 0x3
field public static final int STATUS_FAILURE_BLOCKED = 2; // 0x2
@@ -12351,7 +12330,6 @@
field public static final int STATUS_FAILURE_INCOMPATIBLE = 7; // 0x7
field public static final int STATUS_FAILURE_INVALID = 4; // 0x4
field public static final int STATUS_FAILURE_STORAGE = 6; // 0x6
- field public static final int STATUS_PENDING_STREAMING = -2; // 0xfffffffe
field public static final int STATUS_PENDING_USER_ACTION = -1; // 0xffffffff
field public static final int STATUS_SUCCESS = 0; // 0x0
}
@@ -12359,12 +12337,10 @@
public static class PackageInstaller.Session implements java.io.Closeable {
method public void abandon();
method public void addChildSessionId(int);
- method public void addFile(int, @NonNull String, long, @NonNull byte[], @Nullable byte[]);
method public void close();
method public void commit(@NonNull android.content.IntentSender);
method public void fsync(@NonNull java.io.OutputStream) throws java.io.IOException;
method @NonNull public int[] getChildSessionIds();
- method @Nullable public android.content.pm.DataLoaderParams getDataLoaderParams();
method @NonNull public String[] getNames() throws java.io.IOException;
method public int getParentSessionId();
method public boolean isMultiPackage();
@@ -12372,7 +12348,6 @@
method @NonNull public java.io.InputStream openRead(@NonNull String) throws java.io.IOException;
method @NonNull public java.io.OutputStream openWrite(@NonNull String, long, long) throws java.io.IOException;
method public void removeChildSessionId(int);
- method public void removeFile(int, @NonNull String);
method public void removeSplit(@NonNull String) throws java.io.IOException;
method @Deprecated public void setChecksums(@NonNull String, @NonNull java.util.List<android.content.pm.Checksum>, @Nullable byte[]) throws java.io.IOException;
method public void setStagingProgress(float);
@@ -12443,7 +12418,6 @@
method public void setAppLabel(@Nullable CharSequence);
method public void setAppPackageName(@Nullable String);
method @Deprecated public void setAutoRevokePermissionsMode(boolean);
- method public void setDataLoaderParams(@NonNull android.content.pm.DataLoaderParams);
method public void setInstallLocation(int);
method public void setInstallReason(int);
method public void setInstallScenario(int);
@@ -38369,25 +38343,6 @@
}
-package android.service.dataloader {
-
- public abstract class DataLoaderService extends android.app.Service {
- ctor public DataLoaderService();
- method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
- method @Nullable public android.service.dataloader.DataLoaderService.DataLoader onCreateDataLoader(@NonNull android.content.pm.DataLoaderParams);
- }
-
- public static interface DataLoaderService.DataLoader {
- method public boolean onCreate(@NonNull android.content.pm.DataLoaderParams, @NonNull android.service.dataloader.DataLoaderService.FileSystemConnector);
- method public boolean onPrepareImage(@NonNull java.util.Collection<android.content.pm.InstallationFile>, @NonNull java.util.Collection<java.lang.String>);
- }
-
- public static final class DataLoaderService.FileSystemConnector {
- method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void writeData(@NonNull String, long, long, @NonNull android.os.ParcelFileDescriptor) throws java.io.IOException;
- }
-
-}
-
package android.service.dreams {
public class DreamService extends android.app.Service implements android.view.Window.Callback {
@@ -42609,7 +42564,7 @@
method public String getNetworkOperator();
method public String getNetworkOperatorName();
method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public int getNetworkSelectionMode();
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getNetworkSlicingConfiguration(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.telephony.data.SlicingConfig,android.telephony.TelephonyManager.SlicingException>);
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getNetworkSlicingConfiguration(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.telephony.data.NetworkSlicingConfig,android.telephony.TelephonyManager.NetworkSlicingException>);
method public String getNetworkSpecifier();
method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int getNetworkType();
method @Nullable @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public android.telecom.PhoneAccountHandle getPhoneAccountHandle();
@@ -42660,6 +42615,7 @@
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isModemEnabledForSlot(int);
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int isMultiSimSupported();
method public boolean isNetworkRoaming();
+ method public boolean isRadioInterfaceCapabilitySupported(@NonNull String);
method public boolean isRttSupported();
method public boolean isSmsCapable();
method @Deprecated public boolean isTtyModeSupported();
@@ -42859,11 +42815,13 @@
field public static final int ERROR_TIMEOUT = 1; // 0x1
}
- public static class TelephonyManager.SlicingException extends java.lang.Exception {
- ctor public TelephonyManager.SlicingException(int);
- method public int getErrorCode();
- field public static final int ERROR_MODEM_ERROR = 2; // 0x2
- field public static final int ERROR_TIMEOUT = 1; // 0x1
+ public class TelephonyManager.ModemErrorException extends android.telephony.TelephonyManager.NetworkSlicingException {
+ }
+
+ public static class TelephonyManager.NetworkSlicingException extends java.lang.Exception {
+ }
+
+ public class TelephonyManager.TimeoutException extends android.telephony.TelephonyManager.NetworkSlicingException {
}
public abstract static class TelephonyManager.UssdResponseCallback {
@@ -43073,6 +43031,15 @@
method @NonNull public android.telephony.data.NetworkSliceInfo.Builder setStatus(int);
}
+ public final class NetworkSlicingConfig implements android.os.Parcelable {
+ ctor public NetworkSlicingConfig();
+ method public int describeContents();
+ method @NonNull public java.util.List<android.telephony.data.NetworkSliceInfo> getSliceInfo();
+ method @NonNull public java.util.List<android.telephony.data.UrspRule> getUrspRules();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.NetworkSlicingConfig> CREATOR;
+ }
+
public final class RouteSelectionDescriptor implements android.os.Parcelable {
method public int describeContents();
method @NonNull public java.util.List<java.lang.String> getDataNetworkName();
@@ -43090,30 +43057,14 @@
field public static final int SESSION_TYPE_IPV6 = 1; // 0x1
}
- public final class SlicingConfig implements android.os.Parcelable {
- ctor public SlicingConfig();
- method public int describeContents();
- method @NonNull public java.util.List<android.telephony.data.NetworkSliceInfo> getSliceInfo();
- method @NonNull public java.util.List<android.telephony.data.UrspRule> getUrspRules();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.SlicingConfig> CREATOR;
- }
-
public final class TrafficDescriptor implements android.os.Parcelable {
method public int describeContents();
method @Nullable public String getDataNetworkName();
- method @Nullable public String getOsAppId();
+ method @Nullable public byte[] getOsAppId();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.TrafficDescriptor> CREATOR;
}
- public static final class TrafficDescriptor.Builder {
- ctor public TrafficDescriptor.Builder();
- method @NonNull public android.telephony.data.TrafficDescriptor build();
- method @NonNull public android.telephony.data.TrafficDescriptor.Builder setDataNetworkName(@NonNull String);
- method @NonNull public android.telephony.data.TrafficDescriptor.Builder setOsAppId(@NonNull String);
- }
-
public final class UrspRule implements android.os.Parcelable {
method public int describeContents();
method @IntRange(from=0x0, to=0xff) public int getPrecedence();
@@ -48567,7 +48518,7 @@
method public android.view.View focusSearch(int);
method public void forceHasOverlappingRendering(boolean);
method public void forceLayout();
- method @Nullable public void generateDisplayHash(@NonNull String, @Nullable android.graphics.Rect, @NonNull java.util.concurrent.Executor, @NonNull android.view.displayhash.DisplayHashResultCallback);
+ method public void generateDisplayHash(@NonNull String, @Nullable android.graphics.Rect, @NonNull java.util.concurrent.Executor, @NonNull android.view.displayhash.DisplayHashResultCallback);
method public static int generateViewId();
method public CharSequence getAccessibilityClassName();
method public android.view.View.AccessibilityDelegate getAccessibilityDelegate();
@@ -52912,7 +52863,7 @@
public class Translator {
method public void destroy();
method public boolean isDestroyed();
- method @Nullable public void translate(@NonNull android.view.translation.TranslationRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.view.translation.TranslationResponse>);
+ method @Nullable public void translate(@NonNull android.view.translation.TranslationRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.view.translation.TranslationResponse>);
}
public final class UiTranslationManager {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index f7b4cdc..1eedf74 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -40,6 +40,7 @@
field public static final String BIND_CONTENT_CAPTURE_SERVICE = "android.permission.BIND_CONTENT_CAPTURE_SERVICE";
field public static final String BIND_CONTENT_SUGGESTIONS_SERVICE = "android.permission.BIND_CONTENT_SUGGESTIONS_SERVICE";
field public static final String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH";
+ field public static final String BIND_DISPLAY_HASHING_SERVICE = "android.permission.BIND_DISPLAY_HASHING_SERVICE";
field public static final String BIND_DOMAIN_VERIFICATION_AGENT = "android.permission.BIND_DOMAIN_VERIFICATION_AGENT";
field public static final String BIND_EUICC_SERVICE = "android.permission.BIND_EUICC_SERVICE";
field public static final String BIND_EXTERNAL_STORAGE_SERVICE = "android.permission.BIND_EXTERNAL_STORAGE_SERVICE";
@@ -2321,7 +2322,7 @@
field public static final String SYSTEM_CONFIG_SERVICE = "system_config";
field public static final String SYSTEM_UPDATE_SERVICE = "system_update";
field public static final String TETHERING_SERVICE = "tethering";
- field public static final String TRANSLATION_MANAGER_SERVICE = "transformer";
+ field public static final String TRANSLATION_MANAGER_SERVICE = "translation";
field public static final String UI_TRANSLATION_SERVICE = "ui_translation";
field public static final String VR_SERVICE = "vrmanager";
field public static final String WIFI_NL80211_SERVICE = "wifinl80211";
@@ -2527,6 +2528,18 @@
public class DataLoaderParams {
method @NonNull public static final android.content.pm.DataLoaderParams forIncremental(@NonNull android.content.ComponentName, @NonNull String);
+ method @NonNull public static final android.content.pm.DataLoaderParams forStreaming(@NonNull android.content.ComponentName, @NonNull String);
+ method @NonNull public final String getArguments();
+ method @NonNull public final android.content.ComponentName getComponentName();
+ method @NonNull public final int getType();
+ }
+
+ public final class InstallationFile {
+ method public long getLengthBytes();
+ method public int getLocation();
+ method @Nullable public byte[] getMetadata();
+ method @NonNull public String getName();
+ method @Nullable public byte[] getSignature();
}
public final class InstantAppInfo implements android.os.Parcelable {
@@ -2620,10 +2633,19 @@
public class PackageInstaller {
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean);
field public static final int DATA_LOADER_TYPE_INCREMENTAL = 2; // 0x2
+ field public static final int DATA_LOADER_TYPE_NONE = 0; // 0x0
+ field public static final int DATA_LOADER_TYPE_STREAMING = 1; // 0x1
+ field public static final String EXTRA_DATA_LOADER_TYPE = "android.content.pm.extra.DATA_LOADER_TYPE";
+ field public static final int LOCATION_DATA_APP = 0; // 0x0
+ field public static final int LOCATION_MEDIA_DATA = 2; // 0x2
+ field public static final int LOCATION_MEDIA_OBB = 1; // 0x1
}
public static class PackageInstaller.Session implements java.io.Closeable {
+ method @RequiresPermission("com.android.permission.USE_INSTALLER_V2") public void addFile(int, @NonNull String, long, @NonNull byte[], @Nullable byte[]);
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void commitTransferred(@NonNull android.content.IntentSender);
+ method @Nullable @RequiresPermission("com.android.permission.USE_INSTALLER_V2") public android.content.pm.DataLoaderParams getDataLoaderParams();
+ method @RequiresPermission("com.android.permission.USE_INSTALLER_V2") public void removeFile(int, @NonNull String);
}
public static class PackageInstaller.SessionInfo implements android.os.Parcelable {
@@ -2644,6 +2666,7 @@
public static class PackageInstaller.SessionParams implements android.os.Parcelable {
method @RequiresPermission(android.Manifest.permission.ALLOCATE_AGGRESSIVE) public void setAllocateAggressive(boolean);
method @Deprecated public void setAllowDowngrade(boolean);
+ method @RequiresPermission(allOf={android.Manifest.permission.INSTALL_PACKAGES, "com.android.permission.USE_INSTALLER_V2"}) public void setDataLoaderParams(@NonNull android.content.pm.DataLoaderParams);
method public void setDontKillApp(boolean);
method public void setEnableRollback(boolean);
method public void setEnableRollback(boolean, int);
@@ -7298,10 +7321,6 @@
package android.net {
- public class DnsResolverServiceManager {
- method @NonNull @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public static android.os.IBinder getService(@NonNull android.content.Context);
- }
-
public class EthernetManager {
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public android.net.EthernetManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.TetheredInterfaceCallback);
}
@@ -7861,7 +7880,7 @@
method @Nullable public android.net.wifi.nl80211.WifiNl80211Manager.TxPacketCounters getTxPacketCounters(@NonNull String);
method @Nullable public static android.net.wifi.nl80211.WifiNl80211Manager.OemSecurityType parseOemSecurityTypeElement(int, int, @NonNull byte[]);
method @Deprecated public boolean registerApCallback(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SoftApCallback);
- method public boolean registerCountryCodeChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.CountryCodeChangeListener);
+ method public boolean registerCountryCodeChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.CountryCodeChangedListener);
method public void sendMgmtFrame(@NonNull String, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SendMgmtFrameCallback);
method public void setOnServiceDeadCallback(@NonNull Runnable);
method public boolean setupInterfaceForClientMode(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback);
@@ -7874,7 +7893,7 @@
method public boolean tearDownClientInterface(@NonNull String);
method public boolean tearDownInterfaces();
method public boolean tearDownSoftApInterface(@NonNull String);
- method public void unregisterCountryCodeChangeListener(@NonNull android.net.wifi.nl80211.WifiNl80211Manager.CountryCodeChangeListener);
+ method public void unregisterCountryCodeChangedListener(@NonNull android.net.wifi.nl80211.WifiNl80211Manager.CountryCodeChangedListener);
field public static final String SCANNING_PARAM_ENABLE_6GHZ_RNR = "android.net.wifi.nl80211.SCANNING_PARAM_ENABLE_6GHZ_RNR";
field public static final int SCAN_TYPE_PNO_SCAN = 1; // 0x1
field public static final int SCAN_TYPE_SINGLE_SCAN = 0; // 0x0
@@ -7885,8 +7904,8 @@
field public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1; // 0x1
}
- public static interface WifiNl80211Manager.CountryCodeChangeListener {
- method public void onChanged(@NonNull String);
+ public static interface WifiNl80211Manager.CountryCodeChangedListener {
+ method public void onCountryCodeChanged(@NonNull String);
}
public static class WifiNl80211Manager.OemSecurityType {
@@ -8372,6 +8391,7 @@
field public static final int REASON_ACCOUNT_TRANSFER = 104; // 0x68
field public static final int REASON_ACTIVITY_RECOGNITION = 103; // 0x67
field public static final int REASON_GEOFENCING = 100; // 0x64
+ field public static final int REASON_LOCATION_PROVIDER = 312; // 0x138
field public static final int REASON_OTHER = 1; // 0x1
field public static final int REASON_PUSH_MESSAGING = 101; // 0x65
field public static final int REASON_PUSH_MESSAGING_OVER_QUOTA = 102; // 0x66
@@ -8424,6 +8444,7 @@
field @Deprecated public static final int EVENT_UNSPECIFIED = 0; // 0x0
field @Deprecated public static final int REASON_ACTIVITY_RECOGNITION = 103; // 0x67
field @Deprecated public static final int REASON_GEOFENCING = 100; // 0x64
+ field @Deprecated public static final int REASON_LOCATION_PROVIDER = 312; // 0x138
field @Deprecated public static final int REASON_OTHER = 1; // 0x1
field @Deprecated public static final int REASON_PUSH_MESSAGING = 101; // 0x65
field @Deprecated public static final int REASON_PUSH_MESSAGING_OVER_QUOTA = 102; // 0x66
@@ -9819,12 +9840,30 @@
}
+package android.service.dataloader {
+
+ public abstract class DataLoaderService extends android.app.Service {
+ ctor public DataLoaderService();
+ method @Nullable public android.service.dataloader.DataLoaderService.DataLoader onCreateDataLoader(@NonNull android.content.pm.DataLoaderParams);
+ }
+
+ public static interface DataLoaderService.DataLoader {
+ method public boolean onCreate(@NonNull android.content.pm.DataLoaderParams, @NonNull android.service.dataloader.DataLoaderService.FileSystemConnector);
+ method public boolean onPrepareImage(@NonNull java.util.Collection<android.content.pm.InstallationFile>, @NonNull java.util.Collection<java.lang.String>);
+ }
+
+ public static final class DataLoaderService.FileSystemConnector {
+ method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void writeData(@NonNull String, long, long, @NonNull android.os.ParcelFileDescriptor) throws java.io.IOException;
+ }
+
+}
+
package android.service.displayhash {
public final class DisplayHashParams implements android.os.Parcelable {
method public int describeContents();
method @Nullable public android.util.Size getBufferSize();
- method public boolean isGrayscaleBuffer();
+ method public boolean isUseGrayscale();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.service.displayhash.DisplayHashParams> CREATOR;
}
@@ -9833,17 +9872,17 @@
ctor public DisplayHashParams.Builder();
method @NonNull public android.service.displayhash.DisplayHashParams build();
method @NonNull public android.service.displayhash.DisplayHashParams.Builder setBufferSize(int, int);
- method @NonNull public android.service.displayhash.DisplayHashParams.Builder setGrayscaleBuffer(boolean);
+ method @NonNull public android.service.displayhash.DisplayHashParams.Builder setUseGrayscale(boolean);
}
- public abstract class DisplayHasherService extends android.app.Service {
- ctor public DisplayHasherService();
+ public abstract class DisplayHashingService extends android.app.Service {
+ ctor public DisplayHashingService();
method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
- method @Nullable public abstract void onGenerateDisplayHash(@NonNull byte[], @NonNull android.hardware.HardwareBuffer, @NonNull android.graphics.Rect, @NonNull String, @NonNull android.view.displayhash.DisplayHashResultCallback);
+ method public abstract void onGenerateDisplayHash(@NonNull byte[], @NonNull android.hardware.HardwareBuffer, @NonNull android.graphics.Rect, @NonNull String, @NonNull android.view.displayhash.DisplayHashResultCallback);
method @NonNull public abstract java.util.Map<java.lang.String,android.service.displayhash.DisplayHashParams> onGetDisplayHashAlgorithms();
method @Nullable public abstract android.view.displayhash.VerifiedDisplayHash onVerifyDisplayHash(@NonNull byte[], @NonNull android.view.displayhash.DisplayHash);
- field public static final String SERVICE_INTERFACE = "android.service.displayhash.DisplayHasherService";
- field public static final String SERVICE_META_DATA = "android.displayhash.display_hasher_service";
+ field public static final String SERVICE_INTERFACE = "android.service.displayhash.DisplayHashingService";
+ field public static final String SERVICE_META_DATA = "android.displayhash.display_hashing_service";
}
}
@@ -10361,7 +10400,7 @@
method public void onDisconnected();
method public abstract void onFinishTranslationSession(int);
method public abstract void onTranslationCapabilitiesRequest(int, int, @NonNull java.util.function.Consumer<java.util.Set<android.view.translation.TranslationCapability>>);
- method public abstract void onTranslationRequest(@NonNull android.view.translation.TranslationRequest, int, @NonNull android.os.CancellationSignal, @NonNull android.service.translation.TranslationService.OnTranslationResultCallback);
+ method public abstract void onTranslationRequest(@NonNull android.view.translation.TranslationRequest, int, @Nullable android.os.CancellationSignal, @NonNull android.service.translation.TranslationService.OnTranslationResultCallback);
field public static final String SERVICE_INTERFACE = "android.service.translation.TranslationService";
field public static final String SERVICE_META_DATA = "android.translation_service";
}
@@ -11938,7 +11977,6 @@
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isOpportunisticNetworkEnabled();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String);
- method public boolean isRadioInterfaceCapabilitySupported(@NonNull String);
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRadioOn();
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isTetheringApnRequired();
@@ -14122,6 +14160,7 @@
method @NonNull public java.io.File getFile();
method @Nullable public String getFontFamilyName();
method @NonNull public String getFontVariationSettings();
+ method @NonNull public String getPostScriptName();
method @NonNull public android.graphics.fonts.FontStyle getStyle();
method public int getTtcIndex();
method public void writeToParcel(@NonNull android.os.Parcel, int);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index a77bf32..62922db 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -999,7 +999,7 @@
}
public class Typeface {
- method @NonNull public static java.util.Map<java.lang.String,android.graphics.Typeface> deserializeFontMap(@NonNull java.nio.ByteBuffer) throws java.io.IOException;
+ method @NonNull public static long[] deserializeFontMap(@NonNull java.nio.ByteBuffer, @NonNull java.util.Map<java.lang.String,android.graphics.Typeface>) throws java.io.IOException;
method @Nullable public static android.os.SharedMemory getSystemFontMapSharedMemory();
method @NonNull public static android.os.SharedMemory serializeFontMap(@NonNull java.util.Map<java.lang.String,android.graphics.Typeface>) throws android.system.ErrnoException, java.io.IOException;
}
@@ -1575,6 +1575,10 @@
method public static void setServiceForTest(@Nullable android.os.IBinder);
}
+ public class NetworkWatchlistManager {
+ method @Nullable public byte[] getWatchlistConfigHash();
+ }
+
public class TrafficStats {
method public static long getLoopbackRxBytes();
method public static long getLoopbackRxPackets();
@@ -2010,6 +2014,7 @@
public final class PermissionManager {
method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.permission.PermGroupUsage> getIndicatorAppOpUsageData();
+ method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.permission.PermGroupUsage> getIndicatorAppOpUsageData(boolean);
method @NonNull public android.content.AttributionSource registerAttributionSource(@NonNull android.content.AttributionSource);
}
@@ -2488,6 +2493,7 @@
method @NonNull public java.io.File getFile();
method @Nullable public String getFontFamilyName();
method @NonNull public String getFontVariationSettings();
+ method @NonNull public String getPostScriptName();
method @NonNull public android.graphics.fonts.FontStyle getStyle();
method public int getTtcIndex();
method public void writeToParcel(@NonNull android.os.Parcel, int);
@@ -2740,6 +2746,7 @@
public interface WindowManager extends android.view.ViewManager {
method public default int getDisplayImePolicy(int);
method public default void holdLock(android.os.IBinder, int);
+ method public default boolean isTaskSnapshotSupported();
method public default void setDisplayImePolicy(int, int);
method public default void setForceCrossWindowBlurDisabled(boolean);
method public default void setShouldShowSystemDecors(int, boolean);
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 1d290de..c8a8d36 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -70,6 +70,7 @@
"android/annotation/Nullable.java",
"android/annotation/PluralsRes.java",
"android/annotation/RawRes.java",
+ "android/annotation/RequiresNoPermission.java",
"android/annotation/RequiresPermission.java",
"android/annotation/SdkConstant.java",
"android/annotation/Size.java",
diff --git a/core/java/android/annotation/RequiresNoPermission.java b/core/java/android/annotation/RequiresNoPermission.java
new file mode 100644
index 0000000..6ff4d6e3
--- /dev/null
+++ b/core/java/android/annotation/RequiresNoPermission.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Denotes that the annotated element requires no permissions.
+ *
+ * @hide
+ */
+@Retention(CLASS)
+@Target({ANNOTATION_TYPE,METHOD,CONSTRUCTOR,FIELD,PARAMETER})
+public @interface RequiresNoPermission {
+}
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index df9530f..1cb46b1 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -6475,7 +6475,7 @@
historicalDiscreteAccesses.add(other.mDiscreteAccesses.get(i++));
}
}
- mDiscreteAccesses = historicalDiscreteAccesses;
+ mDiscreteAccesses = deduplicateDiscreteEvents(historicalDiscreteAccesses);
}
private void increaseAccessCount(@UidState int uidState, @OpFlags int flags,
@@ -6996,7 +6996,7 @@
}
result.add(entry);
}
- return result;
+ return deduplicateDiscreteEvents(result);
}
/**
@@ -9819,4 +9819,52 @@
}
}
}
+
+ private static List<AttributedOpEntry> deduplicateDiscreteEvents(List<AttributedOpEntry> list) {
+ int n = list.size();
+ int i = 0;
+ for (int j = 0, k = 0; j < n; i++, j = k) {
+ long currentAccessTime = list.get(j).getLastAccessTime(OP_FLAGS_ALL);
+ k = j + 1;
+ while(k < n && list.get(k).getLastAccessTime(OP_FLAGS_ALL) == currentAccessTime) {
+ k++;
+ }
+ list.set(i, mergeAttributedOpEntries(list.subList(j, k)));
+ }
+ for (; i < n; i++) {
+ list.remove(list.size() - 1);
+ }
+ return list;
+ }
+
+ private static AttributedOpEntry mergeAttributedOpEntries(List<AttributedOpEntry> opEntries) {
+ if (opEntries.size() == 1) {
+ return opEntries.get(0);
+ }
+ LongSparseArray<AppOpsManager.NoteOpEvent> accessEvents = new LongSparseArray<>();
+ LongSparseArray<AppOpsManager.NoteOpEvent> rejectEvents = new LongSparseArray<>();
+ int opCount = opEntries.size();
+ for (int i = 0; i < opCount; i++) {
+ AttributedOpEntry a = opEntries.get(i);
+ ArraySet<Long> keys = a.collectKeys();
+ final int keyCount = keys.size();
+ for (int k = 0; k < keyCount; k++) {
+ final long key = keys.valueAt(k);
+
+ final int uidState = extractUidStateFromKey(key);
+ final int flags = extractFlagsFromKey(key);
+
+ NoteOpEvent access = a.getLastAccessEvent(uidState, uidState, flags);
+ NoteOpEvent reject = a.getLastRejectEvent(uidState, uidState, flags);
+
+ if (access != null) {
+ accessEvents.append(key, access);
+ }
+ if (reject != null) {
+ rejectEvents.append(key, reject);
+ }
+ }
+ }
+ return new AttributedOpEntry(opEntries.get(0).mOp, false, accessEvents, rejectEvents);
+ }
}
diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java
index dfc105a..8574678 100644
--- a/core/java/android/app/ApplicationExitInfo.java
+++ b/core/java/android/app/ApplicationExitInfo.java
@@ -614,7 +614,7 @@
* tombstone traces will be returned for
* {@link #REASON_CRASH_NATIVE}, with an InputStream containing a protobuf with
* <a href="https://android.googlesource.com/platform/system/core/+/refs/heads/master/debuggerd/proto/tombstone.proto">this schema</a>.
- * Note thatbecause these traces are kept in a separate global circular buffer, crashes may be
+ * Note that because these traces are kept in a separate global circular buffer, crashes may be
* overwritten by newer crashes (including from other applications), so this may still return
* null.
*
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index e83557c..4f7c684 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -190,4 +190,18 @@
* Called from SystemUI when it shows the AoD UI.
*/
oneway void setInAmbientMode(boolean inAmbientMode, long animationDuration);
+
+ /**
+ * Called from SystemUI when the device is waking up.
+ *
+ * @hide
+ */
+ oneway void notifyWakingUp(int x, int y, in Bundle extras);
+
+ /**
+ * Called from SystemUI when the device is going to sleep.
+ *
+ * @hide
+ */
+ void notifyGoingToSleep(int x, int y, in Bundle extras);
}
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 6a71c92..8d332ab 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -190,6 +190,30 @@
public static final String COMMAND_DROP = "android.home.drop";
/**
+ * Command for {@link #sendWallpaperCommand}: reported by System UI when the device is waking
+ * up. The x and y arguments are a location (possibly very roughly) corresponding to the action
+ * that caused the device to wake up. For example, if the power button was pressed, this will be
+ * the location on the screen nearest the power button.
+ *
+ * If the location is unknown or not applicable, x and y will be -1.
+ *
+ * @hide
+ */
+ public static final String COMMAND_WAKING_UP = "android.wallpaper.wakingup";
+
+ /**
+ * Command for {@link #sendWallpaperCommand}: reported by System UI when the device is going to
+ * sleep. The x and y arguments are a location (possibly very roughly) corresponding to the
+ * action that caused the device to go to sleep. For example, if the power button was pressed,
+ * this will be the location on the screen nearest the power button.
+ *
+ * If the location is unknown or not applicable, x and y will be -1.
+ *
+ * @hide
+ */
+ public static final String COMMAND_GOING_TO_SLEEP = "android.wallpaper.goingtosleep";
+
+ /**
* Command for {@link #sendWallpaperCommand}: reported when the wallpaper that was already
* set is re-applied by the user.
* @hide
diff --git a/core/java/android/app/time/TimeZoneCapabilities.java b/core/java/android/app/time/TimeZoneCapabilities.java
index 433b420..895a8e4 100644
--- a/core/java/android/app/time/TimeZoneCapabilities.java
+++ b/core/java/android/app/time/TimeZoneCapabilities.java
@@ -207,6 +207,17 @@
mUserHandle = Objects.requireNonNull(userHandle);
}
+ public Builder(@NonNull TimeZoneCapabilities capabilitiesToCopy) {
+ Objects.requireNonNull(capabilitiesToCopy);
+ mUserHandle = capabilitiesToCopy.mUserHandle;
+ mConfigureAutoDetectionEnabledCapability =
+ capabilitiesToCopy.mConfigureAutoDetectionEnabledCapability;
+ mConfigureGeoDetectionEnabledCapability =
+ capabilitiesToCopy.mConfigureGeoDetectionEnabledCapability;
+ mSuggestManualTimeZoneCapability =
+ capabilitiesToCopy.mSuggestManualTimeZoneCapability;
+ }
+
/** Sets the state for the automatic time zone detection enabled config. */
public Builder setConfigureAutoDetectionEnabledCapability(@CapabilityState int value) {
this.mConfigureAutoDetectionEnabledCapability = value;
diff --git a/core/java/android/app/timedetector/TimeDetector.java b/core/java/android/app/timedetector/TimeDetector.java
index 52016b6..a356230 100644
--- a/core/java/android/app/timedetector/TimeDetector.java
+++ b/core/java/android/app/timedetector/TimeDetector.java
@@ -32,6 +32,18 @@
public interface TimeDetector {
/**
+ * The name of the service for shell commands.
+ * @hide
+ */
+ String SHELL_COMMAND_SERVICE_NAME = "time_detector";
+
+ /**
+ * A shell command that prints the current "auto time detection" global setting value.
+ * @hide
+ */
+ String SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED = "is_auto_detection_enabled";
+
+ /**
* A shared utility method to create a {@link ManualTimeSuggestion}.
*
* @hide
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
index a72877e..fe81df0 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -320,6 +320,15 @@
}
/**
+ * Set the host's interaction handler.
+ *
+ * @hide
+ */
+ public void setInteractionHandler(InteractionHandler interactionHandler) {
+ mInteractionHandler = interactionHandler;
+ }
+
+ /**
* Gets a list of all the appWidgetIds that are bound to the current host
*/
public int[] getAppWidgetIds() {
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index a268e16..0d21e09 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -20,8 +20,10 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresNoPermission;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
+import android.annotation.SuppressLint;
import android.annotation.SdkConstant.SdkConstantType;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
@@ -512,6 +514,7 @@
* @return true if priority is set, false on error
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -534,6 +537,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -624,6 +628,7 @@
* @return true if device supports absolute volume
* @hide
*/
+ @RequiresNoPermission
public boolean isAvrcpAbsoluteVolumeSupported() {
if (DBG) Log.d(TAG, "isAvrcpAbsoluteVolumeSupported");
try {
@@ -690,6 +695,7 @@
*
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean shouldSendVolumeKeys(BluetoothDevice device) {
if (isEnabled() && isValidDevice(device)) {
diff --git a/core/java/android/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java
index d81316e..280e8bc 100755
--- a/core/java/android/bluetooth/BluetoothA2dpSink.java
+++ b/core/java/android/bluetooth/BluetoothA2dpSink.java
@@ -187,6 +187,8 @@
* @hide
*/
@Override
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
final IBluetoothA2dpSink service = getService();
@@ -208,6 +210,8 @@
* @hide
*/
@Override
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
final IBluetoothA2dpSink service = getService();
@@ -229,6 +233,8 @@
* @hide
*/
@Override
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
final IBluetoothA2dpSink service = getService();
@@ -256,6 +262,8 @@
* @hide
*/
@RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothAudioConfig getAudioConfig(BluetoothDevice device) {
if (VDBG) log("getAudioConfig(" + device + ")");
final IBluetoothA2dpSink service = getService();
@@ -282,6 +290,7 @@
* @return true if priority is set, false on error
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -304,6 +313,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 972e9e6..052a773 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -21,6 +21,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresNoPermission;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
@@ -716,6 +717,7 @@
* Bluetooth metadata listener. Overrides the default BluetoothMetadataListener
* implementation.
*/
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private static final IBluetoothMetadataListener sBluetoothMetadataListener =
new IBluetoothMetadataListener.Stub() {
@Override
@@ -747,6 +749,7 @@
* @return the default local adapter, or null if Bluetooth is not supported on this hardware
* platform
*/
+ @RequiresNoPermission
public static synchronized BluetoothAdapter getDefaultAdapter() {
if (sAdapter == null) {
IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
@@ -792,6 +795,7 @@
* @param address valid Bluetooth MAC address
* @throws IllegalArgumentException if address is invalid
*/
+ @RequiresNoPermission
public BluetoothDevice getRemoteDevice(String address) {
return new BluetoothDevice(address);
}
@@ -807,6 +811,7 @@
* @param address Bluetooth MAC address (6 bytes)
* @throws IllegalArgumentException if address is invalid
*/
+ @RequiresNoPermission
public BluetoothDevice getRemoteDevice(byte[] address) {
if (address == null || address.length != 6) {
throw new IllegalArgumentException("Bluetooth address must have 6 bytes");
@@ -824,6 +829,7 @@
* Use {@link #isMultipleAdvertisementSupported()} to check whether LE Advertising is supported
* on this device before calling this method.
*/
+ @RequiresNoPermission
public BluetoothLeAdvertiser getBluetoothLeAdvertiser() {
if (!getLeAccess()) {
return null;
@@ -846,6 +852,7 @@
*
* @hide
*/
+ @RequiresNoPermission
public PeriodicAdvertisingManager getPeriodicAdvertisingManager() {
if (!getLeAccess()) {
return null;
@@ -866,6 +873,7 @@
/**
* Returns a {@link BluetoothLeScanner} object for Bluetooth LE scan operations.
*/
+ @RequiresNoPermission
public BluetoothLeScanner getBluetoothLeScanner() {
if (!getLeAccess()) {
return null;
@@ -887,6 +895,7 @@
* @return true if the local adapter is turned on
*/
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
public boolean isEnabled() {
return getState() == BluetoothAdapter.STATE_ON;
}
@@ -900,6 +909,7 @@
* @hide
*/
@SystemApi
+ @RequiresNoPermission
public boolean isLeEnabled() {
final int state = getLeState();
if (DBG) {
@@ -937,6 +947,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean disableBLE() {
if (!isBleScanAlwaysAvailable()) {
@@ -983,6 +994,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean enableBLE() {
if (!isBleScanAlwaysAvailable()) {
@@ -1015,6 +1027,7 @@
};
/** @hide */
+ @RequiresNoPermission
public void disableBluetoothGetStateCache() {
mBluetoothGetStateCache.disableLocal();
}
@@ -1059,6 +1072,7 @@
* @return current state of Bluetooth adapter
*/
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
@AdapterState
public int getState() {
int state = getStateInternal();
@@ -1095,6 +1109,7 @@
* @hide
*/
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
@AdapterState
@UnsupportedAppUsage(publicAlternatives = "Use {@link #getState()} instead to determine "
+ "whether you can use BLE & BT classic.")
@@ -1251,6 +1266,18 @@
return null;
}
+ /** {@hide} */
+ @RequiresBluetoothAdvertisePermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
+ public int getNameLengthForAdvertise() {
+ try {
+ return mService.getNameLengthForAdvertise();
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ return -1;
+ }
+
/**
* Factory reset bluetooth settings.
*
@@ -1637,6 +1664,7 @@
/** @hide */
@UnsupportedAppUsage
+ @RequiresBluetoothScanPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
public int getDiscoverableTimeout() {
if (getState() != STATE_ON) {
@@ -1657,6 +1685,7 @@
/** @hide */
@UnsupportedAppUsage
+ @RequiresBluetoothScanPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
public void setDiscoverableTimeout(int timeout) {
if (getState() != STATE_ON) {
@@ -1702,6 +1731,7 @@
* Set the context for this BluetoothAdapter (only called from BluetoothManager)
* @hide
*/
+ @RequiresNoPermission
public void setContext(Context context) {
mContext = context;
}
@@ -1860,6 +1890,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -1904,6 +1935,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -1952,6 +1984,7 @@
*
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -1984,6 +2017,7 @@
*
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -2009,6 +2043,7 @@
* @return true if Multiple Advertisement feature is supported
*/
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
public boolean isMultipleAdvertisementSupported() {
if (getState() != STATE_ON) {
return false;
@@ -2037,6 +2072,7 @@
* @hide
*/
@SystemApi
+ @RequiresNoPermission
public boolean isBleScanAlwaysAvailable() {
try {
return mManagerService.isBleScanAlwaysAvailable();
@@ -2070,6 +2106,7 @@
};
/** @hide */
+ @RequiresNoPermission
public void disableIsOffloadedFilteringSupportedCache() {
mBluetoothFilteringCache.disableLocal();
}
@@ -2085,6 +2122,7 @@
* @return true if chipset supports on-chip filtering
*/
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
public boolean isOffloadedFilteringSupported() {
if (!getLeAccess()) {
return false;
@@ -2098,6 +2136,7 @@
* @return true if chipset supports on-chip scan batching
*/
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
public boolean isOffloadedScanBatchingSupported() {
if (!getLeAccess()) {
return false;
@@ -2121,6 +2160,7 @@
* @return true if chipset supports LE 2M PHY feature
*/
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
public boolean isLe2MPhySupported() {
if (!getLeAccess()) {
return false;
@@ -2144,6 +2184,7 @@
* @return true if chipset supports LE Coded PHY feature
*/
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
public boolean isLeCodedPhySupported() {
if (!getLeAccess()) {
return false;
@@ -2167,6 +2208,7 @@
* @return true if chipset supports LE Extended Advertising feature
*/
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
public boolean isLeExtendedAdvertisingSupported() {
if (!getLeAccess()) {
return false;
@@ -2190,6 +2232,7 @@
* @return true if chipset supports LE Periodic Advertising feature
*/
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
public boolean isLePeriodicAdvertisingSupported() {
if (!getLeAccess()) {
return false;
@@ -2214,6 +2257,7 @@
* @return the maximum LE advertising data length.
*/
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
public int getLeMaximumAdvertisingDataLength() {
if (!getLeAccess()) {
return 0;
@@ -2236,6 +2280,7 @@
*
* @return true if phone supports Hearing Aid Profile
*/
+ @RequiresNoPermission
private boolean isHearingAidProfileSupported() {
try {
return mManagerService.isHearingAidProfileSupported();
@@ -2274,6 +2319,7 @@
* @return true if there are hw entries available for matching beacons
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean isHardwareTrackingFiltersAvailable() {
if (!getLeAccess()) {
@@ -2420,6 +2466,7 @@
* BluetoothProfile}.
* @hide
*/
+ @RequiresNoPermission
public @NonNull List<Integer> getSupportedProfiles() {
final ArrayList<Integer> supportedProfiles = new ArrayList<Integer>();
@@ -2467,6 +2514,7 @@
};
/** @hide */
+ @RequiresNoPermission
public void disableGetAdapterConnectionStateCache() {
mBluetoothGetAdapterConnectionStateCache.disableLocal();
}
@@ -2491,6 +2539,7 @@
*/
@UnsupportedAppUsage
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
public int getConnectionState() {
if (getState() != STATE_ON) {
return BluetoothAdapter.STATE_DISCONNECTED;
@@ -2541,6 +2590,7 @@
};
/** @hide */
+ @RequiresNoPermission
public void disableGetProfileConnectionStateCache() {
mGetProfileConnectionStateCache.disableLocal();
}
@@ -2741,6 +2791,7 @@
return createNewRfcommSocketAndRecord(name, uuid, false, true);
}
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
private BluetoothServerSocket createNewRfcommSocketAndRecord(String name, UUID uuid,
boolean auth, boolean encrypt) throws IOException {
@@ -2767,6 +2818,7 @@
* permissions.
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothServerSocket listenUsingInsecureRfcommOn(int port) throws IOException {
BluetoothServerSocket socket =
@@ -2799,6 +2851,7 @@
* permissions.
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothServerSocket listenUsingL2capOn(int port, boolean mitm, boolean min16DigitPin)
throws IOException {
@@ -2832,6 +2885,7 @@
* permissions.
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothServerSocket listenUsingL2capOn(int port) throws IOException {
return listenUsingL2capOn(port, false, false);
@@ -2849,6 +2903,7 @@
* permissions.
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothServerSocket listenUsingInsecureL2capOn(int port) throws IOException {
Log.d(TAG, "listenUsingInsecureL2capOn: port=" + port);
@@ -2904,6 +2959,10 @@
* BluetoothProfile#HEARING_AID} or {@link BluetoothProfile#GATT_SERVER}.
* @return true on success, false on error
*/
+ @SuppressLint({
+ "AndroidFrameworkRequiresPermission",
+ "AndroidFrameworkBluetoothPermission"
+ })
public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener,
int profile) {
if (context == null || listener == null) {
@@ -2973,7 +3032,10 @@
* @param profile
* @param proxy Profile proxy object
*/
- @SuppressLint("AndroidFrameworkRequiresPermission")
+ @SuppressLint({
+ "AndroidFrameworkRequiresPermission",
+ "AndroidFrameworkBluetoothPermission"
+ })
public void closeProfileProxy(int profile, BluetoothProfile proxy) {
if (proxy == null) {
return;
@@ -3046,6 +3108,7 @@
}
}
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private final IBluetoothManagerCallback mManagerCallback =
new IBluetoothManagerCallback.Stub() {
@SuppressLint("AndroidFrameworkRequiresPermission")
@@ -3368,7 +3431,6 @@
/**
* @hide
*/
- @SuppressLint("AndroidFrameworkRequiresPermission")
public class StateChangeCallbackWrapper extends IBluetoothStateChangeCallback.Stub {
private BluetoothStateChangeCallback mCallback;
@@ -3619,6 +3681,7 @@
return false;
}
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
@@ -3949,6 +4012,7 @@
@Nullable byte[] value);
}
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private final IBluetoothConnectionCallback mConnectionCallback =
new IBluetoothConnectionCallback.Stub() {
@Override
diff --git a/core/java/android/bluetooth/BluetoothAvrcpController.java b/core/java/android/bluetooth/BluetoothAvrcpController.java
index 887cf3f..5148d5b 100644
--- a/core/java/android/bluetooth/BluetoothAvrcpController.java
+++ b/core/java/android/bluetooth/BluetoothAvrcpController.java
@@ -117,6 +117,8 @@
* {@inheritDoc}
*/
@Override
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
final IBluetoothAvrcpController service =
@@ -137,6 +139,8 @@
* {@inheritDoc}
*/
@Override
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
final IBluetoothAvrcpController service =
@@ -157,6 +161,8 @@
* {@inheritDoc}
*/
@Override
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
final IBluetoothAvrcpController service =
@@ -178,6 +184,8 @@
*
* @return the {@link BluetoothAvrcpPlayerSettings} or {@link null} if there is an error.
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothAvrcpPlayerSettings getPlayerSettings(BluetoothDevice device) {
if (DBG) Log.d(TAG, "getPlayerSettings");
BluetoothAvrcpPlayerSettings settings = null;
@@ -198,6 +206,8 @@
* Sets the player app setting for current player.
* returns true in case setting is supported by remote, false otherwise
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean setPlayerApplicationSetting(BluetoothAvrcpPlayerSettings plAppSetting) {
if (DBG) Log.d(TAG, "setPlayerApplicationSetting");
final IBluetoothAvrcpController service =
@@ -218,6 +228,8 @@
* Send Group Navigation Command to Remote.
* possible keycode values: next_grp, previous_grp defined above
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void sendGroupNavigationCmd(BluetoothDevice device, int keyCode, int keyState) {
Log.d(TAG, "sendGroupNavigationCmd dev = " + device + " key " + keyCode + " State = "
+ keyState);
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 942f843..9d3eed8 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -16,15 +16,12 @@
package android.bluetooth;
-import android.compat.annotation.UnsupportedAppUsage;
+import android.annotation.RequiresNoPermission;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
-import android.annotation.RequiresPermission;
-import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
-import android.bluetooth.annotations.RequiresBluetoothLocationPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
-import android.bluetooth.annotations.RequiresBluetoothScanPermission;
+import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Handler;
import android.os.ParcelUuid;
@@ -158,6 +155,7 @@
/**
* Bluetooth GATT callbacks. Overrides the default BluetoothGattCallback implementation.
*/
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private final IBluetoothGattCallback mBluetoothGattCallback =
new IBluetoothGattCallback.Stub() {
/**
@@ -747,6 +745,7 @@
* Application should call this method as early as possible after it is done with
* this GATT client.
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void close() {
if (DBG) Log.d(TAG, "close()");
@@ -881,6 +880,7 @@
* Unregister the current application and callbacks.
*/
@UnsupportedAppUsage
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
private void unregisterApp() {
if (DBG) Log.d(TAG, "unregisterApp() - mClientIf=" + mClientIf);
@@ -973,6 +973,7 @@
*
* @return true, if the connection attempt was initiated successfully
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean connect() {
try {
@@ -1003,6 +1004,7 @@
* of {@link BluetoothDevice#PHY_OPTION_NO_PREFERRED}, {@link BluetoothDevice#PHY_OPTION_S2} or
* {@link BluetoothDevice#PHY_OPTION_S8}
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void setPreferredPhy(int txPhy, int rxPhy, int phyOptions) {
try {
@@ -1017,6 +1019,7 @@
* Read the current transmitter PHY and receiver PHY of the connection. The values are returned
* in {@link BluetoothGattCallback#onPhyRead}
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void readPhy() {
try {
@@ -1031,6 +1034,7 @@
*
* @return remote bluetooth device
*/
+ @RequiresNoPermission
public BluetoothDevice getDevice() {
return mDevice;
}
@@ -1101,6 +1105,7 @@
* not yet been performed.
*/
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
public List<BluetoothGattService> getServices() {
List<BluetoothGattService> result =
new ArrayList<BluetoothGattService>();
@@ -1129,6 +1134,7 @@
* the remote device.
*/
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
public BluetoothGattService getService(UUID uuid) {
for (BluetoothGattService service : mServices) {
if (service.getDevice().equals(mDevice) && service.getUuid().equals(uuid)) {
@@ -1444,6 +1450,7 @@
* @deprecated Use {@link #abortReliableWrite()}
*/
@Deprecated
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void abortReliableWrite(BluetoothDevice mDevice) {
abortReliableWrite();
@@ -1496,6 +1503,7 @@
* @hide
*/
@UnsupportedAppUsage
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean refresh() {
if (DBG) Log.d(TAG, "refresh() - device: " + mDevice.getAddress());
@@ -1579,6 +1587,7 @@
* or {@link BluetoothGatt#CONNECTION_PRIORITY_LOW_POWER}.
* @throws IllegalArgumentException If the parameters are outside of their specified range.
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean requestConnectionPriority(int connectionPriority) {
if (connectionPriority < CONNECTION_PRIORITY_BALANCED
@@ -1607,6 +1616,7 @@
* @return true, if the request is send to the Bluetooth stack.
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean requestLeConnectionUpdate(int minConnectionInterval, int maxConnectionInterval,
int slaveLatency, int supervisionTimeout,
@@ -1641,6 +1651,7 @@
* @throws UnsupportedOperationException
*/
@Override
+ @RequiresNoPermission
public int getConnectionState(BluetoothDevice device) {
throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead.");
}
@@ -1652,6 +1663,7 @@
* @throws UnsupportedOperationException
*/
@Override
+ @RequiresNoPermission
public List<BluetoothDevice> getConnectedDevices() {
throw new UnsupportedOperationException(
"Use BluetoothManager#getConnectedDevices instead.");
@@ -1665,6 +1677,7 @@
* @throws UnsupportedOperationException
*/
@Override
+ @RequiresNoPermission
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
throw new UnsupportedOperationException(
"Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index fdb8018..865f476 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -16,7 +16,9 @@
package android.bluetooth;
+import android.annotation.RequiresNoPermission;
import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.os.ParcelUuid;
@@ -58,6 +60,7 @@
/**
* Bluetooth GATT interface callbacks
*/
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private final IBluetoothGattServerCallback mBluetoothGattServerCallback =
new IBluetoothGattServerCallback.Stub() {
/**
@@ -428,6 +431,7 @@
* Application should call this method as early as possible after it is done with
* this GATT server.
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void close() {
if (DBG) Log.d(TAG, "close()");
@@ -510,6 +514,7 @@
/**
* Unregister the current application and callbacks.
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
private void unregisterCallback() {
if (DBG) Log.d(TAG, "unregisterCallback() - mServerIf=" + mServerIf);
@@ -618,6 +623,7 @@
* of {@link BluetoothDevice#PHY_OPTION_NO_PREFERRED}, {@link BluetoothDevice#PHY_OPTION_S2} or
* {@link BluetoothDevice#PHY_OPTION_S8}
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void setPreferredPhy(BluetoothDevice device, int txPhy, int rxPhy, int phyOptions) {
try {
@@ -634,6 +640,7 @@
*
* @param device The remote device to send this response to
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void readPhy(BluetoothDevice device) {
try {
@@ -814,6 +821,7 @@
* @return List of services. Returns an empty list if no services have been added yet.
*/
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
public List<BluetoothGattService> getServices() {
return mServices;
}
@@ -830,6 +838,7 @@
* this device.
*/
@RequiresLegacyBluetoothPermission
+ @RequiresNoPermission
public BluetoothGattService getService(UUID uuid) {
for (BluetoothGattService service : mServices) {
if (service.getUuid().equals(uuid)) {
@@ -848,6 +857,7 @@
* @throws UnsupportedOperationException
*/
@Override
+ @RequiresNoPermission
public int getConnectionState(BluetoothDevice device) {
throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead.");
}
@@ -859,6 +869,7 @@
* @throws UnsupportedOperationException
*/
@Override
+ @RequiresNoPermission
public List<BluetoothDevice> getConnectedDevices() {
throw new UnsupportedOperationException(
"Use BluetoothManager#getConnectedDevices instead.");
@@ -872,6 +883,7 @@
* @throws UnsupportedOperationException
*/
@Override
+ @RequiresNoPermission
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
throw new UnsupportedOperationException(
"Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 84e8c51..a1ece7f 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -21,6 +21,7 @@
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
+import android.annotation.SuppressLint;
import android.annotation.SdkConstant.SdkConstantType;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
@@ -339,6 +340,7 @@
private volatile IBluetoothHeadset mService;
private BluetoothAdapter mAdapter;
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
@@ -509,6 +511,7 @@
* {@inheritDoc}
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
@@ -529,6 +532,7 @@
* {@inheritDoc}
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
@@ -549,6 +553,7 @@
* {@inheritDoc}
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getConnectionState(" + device + ")");
@@ -620,6 +625,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -858,6 +864,7 @@
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getAudioState(BluetoothDevice device) {
if (VDBG) log("getAudioState");
@@ -885,6 +892,7 @@
* @param allowed {@code true} if the profile can reroute audio, {@code false} otherwise.
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void setAudioRouteAllowed(boolean allowed) {
if (VDBG) log("setAudioRouteAllowed");
@@ -907,6 +915,7 @@
*
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean getAudioRouteAllowed() {
if (VDBG) log("getAudioRouteAllowed");
@@ -931,6 +940,7 @@
* False to use SCO audio in normal manner
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void setForceScoAudio(boolean forced) {
if (VDBG) log("setForceScoAudio " + String.valueOf(forced));
@@ -991,6 +1001,7 @@
* @hide
*/
@UnsupportedAppUsage
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean connectAudio() {
final IBluetoothHeadset service = mService;
@@ -1019,6 +1030,7 @@
* @hide
*/
@UnsupportedAppUsage
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean disconnectAudio() {
final IBluetoothHeadset service = mService;
@@ -1123,6 +1135,7 @@
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.MODIFY_PHONE_STATE,
@@ -1147,6 +1160,7 @@
*
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.MODIFY_PHONE_STATE,
@@ -1320,6 +1334,7 @@
com.android.internal.R.bool.config_bluetooth_hfp_inband_ringing_support);
}
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private final IBluetoothProfileServiceConnection mConnection =
new IBluetoothProfileServiceConnection.Stub() {
@Override
@@ -1356,6 +1371,7 @@
Log.d(TAG, msg);
}
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index 092130d..eef42d1 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -16,7 +16,6 @@
package android.bluetooth;
-import android.Manifest;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
@@ -449,6 +448,7 @@
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
@@ -476,6 +476,7 @@
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
@@ -499,6 +500,7 @@
* @return list of connected devices; empty list if nothing is connected.
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
@@ -524,6 +526,7 @@
* list if nothing matches the <code>states</code>
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
@@ -548,6 +551,7 @@
* @return the state of connection of the device
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getConnectionState(" + device + ")");
@@ -576,6 +580,7 @@
* @return true if priority is set, false on error
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
@@ -594,6 +599,7 @@
* @return true if connectionPolicy is set, false on error
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
@ConnectionPolicy int connectionPolicy) {
@@ -675,6 +681,7 @@
* #EXTRA_AG_FEATURE_VOICE_RECOGNITION}. This method invocation will fail silently when feature
* is not supported.</p>
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean startVoiceRecognition(BluetoothDevice device) {
if (DBG) log("startVoiceRecognition()");
@@ -700,6 +707,7 @@
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise.
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean sendVendorAtCommand(BluetoothDevice device, int vendorId,
String atCommand) {
@@ -728,6 +736,7 @@
* #EXTRA_AG_FEATURE_VOICE_RECOGNITION}. This method invocation will fail silently when feature
* is not supported.</p>
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean stopVoiceRecognition(BluetoothDevice device) {
if (DBG) log("stopVoiceRecognition()");
@@ -750,6 +759,7 @@
* @param device remote device
* @return list of calls; empty list if none call exists
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothHeadsetClientCall> getCurrentCalls(BluetoothDevice device) {
if (DBG) log("getCurrentCalls()");
@@ -772,6 +782,7 @@
* @param device remote device
* @return bundle of AG indicators; null if device is not in CONNECTED state
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public Bundle getCurrentAgEvents(BluetoothDevice device) {
if (DBG) log("getCurrentCalls()");
@@ -798,6 +809,7 @@
* otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean acceptCall(BluetoothDevice device, int flag) {
if (DBG) log("acceptCall()");
@@ -821,6 +833,7 @@
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_CALL_CHANGED} intent.
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean holdCall(BluetoothDevice device) {
if (DBG) log("holdCall()");
@@ -849,6 +862,7 @@
* supported.</p>
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean rejectCall(BluetoothDevice device) {
if (DBG) log("rejectCall()");
@@ -881,6 +895,7 @@
* #EXTRA_AG_FEATURE_ECC}. This method invocation will fail silently when feature is not
* supported.</p>
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean terminateCall(BluetoothDevice device, BluetoothHeadsetClientCall call) {
if (DBG) log("terminateCall()");
@@ -911,6 +926,7 @@
* #EXTRA_AG_FEATURE_ECC}. This method invocation will fail silently when feature is not
* supported.</p>
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean enterPrivateMode(BluetoothDevice device, int index) {
if (DBG) log("enterPrivateMode()");
@@ -940,6 +956,7 @@
* #EXTRA_AG_FEATURE_MERGE_AND_DETACH}. This method invocation will fail silently when feature
* is not supported.</p>
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean explicitCallTransfer(BluetoothDevice device) {
if (DBG) log("explicitCallTransfer()");
@@ -965,6 +982,7 @@
* successfully; <code>{@link null}</code> otherwise; upon completion HFP sends {@link
* #ACTION_CALL_CHANGED} intent in case of success; {@link #ACTION_RESULT} is sent otherwise;
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothHeadsetClientCall dial(BluetoothDevice device, String number) {
if (DBG) log("dial()");
@@ -991,6 +1009,7 @@
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_RESULT} intent;
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean sendDTMF(BluetoothDevice device, byte code) {
if (DBG) log("sendDTMF()");
@@ -1019,6 +1038,8 @@
* #EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT}. This method invocation will fail silently when
* feature is not supported.</p>
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean getLastVoiceTagNumber(BluetoothDevice device) {
if (DBG) log("getLastVoiceTagNumber()");
final IBluetoothHeadsetClient service =
@@ -1040,6 +1061,8 @@
* Note: This is an internal function and shouldn't be exposed
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getAudioState(BluetoothDevice device) {
if (VDBG) log("getAudioState");
final IBluetoothHeadsetClient service =
@@ -1064,6 +1087,8 @@
* @param allowed if routing is allowed to the device Note: This is an internal function and
* shouldn't be exposed
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void setAudioRouteAllowed(BluetoothDevice device, boolean allowed) {
if (VDBG) log("setAudioRouteAllowed");
final IBluetoothHeadsetClient service =
@@ -1087,6 +1112,8 @@
* @return whether the command succeeded Note: This is an internal function and shouldn't be
* exposed
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean getAudioRouteAllowed(BluetoothDevice device) {
if (VDBG) log("getAudioRouteAllowed");
final IBluetoothHeadsetClient service =
@@ -1113,6 +1140,7 @@
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED} intent;
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean connectAudio(BluetoothDevice device) {
final IBluetoothHeadsetClient service =
@@ -1139,6 +1167,7 @@
* @return <code>true</code> if command has been issued successfully; <code>false</code>
* otherwise; upon completion HFP sends {@link #ACTION_AUDIO_STATE_CHANGED} intent;
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean disconnectAudio(BluetoothDevice device) {
final IBluetoothHeadsetClient service =
@@ -1162,6 +1191,7 @@
* @param device remote device
* @return bundle of AG features; null if no service or AG not connected
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public Bundle getCurrentAgFeatures(BluetoothDevice device) {
final IBluetoothHeadsetClient service =
diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java
index 8ceeff5..fa52eda 100644
--- a/core/java/android/bluetooth/BluetoothHearingAid.java
+++ b/core/java/android/bluetooth/BluetoothHearingAid.java
@@ -21,6 +21,7 @@
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
+import android.annotation.SuppressLint;
import android.annotation.SdkConstant.SdkConstantType;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
@@ -170,6 +171,7 @@
* @return false on immediate error, true otherwise
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -231,6 +233,7 @@
* {@inheritDoc}
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public @NonNull List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
@@ -251,6 +254,7 @@
* {@inheritDoc}
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public @NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(
@NonNull int[] states) {
@@ -272,6 +276,7 @@
* {@inheritDoc}
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public @BluetoothProfile.BtProfileState int getConnectionState(
@NonNull BluetoothDevice device) {
@@ -368,6 +373,7 @@
* @return true if priority is set, false on error
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -390,6 +396,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -490,6 +497,8 @@
* @param volume Absolute volume to be set on remote
* @hide
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void setVolume(int volume) {
if (DBG) Log.d(TAG, "setVolume(" + volume + ")");
@@ -549,6 +558,8 @@
* @hide
*/
@RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getDeviceSide(BluetoothDevice device) {
if (VDBG) {
log("getDeviceSide(" + device + ")");
@@ -575,6 +586,8 @@
* @hide
*/
@RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getDeviceMode(BluetoothDevice device) {
if (VDBG) {
log("getDeviceMode(" + device + ")");
diff --git a/core/java/android/bluetooth/BluetoothHidDevice.java b/core/java/android/bluetooth/BluetoothHidDevice.java
index c214d2b..6565ec0 100644
--- a/core/java/android/bluetooth/BluetoothHidDevice.java
+++ b/core/java/android/bluetooth/BluetoothHidDevice.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
+import android.annotation.SuppressLint;
import android.annotation.SdkConstant.SdkConstantType;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
@@ -439,6 +440,7 @@
/** {@inheritDoc} */
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getConnectedDevices() {
final IBluetoothHidDevice service = getService();
@@ -457,6 +459,7 @@
/** {@inheritDoc} */
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
final IBluetoothHidDevice service = getService();
@@ -475,6 +478,7 @@
/** {@inheritDoc} */
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public int getConnectionState(BluetoothDevice device) {
final IBluetoothHidDevice service = getService();
@@ -514,6 +518,7 @@
* object is required.
* @return true if the command is successfully sent; otherwise false.
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean registerApp(
BluetoothHidDeviceAppSdpSettings sdp,
@@ -560,6 +565,7 @@
*
* @return true if the command is successfully sent; otherwise false.
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean unregisterApp() {
boolean result = false;
@@ -586,6 +592,7 @@
* @param data Report data, not including Report Id.
* @return true if the command is successfully sent; otherwise false.
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean sendReport(BluetoothDevice device, int id, byte[] data) {
boolean result = false;
@@ -613,6 +620,7 @@
* @param data Report data, not including Report Id.
* @return true if the command is successfully sent; otherwise false.
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean replyReport(BluetoothDevice device, byte type, byte id, byte[] data) {
boolean result = false;
@@ -638,6 +646,7 @@
* @param error Error to be sent for SET_REPORT via HANDSHAKE.
* @return true if the command is successfully sent; otherwise false.
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean reportError(BluetoothDevice device, byte error) {
boolean result = false;
@@ -662,6 +671,7 @@
* @return the current user name, or empty string if cannot get the name
* {@hide}
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public String getUserAppName() {
final IBluetoothHidDevice service = getService();
@@ -687,6 +697,7 @@
*
* @return true if the command is successfully sent; otherwise false.
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean connect(BluetoothDevice device) {
boolean result = false;
@@ -712,6 +723,7 @@
*
* @return true if the command is successfully sent; otherwise false.
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean disconnect(BluetoothDevice device) {
boolean result = false;
@@ -748,6 +760,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
diff --git a/core/java/android/bluetooth/BluetoothHidHost.java b/core/java/android/bluetooth/BluetoothHidHost.java
index 70e3809..bef4472 100644
--- a/core/java/android/bluetooth/BluetoothHidHost.java
+++ b/core/java/android/bluetooth/BluetoothHidHost.java
@@ -331,6 +331,7 @@
*/
@SystemApi
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public @NonNull List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
@@ -353,6 +354,7 @@
* @hide
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
@@ -376,6 +378,7 @@
*/
@SystemApi
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public int getConnectionState(@NonNull BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
diff --git a/core/java/android/bluetooth/BluetoothInputStream.java b/core/java/android/bluetooth/BluetoothInputStream.java
index 8eb79b2..95f9229 100644
--- a/core/java/android/bluetooth/BluetoothInputStream.java
+++ b/core/java/android/bluetooth/BluetoothInputStream.java
@@ -16,6 +16,8 @@
package android.bluetooth;
+import android.annotation.SuppressLint;
+
import java.io.IOException;
import java.io.InputStream;
@@ -26,6 +28,7 @@
*
* @hide
*/
+@SuppressLint("AndroidFrameworkBluetoothPermission")
/*package*/ final class BluetoothInputStream extends InputStream {
private BluetoothSocket mSocket;
diff --git a/core/java/android/bluetooth/BluetoothLeAudio.java b/core/java/android/bluetooth/BluetoothLeAudio.java
index 4f095f6..462c7b7 100644
--- a/core/java/android/bluetooth/BluetoothLeAudio.java
+++ b/core/java/android/bluetooth/BluetoothLeAudio.java
@@ -155,6 +155,7 @@
* @return false on immediate error, true otherwise
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean connect(@Nullable BluetoothDevice device) {
if (DBG) log("connect(" + device + ")");
@@ -194,6 +195,7 @@
* @return false on immediate error, true otherwise
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean disconnect(@Nullable BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
@@ -214,6 +216,7 @@
* {@inheritDoc}
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public @NonNull List<BluetoothDevice> getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
@@ -234,6 +237,7 @@
* {@inheritDoc}
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public @NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(
@NonNull int[] states) {
@@ -294,6 +298,7 @@
* @return false on immediate error, true otherwise
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean setActiveDevice(@Nullable BluetoothDevice device) {
if (DBG) log("setActiveDevice(" + device + ")");
@@ -320,6 +325,8 @@
*/
@NonNull
@RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getActiveDevices() {
if (VDBG) log("getActiveDevices()");
try {
@@ -343,6 +350,8 @@
* @hide
*/
@RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getGroupId(@NonNull BluetoothDevice device) {
if (VDBG) log("getGroupId()");
try {
@@ -370,6 +379,7 @@
* @return true if connectionPolicy is set, false on error
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -406,6 +416,7 @@
* @return connection policy of the device
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public @ConnectionPolicy int getConnectionPolicy(@Nullable BluetoothDevice device) {
if (VDBG) log("getConnectionPolicy(" + device + ")");
diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java
index a1e1b63..2374f1c 100644
--- a/core/java/android/bluetooth/BluetoothManager.java
+++ b/core/java/android/bluetooth/BluetoothManager.java
@@ -18,7 +18,9 @@
import android.Manifest;
import android.annotation.RequiresFeature;
+import android.annotation.RequiresNoPermission;
import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
import android.annotation.SystemService;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
@@ -93,6 +95,7 @@
*
* @return the BLUETOOTH Adapter
*/
+ @RequiresNoPermission
public BluetoothAdapter getAdapter() {
return mAdapter;
}
@@ -218,6 +221,7 @@
* @param callback GATT server callback handler that will receive asynchronous callbacks.
* @return BluetoothGattServer instance
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothGattServer openGattServer(Context context,
BluetoothGattServerCallback callback) {
@@ -238,6 +242,7 @@
* @return BluetoothGattServer instance
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothGattServer openGattServer(Context context,
BluetoothGattServerCallback callback, boolean eatt_support) {
@@ -259,6 +264,7 @@
* @return BluetoothGattServer instance
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothGattServer openGattServer(Context context,
BluetoothGattServerCallback callback, int transport) {
@@ -281,6 +287,7 @@
* @return BluetoothGattServer instance
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothGattServer openGattServer(Context context,
BluetoothGattServerCallback callback, int transport, boolean eatt_support) {
diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java
index 3e7b75a..998fde0 100644
--- a/core/java/android/bluetooth/BluetoothMap.java
+++ b/core/java/android/bluetooth/BluetoothMap.java
@@ -18,9 +18,11 @@
import android.Manifest;
import android.annotation.NonNull;
+import android.annotation.RequiresNoPermission;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
+import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Binder;
@@ -126,6 +128,7 @@
*
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getState() {
if (VDBG) log("getState()");
@@ -151,6 +154,7 @@
*
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothDevice getClient() {
if (VDBG) log("getClient()");
@@ -175,6 +179,7 @@
*
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean isConnected(BluetoothDevice device) {
if (VDBG) log("isConnected(" + device + ")");
@@ -198,6 +203,7 @@
*
* @hide
*/
+ @RequiresNoPermission
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")" + "not supported for MAPS");
return false;
@@ -212,6 +218,7 @@
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
@@ -259,6 +266,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -285,6 +293,7 @@
*
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (DBG) log("getDevicesMatchingStates()");
@@ -308,6 +317,7 @@
*
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public int getConnectionState(BluetoothDevice device) {
if (DBG) log("getConnectionState(" + device + ")");
@@ -335,6 +345,7 @@
* @return true if priority is set, false on error
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -357,6 +368,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -391,6 +403,7 @@
* @return priority of the device
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -412,6 +425,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java
index db74a90..f20b533 100644
--- a/core/java/android/bluetooth/BluetoothMapClient.java
+++ b/core/java/android/bluetooth/BluetoothMapClient.java
@@ -20,8 +20,10 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.app.PendingIntent;
+import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.net.Uri;
@@ -192,6 +194,7 @@
* currently connected to the Map service.
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean isConnected(BluetoothDevice device) {
if (VDBG) Log.d(TAG, "isConnected(" + device + ")");
@@ -215,6 +218,7 @@
*
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -243,6 +247,7 @@
*
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -268,6 +273,7 @@
* @hide
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getConnectedDevices() {
if (DBG) Log.d(TAG, "getConnectedDevices()");
@@ -291,6 +297,7 @@
* @hide
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (DBG) Log.d(TAG, "getDevicesMatchingStates()");
@@ -314,6 +321,7 @@
* @hide
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public int getConnectionState(BluetoothDevice device) {
if (DBG) Log.d(TAG, "getConnectionState(" + device + ")");
@@ -341,6 +349,7 @@
* @return true if priority is set, false on error
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -362,6 +371,7 @@
* @return true if connectionPolicy is set, false on error
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -396,6 +406,7 @@
* @return priority of the device
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -416,6 +427,7 @@
* @return connection policy of the device
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -449,6 +461,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.SEND_SMS,
@@ -484,6 +497,7 @@
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.SEND_SMS,
@@ -510,6 +524,7 @@
* @return true if the message is enqueued, false on error
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.READ_SMS,
@@ -536,6 +551,7 @@
* MapSupportedFeatures field is set. False is returned otherwise.
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean isUploadingSupported(BluetoothDevice device) {
final IBluetoothMapClient service = getService();
@@ -564,6 +580,7 @@
* @return <code>true</code> if request has been sent, <code>false</code> on error
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.READ_SMS,
diff --git a/core/java/android/bluetooth/BluetoothOutputStream.java b/core/java/android/bluetooth/BluetoothOutputStream.java
index a0aa2de..ac2b3ed 100644
--- a/core/java/android/bluetooth/BluetoothOutputStream.java
+++ b/core/java/android/bluetooth/BluetoothOutputStream.java
@@ -16,6 +16,8 @@
package android.bluetooth;
+import android.annotation.SuppressLint;
+
import java.io.IOException;
import java.io.OutputStream;
@@ -26,6 +28,7 @@
*
* @hide
*/
+@SuppressLint("AndroidFrameworkBluetoothPermission")
/*package*/ final class BluetoothOutputStream extends OutputStream {
private BluetoothSocket mSocket;
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index b3924b1f..c41c9de 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -240,6 +240,7 @@
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -282,6 +283,7 @@
* @hide
*/
@UnsupportedAppUsage
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
@@ -311,6 +313,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -342,6 +345,7 @@
*/
@SystemApi
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -416,6 +420,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -441,6 +446,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean isTetheringOn() {
if (VDBG) log("isTetheringOn()");
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index 6c2e5bf..e41eb4f 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -110,6 +110,7 @@
*/
public static final int RESULT_CANCELED = 2;
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
@@ -217,6 +218,7 @@
* @hide
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getConnectedDevices() {
log("getConnectedDevices()");
@@ -264,6 +266,7 @@
* @hide
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
log("getDevicesMatchingConnectionStates: states=" + Arrays.toString(states));
@@ -297,6 +300,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -330,6 +334,7 @@
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean disconnect(BluetoothDevice device) {
log("disconnect()");
@@ -347,6 +352,7 @@
return false;
}
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
log("Proxy object connected");
diff --git a/core/java/android/bluetooth/BluetoothPbapClient.java b/core/java/android/bluetooth/BluetoothPbapClient.java
index 2c8fbc2..85b8650 100644
--- a/core/java/android/bluetooth/BluetoothPbapClient.java
+++ b/core/java/android/bluetooth/BluetoothPbapClient.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
+import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
@@ -161,6 +162,7 @@
* @return list of connected devices
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getConnectedDevices() {
if (DBG) {
@@ -187,6 +189,7 @@
* @return list of matching devices
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (DBG) {
@@ -213,6 +216,7 @@
* @return device connection state
*/
@Override
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public int getConnectionState(BluetoothDevice device) {
if (DBG) {
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index 70053ee..161c843 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -17,6 +17,7 @@
package android.bluetooth;
import android.annotation.IntDef;
+import android.annotation.RequiresNoPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
@@ -333,6 +334,7 @@
* @param profile - One of {@link #HEADSET} or {@link #A2DP}
* @param proxy - One of {@link BluetoothHeadset} or {@link BluetoothA2dp}
*/
+ @RequiresNoPermission
public void onServiceConnected(int profile, BluetoothProfile proxy);
/**
@@ -341,6 +343,7 @@
*
* @param profile - One of {@link #HEADSET} or {@link #A2DP}
*/
+ @RequiresNoPermission
public void onServiceDisconnected(int profile);
}
diff --git a/core/java/android/bluetooth/BluetoothProfileConnector.java b/core/java/android/bluetooth/BluetoothProfileConnector.java
index 12abcc4..b20ab75 100644
--- a/core/java/android/bluetooth/BluetoothProfileConnector.java
+++ b/core/java/android/bluetooth/BluetoothProfileConnector.java
@@ -16,7 +16,6 @@
package android.bluetooth;
-import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Context;
@@ -33,6 +32,7 @@
* @param <T> The Bluetooth profile interface for this connection.
* @hide
*/
+@SuppressLint("AndroidFrameworkBluetoothPermission")
public abstract class BluetoothProfileConnector<T> {
private final int mProfileId;
private BluetoothProfile.ServiceListener mServiceListener;
diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java
index c85494c..87da22c 100644
--- a/core/java/android/bluetooth/BluetoothSap.java
+++ b/core/java/android/bluetooth/BluetoothSap.java
@@ -17,6 +17,7 @@
package android.bluetooth;
import android.Manifest;
+import android.annotation.RequiresNoPermission;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
@@ -143,6 +144,7 @@
* connected to the Sap service.
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getState() {
if (VDBG) log("getState()");
@@ -167,6 +169,7 @@
* this proxy object is not connected to the Sap service.
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothDevice getClient() {
if (VDBG) log("getClient()");
@@ -191,6 +194,7 @@
*
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean isConnected(BluetoothDevice device) {
if (VDBG) log("isConnected(" + device + ")");
@@ -214,6 +218,7 @@
*
* @hide
*/
+ @RequiresNoPermission
public boolean connect(BluetoothDevice device) {
if (DBG) log("connect(" + device + ")" + "not supported for SAPS");
return false;
@@ -227,6 +232,7 @@
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean disconnect(BluetoothDevice device) {
if (DBG) log("disconnect(" + device + ")");
@@ -249,6 +255,7 @@
* @return list of connected devices
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getConnectedDevices() {
if (DBG) log("getConnectedDevices()");
@@ -271,6 +278,7 @@
* @return list of matching devices
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
if (DBG) log("getDevicesMatchingStates()");
@@ -293,6 +301,7 @@
* @return device connection state
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
public int getConnectionState(BluetoothDevice device) {
if (DBG) log("getConnectionState(" + device + ")");
@@ -320,6 +329,7 @@
* @return true if priority is set, false on error
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -341,6 +351,7 @@
* @return true if connectionPolicy is set, false on error
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -375,6 +386,7 @@
* @return priority of the device
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -395,6 +407,7 @@
* @return connection policy of the device
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index 5082235..bb4e354 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.SuppressLint;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Handler;
import android.os.ParcelUuid;
@@ -70,6 +71,7 @@
*
* {@see BluetoothSocket}
*/
+@SuppressLint("AndroidFrameworkBluetoothPermission")
public final class BluetoothServerSocket implements Closeable {
private static final String TAG = "BluetoothServerSocket";
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index ef88147..bb409d5 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -16,8 +16,10 @@
package android.bluetooth;
+import android.annotation.RequiresNoPermission;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
+import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.compat.annotation.UnsupportedAppUsage;
import android.net.LocalSocket;
import android.os.Build;
@@ -198,7 +200,6 @@
* @throws IOException On error, for example Bluetooth not available, or insufficient
* privileges
*/
- @SuppressLint("AndroidFrameworkRequiresPermission")
/*package*/ BluetoothSocket(int type, int fd, boolean auth, boolean encrypt,
BluetoothDevice device, int port, ParcelUuid uuid, boolean mitm, boolean min16DigitPin)
throws IOException {
@@ -326,6 +327,7 @@
*
* @return remote device
*/
+ @RequiresNoPermission
public BluetoothDevice getRemoteDevice() {
return mDevice;
}
@@ -338,6 +340,7 @@
*
* @return InputStream
*/
+ @RequiresNoPermission
public InputStream getInputStream() throws IOException {
return mInputStream;
}
@@ -350,6 +353,7 @@
*
* @return OutputStream
*/
+ @RequiresNoPermission
public OutputStream getOutputStream() throws IOException {
return mOutputStream;
}
@@ -360,6 +364,7 @@
*
* @return true if connected false if not connected
*/
+ @RequiresNoPermission
public boolean isConnected() {
return mSocketState == SocketState.CONNECTED;
}
@@ -386,6 +391,7 @@
*
* @throws IOException on error, for example connection failure
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void connect() throws IOException {
if (mDevice == null) throw new IOException("Connect is called on null device");
@@ -637,6 +643,7 @@
*
* @return the maximum supported Transmit packet size for the underlying transport.
*/
+ @RequiresNoPermission
public int getMaxTransmitPacketSize() {
return mMaxTxPacketSize;
}
@@ -649,6 +656,7 @@
*
* @return the maximum supported Receive packet size for the underlying transport.
*/
+ @RequiresNoPermission
public int getMaxReceivePacketSize() {
return mMaxRxPacketSize;
}
@@ -658,6 +666,7 @@
*
* @return one of {@link #TYPE_RFCOMM}, {@link #TYPE_SCO} or {@link #TYPE_L2CAP}
*/
+ @RequiresNoPermission
public int getConnectionType() {
if (mType == TYPE_L2CAP_LE) {
// Treat the LE CoC to be the same type as L2CAP.
@@ -674,6 +683,7 @@
* generate SPP SDP record.
* @hide
*/
+ @RequiresNoPermission
public void setExcludeSdp(boolean excludeSdp) {
mExcludeSdp = excludeSdp;
}
@@ -684,6 +694,7 @@
* connection. This function is currently used for testing only.
* @hide
*/
+ @RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void requestMaximumTxDataLength() throws IOException {
if (mDevice == null) {
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index d82cf19..bc3754a 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.ParcelUuid;
@@ -34,6 +35,7 @@
* @hide
*/
@SystemApi
+@SuppressLint("AndroidFrameworkBluetoothPermission")
public final class BluetoothUuid {
/* See Bluetooth Assigned Numbers document - SDP section, to get the values of UUIDs
diff --git a/core/java/android/bluetooth/le/AdvertisingSet.java b/core/java/android/bluetooth/le/AdvertisingSet.java
index 54a18e6..d7e48ca 100644
--- a/core/java/android/bluetooth/le/AdvertisingSet.java
+++ b/core/java/android/bluetooth/le/AdvertisingSet.java
@@ -16,7 +16,9 @@
package android.bluetooth.le;
+import android.annotation.RequiresNoPermission;
import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothManager;
@@ -216,6 +218,7 @@
*
* @hide
*/
+ @RequiresNoPermission
public int getAdvertiserId() {
return mAdvertiserId;
}
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index de11869..ff279d8 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -16,6 +16,7 @@
package android.bluetooth.le;
+import android.annotation.RequiresNoPermission;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
@@ -89,10 +90,7 @@
*/
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothAdvertisePermission
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_ADVERTISE,
- android.Manifest.permission.BLUETOOTH_CONNECT,
- })
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
public void startAdvertising(AdvertiseSettings settings,
AdvertiseData advertiseData, final AdvertiseCallback callback) {
startAdvertising(settings, advertiseData, null, callback);
@@ -111,10 +109,7 @@
*/
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothAdvertisePermission
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_ADVERTISE,
- android.Manifest.permission.BLUETOOTH_CONNECT,
- })
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
public void startAdvertising(AdvertiseSettings settings,
AdvertiseData advertiseData, AdvertiseData scanResponse,
final AdvertiseCallback callback) {
@@ -169,11 +164,13 @@
}
}
- @SuppressLint("AndroidFrameworkRequiresPermission")
+ @SuppressLint({
+ "AndroidFrameworkBluetoothPermission",
+ "AndroidFrameworkRequiresPermission",
+ })
AdvertisingSetCallback wrapOldCallback(AdvertiseCallback callback, AdvertiseSettings settings) {
return new AdvertisingSetCallback() {
@Override
- @SuppressLint("AndroidFrameworkRequiresPermission")
public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower,
int status) {
if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) {
@@ -186,7 +183,6 @@
/* Legacy advertiser is disabled on timeout */
@Override
- @SuppressLint("AndroidFrameworkRequiresPermission")
public void onAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enabled,
int status) {
if (enabled) {
@@ -247,10 +243,7 @@
*/
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothAdvertisePermission
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_ADVERTISE,
- android.Manifest.permission.BLUETOOTH_CONNECT,
- })
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
public void startAdvertisingSet(AdvertisingSetParameters parameters,
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
@@ -283,10 +276,7 @@
*/
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothAdvertisePermission
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_ADVERTISE,
- android.Manifest.permission.BLUETOOTH_CONNECT,
- })
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
public void startAdvertisingSet(AdvertisingSetParameters parameters,
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
@@ -324,10 +314,7 @@
*/
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothAdvertisePermission
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_ADVERTISE,
- android.Manifest.permission.BLUETOOTH_CONNECT,
- })
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
public void startAdvertisingSet(AdvertisingSetParameters parameters,
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
@@ -370,10 +357,7 @@
*/
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothAdvertisePermission
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_ADVERTISE,
- android.Manifest.permission.BLUETOOTH_CONNECT,
- })
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
public void startAdvertisingSet(AdvertisingSetParameters parameters,
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
@@ -509,6 +493,7 @@
*
* @hide
*/
+ @RequiresNoPermission
public void cleanup() {
mLegacyAdvertisers.clear();
mCallbackWrappers.clear();
@@ -516,7 +501,8 @@
}
// Compute the size of advertisement data or scan resp
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @RequiresBluetoothAdvertisePermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
private int totalBytes(AdvertiseData data, boolean isFlagsIncluded) {
if (data == null) return 0;
// Flags field is omitted if the advertising is not connectable.
@@ -587,8 +573,11 @@
if (data.getIncludeTxPowerLevel()) {
size += OVERHEAD_BYTES_PER_FIELD + 1; // tx power level value is one byte.
}
- if (data.getIncludeDeviceName() && mBluetoothAdapter.getName() != null) {
- size += OVERHEAD_BYTES_PER_FIELD + mBluetoothAdapter.getName().length();
+ if (data.getIncludeDeviceName()) {
+ final int length = mBluetoothAdapter.getNameLengthForAdvertise();
+ if (length >= 0) {
+ size += OVERHEAD_BYTES_PER_FIELD + length;
+ }
}
return size;
}
@@ -597,6 +586,7 @@
return array == null ? 0 : array.length;
}
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
IAdvertisingSetCallback wrap(AdvertisingSetCallback callback, Handler handler) {
return new IAdvertisingSetCallback.Stub() {
@Override
@@ -721,6 +711,7 @@
};
}
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private void postStartSetFailure(Handler handler, final AdvertisingSetCallback callback,
final int error) {
handler.post(new Runnable() {
@@ -731,6 +722,7 @@
});
}
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private void postStartFailure(final AdvertiseCallback callback, final int error) {
mHandler.post(new Runnable() {
@Override
@@ -740,6 +732,7 @@
});
}
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private void postStartSuccess(final AdvertiseCallback callback,
final AdvertiseSettings settings) {
mHandler.post(new Runnable() {
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 4271a90..f27f22b 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -16,9 +16,9 @@
package android.bluetooth.le;
-import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresNoPermission;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
@@ -357,6 +357,7 @@
* @hide
*/
@SystemApi
+ @RequiresBluetoothScanPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
public void startTruncatedScan(List<TruncatedFilter> truncatedFilters, ScanSettings settings,
final ScanCallback callback) {
@@ -376,6 +377,7 @@
*
* @hide
*/
+ @RequiresNoPermission
public void cleanup() {
mLeScanClients.clear();
}
@@ -383,6 +385,7 @@
/**
* Bluetooth GATT interface callbacks
*/
+ @SuppressLint("AndroidFrameworkRequiresPermission")
private class BleScanCallbackWrapper extends IScannerCallback.Stub {
private static final int REGISTRATION_CALLBACK_TIMEOUT_MILLIS = 2000;
@@ -412,8 +415,6 @@
mResultStorages = resultStorages;
}
- @SuppressLint("AndroidFrameworkRequiresPermission")
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
public void startRegistration() {
synchronized (this) {
// Scan stopped.
@@ -441,7 +442,6 @@
}
}
- @SuppressLint("AndroidFrameworkRequiresPermission")
@RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
public void stopLeScan() {
synchronized (this) {
@@ -459,7 +459,6 @@
}
}
- @SuppressLint("AndroidFrameworkRequiresPermission")
@RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
void flushPendingBatchResults() {
synchronized (this) {
@@ -479,7 +478,6 @@
* Application interface registered - app is ready to go
*/
@Override
- @SuppressLint("AndroidFrameworkRequiresPermission")
public void onScannerRegistered(int status, int scannerId) {
Log.d(TAG, "onScannerRegistered() - status=" + status
+ " scannerId=" + scannerId + " mScannerId=" + mScannerId);
@@ -592,6 +590,7 @@
}
}
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private void postCallbackError(final ScanCallback callback, final int errorCode) {
mHandler.post(new Runnable() {
@Override
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java b/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
index 9ea6c48..26978e3 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
@@ -17,6 +17,7 @@
package android.bluetooth.le;
import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.IBluetoothGatt;
@@ -208,6 +209,7 @@
}
}
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private IPeriodicAdvertisingCallback wrap(PeriodicAdvertisingCallback callback,
Handler handler) {
return new IPeriodicAdvertisingCallback.Stub() {
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index 27c579b..c5c4277 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -16,7 +16,6 @@
package android.bluetooth.le;
-import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
diff --git a/core/java/android/bluetooth/le/ScanRecord.java b/core/java/android/bluetooth/le/ScanRecord.java
index 794b512..9b8c2ea 100644
--- a/core/java/android/bluetooth/le/ScanRecord.java
+++ b/core/java/android/bluetooth/le/ScanRecord.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.bluetooth.BluetoothUuid;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.ParcelUuid;
@@ -34,6 +35,7 @@
/**
* Represents a scan record from Bluetooth LE scan.
*/
+@SuppressLint("AndroidFrameworkBluetoothPermission")
public final class ScanRecord {
private static final String TAG = "ScanRecord";
diff --git a/core/java/android/bluetooth/le/TruncatedFilter.java b/core/java/android/bluetooth/le/TruncatedFilter.java
index a753aa6..93f526b 100644
--- a/core/java/android/bluetooth/le/TruncatedFilter.java
+++ b/core/java/android/bluetooth/le/TruncatedFilter.java
@@ -16,6 +16,7 @@
package android.bluetooth.le;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import java.util.List;
@@ -26,6 +27,7 @@
* @hide
*/
@SystemApi
+@SuppressLint("AndroidFrameworkBluetoothPermission")
public final class TruncatedFilter {
private final ScanFilter mFilter;
private final List<ResultStorageDescriptor> mStorageDescriptors;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 318913f..a88c9ed 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4705,10 +4705,9 @@
* @hide
* @see #getSystemService(String)
*/
- // TODO(b/176208267): change it back to translation before S release.
@SystemApi
@SuppressLint("ServiceName")
- public static final String TRANSLATION_MANAGER_SERVICE = "transformer";
+ public static final String TRANSLATION_MANAGER_SERVICE = "translation";
/**
* Official published name of the translation service which supports ui translation function.
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 6ad204e..9934b2a 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -2130,6 +2130,7 @@
*
* @hide
*/
+ @SuppressWarnings("AutoBoxing")
@SystemApi
@Nullable
public Boolean hasRequestRawExternalStorageAccess() {
diff --git a/core/java/android/content/pm/DataLoaderParams.java b/core/java/android/content/pm/DataLoaderParams.java
index f808cfd..a6d3b45 100644
--- a/core/java/android/content/pm/DataLoaderParams.java
+++ b/core/java/android/content/pm/DataLoaderParams.java
@@ -24,7 +24,9 @@
* This class represents the parameters used to configure a DataLoader.
*
* {@see android.service.dataloader.DataLoaderService.DataLoader}
+ * @hide
*/
+@SystemApi
public class DataLoaderParams {
@NonNull
private final DataLoaderParamsParcel mData;
diff --git a/core/java/android/content/pm/InstallationFile.java b/core/java/android/content/pm/InstallationFile.java
index e764020..7e07c45 100644
--- a/core/java/android/content/pm/InstallationFile.java
+++ b/core/java/android/content/pm/InstallationFile.java
@@ -18,16 +18,18 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
/**
* Definition of a file in a streaming installation session.
* You can use this class to retrieve the information of such a file, such as its name, size and
* metadata. These file attributes will be consistent with those used in:
- * {@code android.content.pm.PackageInstaller.Session#addFile}, when the file was first added
- * into the session.
+ * {@code PackageInstaller.Session#addFile}, when the file was first added into the session.
*
* @see android.content.pm.PackageInstaller.Session#addFile
+ * @hide
*/
+@SystemApi
public final class InstallationFile {
private final @NonNull InstallationFileParcel mParcel;
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 8b380b7..5157e08 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -229,12 +229,15 @@
/**
* Type of DataLoader for this session. Will be one of
- * {@link #DATA_LOADER_TYPE_NONE}, {@link #DATA_LOADER_TYPE_STREAMING}.
+ * {@link #DATA_LOADER_TYPE_NONE}, {@link #DATA_LOADER_TYPE_STREAMING},
+ * {@link #DATA_LOADER_TYPE_INCREMENTAL}.
* <p>
* See the individual types documentation for details.
*
* @see Intent#getIntExtra(String, int)
+ * {@hide}
*/
+ @SystemApi
public static final String EXTRA_DATA_LOADER_TYPE = "android.content.pm.extra.DATA_LOADER_TYPE";
/**
@@ -242,6 +245,7 @@
* Caller should make sure DataLoader is able to prepare image and reinitiate the operation.
*
* @see #EXTRA_SESSION_ID
+ * {@hide}
*/
public static final int STATUS_PENDING_STREAMING = -2;
@@ -344,21 +348,25 @@
* Default value, non-streaming installation session.
*
* @see #EXTRA_DATA_LOADER_TYPE
+ * {@hide}
*/
+ @SystemApi
public static final int DATA_LOADER_TYPE_NONE = DataLoaderType.NONE;
/**
* Streaming installation using data loader.
*
* @see #EXTRA_DATA_LOADER_TYPE
+ * {@hide}
*/
+ @SystemApi
public static final int DATA_LOADER_TYPE_STREAMING = DataLoaderType.STREAMING;
/**
* Streaming installation using Incremental FileSystem.
*
* @see #EXTRA_DATA_LOADER_TYPE
- * @hide
+ * {@hide}
*/
@SystemApi
public static final int DATA_LOADER_TYPE_INCREMENTAL = DataLoaderType.INCREMENTAL;
@@ -366,13 +374,18 @@
/**
* Target location for the file in installation session is /data/app/<packageName>-<id>.
* This is the intended location for APKs.
+ * Requires permission to install packages.
+ * {@hide}
*/
+ @SystemApi
public static final int LOCATION_DATA_APP = InstallationFileLocation.DATA_APP;
/**
* Target location for the file in installation session is
* /data/media/<userid>/Android/obb/<packageName>. This is the intended location for OBBs.
+ * {@hide}
*/
+ @SystemApi
public static final int LOCATION_MEDIA_OBB = InstallationFileLocation.MEDIA_OBB;
/**
@@ -380,7 +393,9 @@
* /data/media/<userid>/Android/data/<packageName>.
* This is the intended location for application data.
* Can only be used by an app itself running under specific user.
+ * {@hide}
*/
+ @SystemApi
public static final int LOCATION_MEDIA_DATA = InstallationFileLocation.MEDIA_DATA;
/** @hide */
@@ -1152,7 +1167,10 @@
/**
* @return data loader params or null if the session is not using one.
+ * {@hide}
*/
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.USE_INSTALLER_V2)
public @Nullable DataLoaderParams getDataLoaderParams() {
try {
DataLoaderParamsParcel data = mSession.getDataLoaderParams();
@@ -1189,7 +1207,11 @@
* @throws IllegalStateException if called for non-streaming session
*
* @see android.content.pm.InstallationFile
+ *
+ * {@hide}
*/
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.USE_INSTALLER_V2)
public void addFile(@FileLocation int location, @NonNull String name, long lengthBytes,
@NonNull byte[] metadata, @Nullable byte[] signature) {
try {
@@ -1209,8 +1231,11 @@
* @param name name of a file, e.g. split.
* @throws SecurityException if called after the session has been
* sealed or abandoned
- * @throws IllegalStateException if called for non-streaming session
+ * @throws IllegalStateException if called for non-DataLoader session
+ * {@hide}
*/
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.USE_INSTALLER_V2)
public void removeFile(@FileLocation int location, @NonNull String name) {
try {
mSession.removeFile(location, name);
@@ -2026,7 +2051,13 @@
* staging folder.
*
* @see android.service.dataloader.DataLoaderService.DataLoader
+ *
+ * {@hide}
*/
+ @SystemApi
+ @RequiresPermission(allOf = {
+ Manifest.permission.INSTALL_PACKAGES,
+ Manifest.permission.USE_INSTALLER_V2})
public void setDataLoaderParams(@NonNull DataLoaderParams dataLoaderParams) {
this.dataLoaderParams = dataLoaderParams;
}
diff --git a/core/java/android/content/pm/PackagePartitions.java b/core/java/android/content/pm/PackagePartitions.java
index 98a20f7..52ee4de 100644
--- a/core/java/android/content/pm/PackagePartitions.java
+++ b/core/java/android/content/pm/PackagePartitions.java
@@ -47,7 +47,7 @@
public static final int PARTITION_PRODUCT = 4;
public static final int PARTITION_SYSTEM_EXT = 5;
- @IntDef(flag = true, prefix = { "PARTITION_" }, value = {
+ @IntDef(prefix = { "PARTITION_" }, value = {
PARTITION_SYSTEM,
PARTITION_VENDOR,
PARTITION_ODM,
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index c2ca384..0fc6b2b 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -2807,7 +2807,15 @@
}
}
+ @SuppressWarnings("AndroidFrameworkCompatChange")
private void convertSplitPermissions(ParsingPackage pkg) {
+ // STOPSHIP(b/183905675): REMOVE THIS TERRIBLE, HORRIBLE, NO GOOD, VERY BAD HACK
+ if ("com.android.chrome".equals(pkg.getPackageName())
+ && pkg.getVersionCode() <= 445500399
+ && pkg.getTargetSdkVersion() > Build.VERSION_CODES.R) {
+ pkg.setTargetSdkVersion(Build.VERSION_CODES.R);
+ }
+
final int listSize = mSplitPermissionInfos.size();
for (int is = 0; is < listSize; is++) {
final PermissionManager.SplitPermissionInfo spi = mSplitPermissionInfos.get(is);
diff --git a/core/java/android/hardware/biometrics/CryptoObject.java b/core/java/android/hardware/biometrics/CryptoObject.java
index 0af18df..7648cf2 100644
--- a/core/java/android/hardware/biometrics/CryptoObject.java
+++ b/core/java/android/hardware/biometrics/CryptoObject.java
@@ -18,7 +18,7 @@
import android.annotation.NonNull;
import android.security.identity.IdentityCredential;
-import android.security.keystore.AndroidKeyStoreProvider;
+import android.security.keystore2.AndroidKeyStoreProvider;
import java.security.Signature;
diff --git a/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java b/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java
index bdd5ab6..e7d76f6 100644
--- a/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java
+++ b/core/java/android/hardware/hdmi/HdmiAudioSystemClient.java
@@ -63,7 +63,6 @@
*
* @hide
*/
- // TODO(b/110094868): unhide and add @SystemApi for Q
public interface SetSystemAudioModeCallback {
/**
* Called when the input was changed.
@@ -74,7 +73,6 @@
}
/** @hide */
- // TODO(b/110094868): unhide and add @SystemApi for Q
@Override
public int getDeviceType() {
return HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM;
@@ -143,7 +141,6 @@
*
* @hide
*/
- // TODO(b/110094868): unhide and add @SystemApi for Q
public void setSystemAudioMode(boolean state, @NonNull SetSystemAudioModeCallback callback) {
// TODO(amyjojo): implement this when needed.
}
@@ -156,7 +153,6 @@
*
* @hide
*/
- // TODO(b/110094868): unhide and add @SystemApi for Q
public void setSystemAudioModeOnForAudioOnlySource() {
try {
mService.setSystemAudioModeOnForAudioOnlySource();
diff --git a/core/java/android/hardware/hdmi/HdmiClient.java b/core/java/android/hardware/hdmi/HdmiClient.java
index a921215..0c21746 100644
--- a/core/java/android/hardware/hdmi/HdmiClient.java
+++ b/core/java/android/hardware/hdmi/HdmiClient.java
@@ -65,7 +65,6 @@
* @param isPressed true if this is key press event
*
* @hide
- * TODO(b/110094868): unhide for Q
*/
public void sendVolumeKeyEvent(int keyCode, boolean isPressed) {
try {
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index ad71f15..6079c57 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -1009,7 +1009,6 @@
*
* @return {@link HdmiAudioSystemClient} instance. {@code null} on failure.
*
- * TODO(b/110094868): unhide for Q
* @hide
*/
@Nullable
diff --git a/core/java/android/hardware/hdmi/HdmiUtils.java b/core/java/android/hardware/hdmi/HdmiUtils.java
index 8c94b78..2f4378e 100644
--- a/core/java/android/hardware/hdmi/HdmiUtils.java
+++ b/core/java/android/hardware/hdmi/HdmiUtils.java
@@ -24,7 +24,6 @@
/**
* Various utilities related to HDMI CEC.
*
- * TODO(b/110094868): unhide for Q
* @hide
*/
public final class HdmiUtils {
@@ -84,7 +83,6 @@
}
/**
- * TODO(b/110094868): unhide for Q
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@@ -95,49 +93,49 @@
public @interface HdmiAddressRelativePosition {}
/**
* HDMI relative position is not determined.
- * TODO(b/110094868): unhide for Q
+ *
* @hide
*/
public static final int HDMI_RELATIVE_POSITION_UNKNOWN = 0;
/**
* HDMI relative position: directly blow the device.
- * TODO(b/110094868): unhide for Q
+ *
* @hide
*/
public static final int HDMI_RELATIVE_POSITION_DIRECTLY_BELOW = 1;
/**
* HDMI relative position: indirectly below the device.
- * TODO(b/110094868): unhide for Q
+ *
* @hide
*/
public static final int HDMI_RELATIVE_POSITION_BELOW = 2;
/**
* HDMI relative position: the same device.
- * TODO(b/110094868): unhide for Q
+ *
* @hide
*/
public static final int HDMI_RELATIVE_POSITION_SAME = 3;
/**
* HDMI relative position: directly above the device.
- * TODO(b/110094868): unhide for Q
+ *
* @hide
*/
public static final int HDMI_RELATIVE_POSITION_DIRECTLY_ABOVE = 4;
/**
* HDMI relative position: indirectly above the device.
- * TODO(b/110094868): unhide for Q
+ *
* @hide
*/
public static final int HDMI_RELATIVE_POSITION_ABOVE = 5;
/**
* HDMI relative position: directly below a same device.
- * TODO(b/110094868): unhide for Q
+ *
* @hide
*/
public static final int HDMI_RELATIVE_POSITION_SIBLING = 6;
/**
* HDMI relative position: different branch.
- * TODO(b/110094868): unhide for Q
+ *
* @hide
*/
public static final int HDMI_RELATIVE_POSITION_DIFFERENT_BRANCH = 7;
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 4ee5383..4b8e37c 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -718,7 +718,7 @@
public final void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
@NonNull EditorInfo editorInfo, boolean restarting,
@NonNull IBinder startInputToken) {
- mPrivOps.reportStartInput(startInputToken);
+ mPrivOps.reportStartInputAsync(startInputToken);
if (restarting) {
restartInput(inputConnection, editorInfo);
@@ -819,10 +819,9 @@
if (dispatchOnShowInputRequested(flags, false)) {
showWindow(true);
applyVisibilityInInsetsConsumerIfNecessary(true /* setVisible */);
- } else {
- // If user uses hard keyboard, IME button should always be shown.
- setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition);
}
+ setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition);
+
final boolean isVisible = isInputViewShown();
final boolean visibilityChanged = isVisible != wasVisible;
if (resultReceiver != null) {
diff --git a/core/java/android/net/DnsResolverServiceManager.java b/core/java/android/net/DnsResolverServiceManager.java
deleted file mode 100644
index 1597322..0000000
--- a/core/java/android/net/DnsResolverServiceManager.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net;
-
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.ServiceManager;
-
-import java.util.Objects;
-
-/**
- * Provides a way to obtain the DnsResolver binder objects.
- *
- * @hide
- */
-@SystemApi
-public class DnsResolverServiceManager {
- /**
- * Name to retrieve a {@link android.net.IDnsResolver} IBinder.
- */
- private static final String DNS_RESOLVER_SERVICE = "dnsresolver";
-
- private DnsResolverServiceManager() {}
-
- /**
- * Get an {@link IBinder} representing the DnsResolver stable AIDL interface
- *
- * @param context the context for permission check.
- * @return {@link android.net.IDnsResolver} IBinder.
- */
- @NonNull
- @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
- public static IBinder getService(@NonNull final Context context) {
- Objects.requireNonNull(context);
- context.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- "DnsResolverServiceManager");
- try {
- return ServiceManager.getServiceOrThrow(DNS_RESOLVER_SERVICE);
- } catch (ServiceManager.ServiceNotFoundException e) {
- // Catch ServiceManager#ServiceNotFoundException and rethrow IllegalStateException
- // because ServiceManager#ServiceNotFoundException is @hide so that it can't be listed
- // on the system api. Thus, rethrow IllegalStateException if dns resolver service cannot
- // be found.
- throw new IllegalStateException("Cannot find dns resolver service.");
- }
- }
-}
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index ec83c4e..053856b 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -479,7 +479,8 @@
* @param overrideMask the bitmask that specifies which of the overrides is being
* set or cleared.
* @param overrideValue the override values to set or clear.
- * @param networkTypes the network types this override applies to.
+ * @param networkTypes the network types this override applies to. If no
+ * network types are specified, override values will be ignored.
* {@see TelephonyManager#getAllNetworkTypes()}
* @param timeoutMillis the timeout after which the requested override will
* be automatically cleared, or {@code 0} to leave in the
diff --git a/core/java/android/net/NetworkWatchlistManager.java b/core/java/android/net/NetworkWatchlistManager.java
index 8f6510e..da01dcb 100644
--- a/core/java/android/net/NetworkWatchlistManager.java
+++ b/core/java/android/net/NetworkWatchlistManager.java
@@ -19,6 +19,7 @@
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.TestApi;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -31,6 +32,7 @@
* Class that manage network watchlist in system.
* @hide
*/
+@TestApi
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@SystemService(Context.NETWORK_WATCHLIST_SERVICE)
public class NetworkWatchlistManager {
diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java
index 16d041a..d026e95 100644
--- a/core/java/android/os/BinderProxy.java
+++ b/core/java/android/os/BinderProxy.java
@@ -34,6 +34,9 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
/**
* Java proxy for a native IBinder object.
@@ -262,27 +265,45 @@
Log.e(Binder.TAG, "RemoteException while disabling app freezer");
}
- for (WeakReference<BinderProxy> weakRef : proxiesToQuery) {
- BinderProxy bp = weakRef.get();
- String key;
- if (bp == null) {
- key = "<cleared weak-ref>";
- } else {
- try {
- key = bp.getInterfaceDescriptor();
- if ((key == null || key.isEmpty()) && !bp.isBinderAlive()) {
- key = "<proxy to dead node>";
+ // We run the dump on a separate thread, because there are known cases where
+ // a process overrides getInterfaceDescriptor() and somehow blocks on it, causing
+ // the calling thread (usually AMS) to hit the watchdog.
+ // Do the dumping on a separate thread instead, and give up after a while.
+ ExecutorService executorService = Executors.newSingleThreadExecutor();
+ executorService.submit(() -> {
+ for (WeakReference<BinderProxy> weakRef : proxiesToQuery) {
+ BinderProxy bp = weakRef.get();
+ String key;
+ if (bp == null) {
+ key = "<cleared weak-ref>";
+ } else {
+ try {
+ key = bp.getInterfaceDescriptor();
+ if ((key == null || key.isEmpty()) && !bp.isBinderAlive()) {
+ key = "<proxy to dead node>";
+ }
+ } catch (Throwable t) {
+ key = "<exception during getDescriptor>";
}
- } catch (Throwable t) {
- key = "<exception during getDescriptor>";
+ }
+ Integer i = counts.get(key);
+ if (i == null) {
+ counts.put(key, 1);
+ } else {
+ counts.put(key, i + 1);
}
}
- Integer i = counts.get(key);
- if (i == null) {
- counts.put(key, 1);
- } else {
- counts.put(key, i + 1);
+ });
+
+ try {
+ executorService.shutdown();
+ boolean dumpDone = executorService.awaitTermination(20, TimeUnit.SECONDS);
+ if (!dumpDone) {
+ Log.e(Binder.TAG, "Failed to complete binder proxy dump,"
+ + " dumping what we have so far.");
}
+ } catch (InterruptedException e) {
+ // Ignore
}
try {
ActivityManager.getService().enableAppFreezer(true);
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 1a40f06..17c90d6 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -886,6 +886,24 @@
}
/**
+ * @param micMuted whether to consider the microphone muted when retrieving audio ops
+ * @return A list of permission groups currently or recently used by all apps by all users in
+ * the current profile group.
+ *
+ * @hide
+ */
+ @TestApi
+ @NonNull
+ @RequiresPermission(Manifest.permission.GET_APP_OPS_STATS)
+ public List<PermGroupUsage> getIndicatorAppOpUsageData(boolean micMuted) {
+ // Lazily initialize the usage helper
+ if (mUsageHelper == null) {
+ mUsageHelper = new PermissionUsageHelper(mContext);
+ }
+ return mUsageHelper.getOpUsageData(micMuted);
+ }
+
+ /**
* Determine if a package should be shown in indicators. Only a select few roles, and the
* system app itself, are hidden. These values are updated at most every 15 seconds.
* @hide
diff --git a/core/java/android/service/dataloader/DataLoaderService.java b/core/java/android/service/dataloader/DataLoaderService.java
index 63ec252..7e8acde 100644
--- a/core/java/android/service/dataloader/DataLoaderService.java
+++ b/core/java/android/service/dataloader/DataLoaderService.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
import android.content.pm.DataLoaderParams;
@@ -48,14 +49,19 @@
*
* @see android.content.pm.DataLoaderParams
* @see android.content.pm.PackageInstaller.SessionParams#setDataLoaderParams
+ *
+ * @hide
*/
+@SystemApi
public abstract class DataLoaderService extends Service {
private static final String TAG = "DataLoaderService";
private final DataLoaderBinderService mBinder = new DataLoaderBinderService();
/**
* DataLoader interface. Each instance corresponds to a single installation session.
+ * @hide
*/
+ @SystemApi
public interface DataLoader {
/**
* A virtual constructor.
@@ -112,7 +118,9 @@
/**
* DataLoader factory method.
* An installation session uses it to create an instance of DataLoader.
+ * @hide
*/
+ @SystemApi
public @Nullable DataLoader onCreateDataLoader(@NonNull DataLoaderParams dataLoaderParams) {
return null;
}
@@ -178,7 +186,10 @@
/**
* Provides access to the installation image.
+ *
+ * @hide
*/
+ @SystemApi
public static final class FileSystemConnector {
/**
* Create a wrapper for a native instance.
diff --git a/core/java/android/service/displayhash/DisplayHashParams.java b/core/java/android/service/displayhash/DisplayHashParams.java
index fcce91a..2ec9d5d 100644
--- a/core/java/android/service/displayhash/DisplayHashParams.java
+++ b/core/java/android/service/displayhash/DisplayHashParams.java
@@ -28,7 +28,7 @@
import com.android.internal.util.DataClass;
/**
- * Information passed from the {@link DisplayHasherService} to system server about how to get the
+ * Information passed from the {@link DisplayHashingService} to system server about how to get the
* display data that will be used to generate the {@link android.view.displayhash.DisplayHash}
*
* @hide
@@ -38,9 +38,9 @@
public final class DisplayHashParams implements Parcelable {
/**
* The size to scale the buffer to so the hash algorithm can properly generate the hash. The
- * buffer given to the {@link DisplayHasherService#onGenerateDisplayHash(byte[], HardwareBuffer,
- * Rect, String, DisplayHashResultCallback)} will be stretched based on the value set here.
- * If {@code null}, the buffer size will not be changed.
+ * buffer given to the {@link DisplayHashingService#onGenerateDisplayHash(byte[],
+ * HardwareBuffer, Rect, String, DisplayHashResultCallback)} will be stretched based on the
+ * value set here. If {@code null}, the buffer size will not be changed.
*/
@Nullable
private final Size mBufferSize;
@@ -48,7 +48,7 @@
/**
* Whether the content will be captured in grayscale or color.
*/
- private final boolean mGrayscaleBuffer;
+ private final boolean mUseGrayscale;
/**
* A builder for {@link DisplayHashParams}
@@ -56,7 +56,7 @@
public static final class Builder {
@Nullable
private Size mBufferSize;
- private boolean mGrayscaleBuffer;
+ private boolean mUseGrayscale;
/**
* Creates a new Builder.
@@ -68,8 +68,8 @@
* The size to scale the buffer to so the hash algorithm can properly generate the hash.
*/
@NonNull
- public Builder setBufferSize(int w, int h) {
- mBufferSize = new Size(w, h);
+ public Builder setBufferSize(int width, int height) {
+ mBufferSize = new Size(width, height);
return this;
}
@@ -77,15 +77,15 @@
* Whether the content will be captured in grayscale or color.
*/
@NonNull
- public Builder setGrayscaleBuffer(boolean value) {
- mGrayscaleBuffer = value;
+ public Builder setUseGrayscale(boolean useGrayscale) {
+ mUseGrayscale = useGrayscale;
return this;
}
/** Builds the instance. This builder should not be touched after calling this! */
@NonNull
public DisplayHashParams build() {
- return new DisplayHashParams(mBufferSize, mGrayscaleBuffer);
+ return new DisplayHashParams(mBufferSize, mUseGrayscale);
}
}
@@ -109,28 +109,28 @@
*
* @param bufferSize
* The size to scale the buffer to so the hash algorithm can properly generate the hash. The
- * buffer given to the {@link DisplayHasherService#onGenerateDisplayHash(byte[], HardwareBuffer,
- * Rect, String, DisplayHashResultCallback)} will be stretched based on the value set here.
- * If {@code null}, the buffer size will not be changed.
- * @param grayscaleBuffer
+ * buffer given to the {@link DisplayHashingService#onGenerateDisplayHash(byte[],
+ * HardwareBuffer, Rect, String, DisplayHashResultCallback)} will be stretched based on the
+ * value set here. If {@code null}, the buffer size will not be changed.
+ * @param useGrayscale
* Whether the content will be captured in grayscale or color.
* @hide
*/
@DataClass.Generated.Member
public DisplayHashParams(
@Nullable Size bufferSize,
- boolean grayscaleBuffer) {
+ boolean useGrayscale) {
this.mBufferSize = bufferSize;
- this.mGrayscaleBuffer = grayscaleBuffer;
+ this.mUseGrayscale = useGrayscale;
// onConstructed(); // You can define this method to get a callback
}
/**
* The size to scale the buffer to so the hash algorithm can properly generate the hash. The
- * buffer given to the {@link DisplayHasherService#onGenerateDisplayHash(byte[], HardwareBuffer,
- * Rect, String, DisplayHashResultCallback)} will be stretched based on the value set here.
- * If {@code null}, the buffer size will not be changed.
+ * buffer given to the {@link DisplayHashingService#onGenerateDisplayHash(byte[],
+ * HardwareBuffer, Rect, String, DisplayHashResultCallback)} will be stretched based on the
+ * value set here. If {@code null}, the buffer size will not be changed.
*/
@DataClass.Generated.Member
public @Nullable Size getBufferSize() {
@@ -141,8 +141,8 @@
* Whether the content will be captured in grayscale or color.
*/
@DataClass.Generated.Member
- public boolean isGrayscaleBuffer() {
- return mGrayscaleBuffer;
+ public boolean isUseGrayscale() {
+ return mUseGrayscale;
}
@Override
@@ -153,7 +153,7 @@
return "DisplayHashParams { " +
"bufferSize = " + mBufferSize + ", " +
- "grayscaleBuffer = " + mGrayscaleBuffer +
+ "useGrayscale = " + mUseGrayscale +
" }";
}
@@ -164,7 +164,7 @@
// void parcelFieldName(Parcel dest, int flags) { ... }
byte flg = 0;
- if (mGrayscaleBuffer) flg |= 0x2;
+ if (mUseGrayscale) flg |= 0x2;
if (mBufferSize != null) flg |= 0x1;
dest.writeByte(flg);
if (mBufferSize != null) dest.writeSize(mBufferSize);
@@ -182,11 +182,11 @@
// static FieldType unparcelFieldName(Parcel in) { ... }
byte flg = in.readByte();
- boolean grayscaleBuffer = (flg & 0x2) != 0;
+ boolean useGrayscale = (flg & 0x2) != 0;
Size bufferSize = (flg & 0x1) == 0 ? null : (Size) in.readSize();
this.mBufferSize = bufferSize;
- this.mGrayscaleBuffer = grayscaleBuffer;
+ this.mUseGrayscale = useGrayscale;
// onConstructed(); // You can define this method to get a callback
}
@@ -206,10 +206,10 @@
};
@DataClass.Generated(
- time = 1617735166254L,
+ time = 1618436855096L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/service/displayhash/DisplayHashParams.java",
- inputSignatures = "private final @android.annotation.Nullable android.util.Size mBufferSize\nprivate final boolean mGrayscaleBuffer\nclass DisplayHashParams extends java.lang.Object implements [android.os.Parcelable]\nprivate @android.annotation.Nullable android.util.Size mBufferSize\nprivate boolean mGrayscaleBuffer\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams.Builder setBufferSize(int,int)\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams.Builder setGrayscaleBuffer(boolean)\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams build()\nclass Builder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genAidl=true, genToString=true, genParcelable=true, genHiddenConstructor=true)")
+ inputSignatures = "private final @android.annotation.Nullable android.util.Size mBufferSize\nprivate final boolean mUseGrayscale\nclass DisplayHashParams extends java.lang.Object implements [android.os.Parcelable]\nprivate @android.annotation.Nullable android.util.Size mBufferSize\nprivate boolean mUseGrayscale\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams.Builder setBufferSize(int,int)\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams.Builder setUseGrayscale(boolean)\npublic @android.annotation.NonNull android.service.displayhash.DisplayHashParams build()\nclass Builder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genAidl=true, genToString=true, genParcelable=true, genHiddenConstructor=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/service/displayhash/DisplayHasherService.java b/core/java/android/service/displayhash/DisplayHashingService.java
similarity index 84%
rename from core/java/android/service/displayhash/DisplayHasherService.java
rename to core/java/android/service/displayhash/DisplayHashingService.java
index d300cf1..e8bb485 100644
--- a/core/java/android/service/displayhash/DisplayHasherService.java
+++ b/core/java/android/service/displayhash/DisplayHashingService.java
@@ -45,21 +45,21 @@
* @hide
*/
@SystemApi
-public abstract class DisplayHasherService extends Service {
+public abstract class DisplayHashingService extends Service {
/** @hide **/
public static final String EXTRA_VERIFIED_DISPLAY_HASH =
"android.service.displayhash.extra.VERIFIED_DISPLAY_HASH";
/**
- * Name under which a DisplayHasherService component publishes information
+ * Name under which a DisplayHashingService component publishes information
* about itself. This meta-data must reference an XML resource containing a
- * {@link com.android.internal.R.styleable#DisplayHasherService} tag.
+ * {@link com.android.internal.R.styleable#DisplayHashingService} tag.
*
* @hide
*/
@SystemApi
- public static final String SERVICE_META_DATA = "android.displayhash.display_hasher_service";
+ public static final String SERVICE_META_DATA = "android.displayhash.display_hashing_service";
/**
* The {@link Intent} action that must be declared as handled by a service in its manifest
@@ -69,18 +69,18 @@
*/
@SystemApi
public static final String SERVICE_INTERFACE =
- "android.service.displayhash.DisplayHasherService";
+ "android.service.displayhash.DisplayHashingService";
- private DisplayHasherServiceWrapper mWrapper;
+ private DisplayHashingServiceWrapper mWrapper;
private Handler mHandler;
- public DisplayHasherService() {
+ public DisplayHashingService() {
}
@Override
public void onCreate() {
super.onCreate();
- mWrapper = new DisplayHasherServiceWrapper();
+ mWrapper = new DisplayHashingServiceWrapper();
mHandler = new Handler(Looper.getMainLooper(), null, true);
}
@@ -105,7 +105,6 @@
* if successfully generated a DisplayHash or {@link
* DisplayHashResultCallback#onDisplayHashError(int)} if failed.
*/
- @Nullable
public abstract void onGenerateDisplayHash(@NonNull byte[] salt,
@NonNull HardwareBuffer buffer, @NonNull Rect bounds,
@NonNull String hashAlgorithm, @NonNull DisplayHashResultCallback callback);
@@ -125,8 +124,8 @@
* HardwareBuffer, Rect, String, DisplayHashResultCallback)} to
* generate the token.
* @param displayHash The token to verify that it was generated by the system.
- * @return a {@link VerifiedDisplayHash} if the token was generated by the system or null
- * if the token cannot be verified.
+ * @return a {@link VerifiedDisplayHash} if the provided display hash was originally generated
+ * by the system or null if the system did not generate the display hash.
*/
@Nullable
public abstract VerifiedDisplayHash onVerifyDisplayHash(@NonNull byte[] salt,
@@ -150,13 +149,13 @@
callback.sendResult(data);
}
- private final class DisplayHasherServiceWrapper extends IDisplayHasherService.Stub {
+ private final class DisplayHashingServiceWrapper extends IDisplayHashingService.Stub {
@Override
public void generateDisplayHash(byte[] salt, HardwareBuffer buffer, Rect bounds,
String hashAlgorithm, RemoteCallback callback) {
mHandler.sendMessage(
- obtainMessage(DisplayHasherService::onGenerateDisplayHash,
- DisplayHasherService.this, salt, buffer, bounds,
+ obtainMessage(DisplayHashingService::onGenerateDisplayHash,
+ DisplayHashingService.this, salt, buffer, bounds,
hashAlgorithm, new DisplayHashResultCallback() {
@Override
public void onDisplayHashResult(
@@ -179,14 +178,14 @@
public void verifyDisplayHash(byte[] salt, DisplayHash displayHash,
RemoteCallback callback) {
mHandler.sendMessage(
- obtainMessage(DisplayHasherService::verifyDisplayHash,
- DisplayHasherService.this, salt, displayHash, callback));
+ obtainMessage(DisplayHashingService::verifyDisplayHash,
+ DisplayHashingService.this, salt, displayHash, callback));
}
@Override
public void getDisplayHashAlgorithms(RemoteCallback callback) {
- mHandler.sendMessage(obtainMessage(DisplayHasherService::getDisplayHashAlgorithms,
- DisplayHasherService.this, callback));
+ mHandler.sendMessage(obtainMessage(DisplayHashingService::getDisplayHashAlgorithms,
+ DisplayHashingService.this, callback));
}
}
}
diff --git a/core/java/android/service/displayhash/IDisplayHasherService.aidl b/core/java/android/service/displayhash/IDisplayHashingService.aidl
similarity index 98%
rename from core/java/android/service/displayhash/IDisplayHasherService.aidl
rename to core/java/android/service/displayhash/IDisplayHashingService.aidl
index d9dcdca..56e1e0a 100644
--- a/core/java/android/service/displayhash/IDisplayHasherService.aidl
+++ b/core/java/android/service/displayhash/IDisplayHashingService.aidl
@@ -26,7 +26,7 @@
*
* @hide
*/
-oneway interface IDisplayHasherService {
+oneway interface IDisplayHashingService {
/**
* Generates the DisplayHash that can be used to validate that the system generated the token.
*
diff --git a/core/java/android/service/translation/TranslationService.java b/core/java/android/service/translation/TranslationService.java
index 7edf2e2..a3bbdb9 100644
--- a/core/java/android/service/translation/TranslationService.java
+++ b/core/java/android/service/translation/TranslationService.java
@@ -32,6 +32,7 @@
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.IBinder;
+import android.os.ICancellationSignal;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ResultReceiver;
@@ -149,18 +150,15 @@
*/
private final ITranslationDirectManager mClientInterface =
new ITranslationDirectManager.Stub() {
- // TODO: Implement cancellation signal
- @NonNull
- private final CancellationSignal mCancellationSignal = new CancellationSignal();
-
@Override
public void onTranslationRequest(TranslationRequest request, int sessionId,
- ITranslationCallback callback)
+ ICancellationSignal transport, ITranslationCallback callback)
throws RemoteException {
final OnTranslationResultCallback translationResultCallback =
new OnTranslationResultCallbackWrapper(callback);
mHandler.sendMessage(obtainMessage(TranslationService::onTranslationRequest,
- TranslationService.this, request, sessionId, mCancellationSignal,
+ TranslationService.this, request, sessionId,
+ CancellationSignal.fromTransport(transport),
translationResultCallback));
}
@@ -235,7 +233,7 @@
* @param cancellationSignal
*/
public abstract void onTranslationRequest(@NonNull TranslationRequest request, int sessionId,
- @NonNull CancellationSignal cancellationSignal,
+ @Nullable CancellationSignal cancellationSignal,
@NonNull OnTranslationResultCallback callback);
/**
diff --git a/core/java/android/service/voice/HotwordDetectionService.java b/core/java/android/service/voice/HotwordDetectionService.java
index 23b2103..ea854e8 100644
--- a/core/java/android/service/voice/HotwordDetectionService.java
+++ b/core/java/android/service/voice/HotwordDetectionService.java
@@ -24,8 +24,11 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.app.Service;
+import android.content.ContentCaptureOptions;
+import android.content.Context;
import android.content.Intent;
import android.media.AudioFormat;
import android.os.Bundle;
@@ -38,6 +41,8 @@
import android.os.RemoteException;
import android.os.SharedMemory;
import android.util.Log;
+import android.view.contentcapture.ContentCaptureManager;
+import android.view.contentcapture.IContentCaptureManager;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
@@ -122,6 +127,9 @@
private Handler mHandler;
+ @Nullable
+ private ContentCaptureManager mContentCaptureManager;
+
private final IHotwordDetectionService mInterface = new IHotwordDetectionService.Stub() {
@Override
public void detectFromDspSource(
@@ -187,6 +195,13 @@
Log.i(TAG, "Unsupported audio source " + audioSource);
}
}
+
+ @Override
+ public void updateContentCaptureManager(IContentCaptureManager manager,
+ ContentCaptureOptions options) {
+ mContentCaptureManager = new ContentCaptureManager(
+ HotwordDetectionService.this, manager, options);
+ }
};
@CallSuper
@@ -207,6 +222,16 @@
return null;
}
+ @Override
+ @SuppressLint("OnNameExpected")
+ public @Nullable Object getSystemService(@ServiceName @NonNull String name) {
+ if (Context.CONTENT_CAPTURE_MANAGER_SERVICE.equals(name)) {
+ return mContentCaptureManager;
+ } else {
+ return super.getSystemService(name);
+ }
+ }
+
/**
* Called when the device hardware (such as a DSP) detected the hotword, to request second stage
* validation before handing over the audio to the {@link AlwaysOnHotwordDetector}.
diff --git a/core/java/android/service/voice/IHotwordDetectionService.aidl b/core/java/android/service/voice/IHotwordDetectionService.aidl
index d242160..2ffe787 100644
--- a/core/java/android/service/voice/IHotwordDetectionService.aidl
+++ b/core/java/android/service/voice/IHotwordDetectionService.aidl
@@ -22,6 +22,8 @@
import android.os.PersistableBundle;
import android.os.SharedMemory;
import android.service.voice.IDspHotwordDetectionCallback;
+import android.view.contentcapture.IContentCaptureManager;
+import android.content.ContentCaptureOptions;
/**
* Provide the interface to communicate with hotword detection service.
@@ -42,6 +44,12 @@
in PersistableBundle options,
in IDspHotwordDetectionCallback callback);
- void updateState(in PersistableBundle options, in SharedMemory sharedMemory,
- in IRemoteCallback callback);
+ void updateState(
+ in PersistableBundle options,
+ in SharedMemory sharedMemory,
+ in IRemoteCallback callback);
+
+ void updateContentCaptureManager(
+ in IContentCaptureManager contentCaptureManager,
+ in ContentCaptureOptions options);
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index d89c29a..87fb611 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -37,6 +37,7 @@
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.TypedArray;
+import android.graphics.BLASTBufferQueue;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
@@ -208,8 +209,8 @@
int mCurHeight;
float mZoom = 0f;
int mWindowFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
- int mWindowPrivateFlags =
- WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
+ int mWindowPrivateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS
+ | WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST;
int mCurWindowFlags = mWindowFlags;
int mCurWindowPrivateFlags = mWindowPrivateFlags;
Rect mPreviewSurfacePosition;
@@ -253,6 +254,7 @@
private int mDisplayState;
SurfaceControl mSurfaceControl = new SurfaceControl();
+ BLASTBufferQueue mBlastBufferQueue;
final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() {
{
@@ -974,7 +976,14 @@
View.VISIBLE, 0, -1, mWinFrames, mMergedConfiguration, mSurfaceControl,
mInsetsState, mTempControls, mSurfaceSize);
if (mSurfaceControl.isValid()) {
- mSurfaceHolder.mSurface.copyFrom(mSurfaceControl);
+ Surface blastSurface = getOrCreateBLASTSurface(mSurfaceSize.x,
+ mSurfaceSize.y, mFormat);
+ // If blastSurface == null that means it hasn't changed since the last
+ // time we called. In this situation, avoid calling transferFrom as we
+ // would then inc the generation ID and cause EGL resources to be recreated.
+ if (blastSurface != null) {
+ mSurfaceHolder.mSurface.transferFrom(blastSurface);
+ }
}
if (!mLastSurfaceSize.equals(mSurfaceSize)) {
mLastSurfaceSize.set(mSurfaceSize.x, mSurfaceSize.y);
@@ -1455,13 +1464,12 @@
return;
}
Surface surface = mSurfaceHolder.getSurface();
- boolean widthIsLarger =
- mSurfaceControl.getWidth() > mSurfaceControl.getHeight();
- int smaller = widthIsLarger ? mSurfaceControl.getWidth()
- : mSurfaceControl.getHeight();
+ boolean widthIsLarger = mSurfaceSize.x > mSurfaceSize.y;
+ int smaller = widthIsLarger ? mSurfaceSize.x
+ : mSurfaceSize.y;
float ratio = (float) MIN_BITMAP_SCREENSHOT_WIDTH / (float) smaller;
- int width = (int) (ratio * mSurfaceControl.getWidth());
- int height = (int) (ratio * mSurfaceControl.getHeight());
+ int width = (int) (ratio * mSurfaceSize.x);
+ int height = (int) (ratio * mSurfaceSize.y);
if (width <= 0 || height <= 0) {
Log.e(TAG, "wrong width and height values of bitmap " + width + " " + height);
return;
@@ -1842,6 +1850,21 @@
public void onDisplayAdded(int displayId) {
}
};
+
+ private Surface getOrCreateBLASTSurface(int width, int height, int format) {
+ Surface ret = null;
+ if (mBlastBufferQueue == null) {
+ mBlastBufferQueue = new BLASTBufferQueue("Wallpaper", mSurfaceControl, width,
+ height, format);
+ // We only return the Surface the first time, as otherwise
+ // it hasn't changed and there is no need to update.
+ ret = mBlastBufferQueue.createSurface();
+ } else {
+ mBlastBufferQueue.update(mSurfaceControl, width, height, format);
+ }
+
+ return ret;
+ }
}
private boolean isValid(RectF area) {
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 340fa40..4b18c5a 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -796,13 +796,14 @@
/**
* Notify {@link PhysicalChannelConfig} has changed for a specific subscription.
*
+ * @param slotIndex for which physical channel configs changed.
* @param subId the subId
* @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel.
*/
- public void notifyPhysicalChannelConfigForSubscriber(
- int subId, List<PhysicalChannelConfig> configs) {
+ public void notifyPhysicalChannelConfigForSubscriber(int slotIndex, int subId,
+ List<PhysicalChannelConfig> configs) {
try {
- sRegistry.notifyPhysicalChannelConfigForSubscriber(subId, configs);
+ sRegistry.notifyPhysicalChannelConfigForSubscriber(slotIndex, subId, configs);
} catch (RemoteException ex) {
// system server crash
}
diff --git a/core/java/android/text/FontConfig.java b/core/java/android/text/FontConfig.java
index 33b7c75..2f7fb2f 100644
--- a/core/java/android/text/FontConfig.java
+++ b/core/java/android/text/FontConfig.java
@@ -194,6 +194,7 @@
public static final class Font implements Parcelable {
private final @NonNull File mFile;
private final @Nullable File mOriginalFile;
+ private final @NonNull String mPostScriptName;
private final @NonNull FontStyle mStyle;
private final @IntRange(from = 0) int mIndex;
private final @NonNull String mFontVariationSettings;
@@ -204,11 +205,12 @@
*
* @hide Only system server can create this instance and passed via IPC.
*/
- public Font(@NonNull File file, @Nullable File originalFile, @NonNull FontStyle style,
- @IntRange(from = 0) int index, @NonNull String fontVariationSettings,
- @Nullable String fontFamilyName) {
+ public Font(@NonNull File file, @Nullable File originalFile, @NonNull String postScriptName,
+ @NonNull FontStyle style, @IntRange(from = 0) int index,
+ @NonNull String fontVariationSettings, @Nullable String fontFamilyName) {
mFile = file;
mOriginalFile = originalFile;
+ mPostScriptName = postScriptName;
mStyle = style;
mIndex = index;
mFontVariationSettings = fontVariationSettings;
@@ -224,6 +226,7 @@
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString8(mFile.getAbsolutePath());
dest.writeString8(mOriginalFile == null ? null : mOriginalFile.getAbsolutePath());
+ dest.writeString8(mPostScriptName);
dest.writeInt(mStyle.getWeight());
dest.writeInt(mStyle.getSlant());
dest.writeInt(mIndex);
@@ -238,14 +241,15 @@
File path = new File(source.readString8());
String originalPathStr = source.readString8();
File originalPath = originalPathStr == null ? null : new File(originalPathStr);
+ String postScriptName = source.readString8();
int weight = source.readInt();
int slant = source.readInt();
int index = source.readInt();
String varSettings = source.readString8();
String fallback = source.readString8();
- return new Font(path, originalPath, new FontStyle(weight, slant), index,
- varSettings, fallback);
+ return new Font(path, originalPath, postScriptName, new FontStyle(weight, slant),
+ index, varSettings, fallback);
}
@Override
@@ -314,6 +318,13 @@
}
/**
+ * Returns the PostScript name of this font.
+ */
+ public @NonNull String getPostScriptName() {
+ return mPostScriptName;
+ }
+
+ /**
* Returns the list of axes associated to this font.
* @deprecated Use getFontVariationSettings
* @hide
diff --git a/core/java/android/text/method/TranslationTransformationMethod.java b/core/java/android/text/method/TranslationTransformationMethod.java
index 7db999a8..54c0ffc 100644
--- a/core/java/android/text/method/TranslationTransformationMethod.java
+++ b/core/java/android/text/method/TranslationTransformationMethod.java
@@ -78,24 +78,11 @@
if (TextUtils.isEmpty(translatedText) || isWhitespace(translatedText.toString())) {
return source;
} else {
- // TODO(b/179693024): Remove this once we have the fix to pad the view text instead.
- translatedText = ellipsize(translatedText, ((TextView) view).getText().length());
// TODO(b/174283799): apply the spans to the text
return translatedText;
}
}
- private static CharSequence ellipsize(CharSequence text, int newLength) {
- if (text.length() <= newLength) {
- return text;
- }
- String ellipsis = String.valueOf('\u2026');
- if (newLength == 1) {
- return ellipsis;
- }
- return TextUtils.concat(TextUtils.trimToSize(text, newLength - 1), ellipsis);
- }
-
@Override
public void onFocusChanged(View view, CharSequence sourceText,
boolean focused, int direction,
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 0a3963d..be172f7 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -693,71 +693,79 @@
ThreadedRenderer.setFPSDivisor(divisor);
}
+ private void traceMessage(String msg) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, msg);
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
+
void doFrame(long frameTimeNanos, int frame,
DisplayEventReceiver.VsyncEventData vsyncEventData) {
final long startNanos;
final long frameIntervalNanos = vsyncEventData.frameInterval;
- synchronized (mLock) {
- if (!mFrameScheduled) {
- return; // no work to do
- }
-
- if (DEBUG_JANK && mDebugPrintNextFrameTimeDelta) {
- mDebugPrintNextFrameTimeDelta = false;
- Log.d(TAG, "Frame time delta: "
- + ((frameTimeNanos - mLastFrameTimeNanos) * 0.000001f) + " ms");
- }
-
- long intendedFrameTimeNanos = frameTimeNanos;
- startNanos = System.nanoTime();
- final long jitterNanos = startNanos - frameTimeNanos;
- if (jitterNanos >= frameIntervalNanos) {
- final long skippedFrames = jitterNanos / frameIntervalNanos;
- if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) {
- Log.i(TAG, "Skipped " + skippedFrames + " frames! "
- + "The application may be doing too much work on its main thread.");
- }
- final long lastFrameOffset = jitterNanos % frameIntervalNanos;
- if (DEBUG_JANK) {
- Log.d(TAG, "Missed vsync by " + (jitterNanos * 0.000001f) + " ms "
- + "which is more than the frame interval of "
- + (frameIntervalNanos * 0.000001f) + " ms! "
- + "Skipping " + skippedFrames + " frames and setting frame "
- + "time to " + (lastFrameOffset * 0.000001f) + " ms in the past.");
- }
- frameTimeNanos = startNanos - lastFrameOffset;
- }
-
- if (frameTimeNanos < mLastFrameTimeNanos) {
- if (DEBUG_JANK) {
- Log.d(TAG, "Frame time appears to be going backwards. May be due to a "
- + "previously skipped frame. Waiting for next vsync.");
- }
- scheduleVsyncLocked();
- return;
- }
-
- if (mFPSDivisor > 1) {
- long timeSinceVsync = frameTimeNanos - mLastFrameTimeNanos;
- if (timeSinceVsync < (frameIntervalNanos * mFPSDivisor) && timeSinceVsync > 0) {
- scheduleVsyncLocked();
- return;
- }
- }
-
- mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos, vsyncEventData.id,
- vsyncEventData.frameDeadline, startNanos, vsyncEventData.frameInterval);
- mFrameScheduled = false;
- mLastFrameTimeNanos = frameTimeNanos;
- mLastFrameIntervalNanos = frameIntervalNanos;
- mLastVsyncEventData = vsyncEventData;
- }
-
try {
if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW,
"Choreographer#doFrame " + vsyncEventData.id);
}
+ synchronized (mLock) {
+ if (!mFrameScheduled) {
+ traceMessage("Frame not scheduled");
+ return; // no work to do
+ }
+
+ if (DEBUG_JANK && mDebugPrintNextFrameTimeDelta) {
+ mDebugPrintNextFrameTimeDelta = false;
+ Log.d(TAG, "Frame time delta: "
+ + ((frameTimeNanos - mLastFrameTimeNanos) * 0.000001f) + " ms");
+ }
+
+ long intendedFrameTimeNanos = frameTimeNanos;
+ startNanos = System.nanoTime();
+ final long jitterNanos = startNanos - frameTimeNanos;
+ if (jitterNanos >= frameIntervalNanos) {
+ final long skippedFrames = jitterNanos / frameIntervalNanos;
+ if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) {
+ Log.i(TAG, "Skipped " + skippedFrames + " frames! "
+ + "The application may be doing too much work on its main thread.");
+ }
+ final long lastFrameOffset = jitterNanos % frameIntervalNanos;
+ if (DEBUG_JANK) {
+ Log.d(TAG, "Missed vsync by " + (jitterNanos * 0.000001f) + " ms "
+ + "which is more than the frame interval of "
+ + (frameIntervalNanos * 0.000001f) + " ms! "
+ + "Skipping " + skippedFrames + " frames and setting frame "
+ + "time to " + (lastFrameOffset * 0.000001f) + " ms in the past.");
+ }
+ frameTimeNanos = startNanos - lastFrameOffset;
+ }
+
+ if (frameTimeNanos < mLastFrameTimeNanos) {
+ if (DEBUG_JANK) {
+ Log.d(TAG, "Frame time appears to be going backwards. May be due to a "
+ + "previously skipped frame. Waiting for next vsync.");
+ }
+ traceMessage("Frame time goes backward");
+ scheduleVsyncLocked();
+ return;
+ }
+
+ if (mFPSDivisor > 1) {
+ long timeSinceVsync = frameTimeNanos - mLastFrameTimeNanos;
+ if (timeSinceVsync < (frameIntervalNanos * mFPSDivisor) && timeSinceVsync > 0) {
+ traceMessage("Frame skipped due to FPSDivisor");
+ scheduleVsyncLocked();
+ return;
+ }
+ }
+
+ mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos, vsyncEventData.id,
+ vsyncEventData.frameDeadline, startNanos, vsyncEventData.frameInterval);
+ mFrameScheduled = false;
+ mLastFrameTimeNanos = frameTimeNanos;
+ mLastFrameIntervalNanos = frameIntervalNanos;
+ mLastVsyncEventData = vsyncEventData;
+ }
+
AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS);
mFrameInfo.markInputHandlingStart();
@@ -870,7 +878,12 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private void scheduleVsyncLocked() {
- mDisplayEventReceiver.scheduleVsync();
+ try {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Choreographer#scheduleVsyncLocked");
+ mDisplayEventReceiver.scheduleVsync();
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
}
private boolean isRunningOnLooperThreadLocked() {
@@ -967,32 +980,40 @@
@Override
public void onVsync(long timestampNanos, long physicalDisplayId, int frame,
VsyncEventData vsyncEventData) {
- // Post the vsync event to the Handler.
- // The idea is to prevent incoming vsync events from completely starving
- // the message queue. If there are no messages in the queue with timestamps
- // earlier than the frame time, then the vsync event will be processed immediately.
- // Otherwise, messages that predate the vsync event will be handled first.
- long now = System.nanoTime();
- if (timestampNanos > now) {
- Log.w(TAG, "Frame time is " + ((timestampNanos - now) * 0.000001f)
- + " ms in the future! Check that graphics HAL is generating vsync "
- + "timestamps using the correct timebase.");
- timestampNanos = now;
- }
+ try {
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW,
+ "Choreographer#onVsync " + vsyncEventData.id);
+ }
+ // Post the vsync event to the Handler.
+ // The idea is to prevent incoming vsync events from completely starving
+ // the message queue. If there are no messages in the queue with timestamps
+ // earlier than the frame time, then the vsync event will be processed immediately.
+ // Otherwise, messages that predate the vsync event will be handled first.
+ long now = System.nanoTime();
+ if (timestampNanos > now) {
+ Log.w(TAG, "Frame time is " + ((timestampNanos - now) * 0.000001f)
+ + " ms in the future! Check that graphics HAL is generating vsync "
+ + "timestamps using the correct timebase.");
+ timestampNanos = now;
+ }
- if (mHavePendingVsync) {
- Log.w(TAG, "Already have a pending vsync event. There should only be "
- + "one at a time.");
- } else {
- mHavePendingVsync = true;
- }
+ if (mHavePendingVsync) {
+ Log.w(TAG, "Already have a pending vsync event. There should only be "
+ + "one at a time.");
+ } else {
+ mHavePendingVsync = true;
+ }
- mTimestampNanos = timestampNanos;
- mFrame = frame;
- mLastVsyncEventData = vsyncEventData;
- Message msg = Message.obtain(mHandler, this);
- msg.setAsynchronous(true);
- mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
+ mTimestampNanos = timestampNanos;
+ mFrame = frame;
+ mLastVsyncEventData = vsyncEventData;
+ Message msg = Message.obtain(mHandler, this);
+ msg.setAsynchronous(true);
+ mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
}
@Override
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 0f032e9..88406ff 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -858,4 +858,6 @@
void unregisterCrossWindowBlurEnabledListener(ICrossWindowBlurEnabledListener listener);
void setForceCrossWindowBlurDisabled(boolean disable);
+
+ boolean isTaskSnapshotSupported();
}
diff --git a/core/java/android/view/ScrollCaptureConnection.java b/core/java/android/view/ScrollCaptureConnection.java
index a6d786e..5fcb011 100644
--- a/core/java/android/view/ScrollCaptureConnection.java
+++ b/core/java/android/view/ScrollCaptureConnection.java
@@ -185,7 +185,8 @@
}
Log.w(TAG, "close(): capture session still active! Ending now.");
// -> UiThread
- mUiThread.execute(() -> mLocal.onScrollCaptureEnd(() -> { /* ignore */ }));
+ final ScrollCaptureCallback callback = mLocal;
+ mUiThread.execute(() -> callback.onScrollCaptureEnd(() -> { /* ignore */ }));
mActive = false;
}
mActive = false;
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 21f75d4..4977a6e 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -35,6 +35,7 @@
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.Bitmap;
import android.graphics.ColorSpace;
+import android.graphics.GraphicBuffer;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Point;
@@ -188,6 +189,10 @@
IBinder displayToken, int mode);
private static native void nativeReparent(long transactionObj, long nativeObject,
long newParentNativeObject);
+ private static native void nativeSetBuffer(long transactionObj, long nativeObject,
+ GraphicBuffer buffer);
+ private static native void nativeSetColorSpace(long transactionObj, long nativeObject,
+ int colorSpace);
private static native void nativeOverrideHdrTypes(IBinder displayToken, int[] modes);
@@ -2590,6 +2595,16 @@
= sRegistry.registerNativeAllocation(this, mNativeObject);
}
+ /**
+ * Create a transaction object that wraps a native peer.
+ * @hide
+ */
+ Transaction(long nativeObject) {
+ mNativeObject = nativeObject;
+ mFreeNativeResources =
+ sRegistry.registerNativeAllocation(this, mNativeObject);
+ }
+
private Transaction(Parcel in) {
readFromParcel(in);
}
@@ -3362,6 +3377,31 @@
return this;
}
+ /**
+ * Set a buffer for a SurfaceControl. This can only be used for SurfaceControls that were
+ * created as type {@link #FX_SURFACE_BLAST}
+ *
+ * @hide
+ */
+ public Transaction setBuffer(SurfaceControl sc, GraphicBuffer buffer) {
+ checkPreconditions(sc);
+ nativeSetBuffer(mNativeObject, sc.mNativeObject, buffer);
+ return this;
+ }
+
+ /**
+ * Set the color space for the SurfaceControl. The supported color spaces are SRGB
+ * and Display P3, other color spaces will be treated as SRGB. This can only be used for
+ * SurfaceControls that were created as type {@link #FX_SURFACE_BLAST}
+ *
+ * @hide
+ */
+ public Transaction setColorSpace(SurfaceControl sc, ColorSpace colorSpace) {
+ checkPreconditions(sc);
+ nativeSetColorSpace(mNativeObject, sc.mNativeObject, colorSpace.getId());
+ return this;
+ }
+
/**
* Merge the other transaction into this transaction, clearing the
* other transaction as if it had been applied.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d6b5a2c..a757295 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -30927,7 +30927,6 @@
* @param executor The executor that the callback should be invoked on.
* @param callback The callback to handle the results of generating the display hash
*/
- @Nullable
public void generateDisplayHash(@NonNull String hashAlgorithm,
@Nullable Rect bounds, @NonNull Executor executor,
@NonNull DisplayHashResultCallback callback) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 76eb882..3cfda57 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1355,6 +1355,16 @@
}
}
+ private void addASurfaceTransactionCallback() {
+ HardwareRenderer.ASurfaceTransactionCallback callback = (nativeTransactionObj,
+ nativeSurfaceControlObj,
+ frameNr) -> {
+ Transaction t = new Transaction(nativeTransactionObj);
+ mergeWithNextTransaction(t, frameNr);
+ };
+ mAttachInfo.mThreadedRenderer.setASurfaceTransactionCallback(callback);
+ }
+
@UnsupportedAppUsage
private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
mAttachInfo.mHardwareAccelerated = false;
@@ -1391,6 +1401,7 @@
final boolean translucent = attrs.format != PixelFormat.OPAQUE || hasSurfaceInsets;
mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(mContext, translucent,
attrs.getTitle().toString());
+ addASurfaceTransactionCallback();
mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl);
updateColorModeIfNeeded(attrs.getColorMode());
updateForceDarkMode();
@@ -9309,11 +9320,11 @@
* Handles an inbound request for scroll capture from the system. A search will be
* dispatched through the view tree to locate scrolling content.
* <p>
- * A call to {@link IScrollCaptureCallbacks#onScrollCaptureResponse(ScrollCaptureResponse)}
- * will follow.
+ * A call to
+ * {@link IScrollCaptureResponseListener#onScrollCaptureResponse} will follow.
*
* @param listener to receive responses
- * @see ScrollCaptureTargetSelector
+ * @see ScrollCaptureSearchResults
*/
public void handleScrollCaptureRequest(@NonNull IScrollCaptureResponseListener listener) {
ScrollCaptureSearchResults results =
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index cca8257..60516eb 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -4568,4 +4568,13 @@
default void holdLock(IBinder token, int durationMs) {
throw new UnsupportedOperationException();
}
+
+ /**
+ * Used for testing to check if the system supports TaskSnapshot mechanism.
+ * @hide
+ */
+ @TestApi
+ default boolean isTaskSnapshotSupported() {
+ return false;
+ }
}
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 2bed311..07eeb03 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -335,4 +335,13 @@
} catch (RemoteException e) {
}
}
+
+ @Override
+ public boolean isTaskSnapshotSupported() {
+ try {
+ return WindowManagerGlobal.getWindowManagerService().isTaskSnapshotSupported();
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
}
diff --git a/core/java/android/view/displayhash/DisplayHash.java b/core/java/android/view/displayhash/DisplayHash.java
index 4148486..4ec0a59 100644
--- a/core/java/android/view/displayhash/DisplayHash.java
+++ b/core/java/android/view/displayhash/DisplayHash.java
@@ -16,6 +16,7 @@
package android.view.displayhash;
+import android.annotation.CurrentTimeMillisLong;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.graphics.Rect;
@@ -31,6 +32,7 @@
/**
* The timestamp when the hash was generated.
*/
+ @CurrentTimeMillisLong
private final long mTimeMillis;
/**
@@ -73,7 +75,7 @@
* @hide
*/
@SystemApi
- public DisplayHash(long timeMillis, @NonNull Rect boundsInWindow,
+ public DisplayHash(@CurrentTimeMillisLong long timeMillis, @NonNull Rect boundsInWindow,
@NonNull String hashAlgorithm, @NonNull byte[] imageHash, @NonNull byte[] hmac) {
mTimeMillis = timeMillis;
mBoundsInWindow = boundsInWindow;
@@ -92,6 +94,7 @@
* @hide
*/
@SystemApi
+ @CurrentTimeMillisLong
public long getTimeMillis() {
return mTimeMillis;
}
diff --git a/core/java/android/view/displayhash/DisplayHashManager.java b/core/java/android/view/displayhash/DisplayHashManager.java
index 69dfc38..4f5fef6 100644
--- a/core/java/android/view/displayhash/DisplayHashManager.java
+++ b/core/java/android/view/displayhash/DisplayHashManager.java
@@ -35,7 +35,8 @@
import java.util.Set;
/**
- * Utility class for DisplayHash requests.
+ * Manages DisplayHash requests. The manager object can be retrieved by calling
+ * {@code Context.getSystemService(Context.DISPLAY_HASH_SERVICE)}
*/
@SystemService(DISPLAY_HASH_SERVICE)
public final class DisplayHashManager {
@@ -75,7 +76,7 @@
return sSupportedHashAlgorithms;
} catch (RemoteException e) {
Log.e(TAG, "Failed to send request getSupportedHashingAlgorithms", e);
- return Collections.emptySet();
+ throw e.rethrowFromSystemServer();
}
}
}
@@ -93,7 +94,7 @@
return WindowManagerGlobal.getWindowManagerService().verifyDisplayHash(displayHash);
} catch (RemoteException e) {
Log.e(TAG, "Failed to send request verifyImpressionToken", e);
- return null;
+ throw e.rethrowFromSystemServer();
}
}
diff --git a/core/java/android/view/displayhash/VerifiedDisplayHash.java b/core/java/android/view/displayhash/VerifiedDisplayHash.java
index 16a428e..b17c068 100644
--- a/core/java/android/view/displayhash/VerifiedDisplayHash.java
+++ b/core/java/android/view/displayhash/VerifiedDisplayHash.java
@@ -16,6 +16,7 @@
package android.view.displayhash;
+import android.annotation.CurrentTimeMillisLong;
import android.annotation.NonNull;
import android.graphics.Rect;
import android.os.Parcelable;
@@ -30,6 +31,7 @@
/**
* The timestamp when the hash was generated.
*/
+ @CurrentTimeMillisLong
private final long mTimeMillis;
/**
@@ -78,7 +80,7 @@
- // Code below generated by codegen v1.0.22.
+ // Code below generated by codegen v1.0.23.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -106,11 +108,13 @@
*/
@DataClass.Generated.Member
public VerifiedDisplayHash(
- long timeMillis,
+ @CurrentTimeMillisLong long timeMillis,
@NonNull Rect boundsInWindow,
@NonNull String hashAlgorithm,
@NonNull byte[] imageHash) {
this.mTimeMillis = timeMillis;
+ com.android.internal.util.AnnotationValidations.validate(
+ CurrentTimeMillisLong.class, null, mTimeMillis);
this.mBoundsInWindow = boundsInWindow;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mBoundsInWindow);
@@ -128,7 +132,7 @@
* The timestamp when the hash was generated.
*/
@DataClass.Generated.Member
- public long getTimeMillis() {
+ public @CurrentTimeMillisLong long getTimeMillis() {
return mTimeMillis;
}
@@ -200,6 +204,8 @@
byte[] imageHash = in.createByteArray();
this.mTimeMillis = timeMillis;
+ com.android.internal.util.AnnotationValidations.validate(
+ CurrentTimeMillisLong.class, null, mTimeMillis);
this.mBoundsInWindow = boundsInWindow;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mBoundsInWindow);
@@ -228,10 +234,10 @@
};
@DataClass.Generated(
- time = 1613168749684L,
- codegenVersion = "1.0.22",
+ time = 1617747271440L,
+ codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/view/displayhash/VerifiedDisplayHash.java",
- inputSignatures = "private final long mTimeMillis\nprivate final @android.annotation.NonNull android.graphics.Rect mBoundsInWindow\nprivate final @android.annotation.NonNull java.lang.String mHashAlgorithm\nprivate final @android.annotation.NonNull byte[] mImageHash\nprivate java.lang.String imageHashToString()\nprivate java.lang.String byteArrayToString(byte[])\nclass VerifiedDisplayHash extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genAidl=true)")
+ inputSignatures = "private final @android.annotation.CurrentTimeMillisLong long mTimeMillis\nprivate final @android.annotation.NonNull android.graphics.Rect mBoundsInWindow\nprivate final @android.annotation.NonNull java.lang.String mHashAlgorithm\nprivate final @android.annotation.NonNull byte[] mImageHash\nprivate java.lang.String imageHashToString()\nprivate java.lang.String byteArrayToString(byte[])\nclass VerifiedDisplayHash extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genAidl=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 616910a..d6292ca 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -581,7 +581,7 @@
*/
public void reportPerceptible(IBinder windowToken, boolean perceptible) {
try {
- mService.reportPerceptible(windowToken, perceptible);
+ mService.reportPerceptibleAsync(windowToken, perceptible);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/view/translation/ITranslationDirectManager.aidl b/core/java/android/view/translation/ITranslationDirectManager.aidl
index 525a779..6b00c07 100644
--- a/core/java/android/view/translation/ITranslationDirectManager.aidl
+++ b/core/java/android/view/translation/ITranslationDirectManager.aidl
@@ -16,6 +16,7 @@
package android.view.translation;
+import android.os.ICancellationSignal;
import android.view.translation.TranslationRequest;
import android.service.translation.ITranslationCallback;
@@ -27,6 +28,6 @@
*/
oneway interface ITranslationDirectManager {
void onTranslationRequest(in TranslationRequest request, int sessionId,
- in ITranslationCallback callback);
+ in ICancellationSignal transport, in ITranslationCallback callback);
void onFinishTranslationSession(int sessionId);
}
diff --git a/core/java/android/view/translation/Translator.java b/core/java/android/view/translation/Translator.java
index 6b26e06..188d562 100644
--- a/core/java/android/view/translation/Translator.java
+++ b/core/java/android/view/translation/Translator.java
@@ -26,8 +26,10 @@
import android.content.Context;
import android.os.Binder;
import android.os.Bundle;
+import android.os.CancellationSignal;
import android.os.Handler;
import android.os.IBinder;
+import android.os.ICancellationSignal;
import android.os.RemoteException;
import android.service.translation.ITranslationCallback;
import android.util.Log;
@@ -227,11 +229,13 @@
*
* @param request {@link TranslationRequest} request to be translate.
*
- * @return {@link TranslationRequest} containing translated request,
- * or null if translation could not be done.
- * @throws IllegalStateException if this TextClassification session was destroyed when calls
+ * @throws IllegalStateException if this Translator session was destroyed when called.
+ *
+ * @deprecated use {@link #translate(TranslationRequest, CancellationSignal,
+ * Executor, Consumer)} instead.
+ * @hide
*/
- //TODO: Add cancellation signal
+ @Deprecated
@Nullable
public void translate(@NonNull TranslationRequest request,
@NonNull @CallbackExecutor Executor executor,
@@ -250,7 +254,52 @@
final ITranslationCallback responseCallback =
new TranslationResponseCallbackImpl(callback, executor);
try {
- mDirectServiceBinder.onTranslationRequest(request, mId, responseCallback);
+ mDirectServiceBinder.onTranslationRequest(request, mId,
+ CancellationSignal.createTransport(), responseCallback);
+ } catch (RemoteException e) {
+ Log.w(TAG, "RemoteException calling requestTranslate(): " + e);
+ }
+ }
+
+ /**
+ * Requests a translation for the provided {@link TranslationRequest} using the Translator's
+ * source spec and destination spec.
+ *
+ * @param request {@link TranslationRequest} request to be translate.
+ * @param cancellationSignal signal to cancel the operation in progress.
+ * @param executor Executor to run callback operations
+ * @param callback {@link Consumer} to receive the translation response. Multiple responses may
+ * be received if {@link TranslationRequest#FLAG_PARTIAL_RESPONSES} is set.
+ *
+ * @throws IllegalStateException if this Translator session was destroyed when called.
+ */
+ @Nullable
+ public void translate(@NonNull TranslationRequest request,
+ @Nullable CancellationSignal cancellationSignal,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<TranslationResponse> callback) {
+ Objects.requireNonNull(request, "Translation request cannot be null");
+ Objects.requireNonNull(executor, "Executor cannot be null");
+ Objects.requireNonNull(callback, "Callback cannot be null");
+
+ if (isDestroyed()) {
+ // TODO(b/176464808): Disallow multiple Translator now, it will throw
+ // IllegalStateException. Need to discuss if we can allow multiple Translators.
+ throw new IllegalStateException(
+ "This translator has been destroyed");
+ }
+
+ ICancellationSignal transport = null;
+ if (cancellationSignal != null) {
+ transport = CancellationSignal.createTransport();
+ cancellationSignal.setRemote(transport);
+ }
+ final ITranslationCallback responseCallback =
+ new TranslationResponseCallbackImpl(callback, executor);
+
+ try {
+ mDirectServiceBinder.onTranslationRequest(request, mId, transport,
+ responseCallback);
} catch (RemoteException e) {
Log.w(TAG, "RemoteException calling requestTranslate(): " + e);
}
@@ -298,7 +347,8 @@
final ITranslationCallback translationCallback =
new TranslationResponseCallbackImpl(callback, executor);
try {
- mDirectServiceBinder.onTranslationRequest(request, mId, translationCallback);
+ mDirectServiceBinder.onTranslationRequest(request, mId,
+ CancellationSignal.createTransport(), translationCallback);
} catch (RemoteException e) {
Log.w(TAG, "RemoteException calling flushRequest");
}
diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java
index c09e8bd..00aeede 100644
--- a/core/java/android/view/translation/UiTranslationController.java
+++ b/core/java/android/view/translation/UiTranslationController.java
@@ -362,17 +362,20 @@
continue;
}
mActivity.runOnUiThread(() -> {
- if (view.getViewTranslationCallback() == null) {
+ final ViewTranslationCallback callback = view.getViewTranslationCallback();
+ if (callback == null) {
if (DEBUG) {
Log.d(TAG, view + " doesn't support showing translation because of "
+ "null ViewTranslationCallback.");
}
return;
}
+
+ // TODO: Do this for specific views on request only.
+ callback.enableContentPadding();
+
view.onTranslationResponse(response);
- if (view.getViewTranslationCallback() != null) {
- view.getViewTranslationCallback().onShowTranslation(view);
- }
+ callback.onShowTranslation(view);
});
}
}
diff --git a/core/java/android/view/translation/ViewTranslationCallback.java b/core/java/android/view/translation/ViewTranslationCallback.java
index c895984..78b4855 100644
--- a/core/java/android/view/translation/ViewTranslationCallback.java
+++ b/core/java/android/view/translation/ViewTranslationCallback.java
@@ -48,4 +48,16 @@
* @return {@code true} if the View handles clearing the translation.
*/
boolean onClearTranslation(@NonNull View view);
+
+ /**
+ * Enables padding on the view's original content.
+ * <p>
+ * This is useful when we do not modify the content directly, rather use a mechanism like
+ * {@link android.text.method.TransformationMethod}. If the app misbehaves when the displayed
+ * translation and the underlying content have different sizes, the platform intelligence can
+ * request that the original content be padded to make the sizes match.
+ *
+ * @hide
+ */
+ default void enableContentPadding() {}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 40c79cf..1953a76 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -770,6 +770,8 @@
private final boolean mUseInternationalizedInput;
// True if fallback fonts that end up getting used should be allowed to affect line spacing.
/* package */ boolean mUseFallbackLineSpacing;
+ // True if the view text can be padded for compat reasons, when the view is translated.
+ private final boolean mUseTextPaddingForUiTranslation;
@ViewDebug.ExportedProperty(category = "text")
@UnsupportedAppUsage
@@ -1480,6 +1482,8 @@
final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
mUseInternationalizedInput = targetSdkVersion >= VERSION_CODES.O;
mUseFallbackLineSpacing = targetSdkVersion >= VERSION_CODES.P;
+ // TODO(b/179693024): Use a ChangeId instead.
+ mUseTextPaddingForUiTranslation = targetSdkVersion <= Build.VERSION_CODES.R;
if (inputMethod != null) {
Class<?> c;
@@ -2372,6 +2376,12 @@
@ViewDebug.CapturedViewProperty
@InspectableProperty
public CharSequence getText() {
+ if (mUseTextPaddingForUiTranslation
+ && mDefaultTranslationCallback != null
+ && mDefaultTranslationCallback.isTextPaddingEnabled()
+ && mDefaultTranslationCallback.isShowingTranslation()) {
+ return mDefaultTranslationCallback.getPaddedText(mText, mTransformed);
+ }
return mText;
}
diff --git a/core/java/android/widget/TextViewTranslationCallback.java b/core/java/android/widget/TextViewTranslationCallback.java
index a479b8a..73f19a7 100644
--- a/core/java/android/widget/TextViewTranslationCallback.java
+++ b/core/java/android/widget/TextViewTranslationCallback.java
@@ -17,6 +17,7 @@
package android.widget;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.Build;
import android.text.method.TranslationTransformationMethod;
import android.util.Log;
@@ -33,7 +34,7 @@
*/
public class TextViewTranslationCallback implements ViewTranslationCallback {
- private static final String TAG = "TextViewTranslationCallback";
+ private static final String TAG = "TextViewTranslationCb";
// TODO(b/182433547): remove Build.IS_DEBUGGABLE before ship. Enable the logging in debug build
// to help the debug during the development phase
@@ -41,6 +42,9 @@
|| Build.IS_DEBUGGABLE;
private TranslationTransformationMethod mTranslationTransformation;
+ private boolean mIsShowingTranslation = false;
+ private boolean mIsTextPaddingEnabled = false;
+ private CharSequence mPaddedText;
/**
* Invoked by the platform when receiving the successful {@link ViewTranslationResponse} for the
@@ -74,6 +78,7 @@
*/
@Override
public boolean onShowTranslation(@NonNull View view) {
+ mIsShowingTranslation = true;
if (mTranslationTransformation != null) {
((TextView) view).setTransformationMethod(mTranslationTransformation);
} else {
@@ -90,6 +95,7 @@
*/
@Override
public boolean onHideTranslation(@NonNull View view) {
+ mIsShowingTranslation = false;
// Restore to original text content.
if (mTranslationTransformation != null) {
((TextView) view).setTransformationMethod(
@@ -110,9 +116,9 @@
public boolean onClearTranslation(@NonNull View view) {
// Restore to original text content and clear TranslationTransformation
if (mTranslationTransformation != null) {
- ((TextView) view).setTransformationMethod(
- mTranslationTransformation.getOriginalTransformationMethod());
+ onHideTranslation(view);
clearTranslationTransformation();
+ mPaddedText = null;
} else {
if (DEBUG) {
// TODO(b/182433547): remove before S release
@@ -121,4 +127,59 @@
}
return true;
}
+
+ boolean isShowingTranslation() {
+ return mIsShowingTranslation;
+ }
+
+ @Override
+ public void enableContentPadding() {
+ mIsTextPaddingEnabled = true;
+ }
+
+ /**
+ * Returns whether readers of the view text should receive padded text for compatibility
+ * reasons. The view's original text will be padded to match the length of the translated text.
+ */
+ boolean isTextPaddingEnabled() {
+ return mIsTextPaddingEnabled;
+ }
+
+ /**
+ * Returns the view's original text with padding added. If the translated text isn't longer than
+ * the original text, returns the original text itself.
+ *
+ * @param text the view's original text
+ * @param translatedText the view's translated text
+ * @see #isTextPaddingEnabled()
+ */
+ @Nullable
+ CharSequence getPaddedText(CharSequence text, CharSequence translatedText) {
+ if (text == null) {
+ return null;
+ }
+ if (mPaddedText == null) {
+ mPaddedText = computePaddedText(text, translatedText);
+ }
+ return mPaddedText;
+ }
+
+ @NonNull
+ private CharSequence computePaddedText(CharSequence text, CharSequence translatedText) {
+ if (translatedText == null) {
+ return text;
+ }
+ int newLength = translatedText.length();
+ if (newLength <= text.length()) {
+ return text;
+ }
+ StringBuilder sb = new StringBuilder(newLength);
+ sb.append(text);
+ for (int i = text.length(); i < newLength; i++) {
+ sb.append(COMPAT_PAD_CHARACTER);
+ }
+ return sb;
+ }
+
+ private static final char COMPAT_PAD_CHARACTER = '\u2002';
}
diff --git a/core/java/android/window/StartingWindowInfo.java b/core/java/android/window/StartingWindowInfo.java
index 08bb1a9..385d6cff 100644
--- a/core/java/android/window/StartingWindowInfo.java
+++ b/core/java/android/window/StartingWindowInfo.java
@@ -142,6 +142,12 @@
*/
public boolean isKeyguardOccluded = false;
+ /**
+ * TaskSnapshot.
+ * @hide
+ */
+ public TaskSnapshot mTaskSnapshot;
+
public StartingWindowInfo() {
}
@@ -164,6 +170,7 @@
dest.writeTypedObject(mainWindowLayoutParams, flags);
dest.writeInt(splashScreenThemeResId);
dest.writeBoolean(isKeyguardOccluded);
+ dest.writeTypedObject(mTaskSnapshot, flags);
}
void readFromParcel(@NonNull Parcel source) {
@@ -175,6 +182,7 @@
mainWindowLayoutParams = source.readTypedObject(WindowManager.LayoutParams.CREATOR);
splashScreenThemeResId = source.readInt();
isKeyguardOccluded = source.readBoolean();
+ mTaskSnapshot = source.readTypedObject(TaskSnapshot.CREATOR);
}
@Override
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
index 9d06bb9..0854955 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
@@ -230,7 +230,6 @@
context.getDrawable(R.drawable.ic_accessibility_color_inversion),
Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
- // TODO: Update with shortcut icon
final ToggleAllowListingFeatureTarget reduceBrightColors =
new ToggleAllowListingFeatureTarget(context,
shortcutType,
@@ -238,7 +237,7 @@
REDUCE_BRIGHT_COLORS_COMPONENT_NAME.flattenToString()),
REDUCE_BRIGHT_COLORS_COMPONENT_NAME.flattenToString(),
context.getString(R.string.reduce_bright_colors_feature_name),
- null,
+ context.getDrawable(R.drawable.ic_accessibility_reduce_bright_colors),
Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED);
targets.add(magnification);
diff --git a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
index 20e520e..4365966 100644
--- a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
+++ b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
@@ -30,7 +30,7 @@
*/
oneway interface IInputMethodPrivilegedOperations {
void setImeWindowStatusAsync(int vis, int backDisposition);
- void reportStartInput(in IBinder startInputToken, in IVoidResultCallback resultCallback);
+ void reportStartInputAsync(in IBinder startInputToken);
void createInputContentUriToken(in Uri contentUri, in String packageName,
in IIInputContentUriTokenResultCallback resultCallback);
void reportFullscreenMode(boolean fullscreen, in IVoidResultCallback resultCallback);
diff --git a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
index 1000914..555488d 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
@@ -123,21 +123,18 @@
}
/**
- * Calls {@link IInputMethodPrivilegedOperations#reportStartInput(IBinder,
- * IVoidResultCallback)}.
+ * Calls {@link IInputMethodPrivilegedOperations#reportStartInputAsync(IBinder)}.
*
* @param startInputToken {@link IBinder} token to distinguish startInput session
*/
@AnyThread
- public void reportStartInput(IBinder startInputToken) {
+ public void reportStartInputAsync(IBinder startInputToken) {
final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
if (ops == null) {
return;
}
try {
- final Completable.Void value = Completable.createVoid();
- ops.reportStartInput(startInputToken, ResultCallbacks.of(value));
- Completable.getResult(value);
+ ops.reportStartInputAsync(startInputToken);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/com/android/internal/os/BinderLatencyObserver.java b/core/java/com/android/internal/os/BinderLatencyObserver.java
index 4ca59be..0079801 100644
--- a/core/java/com/android/internal/os/BinderLatencyObserver.java
+++ b/core/java/com/android/internal/os/BinderLatencyObserver.java
@@ -157,7 +157,10 @@
FrameworkStatsLog.BINDER_LATENCY_REPORTED,
atom.getBytes(),
mPeriodicSamplingInterval,
- 1);
+ 1,
+ mBucketCount,
+ mFirstBucketSize,
+ mBucketScaleFactor);
}
private void noteLatencyDelayed() {
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index e438d39..a0a0f32 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -92,7 +92,7 @@
void notifyRegistrationFailed(int slotIndex, int subId, in CellIdentity cellIdentity,
String chosenPlmn, int domain, int causeCode, int additionalCauseCode);
void notifyBarringInfoChanged(int slotIndex, int subId, in BarringInfo barringInfo);
- void notifyPhysicalChannelConfigForSubscriber(in int subId,
+ void notifyPhysicalChannelConfigForSubscriber(in int phoneId, in int subId,
in List<PhysicalChannelConfig> configs);
void notifyDataEnabled(in int phoneId, int subId, boolean enabled, int reason);
void notifyAllowedNetworkTypesChanged(in int phoneId, in int subId, in int reason, in long allowedNetworkType);
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index 90c7282..61a5014 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -95,6 +95,11 @@
*/
public static final int ACTION_START_RECENTS_ANIMATION = 8;
+ /**
+ * Time it takes the sensor to detect rotation.
+ */
+ public static final int ACTION_ROTATE_SCREEN_SENSOR = 9;
+
private static final int[] ACTIONS_ALL = {
ACTION_EXPAND_PANEL,
ACTION_TOGGLE_RECENTS,
@@ -104,7 +109,8 @@
ACTION_TURN_ON_SCREEN,
ACTION_ROTATE_SCREEN,
ACTION_FACE_WAKE_AND_UNLOCK,
- ACTION_START_RECENTS_ANIMATION
+ ACTION_START_RECENTS_ANIMATION,
+ ACTION_ROTATE_SCREEN_SENSOR
};
/** @hide */
@@ -117,7 +123,8 @@
ACTION_TURN_ON_SCREEN,
ACTION_ROTATE_SCREEN,
ACTION_FACE_WAKE_AND_UNLOCK,
- ACTION_START_RECENTS_ANIMATION
+ ACTION_START_RECENTS_ANIMATION,
+ ACTION_ROTATE_SCREEN_SENSOR
})
@Retention(RetentionPolicy.SOURCE)
public @interface Action {
@@ -133,6 +140,7 @@
FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN,
FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK,
FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_START_RECENTS_ANIMATION,
+ FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_SENSOR
};
private static LatencyTracker sLatencyTracker;
@@ -209,6 +217,8 @@
return "ACTION_FACE_WAKE_AND_UNLOCK";
case 9:
return "ACTION_START_RECENTS_ANIMATION";
+ case 11:
+ return "ACTION_ROTATE_SCREEN_SENSOR";
default:
throw new IllegalArgumentException("Invalid action");
}
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index fd13c26b..93cd4e9 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -85,7 +85,7 @@
oneway void reportActivityView(in IInputMethodClient parentClient, int childDisplayId,
in float[] matrixValues, in IVoidResultCallback resultCallback);
- oneway void reportPerceptible(in IBinder windowToken, boolean perceptible);
+ oneway void reportPerceptibleAsync(in IBinder windowToken, boolean perceptible);
/** Remove the IME surface. Requires INTERNAL_SYSTEM_WINDOW permission. */
oneway void removeImeSurface(in IVoidResultCallback resultCallback);
/** Remove the IME surface. Requires passing the currently focused window. */
diff --git a/core/java/com/android/internal/view/RecyclerViewCaptureHelper.java b/core/java/com/android/internal/view/RecyclerViewCaptureHelper.java
index 934241a..75bf1ce 100644
--- a/core/java/com/android/internal/view/RecyclerViewCaptureHelper.java
+++ b/core/java/com/android/internal/view/RecyclerViewCaptureHelper.java
@@ -105,6 +105,14 @@
int prevAnchorTop = anchor.getTop();
// Note: requestChildRectangleOnScreen may modify rectangle, must pass pass in a copy here
Rect input = new Rect(requestedContentBounds);
+ // Expand input rect to get the requested rect to be in the center
+ int remainingHeight = recyclerView.getHeight() - recyclerView.getPaddingTop()
+ - recyclerView.getPaddingBottom() - input.height();
+ if (remainingHeight > 0) {
+ input.inset(0, -remainingHeight / 2);
+ }
+ Log.d(TAG, "input (post center adjustment) = " + input);
+
if (recyclerView.requestChildRectangleOnScreen(anchor, input, true)) {
int scrolled = prevAnchorTop - anchor.getTop(); // inverse of movement
Log.d(TAG, "RecyclerView scrolled by " + scrolled + " px");
diff --git a/core/java/com/android/internal/view/ScrollCaptureViewSupport.java b/core/java/com/android/internal/view/ScrollCaptureViewSupport.java
index a41511b..8aa2d57 100644
--- a/core/java/com/android/internal/view/ScrollCaptureViewSupport.java
+++ b/core/java/com/android/internal/view/ScrollCaptureViewSupport.java
@@ -17,6 +17,7 @@
package com.android.internal.view;
import android.annotation.UiThread;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.HardwareRenderer;
@@ -26,6 +27,7 @@
import android.graphics.RectF;
import android.graphics.RenderNode;
import android.os.CancellationSignal;
+import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display.ColorMode;
@@ -53,11 +55,14 @@
private static final String TAG = "ScrollCaptureViewSupport";
- private static final boolean WAIT_FOR_ANIMATION = true;
+ private static final String SETTING_CAPTURE_DELAY = "screenshot.scroll_capture_delay";
+ private static final long SETTING_CAPTURE_DELAY_DEFAULT = 60L; // millis
private final WeakReference<V> mWeakView;
private final ScrollCaptureViewHelper<V> mViewHelper;
private final ViewRenderer mRenderer;
+ private final long mPostScrollDelayMillis;
+
private boolean mStarted;
private boolean mEnded;
@@ -66,6 +71,10 @@
mRenderer = new ViewRenderer();
// TODO(b/177649144): provide access to color space from android.media.Image
mViewHelper = viewHelper;
+ Context context = containingView.getContext();
+ ContentResolver contentResolver = context.getContentResolver();
+ mPostScrollDelayMillis = Settings.Global.getLong(contentResolver,
+ SETTING_CAPTURE_DELAY, SETTING_CAPTURE_DELAY_DEFAULT);
}
/** Based on ViewRootImpl#updateColorModeIfNeeded */
@@ -120,37 +129,41 @@
public final void onScrollCaptureImageRequest(ScrollCaptureSession session,
CancellationSignal signal, Rect requestRect, Consumer<Rect> onComplete) {
if (signal.isCanceled()) {
+ Log.w(TAG, "onScrollCaptureImageRequest: cancelled!");
return;
}
+
V view = mWeakView.get();
if (view == null || !view.isVisibleToUser()) {
// Signal to the controller that we have a problem and can't continue.
onComplete.accept(new Rect());
return;
}
+
// Ask the view to scroll as needed to bring this area into view.
ScrollResult scrollResult = mViewHelper.onScrollRequested(view, session.getScrollBounds(),
requestRect);
+
if (scrollResult.availableArea.isEmpty()) {
onComplete.accept(scrollResult.availableArea);
return;
}
- view.invalidate(); // don't wait for vsync
// For image capture, shift back by scrollDelta to arrive at the location within the view
// where the requested content will be drawn
Rect viewCaptureArea = new Rect(scrollResult.availableArea);
viewCaptureArea.offset(0, -scrollResult.scrollDelta);
- if (WAIT_FOR_ANIMATION) {
- view.postOnAnimation(() -> {
+ Runnable captureAction = () -> {
+ if (signal.isCanceled()) {
+ Log.w(TAG, "onScrollCaptureImageRequest: cancelled! skipping render.");
+ } else {
mRenderer.renderView(view, viewCaptureArea);
onComplete.accept(new Rect(scrollResult.availableArea));
- });
- } else {
- mRenderer.renderView(view, viewCaptureArea);
- onComplete.accept(new Rect(scrollResult.availableArea));
- }
+ }
+ };
+
+ view.postOnAnimationDelayed(captureAction, mPostScrollDelayMillis);
}
@Override
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index ffba628..4194acb 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -30,6 +30,7 @@
#include <android/hardware/display/IDeviceProductInfoConstants.h>
#include <android/os/IInputConstants.h>
#include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/android_graphics_GraphicBuffer.h>
#include <android_runtime/android_hardware_HardwareBuffer.h>
#include <android_runtime/android_view_Surface.h>
#include <android_runtime/android_view_SurfaceSession.h>
@@ -253,6 +254,15 @@
}
}
+constexpr ui::Dataspace fromNamedColorSpaceValueToDataspace(const jint colorSpace) {
+ switch (colorSpace) {
+ case JNamedColorSpace::DISPLAY_P3:
+ return ui::Dataspace::DISPLAY_P3;
+ default:
+ return ui::Dataspace::V0_SRGB;
+ }
+}
+
constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) {
switch (colorMode) {
case ui::ColorMode::DISPLAY_P3:
@@ -553,6 +563,23 @@
transaction->setGeometry(ctrl, source, dst, orientation);
}
+static void nativeSetBuffer(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
+ jobject bufferObject) {
+ auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+ SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
+ sp<GraphicBuffer> buffer(
+ android_graphics_GraphicBuffer_getNativeGraphicsBuffer(env, bufferObject));
+ transaction->setBuffer(ctrl, buffer);
+}
+
+static void nativeSetColorSpace(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
+ jint colorSpace) {
+ auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+ SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
+ ui::Dataspace dataspace = fromNamedColorSpaceValueToDataspace(colorSpace);
+ transaction->setDataspace(ctrl, dataspace);
+}
+
static void nativeSetBlurRegions(JNIEnv* env, jclass clazz, jlong transactionObj,
jlong nativeObject, jobjectArray regions, jint regionsLength) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -1877,6 +1904,10 @@
(void*)nativeGetDisplayedContentSample },
{"nativeSetGeometry", "(JJLandroid/graphics/Rect;Landroid/graphics/Rect;J)V",
(void*)nativeSetGeometry },
+ {"nativeSetBuffer", "(JJLandroid/graphics/GraphicBuffer;)V",
+ (void*)nativeSetBuffer },
+ {"nativeSetColorSpace", "(JJI)V",
+ (void*)nativeSetColorSpace },
{"nativeSyncInputWindows", "(J)V",
(void*)nativeSyncInputWindows },
{"nativeGetDisplayBrightnessSupport", "(Landroid/os/IBinder;)Z",
diff --git a/core/proto/android/internal/OWNERS b/core/proto/android/internal/OWNERS
new file mode 100644
index 0000000..24e24c2
--- /dev/null
+++ b/core/proto/android/internal/OWNERS
@@ -0,0 +1,2 @@
+# Binder
+per-file binder_latency.proto = file:/core/java/com/android/internal/os/BINDER_OWNERS
\ No newline at end of file
diff --git a/core/proto/android/internal/binder_latency.proto b/core/proto/android/internal/binder_latency.proto
index e32c3e3..8b11f5b 100644
--- a/core/proto/android/internal/binder_latency.proto
+++ b/core/proto/android/internal/binder_latency.proto
@@ -34,6 +34,7 @@
UNKNOWN_PROCESS_SOURCE = 0;
SYSTEM_SERVER = 1;
TELEPHONY = 2;
+ BLUETOOTH = 3;
}
enum ServiceClassName {
@@ -74,4 +75,19 @@
// Stores the count of samples for each bucket. The number of buckets and
// their sizes are controlled server side with a flag.
repeated int32 buckets = 3;
-}
\ No newline at end of file
+
+ // Params for histogram buckets.
+ // The number of buckets in the histogram. Store this value separately
+ // as the tail of empty buckets is truncated when stored in the proto to
+ // conserve space. Thus it is not possible to infer this value from there.
+ optional int32 bucket_count = 4;
+
+ // The size (upper bound) of the first bucket (used to avoid creating an
+ // excessive amount of small buckets). E.g. for first_bucket_size of 5, the
+ // first bucket will be [0, 5) and the second will be [5, 5 * scaleFactor).
+ optional int32 first_bucket_size = 5;
+
+ // The rate in which each consecutive bucket increases (before rounding).
+ // Implemented in: com.android.internal.os.BinderLatencyBuckets.
+ optional float scale_factor = 6;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 925a212..9d65e71 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4099,6 +4099,15 @@
<permission android:name="com.android.permission.INSTALL_EXISTING_PACKAGES"
android:protectionLevel="signature|privileged" />
+ <!-- Allows an application to use the package installer v2 APIs.
+ <p>The package installer v2 APIs are still a work in progress and we're
+ currently validating they work in all scenarios.
+ <p>Not for use by third-party applications.
+ @hide
+ -->
+ <permission android:name="com.android.permission.USE_INSTALLER_V2"
+ android:protectionLevel="signature|installer" />
+
<!-- Allows an application to use System Data Loaders.
<p>Not for use by third-party applications.
@hide
@@ -5673,12 +5682,12 @@
<permission android:name="android.permission.CONTROL_DEVICE_STATE"
android:protectionLevel="signature" />
- <!-- Must be required by a
- {@link android.service.displayhash.DisplayHasherService}
+ <!-- @hide @SystemApi Must be required by a
+ {@link android.service.displayhash.DisplayHashingService}
to ensure that only the system can bind to it.
- @hide This is not a third-party API (intended for OEMs and system apps).
+ This is not a third-party API (intended for OEMs and system apps).
-->
- <permission android:name="android.permission.BIND_DISPLAY_HASHER_SERVICE"
+ <permission android:name="android.permission.BIND_DISPLAY_HASHING_SERVICE"
android:protectionLevel="signature" />
<!-- @hide @TestApi Allows an application to enable/disable toast rate limiting.
diff --git a/core/res/res/drawable/ic_accessibility_reduce_bright_colors.xml b/core/res/res/drawable/ic_accessibility_reduce_bright_colors.xml
new file mode 100644
index 0000000..1e840d2
--- /dev/null
+++ b/core/res/res/drawable/ic_accessibility_reduce_bright_colors.xml
@@ -0,0 +1,63 @@
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape android:shape="oval">
+ <solid
+ android:color="@color/GM2_grey_700"/>
+ <size
+ android:height="@dimen/accessibility_icon_size"
+ android:width="@dimen/accessibility_icon_size"/>
+ </shape>
+ </item>
+ <item
+ android:gravity="center">
+ <vector
+ android:width="@dimen/accessibility_icon_foreground_size"
+ android:height="@dimen/accessibility_icon_foreground_size"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M17,12.1L15.59,10.69L13.05,13.22V7.05H11.05V13.22L8.51,10.69L7.1,12.1L12.05,17.05L17,12.1Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M2.05,13.05H4.05C4.6,13.05 5.05,12.6 5.05,12.05C5.05,11.5 4.6,11.05 4.05,11.05H2.05C1.5,11.05 1.05,11.5 1.05,12.05C1.05,12.6 1.5,13.05 2.05,13.05Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M20.05,13.05H22.05C22.6,13.05 23.05,12.6 23.05,12.05C23.05,11.5 22.6,11.05 22.05,11.05H20.05C19.5,11.05 19.05,11.5 19.05,12.05C19.05,12.6 19.5,13.05 20.05,13.05Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M11.05,2.05V4.05C11.05,4.6 11.5,5.05 12.05,5.05C12.6,5.05 13.05,4.6 13.05,4.05V2.05C13.05,1.5 12.6,1.05 12.05,1.05C11.5,1.05 11.05,1.5 11.05,2.05Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M11.05,20.05V22.05C11.05,22.6 11.5,23.05 12.05,23.05C12.6,23.05 13.05,22.6 13.05,22.05V20.05C13.05,19.5 12.6,19.05 12.05,19.05C11.5,19.05 11.05,19.5 11.05,20.05Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M6.04,4.63C5.65,4.24 5.01,4.24 4.63,4.63C4.24,5.02 4.24,5.66 4.63,6.04L5.69,7.1C6.08,7.49 6.72,7.49 7.1,7.1C7.49,6.71 7.49,6.07 7.1,5.69L6.04,4.63Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M18.41,17C18.02,16.61 17.38,16.61 17,17C16.61,17.39 16.61,18.03 17,18.41L18.06,19.47C18.45,19.86 19.09,19.86 19.47,19.47C19.86,19.08 19.86,18.44 19.47,18.06L18.41,17Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M19.47,6.04C19.86,5.65 19.86,5.01 19.47,4.63C19.08,4.24 18.44,4.24 18.06,4.63L17,5.69C16.61,6.08 16.61,6.72 17,7.1C17.39,7.49 18.03,7.49 18.41,7.1L19.47,6.04Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M7.1,18.41C7.49,18.02 7.49,17.38 7.1,17C6.71,16.61 6.07,16.61 5.69,17L4.63,18.06C4.24,18.45 4.24,19.09 4.63,19.47C5.02,19.86 5.66,19.86 6.04,19.47L7.1,18.41Z"
+ android:fillColor="#ffffff"/>
+ </vector>
+ </item>
+</layer-list>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 8b225b3..445bac5 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Opgedateer deur jou administrateur"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Uitgevee deur jou administrateur"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Batterybespaarder skakel Donkertema aan en beperk of skakel agtergrondaktiwiteit, sommige visuele effekte en ander kenmerke, soos \"Ok Google\", af\n\n"<annotation id="url">"Kom meer te wete"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Batterybespaarder skakel Donkertema aan en beperk of skakel agtergrondaktiwiteit, sommige visuele effekte en ander kenmerke, soos \"Ok Google\", af."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Databespaarder verhoed sommige programme om data in die agtergrond te stuur of te aanvaar om datagebruik te help verminder. \'n Program wat jy tans gebruik kan by data ingaan, maar sal dit dalk minder gereeld doen. Dit kan byvoorbeeld beteken dat prente nie wys totdat jy op hulle tik nie."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Skakel Databespaarder aan?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Skakel aan"</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Maak toe"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Antwoord"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Wys af"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Lui af"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Inkomende oproep"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Hierdie kennisgewing is gedegradeer na Stil. Tik om terugvoer te gee."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Hierdie kennisgewing is hoër gegradeer. Tik om terugvoer te gee."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Hierdie kennisgewing is laer gegradeer. Tik om terugvoer te gee."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Probeer verbeterde kennisgewings"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Skakel verbeterde kennisgewings aan sodat jy aanhou om voorgestelde handelinge, antwoorde en meer te ontvang. Android se aanpasbare kennisgewings word nie meer gesteun nie."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Skakel aan"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Nie nou nie"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Kom meer te wete"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Verbeterde kennisgewings kan alle kennisgewinginhoud lees, insluitend persoonlike inligting soos kontakname en boodskappe. Hierdie kenmerk kan ook kennisgewings toemaak of handelingknoppies in kennisgewings gebruik, soos om foonoproepe te beantwoord.\n\nHierdie kenmerk kan ook Prioriteitmodus aan- of afskakel en soortgelyke instellings verander."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Roetinemodus-inligtingkennisgewing"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Battery kan afloop voordat dit normaalweg gelaai word"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batterybespaarder is geaktiveer om batterylewe te verleng"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 834eb74..52f0540 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1852,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"የባትሪ ኃይል ቆጣቢ የጠቆር ያለ ገጽታን ያበራል እና የጀርባ እንቅስቃሴን፣ አንዳንድ የእይታ ውጤቶችን እና እንደ «Hey Google» ያሉ ባህሪያትን ይገድባል ወይም ያጠፋል።\n\n"<annotation id="url">"የበለጠ ለመረዳት"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"የባትሪ ኃይል ቆጣቢ የጠቆር ያለ ገጽታን ያበራል እና የጀርባ እንቅስቃሴን፣ አንዳንድ የእይታ ውጤቶችን እና እንደ «Hey Google» ያሉ ባህሪያትን ይገድባል ወይም ያጠፋል።"</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>
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"ዝጋ"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>፦ <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"መልስ"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"አትቀበል"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"ስልኩን ዝጋ"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"ገቢ ጥሪ"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"ይህ ማሳወቂያ ወደ ዝምታ ዝቅ ብሏል። ግብረመልስ ለመስጠት መታ ያድርጉ።"</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"ይህ ማሳወቂያ ከፍተኛ ደረጃ ተሰጥቶታል። ግብረመልስ ለመስጠት መታ ያድርጉ።"</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"ይህ ማሳወቂያ ዝቅተኛ ደረጃ ተሰጥቶታል። ግብረመልስ ለመስጠት መታ ያድርጉ።"</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"የተሻሻሉ ማሳወቂያዎችን ይሞክሩ"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"የተጠቆሙ እርምጃዎችን፣ ምላሾችን እና ሌሎችን ማግኘትን ለመቀጠል የተሻሻሉ ማሳወቂያዎችን ያብሩ። የAndroid አስማሚ ማሳወቂያዎች ከአሁን በኋላ አይደገፉም።"</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"አብራ"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"አሁን አይደለም"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"የበለጠ ለመረዳት"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"የተሻሻሉ ማሳወቂያዎች እንደ የእውቂያ ስሞች እና መልዕክቶች ያሉ የግል መረጃዎችን ጨምሮ ሁሉንም የማሳወቂያ ይዘቶችን ማንበብ ይችላሉ። ይህ ባህሪ ማሳወቂያዎችን ማሰናከል ወይም እንደ የስልክ ጥሪዎችን ማንሳት በመሳሰሉ ማሳወቂያዎች ውስጥ ባሉ አዝራሮች ላይ እርምጃዎችንም አዝራሮች ላይ እርምጃዎችንም መውሰድ ይችላል።\n\nይህ ባህሪ የቅድሚያ ሁነታን ማብራት ወይም ማጥፋት እና ተዛማጅ ቅንብሮችን መለወጥ ይችላል።"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"የዕለት ተዕለት ሁነታ መረጃ ማሳወቂያዎች"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ባትሪ ከተለመደው ኃይል መሙላት በፊት ሊያልቅ ይችላል"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"የባትሪ ቆጣቢ የባትሪ ዕድሜን ለማራዘም ገብሯል።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 4623057..a78c0e3 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -550,10 +550,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"يسمح هذا الإذن للتطبيق باكتشاف الأجهزة القريبة التي تتضمّن بلوتوث والاقتران بها."</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"تسمح بالربط الأجهزة المقترنة التي تتضمّن بلوتوث."</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"يسمح هذا الإذن للتطبيق بالارتباط بالأجهزة المقترنة التي تتضمّن بلوتوث."</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"عرض الإعلانات على الأجهزة القريبة التي تتضمن بلوتوث"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"للسماح للتطبيق بعرض إعلانات على الأجهزة القريبة التي تتضمّن بلوتوث."</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"تحديد الموضع النسبي بين الأجهزة المجاورة التي تستخدم النطاق الواسع جدًا"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"يسمح هذا الإذن للتطبيق بتحديد الموضع النسبي بين الأجهزة المجاورة التي تستخدم النطاق الواسع جدًا."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"معلومات الخدمات المدفوعة باستخدام الاتصال قصير المدى NFC المفضّل"</string>
@@ -1946,10 +1944,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"يؤدي استخدام خيار \"توفير شحن البطارية\" إلى تفعيل \"المظهر الداكن\" وتقييد أو إيقاف النشاط في الخلفية وبعض التأثيرات المرئية والميزات الأخرى، مثلاً \"Ok Google\".\n\n"<annotation id="url">"مزيد من المعلومات"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"يؤدي استخدام خيار \"توفير شحن البطارية\" إلى تفعيل \"المظهر الداكن\" وتقييد أو إيقاف النشاط في الخلفية وبعض التأثيرات المرئية والميزات الأخرى، مثلاً \"Ok Google\"."</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>
@@ -2057,6 +2053,8 @@
<string name="close_button_text" msgid="10603510034455258">"إغلاق"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"ردّ"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"رفض"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"قطع الاتصال"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"مكالمة واردة"</string>
@@ -2208,18 +2206,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"تم خفض ترتيب هذا الإشعار إلى الوضع \"صامت\". انقر لإرسال ملاحظات وآراء."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"تمت زيادة ترتيب هذا الإشعار. انقر لإرسال ملاحظات وآراء."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"تم خفض ترتيب هذا الإشعار. انقر لإرسال ملاحظات وآراء."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"تجربة الإشعارات المحسّنة"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"لمواصلة الحصول على الردود والإجراءات المقترحة والمزيد، عليك تفعيل الإشعارات المحسّنة. لم تعد الإشعارات التكيُّفية لنظام التشغيل Android متاحة."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"تفعيل"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"لاحقًا"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"مزيد من المعلومات"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"يمكن للإشعارات المحسّنة قراءة كل محتوى الإشعارات، بما في ذلك المعلومات الشخصية، مثلاً أسماء جهات الاتصال والرسائل. يمكن لهذه الميزة أيضًا إغلاق الإشعارات أو اتخاذ إجراءات من خلال الأزرار في الإشعارات، مثلاً الردّ على مكالمات الهاتف.\n\nويمكن لهذه الميزة أيضًا تفعيل وضع \"الأولوية\" أو إيقافه وتغيير الإعدادات ذات الصلة."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"إشعار معلومات \"وضع سلسلة الإجراءات\""</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"قد تنفد طاقة البطارية قبل الشحن المعتاد"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"تم تفعيل \"توفير شحن البطارية\" لإطالة عمرها."</string>
@@ -2256,7 +2248,7 @@
<item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> و<xliff:g id="COUNT_3">%d</xliff:g> ملف</item>
<item quantity="one"><xliff:g id="FILE_NAME_0">%s</xliff:g> وملف (<xliff:g id="COUNT_1">%d</xliff:g>)</item>
</plurals>
- <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"ليس هناك أشخاص مقترحون للمشاركة معهم"</string>
+ <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"ليس هناك أشخاص مقترحون للمشاركة معهم."</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"قائمة التطبيقات"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"لم يتم منح هذا التطبيق إذن تسجيل، ولكن يمكنه تسجيل الصوت من خلال جهاز USB هذا."</string>
<string name="accessibility_system_action_home_label" msgid="3234748160850301870">"الشاشة الرئيسية"</string>
@@ -2411,14 +2403,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"يمكنك الآن تكبير جزء من الشاشة."</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"التفعيل من خلال \"الإعدادات\""</string>
<string name="dismiss_action" msgid="1728820550388704784">"إغلاق"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"إزالة حظر ميكروفون الجهاز"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"إزالة حظر كاميرا الجهاز"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"للتطبيق <b><xliff:g id="APP">%s</xliff:g></b> وكل التطبيقات والخدمات"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"إزالة الحظر"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"الخصوصية في جهاز الاستشعار"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"رمز التطبيق"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"الصورة الذهنية للعلامة التجارية للتطبيق"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index a815db7..4d6b0b7 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -319,10 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"শাৰীৰিক কাৰ্যকলাপ এক্সেছ কৰা"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"কেমেৰা"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ফট\' তুলিব আৰু ভিডিঅ\' ৰেকৰ্ড কৰিব পাৰে"</string>
- <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
- <skip />
- <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
- <skip />
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"নিকটৱৰ্তী ডিভাইচ"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"নিকটৱৰ্তী ডিভাইচসমূহ বিচাৰি পাওক আৰু সেইবোৰৰ সৈতে সংযোগ কৰক"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"কল লগসমূহ"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ফ\'নৰ কল লগ পঢ়ক আৰু লিখক"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ফ’ন"</string>
@@ -540,14 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"এপ্টোক নিকটৱৰ্তী ব্লুটুথ ডিভাইচ বিচাৰি উলিয়াবলৈ আৰু সেইসমূহৰ সৈতে পেয়াৰ কৰিবলৈ অনুমতি দিয়ে"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"পেয়াৰ কৰা ব্লুটুথ ডিভাইচৰ সৈতে সংযোগ কৰক"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"এপ্টোক পেয়াৰ কৰা ব্লুটুথ ডিভাইচৰ সৈতে সংযোগ কৰিবলৈ অনুমতি দিয়ে"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"নিকটৱৰ্তী ব্লুটুথ ডিভাইচত বিজ্ঞাপন প্ৰচাৰ কৰা"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"এপ্টোক নিকটৱৰ্তী ব্লুটুথ ডিভাইচত বিজ্ঞাপন প্ৰচাৰ কৰিবলৈ দিয়ে"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"নিকটৱৰ্তী আল্ট্ৰা-ৱাইডবেণ্ড ডিভাইচৰ মাজৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰক"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"এপ্টোক নিকটৱৰ্তী আল্ট্ৰা-ৱাইডবেণ্ড ডিভাইচসমূহৰ মাজৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ক"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"অগ্ৰাধিকাৰ দিয়া NFC পৰিশোধ সেৱাৰ তথ্য"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"এপ্টোক অগ্ৰাধিকাৰ দিয়া nfc পৰিশোধ সেৱাৰ পঞ্জীকৃত সহায়কসমূহ আৰু পৰিশোধ কৰিব লগা লক্ষ্যস্থান দৰে তথ্য পাবলৈ অনুমতি দিয়ে।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"নিয়েৰ ফিল্ড কমিউনিকেশ্বন নিয়ন্ত্ৰণ কৰক"</string>
@@ -1858,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"বেটাৰী সঞ্চয়কাৰীয়ে গাঢ় থীম অন কৰে আৰু নেপথ্যৰ কাৰ্যকলাপ, কিছুমান ভিজুৱেল ইফেক্ট আৰু “Hey Google”ৰ দৰে সুবিধাসমূহ অফ কৰে অথবা সীমাবদ্ধ কৰে\n\n"<annotation id="url">"অধিক জানক"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"বেটাৰী সঞ্চয়কাৰীয়ে গাঢ় থীম অন কৰে আৰু নেপথ্যৰ কাৰ্যকলাপ, কিছুমান ভিজুৱেল ইফেক্ট আৰু “Hey Google”ৰ দৰে সুবিধাসমূহ অফ কৰে অথবা সীমাবদ্ধ কৰে।"</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>
@@ -1937,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"বন্ধ কৰক"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"উত্তৰ দিয়ক"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"প্ৰত্যাখ্যান কৰক"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"কল কাটি দিয়ক"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"অন্তৰ্গামী কল"</string>
@@ -2080,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"এই জাননীটোৰ গুৰুত্ব নীৰৱলৈ হ্ৰাস কৰা হৈছে। মতামত দিবলৈ টিপক।"</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"এই জাননীটোৰ স্থান ওপৰলৈ কৰা হৈছে। মতামত দিবলৈ টিপক।"</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"এই জাননীটোৰ স্থান তললৈ কৰা হৈছে। মতামত দিবলৈ টিপক।"</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"উন্নত জাননী ব্যৱহাৰ কৰি চাওক"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"পৰামৰ্শ দিয়া কাৰ্য, প্ৰত্যুত্তৰ আৰু বহুতো সুবিধা পাই থাকিবলৈ উন্নত জাননী অন কৰক। Androidৰ অভিযোজিত জাননী আৰু সমৰ্থিত নহয়।"</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"অন কৰক"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"এতিয়া নহয়"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"অধিক জানক"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"উন্নত প্ৰত্যুত্তৰে সম্পৰ্কৰ নাম আৰু বাৰ্তাৰ দৰে ব্যক্তিগত তথ্যৰ লগতে আটাইবোৰ জাননীৰ সমল পঢ়িব পাৰে। এই সুবিধাটোৱে জাননী অগ্ৰাহ্য কৰাৰ লগতে জাননীত থকা ফ’ন কলৰ উত্তৰ দিয়াৰ দৰে কাৰ্য বুটামৰ ওপৰত কাৰ্যব্যৱস্থা ল’ব পাৰে।\n\nলগতে, এই সুবিধাটোৱে অগ্ৰাধিকাৰ দিয়া ম’ড অন অথবা অফ কৰিব পাৰে আৰু সম্পৰ্কিত ছেটিং সলনি কৰিব পাৰে।"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ৰুটিন ম’ডৰ তথ্য জাননী"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"চ্চাৰ্জ কৰাৰ সচৰাচৰ সময়ৰ আগতেই বেটাৰি শেষ হ’ব পাৰে"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"বেটাৰিৰ খৰচ কমাবলৈ বেটাৰি সঞ্চয়কাৰী অন কৰা হৈছে"</string>
@@ -2279,14 +2267,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"আপুনি এতিয়া আপোনাৰ স্ক্ৰীনখনৰ কিছু অংশ বিবৰ্ধন কৰিব পাৰে"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ছেটিঙত অন কৰক"</string>
<string name="dismiss_action" msgid="1728820550388704784">"অগ্ৰাহ্য কৰক"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"ডিভাইচৰ মাইক্ৰ\'ফ\'ন অৱৰোধৰ পৰা আঁতৰাওক"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"ডিভাইচৰ কেমেৰ অৱৰোধৰ পৰা আঁতৰাওক"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> আৰু আটাইবোৰ এপ আৰু সেৱাৰ বাবে"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"অৱৰোধৰ পৰা আঁতৰাওক"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ছেন্সৰ সম্পৰ্কীয় গোপনীয়তাৰ নীতি"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"এপ্লিকেশ্বনৰ চিহ্ন"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"এপ্লিকেশ্বনৰ ব্ৰেণ্ডৰ প্ৰতিচ্ছবি"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 70c4534..69e0400 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -538,10 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Tətbiqə yaxınlıqdakı Bluetooth cihazlarını aşkarlamaq və birləşdirməyə icazə verir"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"birləşdirilmiş Bluetooth cihazlarına qoşulmaq"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Tətbiqə birləşdirilmiş Bluetooth cihazlarına qoşulmağa icazə verir"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"yaxınlıqdakı Bluetooth cihazlarında reklam etmək"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Tətbiqə yaxınlıqdakı Bluetooth cihazlarında reklam etmək imkanı verir"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"yaxınlıqdakı Ultra Genişzolaqlı cihazları arasında nisbi mövqeyi təyin etmək"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Tətbiqə yaxınlıqdakı Ultra Genişzolaqlı cihazları arasında nisbi mövqeyi təyin etməyə icazə verin"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Tərcih edilən NFC ödəniş xidməti məlumatı"</string>
@@ -1244,7 +1242,7 @@
<string name="unsupported_display_size_show" msgid="980129850974919375">"Həmişə göstərin"</string>
<string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> Android OS sisteminin uyğunsuz versiyası üçün hazırlandı və gözlənilməz şəkildə davrana bilər. Tətbiqin güncəllənmiş versiyası əlçatan ola bilər."</string>
<string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Həmişə göstərin"</string>
- <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Güncəlləməni yoxlayın"</string>
+ <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Güncəllənmə olmasını yoxlayın"</string>
<string name="smv_application" msgid="3775183542777792638">"Tətbiq <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) StrictMode siyasətini pozdu."</string>
<string name="smv_process" msgid="1398801497130695446">"<xliff:g id="PROCESS">%1$s</xliff:g> prosesi StrictMode siyasətini pozdu."</string>
<string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Telefon yenilənir…"</string>
@@ -1575,7 +1573,7 @@
<string name="storage_usb_drive_label" msgid="6631740655876540521">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB drayv"</string>
<string name="storage_usb" msgid="2391213347883616886">"USB yaddaş"</string>
<string name="extract_edit_menu_button" msgid="63954536535863040">"Düzəliş edin"</string>
- <string name="data_usage_warning_title" msgid="9034893717078325845">"Data xəbərdarlığı"</string>
+ <string name="data_usage_warning_title" msgid="9034893717078325845">"Trafik xəbərdarlığı"</string>
<string name="data_usage_warning_body" msgid="1669325367188029454">"<xliff:g id="APP">%s</xliff:g> data istifadə etdiniz"</string>
<string name="data_usage_mobile_limit_title" msgid="3911447354393775241">"Mobil data limitinə çatdı"</string>
<string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"Wi-Fi data limitinə çatdı"</string>
@@ -1854,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Admin tərəfindən yeniləndi"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Admin tərəfindən silindi"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Enerjiyə Qənaət funksiyası Qaranlıq temanı aktiv edir və arxa fondakı fəaliyyəti, bəzi vizual effektləri və “Hey Google” kimi digər funksiyaları məhdudlaşdırır və ya deaktiv edir\n\n"<annotation id="url">"Ətraflı məlumat"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Enerjiyə Qənaət funksiyası Qaranlıq temanı aktiv edir və arxa fondakı fəaliyyəti, bəzi vizual effektləri və “Hey Google” kimi digər funksiyaları məhdudlaşdırır və ya deaktiv edir."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Mobil interneti qənaətlə işlətmək məqsədilə Data Qanaəti bəzi tətbiqlərin fonda data göndərməsinin və qəbulunun qarşısını alır. Hazırda işlətdiyiniz tətbiq nisbətən az müntəzəmliklə data istifadə edə bilər. Örnək olaraq bu, o deməkdir ki, şəkil fayllarına toxunmadıqca onlar açılmayacaq."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Trafikə qənaət edilsin?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Aktivləşdirin"</string>
@@ -1933,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Qapadın"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Cavab verin"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"İmtina edin"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Dəstəyi asın"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Gələn zəng"</string>
@@ -1965,7 +1962,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Tətbiq əlçatan deyil"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> hazırda əlçatan deyil."</string>
<string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Bu tətbiq köhnə Android versiyası üçün hazırlanıb və düzgün işləməyə bilər. Güncəlləməni yoxlayın və ya developer ilə əlaqə saxlayın."</string>
- <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Güncəlləməni yoxlayın"</string>
+ <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Güncəllənmə olmasını yoxlayın"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Yeni mesajlarınız var"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Baxmaq üçün SMS tətbiqini açın"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Bəzi funksiyalar məhdudlaşdırıla bilər"</string>
@@ -2076,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Bu bildiriş Səssiz rejimə keçirilib. Rəy bildirmək üçün toxunun."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Bu bildiriş yuxarı sıraya keçirilib. Rəy bildirmək üçün toxunun."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Bu bildiriş aşağı sıraya keçirilib. Rəy bildirmək üçün toxunun."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Genişləndirilmiş bildirişləri sınayın"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Təklif olunan əməliyyatlar, cavablar və daha çoxunu almağa davam etmək üçün genişləndirilmiş bildirişləri aktiv edin. Android Adaptiv Bildirişləri artıq dəstəklənmir."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Aktiv edin"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"İndi yox"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Ətraflı məlumat"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Genişləndirilmiş bildirişlər, kontakt adları və mesajlar kimi şəxsi məlumatlar daxil olmaqla bütün bildiriş məzmununu oxuya bilər. Bu funksiya həmçinin bildirişləri qapada və ya telefon zənglərinə cavab vermək kimi bildirişlərdəki düymələr üzərində əməliyyatlar edə bilər.\n\nBu funksiya həmçinin Prioritet rejimini aktiv və ya deaktiv edə və əlaqəli ayarları dəyişdirə bilər."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rejim üçün məlumat bildirişi"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Batareya həmişəki vaxtdan əvvəl bitə bilər"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Enerjiyə Qənaət rejimi batareya istifadəsinin müddətini artırmaq üçün aktiv edilir"</string>
@@ -2275,14 +2266,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"İndi ekranınızın bir hissəsini böyüdə bilərsiniz"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ayarlarda aktiv edin"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Qapadın"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Cihaz mikrofonunu blokdan çıxarın"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Cihaz kamerasını blokdan çıxarın"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> və bütün tətbiqlər və cihazlar üçün"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Blokdan çıxarın"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor Məxfiliyi"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Tətbiq ikonası"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Tətbiqin brend şəkli"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 1cd4c12..5a7e890 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1875,10 +1875,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Ažurirao je administrator"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao je administrator"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Potvrdi"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Ušteda baterije uključuje Tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizuelne efekte i funkcije, na primer, „Hej Google“.\n\n"<annotation id="url">"Saznajte više"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Ušteda baterije uključuje Tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizuelne efekte i funkcije, na primer, „Hej Google“."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Da bi se smanjila potrošnja podataka, Ušteda podataka sprečava neke aplikacije da šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može da pristupa podacima, ali će to činiti ređe. Na primer, slike se neće prikazivati dok ih ne dodirnete."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Želite da uključite Uštedu podataka?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Uključi"</string>
@@ -1962,6 +1960,7 @@
<string name="close_button_text" msgid="10603510034455258">"Zatvori"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Odgovori"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Odbij"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Prekini vezu"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Dolazni poziv"</string>
@@ -2107,18 +2106,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Ovo obaveštenje je degradirano u Nečujno. Dodirnite da biste naveli povratne informacije."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Ovo obaveštenje je rangirano više. Dodirnite da biste naveli povratne informacije."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Ovo obaveštenje je rangirano niže. Dodirnite da biste naveli povratne informacije."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Probajte poboljšana obaveštenja"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Uključite poboljšana obaveštenja da biste i dalje dobijali preporučene radnje, odgovore i drugo. Prilagodljiva obaveštenja za Android više nisu podržana."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Uključi"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Ne sada"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saznajte više"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Poboljšana obaveštenja mogu da čitaju sadržaj svih obaveštenja, uključujući lične podatke, poput imena kontakata i poruka. Ova funkcija može i da odbacuje obaveštenja ili aktivira dugmad u obaveštenjima, poput javljanja na telefonske pozive.\n\nOva funkcija može i da uključi ili isključi Prioritetni režim i da menja povezana podešavanja."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Obaveštenje o informacijama Rutinskog režima"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterija će se možda isprazniti pre uobičajenog punjenja"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Ušteda baterije je aktivirana da bi se produžilo trajanje baterije"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index c1abeca..bdfab40 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -544,10 +544,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Дазваляе праграме выяўляць прылады з Bluetooth і спалучацца з імі"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"падключацца да спалучаных прылад з Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Дазваляе праграме падключацца да спалучаных прылад з Bluetooth"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"адпраўляць рэкламу на прылады з Bluetooth паблізу"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Дазволіць праграме адпраўляць рэкламу на прылады з Bluetooth, якія знаходзяцца паблізу"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"вызначаць адлегласць паміж прыладамі з звышшырокапалоснай сувяззю"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Дазволіць праграме вызначаць адлегласць паміж прыладамі паблізу, якія выкарыстоўваюць звышшырокапалосную сувязь"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Інфармацыя пра прыярытэтны сэрвіс аплаты NFC"</string>
@@ -1753,8 +1751,8 @@
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Гатова"</string>
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Дэактываваць камбінацыю хуткага доступу"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Выкарыстоўваць камбінацыю хуткага доступу"</string>
- <string name="color_inversion_feature_name" msgid="326050048927789012">"Інверсія колеру"</string>
- <string name="color_correction_feature_name" msgid="3655077237805422597">"Карэкцыя колеру"</string>
+ <string name="color_inversion_feature_name" msgid="326050048927789012">"Інверсія колераў"</string>
+ <string name="color_correction_feature_name" msgid="3655077237805422597">"Карэкцыя колераў"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Дадатковае памяншэнне яркасці"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Клавішы гучнасці ўтрымліваліся націснутымі. Уключана служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Клавішы гучнасці ўтрымліваліся націснутымі. Служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" выключана."</string>
@@ -1900,10 +1898,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"У рэжыме эканоміі зараду ўключаецца цёмная тэма і абмяжоўваюцца ці выключаюцца дзеянні ў фонавым рэжыме, некаторыя візуальныя эфекты і функцыі, напрыклад \"Ok Google\"\n\n"<annotation id="url">"Даведацца больш"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"У рэжыме эканоміі зараду ўключаецца цёмная тэма і абмяжоўваюцца ці выключаюцца дзеянні ў фонавым рэжыме, некаторыя візуальныя эфекты і функцыі, напрыклад \"Ok Google\"."</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>
@@ -1995,6 +1991,8 @@
<string name="close_button_text" msgid="10603510034455258">"Закрыць"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Адказаць"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Адхіліць"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Завяршыць"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Уваходны выклік"</string>
@@ -2142,18 +2140,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Гэта апавяшчэнне пераведзена ў рэжым \"Без гуку\". Націсніце тут і дайце водгук."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Гэта апавяшчэнне ацэнена як важнае. Націсніце тут і дайце водгук."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Гэта апавяшчэнне ацэнена як няважнае. Націсніце тут і дайце водгук."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Палепшаныя апавяшчэнні"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Каб і далей атрымліваць прапановы дзеянняў, адказаў і іншага змесціва, уключыце палепшаныя апавяшчэнні. Адаптыўныя апавяшчэнні Android больш не падтрымліваюцца."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Уключыць"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Не зараз"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Даведацца больш"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Палепшаныя апавяшчэнні маюць доступ да змесціва ўсіх апавяшчэнняў, у тым ліку да асабістай інфармацыі – імён кантактаў і паведамленняў. Гэта функцыя таксама можа адхіляць апавяшчэнні ці актываваць у іх кнопкі дзеянняў, у тым ліку адказваць на тэлефонныя выклікі.\n\nГэта функцыя можа ўключаць і выключаць прыярытэтны рэжым, а таксама змяняць звязаныя налады."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Апавяшчэнне з інфармацыяй пра ўсталяваны рэжым"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Акумулятар можа разрадзіцца хутчэй, чым прыйдзе час звычайнай зарадкі"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Каб павялічыць тэрмін работы акумулятара, уключаны рэжым эканоміі зараду"</string>
@@ -2343,14 +2335,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Цяпер можна павялічваць частку экрана"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Уключыць у Наладах"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Адхіліць"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Разблакіруйце мікрафон прылады"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Разблакіруйце камеру прылады"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Для праграмы <b><xliff:g id="APP">%s</xliff:g></b> і ўсіх праграм і сэрвісаў"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Разблакіраваць"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Прыватнасць інфармацыі з датчыка"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Значок праграмы"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Відарыс брэнда праграмы"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 52e686c92..5b8a81c 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1852,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Режимът за запазване на батерията включва тъмната тема и ограничава или изключва активността на заден план, някои визуални ефекти и различни функции, като например „Ok Google“.\n\n"<annotation id="url">"Научете повече"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Режимът за запазване на батерията включва тъмната тема и ограничава или изключва активността на заден план, някои визуални ефекти и различни функции, като например „Ok Google“."</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>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Затваряне"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"„<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>“: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Отговор"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Видеообаждане"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Отхвърляне"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Затваряне"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Входящо обаждане"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Това известие бе понижено до беззвучно. Докоснете, за да изпратите отзиви."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Това известие бе класирано по-високо. Докоснете, за да изпратите отзиви."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Това известие бе класирано по-ниско. Докоснете, за да изпратите отзиви."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Изпробвайте подобрен. известия"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"За да продължите да получавате предложени действия, отговори и др., включете функцията за подобрени известия. Адаптивните известия за Android вече не се поддържат."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Включване"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Не сега"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Научете повече"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Функцията за подобрени известия може да чете цялото съдържание в дадено известие, включително личната информация, като например имената на контактите и текстовите съобщения. Тя има възможност да отхвърля известията или да предприема действия по бутоните в тях, като например приемане на телефонни обаждания.\n\nСъщо така функцията може да включва или изключва приоритетния режим и да променя сродни настройки."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Известие с информация за режима на поредица"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батерията може да се изтощи преди обичайното зареждане"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Режимът за запазване на батерията е активиран с цел удължаване на живота на батерията"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 17be781..57f2157 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -319,10 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"শারীরিক অ্যাক্টিভিটি অ্যাক্সেস করা"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"ক্যামেরা"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ছবি তোলা এবং ভিডিও রেকর্ড"</string>
- <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
- <skip />
- <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
- <skip />
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"আশেপাশের ডিভাইস"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"আশেপাশের ডিভাইস খুঁজে দেখুন ও তার সাথে কানেক্ট করুন"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"কল লগ"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ফোন কল লগ পড়ে এবং দেখে"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ফোন"</string>
@@ -540,14 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"অ্যাপটিকে কাছাকাছি ব্লুটুথ ডিভাইস খুঁজে দেখতে এবং তার সাথে পেয়ার করার অনুমতি দেয়"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"পেয়ার করা ব্লুটুথ ডিভাইসের সাথে কানেক্ট করুন"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"অ্যাপটিকে পেয়ার করা ব্লুটুথ ডিভাইসের সাথে কানেক্ট করতে অনুমতি দেয়"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"আশেপাশের ব্লুটুথ ডিভাইস বিজ্ঞাপন দেখান"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"আশেপাশের ব্লুটুথ ডিভাইস বিজ্ঞাপন দেওয়ার জন্য অ্যাপকে অনুমতি দেয়"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"আশেপাশের Ultra-Wideband ডিভাইসগুলির আপেক্ষিক অবস্থান নির্ণয় করুন"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"অ্যাপকে আশেপাশের Ultra-Wideband ডিভাইসগুলির আপেক্ষিক অবস্থান নির্ণয় করার অনুমতি দিন"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"পছন্দের NFC পেমেন্ট পরিষেবার তথ্য"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"অ্যাপের মাধ্যমে পছন্দসই এনএফসি পেমেন্ট পরিষেবার তথ্য, যেমন রেজিস্ট্রার করার সহায়তা এবং রুট ডেস্টিনেশন সম্পর্কিত তথ্য অ্যাক্সেস করার অনুমতি দেয়।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"নিয়ার ফিল্ড কমিউনিকেশন নিয়ন্ত্রণ করে"</string>
@@ -1858,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"ব্যাটারি সেভার ডার্ক থিম চালু করে এবং ব্যাকগ্রাউন্ড অ্যাক্টিভিটি, কিছু ভিজ্যুয়াল এফেক্ট এবং “Ok Google”-এর মতো ফিচার সীমিত করে বা বন্ধ করে দেয়\n\n"<annotation id="url">"আরও জানুন"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"ব্যাটারি সেভার ডার্ক থিম চালু করে এবং ব্যাকগ্রাউন্ড অ্যাক্টিভিটি, কিছু ভিজ্যুয়াল এফেক্ট এবং “Ok Google”-এর মতো ফিচার সীমিত করে বা বন্ধ করে দেয়।"</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>
@@ -1937,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"বন্ধ করুন"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"উত্তর"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"বাতিল করুন"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"কল কেটে দেওয়া"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"ইনকামিং কল"</string>
@@ -2080,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"এই বিজ্ঞপ্তির গুরুত্ব কমিয়ে মিউট হিসেবে সেট করা হয়েছে। মতামত জানাতে ট্যাপ করুন।"</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"এই বিজ্ঞপ্তির গুরুত্ব বাড়ানো হয়েছে। মতামত জানাতে ট্যাপ করুন।"</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"এই বিজ্ঞপ্তির গুরুত্ব কমানো হয়েছে। মতামত জানাতে ট্যাপ করুন।"</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"উন্নত নোটিফিকেশন ব্যবহার করুন"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"সাজেস্ট করা অ্যাকশন, উত্তর এবং আরও অনেক কিছু পাওয়া চালিয়ে যেতে, উন্নত নোটিফিকেশন পাওয়ার সুবিধা চালু করুন। Android অ্যাডাপ্টিভ নোটিফিকেশন আর কাজ করবে না।"</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"চালু করুন"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"এখন নয়"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"আরও জানুন"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"উন্নত নোটিফিকেশন পরিচিতির নাম এবং মেসেজের মতো ব্যক্তিগত তথ্য ছাড়াও নোটিফিকেশনের সবকটি কন্টেন্ট পড়তে পারবে। এছাড়াও, এই ফিচার নোটিফিকেশন বাতিল করতে পারবে এবং নোটিফিকেশনে থাকা বোতামের সাহায্যে অ্যাকশন নিতে পারবে, যেমন ফোন কলের উত্তর দেওয়া।\n\nএই ফিচার প্রায়োরিটি মোড চালু বা বন্ধ করতে এবং সেই সম্পর্কিত সেটিংস পরিবর্তনও করতে পারবে।"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"রুটিন মোডের তথ্য সংক্রান্ত বিজ্ঞপ্তি"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"সাধারণত যখন চার্জ দেন, তার আগে চার্জ শেষ হয়ে যেতে পারে"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ডিভাইস বেশিক্ষণ চালু রাখতে ব্যাটারি সেভার চালু করা হয়েছে"</string>
@@ -2279,14 +2267,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"আপনার স্ক্রিনের অংশ এখন আপনি বড় করে দেখতে পারবেন"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"সেটিংস থেকে চালু করুন"</string>
<string name="dismiss_action" msgid="1728820550388704784">"বাতিল করুন"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"ডিভাইসের মাইক্রোফোন আনব্লক করুন"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"ডিভাইসের ক্যামেরা আনব্লক করুন"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> এবং সবকটি অ্যাপ ও পরিষেবার জন্য"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"আনব্লক করুন"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"সেন্সর গোপনীয়তা"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"অ্যাপের আইকন"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"অ্যাপের ব্র্যান্ড ছবি"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index b034223..195b8f7 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1875,10 +1875,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Ažurirao je vaš administrator"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao je vaš administrator"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Uredu"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Ušteda baterije uključuje Tamnu temu i ograničava ili isključuje aktivnosti u pozadini, određene vizuelne efekte i funkcije kao što je \"Ok Google\"\n\n"<annotation id="url">"Saznajte više"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Ušteda baterije uključuje Tamnu temu i ograničava ili isključuje aktivnosti u pozadini, određene vizuelne efekte i funkcije kao što je \"Ok Google\"."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Radi smanjenja prijenosa podataka, Ušteda podataka sprečava da neke aplikacije šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može pristupiti podacima, ali će to činiti rjeđe. Naprimjer, to može značiti da se slike ne prikazuju dok ih ne dodirnete."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Uključiti Uštedu podataka?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Uključi"</string>
@@ -1962,6 +1960,7 @@
<string name="close_button_text" msgid="10603510034455258">"Zatvori"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Odgovori"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Videozapis"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Odbaci"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Prekini vezu"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Dolazni poziv"</string>
@@ -2107,18 +2106,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Značaj ovog obavještenja je umanjen na Nečujno. Dodirnite da pošaljete povratne informacije."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Značaj ovog obavještenja je povećan. Dodirnite da pošaljete povratne informacije."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Značaj ovog obavještenja je umanjen. Dodirnite da pošaljete povratne informacije."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Probajte poboljšana obavještenja"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Da nastavite primati prijedloge radnji, odgovore i još mnogo toga, uključite poboljšana obavještenja. Prilagodljiva obavještenja Androida više nisu podržana."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Uključi"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Ne sada"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saznajte više"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Poboljšana obavještenja mogu čitati sav sadržaj obavještenja, uključujući lične informacije kao što su imena kontakata i poruke. Ova funkcija također može odbaciti obavještenja ili poduzeti radnje vezane za dugmad u obavještenjima, kao što je javljanje na telefonske pozive.\n\nOva funkcija također može uključiti ili isključiti način rada Prioriteti i promijeniti srodne postavke."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Obavještenje za informacije Rutinskog načina"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Moguće je da će se baterija isprazniti prije uobičajenog punjenja"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Ušteda baterije je aktivirana da bi se produžio vijek trajanja baterije"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 96f0b7c..7fd2ede 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Actualitzat per l\'administrador"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Suprimit per l\'administrador"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"D\'acord"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Estalvi de bateria activa el tema fosc i limita o desactiva l\'activitat en segon pla, alguns efectes visuals i funcions com \"Hey Google\".\n\n"<annotation id="url">"Més informació"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Estalvi de bateria activa el tema fosc i limita o desactiva l\'activitat en segon pla, alguns efectes visuals i funcions com \"Hey Google\"."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Per reduir l\'ús de dades, la funció Economitzador de dades evita que determinades aplicacions enviïn o rebin dades en segon pla. L\'aplicació que estiguis fent servir podrà accedir a les dades, però menys sovint. Això vol dir, per exemple, que les imatges no es mostraran fins que no les toquis."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Activar l\'Economitzador de dades?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Activa"</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Tanca"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Respon"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Vídeo"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Rebutja"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Penja"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Trucada entrant"</string>
@@ -1948,7 +1947,7 @@
<string name="user_creation_adding" msgid="7305185499667958364">"Concedeixes permís a <xliff:g id="APP">%1$s</xliff:g> per crear un usuari amb el compte <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="52674936078683285">"Afegeix un idioma"</string>
<string name="country_selection_title" msgid="5221495687299014379">"Preferència de regió"</string>
- <string name="search_language_hint" msgid="7004225294308793583">"Nom de l\'idioma"</string>
+ <string name="search_language_hint" msgid="7004225294308793583">"Escriu el nom de l\'idioma"</string>
<string name="language_picker_section_suggested" msgid="6556199184638990447">"Suggerits"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"Tots els idiomes"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"Totes les regions"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"El nivell d\'aquesta notificació s\'ha disminuït a Silenci. Toca per proporcionar suggeriments."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Aquesta notificació s\'ha classificat amb un nivell superior. Toca per proporcionar suggeriments."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Aquesta notificació s\'ha classificat amb un nivell inferior. Toca per proporcionar suggeriments."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Prova notificacions millorades"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Per continuar rebent accions suggerides, respostes i més, activa les notificacions millorades. Les notificacions adaptatives d\'Android ja no s\'admeten."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Activa"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Ara no"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Més informació"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Les notificacions millorades poden llegir tot el contingut de les notificacions, inclosa la informació personal com els noms dels contactes i els missatges. Aquesta funció també pot ignorar les notificacions o fer accions amb els botons de les notificacions, com ara contestar a trucades.\n\nA més, pot activar i desactivar el mode Prioritat i canviar-ne la configuració."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificació d\'informació del mode de rutina"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"És possible que la bateria s\'esgoti abans de la càrrega habitual"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"S\'ha activat l\'estalvi de bateria per prolongar-ne la durada"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 0dd472f..0448954 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1406,10 +1406,10 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Bylo zjištěno analogové zvukové příslušenství"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Připojené zařízení není s tímto telefonem kompatibilní. Klepnutím zobrazíte další informace."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"Ladění přes USB připojeno"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"Klepnutím vypnete ladění přes USB"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"Klepnutím ladění přes USB vypnete"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Vyberte, chcete-li zakázat ladění přes USB."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Bezdrátové ladění je připojeno"</string>
- <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Klepnutím vypnete bezdrátové ladění"</string>
+ <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Klepnutím bezdrátové ladění vypnete"</string>
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Vyberte, chcete-li zakázat bezdrátové ladění."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Režim správce testů je aktivní"</string>
<string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Chcete-li deaktivovat režim správce testů, restartujte zařízení do továrního nastavení."</string>
@@ -1734,13 +1734,13 @@
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"Nezapínat"</string>
<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, aby nad vaším zařízením měla plnou kontrolu?"</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, nikoli u většiny aplikací."</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">"Může číst veškerý obsah obrazovky a zobrazovat obsah přes ostatní aplikace."</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>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Zobrazení a provádění akcí"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Může sledovat vaše interakce s aplikací nebo hardwarovým senzorem a komunikovat s aplikacemi namísto vás."</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Služba může sledovat vaše interakce s aplikací nebo hardwarovým senzorem a komunikovat s aplikacemi namísto vás."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Povolit"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Zakázat"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Chcete-li některou funkci začít používat, klepněte na ni:"</string>
@@ -1898,10 +1898,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Aktualizováno administrátorem"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Smazáno administrátorem"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Spořič baterie zapne tmavý motiv a omezí nebo vypne aktivitu na pozadí, některé vizuální efekty a funkce jako „Ok Google“\n\n"<annotation id="url">"Další informace"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Spořič baterie zapne tmavý motiv a omezí nebo vypne aktivitu na pozadí, některé vizuální efekty a funkce jako „Ok Google“."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Z důvodu snížení využití dat brání spořič dat některým aplikacím v odesílání nebo příjmu dat na pozadí. Aplikace, kterou právě používáte, data přenášet může, ale může tak činit méně často. V důsledku toho se například obrázky nemusejí zobrazit, dokud na ně neklepnete."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Chcete zapnout Spořič dat?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Zapnout"</string>
@@ -1993,6 +1991,8 @@
<string name="close_button_text" msgid="10603510034455258">"Zavřít"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Přijmout"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Odmítnout"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Zavěsit"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Příchozí hovor"</string>
@@ -2140,18 +2140,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Toto oznámení bylo ztlumeno. Po klepnutí můžete zadat zpětnou vazbu."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"U tohoto oznámení byla zvýšena priorita. Po klepnutí můžete zadat zpětnou vazbu."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"U tohoto oznámení byla snížena priorita. Po klepnutí můžete zadat zpětnou vazbu."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Vyzkoušejte vylepšená oznámení"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Pokud chcete dál dostávat návrhy akcí, odpovědí a další, zapněte vylepšená oznámení. Adaptivní oznámení systému Android už nejsou podporována."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Zapnout"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Teď ne"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Další informace"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Vylepšená oznámení mohou číst veškerý obsah oznámení včetně osobních údajů, jako jsou jména kontaktů a obsah zpráv. Tato funkce také může zavírat oznámení nebo aktivovat tlačítka v oznámeních, například přijímat telefonické hovory.\n\nMůže také zapnout nebo vypnout prioritní režim a změnit související nastavení."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Informační oznámení režimu sledu činností"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterie se možná vybije před obvyklým časem nabití"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Byl aktivován spořič baterie za účelem prodloužení výdrže"</string>
@@ -2349,5 +2343,5 @@
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikace"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Image značky aplikace"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"Zkontrolujte nastavení přístupu"</string>
- <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> může zobrazit a ovládat tuto obrazovku. Klepnutím to zkontrolujete."</string>
+ <string name="view_and_control_notification_content" msgid="8003766498562604034">"Tuto obrazovku může zobrazit a ovládat služba <xliff:g id="SERVICE_NAME">%s</xliff:g>. Klepnutím to zkontrolujete."</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 94b9a92..55fcea3 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -566,8 +566,8 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Tillader, at appen kan ændre din billedsamling."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"læse placeringer fra din mediesamling"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Tillader, at appen kan læse placeringer fra din mediesamling."</string>
- <string name="biometric_app_setting_name" msgid="3339209978734534457">"Brug biometriske systemer"</string>
- <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Brug biometriske systemer eller skærmlås"</string>
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Brug biometri"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Brug biometri eller skærmlås"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Bekræft, at det er dig"</string>
<string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Brug dine biometriske data for at fortsætte"</string>
<string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Brug dine biometriske data eller din skærmlås for at fortsætte"</string>
@@ -1854,10 +1854,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Opdateret af din administrator"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Slettet af din administrator"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Batterisparefunktionen aktiverer Mørkt tema og deaktiverer eller begrænser aktivitet i baggrunden, visse visuelle effekter og funktioner som f.eks. \"Hey Google\"\n\n"<annotation id="url">"Få flere oplysninger"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Batterisparefunktionen aktiverer Mørkt tema og deaktiverer eller begrænser aktivitet i baggrunden, visse visuelle effekter og funktioner som f.eks. \"Hey Google\"."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Datasparefunktionen forhindrer nogle apps i at sende eller modtage data i baggrunden for at reducere dataforbruget. En app, der er i brug, kan få adgang til data, men gør det måske ikke så ofte. Dette kan f.eks. betyde, at billeder ikke vises, før du trykker på dem."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Vil du aktivere Datasparefunktion?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Aktivér"</string>
@@ -1933,6 +1931,8 @@
<string name="close_button_text" msgid="10603510034455258">"Luk"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Besvar"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Afvis"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Læg på"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Indgående opkald"</string>
@@ -2076,18 +2076,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Denne notifikation blev angivet som Lydløs. Tryk for at give feedback."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Denne notifikation blev placeret højere. Tryk for at give feedback."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Denne notifikation blev placeret lavere. Tryk for at give feedback."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Prøv forbedrede notifikationer"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Aktivér forbedrede notifikationer for at fortsætte med at få forslag til handlinger, svar og meget mere. Tilpassede Android-notifikationer understøttes ikke længere."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Aktivér"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Ikke nu"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Få flere oplysninger"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Forbedrede notifikationer kan læse alt indhold i notifikationer, bl.a. personlige oplysninger som f.eks. beskeder og navne på kontakter. Denne funktion kan også afvise notifikationer eller aktivere knapper i notifikationer, herunder besvare opkald.\n\nDenne funktion kan også aktivere og deaktivere tilstanden Prioritet samt ændre relaterede indstillinger."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notifikation med oplysninger om rutinetilstand"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Enheden løber muligvis tør for batteri, inden du normalt oplader den"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batterisparefunktion er aktiveret for at forlænge batteritiden"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 6e8ab72..7d42e1b 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -319,10 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"Zugriff auf körperliche Aktivität"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"Bilder und Videos aufnehmen"</string>
- <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
- <skip />
- <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
- <skip />
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Geräte in der Nähe"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"Geräte in der Nähe finden und eine Verbindung herstellen"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Anrufliste"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"Schreib- und Lesezugriff auf Anrufliste"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -540,14 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Erlaubt der App, Bluetooth-Geräte in der Nähe zu finden und zu koppeln"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"Mit gekoppelten Bluetooth-Geräten verbinden"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Erlaubt der App, sich mit gekoppelten Bluetooth-Geräten zu verbinden"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"Inhalte an Bluetooth-Geräte in der Nähe senden"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Erlaubt der App, Inhalte an Bluetooth-Geräte in der Nähe zu senden"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"Relative Distanz zwischen Ultrabreitband-Geräten in der Nähe bestimmen"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Ermöglicht der App, die relative Distanz zwischen Ultrabreitband-Geräten in der Nähe zu bestimmen"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informationen zum bevorzugten NFC-Zahlungsdienst"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ermöglicht der App, Informationen zum bevorzugten NFC-Zahlungsdienst abzurufen, etwa registrierte Hilfsmittel oder das Routenziel."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Nahfeldkommunikation steuern"</string>
@@ -1937,6 +1931,8 @@
<string name="close_button_text" msgid="10603510034455258">"Schließen"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Annehmen"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Ablehnen"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Auflegen"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Eingehender Anruf"</string>
@@ -2007,7 +2003,7 @@
<string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"In den Texteingabemodus wechseln, um die Uhrzeit einzugeben."</string>
<string name="time_picker_radial_mode_description" msgid="1222342577115016953">"In den Uhrzeitmodus wechseln, um die Uhrzeit einzugeben."</string>
<string name="autofill_picker_accessibility_title" msgid="4425806874792196599">"Optionen für automatisches Ausfüllen"</string>
- <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Für \"Automatisches Ausfüllen\" speichern"</string>
+ <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Für „Automatisches Ausfüllen“ speichern"</string>
<string name="autofill_error_cannot_autofill" msgid="6528827648643138596">"Inhalte können nicht automatisch ausgefüllt werden"</string>
<string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Keine Vorschläge für automatisches Ausfüllen"</string>
<plurals name="autofill_picker_some_suggestions" formatted="false" msgid="6651883186966959978">
@@ -2279,14 +2275,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Du kannst das Display teilweise vergrößern"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"In den Einstellungen aktivieren"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Schließen"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Blockierung des Gerätemikrofons aufheben"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Blockierung der Gerätekamera aufheben"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Für <b><xliff:g id="APP">%s</xliff:g></b> und alle Apps und Dienste"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Blockierung aufheben"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Datenschutz für Sensoren"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"App-Symbol"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"App-Branding-Hintergrundbild"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 517ba84..1612a7b 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1852,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Η Εξοικονόμηση μπαταρίας ενεργοποιεί το Σκούρο θέμα και περιορίζει ή απενεργοποιεί τη δραστηριότητα στο παρασκήνιο, ορισμένα οπτικά εφέ και λειτουργίες όπως την εντολή \"Ok Google\"\n\n"<annotation id="url">"Μάθετε περισσότερα"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Η Εξοικονόμηση μπαταρίας ενεργοποιεί το Σκούρο θέμα και περιορίζει ή απενεργοποιεί τη δραστηριότητα στο παρασκήνιο, ορισμένα οπτικά εφέ και λειτουργίες όπως την εντολή \"Ok Google\"."</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>
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Κλείσιμο"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Απάντηση"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Απόρριψη"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Τερματισμός"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Εισερχόμενη κλήση"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Αυτή η ειδοποίηση υποβιβάστηκε στις Αθόρυβες. Πατήστε για να υποβάλετε σχόλια."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Αυτή η ειδοποίηση κατατάχθηκε ψηλότερα. Πατήστε για να υποβάλετε σχόλια."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Αυτή η ειδοποίηση κατατάχθηκε χαμηλότερα. Πατήστε για να υποβάλετε σχόλια."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Δοκιμή βελτιωμ. ειδοποιήσεων"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Για να συνεχίσετε να λαμβάνετε προτεινόμενες ενέργειες, απαντήσεις και άλλα, ενεργοποιήστε τις βελτιωμένες ειδοποιήσεις. Δεν υποστηρίζονται πλέον οι Προσαρμοστικές ειδοποιήσεις Android."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Ενεργοποίηση"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Όχι τώρα"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Μάθετε περισσότερα"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Οι Βελτιωμένες ειδοποιήσεις έχουν τη δυνατότητα ανάγνωσης όλου του περιεχομένου ειδοποιήσεων, συμπεριλαμβανομένων των προσωπικών πληροφοριών, όπως ονομάτων επαφών και μηνυμάτων. Αυτή η λειτουργία έχει επίσης τη δυνατότητα παράβλεψης ειδοποιήσεων ή λήψης ενεργειών σε κουμπιά στις ειδοποιήσεις, όπως η απάντηση τηλεφωνικών κλήσεων.\n\nΕπίσης, έχει τη δυνατότητα ενεργοποίησης ή απενεργοποίησης της λειτουργίας Προτεραιότητας, καθώς και αλλαγής των σχετικών ρυθμίσεων."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Ειδοποίηση πληροφοριών λειτουργίας Ρουτίνας"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Η μπαταρία μπορεί να εξαντληθεί πριν από τη συνηθισμένη φόρτιση"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Η Εξοικονόμηση μπαταρίας ενεργοποιήθηκε για την επέκταση της διάρκειας ζωής της μπαταρίας"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index e841e27..9692781 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Battery Saver turns on Dark theme and limits or turns off background activity, some visual effects and features like \'Hey Google\'\n\n"<annotation id="url">"Learn more"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Battery Saver turns on Dark theme and limits or turns off background activity, some visual effects and features like \'Hey Google\'."</string>
<string name="data_saver_description" msgid="4995164271550590517">"To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app you\'re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Turn on Data Saver?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Turn on"</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Close"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Answer"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Decline"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Hang up"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Incoming call"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"This notification was demoted to silent. Tap to provide feedback."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"This notification was ranked higher. Tap to provide feedback."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"This notification was ranked lower. Tap to provide feedback."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Try enhanced notifications"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"To keep getting suggested actions, replies and more, turn on enhanced notifications. Android Adaptive Notifications are no longer supported."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Turn on"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Not now"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Learn more"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Enhanced notifications can read all notification content, including personal information like contact names and messages. This feature can also dismiss notifications or take actions on buttons in notifications, such as answering phone calls.\n\nThis feature can also turn Priority mode on or off and change related settings."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Routine Mode info notification"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Battery may run out before usual charge"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Battery Saver activated to extend battery life"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 52d6dc5..f41ab42 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Battery Saver turns on Dark theme and limits or turns off background activity, some visual effects and features like \'Hey Google\'\n\n"<annotation id="url">"Learn more"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Battery Saver turns on Dark theme and limits or turns off background activity, some visual effects and features like \'Hey Google\'."</string>
<string name="data_saver_description" msgid="4995164271550590517">"To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app you\'re currently using can access data, but may do so less frequently. This may mean, for example, that images don\'t display until you tap them."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Turn on Data Saver?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Turn on"</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Close"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Answer"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Decline"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Hang up"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Incoming call"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"This notification was demoted to silent. Tap to provide feedback."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"This notification was ranked higher. Tap to provide feedback."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"This notification was ranked lower. Tap to provide feedback."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Try enhanced notifications"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"To keep getting suggested actions, replies and more, turn on enhanced notifications. Android Adaptive Notifications are no longer supported."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Turn on"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Not now"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Learn more"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Enhanced notifications can read all notification content, including personal information like contact names and messages. This feature can also dismiss notifications or take actions on buttons in notifications, such as answering phone calls.\n\nThis feature can also turn Priority mode on or off and change related settings."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Routine Mode info notification"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Battery may run out before usual charge"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Battery Saver activated to extend battery life"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index a25f29c..098a936 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Battery Saver turns on Dark theme and limits or turns off background activity, some visual effects and features like \'Hey Google\'\n\n"<annotation id="url">"Learn more"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Battery Saver turns on Dark theme and limits or turns off background activity, some visual effects and features like \'Hey Google\'."</string>
<string name="data_saver_description" msgid="4995164271550590517">"To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app that you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Turn on Data Saver?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Turn on"</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Close"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Answer"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Decline"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Hang up"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Incoming call"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"This notification was demoted to silent. Tap to provide feedback."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"This notification was ranked higher. Tap to provide feedback."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"This notification was ranked lower. Tap to provide feedback."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Try enhanced notifications"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"To keep getting suggested actions, replies and more, turn on enhanced notifications. Android Adaptive Notifications are no longer supported."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Turn on"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Not now"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Learn more"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Enhanced notifications can read all notification content, including personal information like contact names and messages. This feature can also dismiss notifications or take actions on buttons in notifications, such as answering phone calls.\n\nThis feature can also turn Priority mode on or off and change related settings."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Routine Mode info notification"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Battery may run out before usual charge"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Battery Saver activated to extend battery life"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index dbb72e9..a7e1f5f 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Updated by your admin"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Deleted by your admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Battery Saver turns on Dark theme and limits or turns off background activity, some visual effects and features like \'Hey Google\'\n\n"<annotation id="url">"Learn more"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Battery Saver turns on Dark theme and limits or turns off background activity, some visual effects and features like \'Hey Google\'."</string>
<string name="data_saver_description" msgid="4995164271550590517">"To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app that you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Turn on Data Saver?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Turn on"</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Close"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Answer"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Decline"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Hang up"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Incoming call"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"This notification was demoted to silent. Tap to provide feedback."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"This notification was ranked higher. Tap to provide feedback."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"This notification was ranked lower. Tap to provide feedback."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Try enhanced notifications"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"To keep getting suggested actions, replies and more, turn on enhanced notifications. Android Adaptive Notifications are no longer supported."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Turn on"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Not now"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Learn more"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Enhanced notifications can read all notification content, including personal information like contact names and messages. This feature can also dismiss notifications or take actions on buttons in notifications, such as answering phone calls.\n\nThis feature can also turn Priority mode on or off and change related settings."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Routine Mode info notification"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Battery may run out before usual charge"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Battery Saver activated to extend battery life"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 0c50419..2cdf5ba 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1929,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Close"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Answer"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Decline"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Hang Up"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Incoming call"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 128e2fb..6a1cddc 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -321,7 +321,7 @@
<string name="permgroupdesc_camera" msgid="7585150538459320326">"tomar fotografías y grabar videos"</string>
<string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Dispositivos cercanos"</string>
<string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"descubrir y conectarse a dispositivos cercanos"</string>
- <string name="permgrouplab_calllog" msgid="7926834372073550288">"Llamadas"</string>
+ <string name="permgrouplab_calllog" msgid="7926834372073550288">"Registros de llamadas"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"leer y escribir el registro de llamadas telefónicas"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Teléfono"</string>
<string name="permgroupdesc_phone" msgid="270048070781478204">"hacer y administrar llamadas telefónicas"</string>
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Tu administrador actualizó este paquete"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Tu administrador borró este paquete"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"El Ahorro de batería activa el Tema oscuro y limita o desactiva la actividad en segundo plano, algunos efectos visuales y otras funciones, como \"Hey Google\"\n\n"<annotation id="url">"Más información"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"El Ahorro de batería activa el Tema oscuro y limita o desactiva la actividad en segundo plano, algunos efectos visuales y otras funciones, como \"Hey Google\"."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Para reducir el uso de datos, el modo Ahorro de datos evita que algunas apps envíen y reciban datos en segundo plano. La app que estés usando podrá acceder a los datos, pero con menor frecuencia. De esta forma, por ejemplo, las imágenes no se mostrarán hasta que las presiones."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"¿Deseas activar Ahorro de datos?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Activar"</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Cerrar"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Responder"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Rechazar"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Colgar"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Llamada entrante"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Esta notificación descendió de a Silenciada. Presiona para enviar comentarios."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Esta notificación recibió una clasificación superior. Presiona para enviar comentarios."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Esta notificación recibió una clasificación inferior. Presiona para enviar comentarios."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Prueba las notif. mejoradas"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Activa las notificaciones mejoradas para seguir recibiendo acciones sugeridas, respuestas y mucho más. Ya no se admiten las notificaciones adaptables de Android."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Activar"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Ahora no"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Más información"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Las notificaciones mejoradas pueden leer todo el contenido de notificaciones, incluido el que contenga información personal, como nombres de contactos y mensajes. Esta función también podrá descartar notificaciones o realizar acciones en botones de notificaciones, como responder llamadas.\n\nTambién puede activar o desactivar el Modo prioridad y cambiar la configuración relacionada."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificación de información del modo de Rutinas"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Es posible que la batería se agote antes de la carga habitual"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Se activó el Ahorro de batería para extender la duración de la batería"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 7bed3e6..62ecf65 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -34,7 +34,7 @@
<string name="defaultMsisdnAlphaTag" msgid="2285034592902077488">"MSISDN1"</string>
<string name="mmiError" msgid="2862759606579822246">"Se ha producido un problema de conexión o el código MMI no es válido."</string>
<string name="mmiFdnError" msgid="3975490266767565852">"La operación solo es válida para números de marcación fija."</string>
- <string name="mmiErrorWhileRoaming" msgid="1204173664713870114">"No se puede cambiar la configuración de desvío de llamadas desde tu teléfono mientras estás en itinerancia."</string>
+ <string name="mmiErrorWhileRoaming" msgid="1204173664713870114">"No se puede cambiar la configuración de desvío de llamadas desde tu teléfono mientras estás en roaming."</string>
<string name="serviceEnabled" msgid="7549025003394765639">"El servicio se ha habilitado."</string>
<string name="serviceEnabledFor" msgid="1463104778656711613">"Se ha habilitado el servicio para:"</string>
<string name="serviceDisabled" msgid="641878791205871379">"El servicio se ha inhabilitado."</string>
@@ -108,19 +108,19 @@
<string name="serviceClassDataSync" msgid="7895071363569133704">"Sincronización"</string>
<string name="serviceClassPacket" msgid="1430642951399303804">"Paquete"</string>
<string name="serviceClassPAD" msgid="6850244583416306321">"PAD"</string>
- <string name="roamingText0" msgid="7793257871609854208">"Indicador de itinerancia activado"</string>
- <string name="roamingText1" msgid="5073028598334616445">"Indicador de itinerancia desactivado"</string>
- <string name="roamingText2" msgid="2834048284153110598">"Indicador de itinerancia parpadeante"</string>
+ <string name="roamingText0" msgid="7793257871609854208">"Indicador de roaming activado"</string>
+ <string name="roamingText1" msgid="5073028598334616445">"Indicador de roaming desactivado"</string>
+ <string name="roamingText2" msgid="2834048284153110598">"Indicador de roaming parpadeante"</string>
<string name="roamingText3" msgid="831690234035748988">"Fuera del vecindario"</string>
<string name="roamingText4" msgid="2171252529065590728">"Fuera del edificio"</string>
- <string name="roamingText5" msgid="4294671587635796641">"Itinerancia: sistema preferido"</string>
- <string name="roamingText6" msgid="5536156746637992029">"Itinerancia: sistema disponible"</string>
- <string name="roamingText7" msgid="1783303085512907706">"Itinerancia: partner de alianza"</string>
- <string name="roamingText8" msgid="7774800704373721973">"Itinerancia: partner de gran calidad"</string>
- <string name="roamingText9" msgid="1933460020190244004">"Itinerancia: funcionalidad de servicio completa"</string>
- <string name="roamingText10" msgid="7434767033595769499">"Itinerancia: funcionalidad de servicio parcial"</string>
- <string name="roamingText11" msgid="5245687407203281407">"Banner de itinerancia activado"</string>
- <string name="roamingText12" msgid="673537506362152640">"Banner de itinerancia desactivado"</string>
+ <string name="roamingText5" msgid="4294671587635796641">"Roaming: sistema preferido"</string>
+ <string name="roamingText6" msgid="5536156746637992029">"Roaming: sistema disponible"</string>
+ <string name="roamingText7" msgid="1783303085512907706">"Roaming: partner de alianza"</string>
+ <string name="roamingText8" msgid="7774800704373721973">"Roaming: partner de gran calidad"</string>
+ <string name="roamingText9" msgid="1933460020190244004">"Roaming: funcionalidad de servicio completa"</string>
+ <string name="roamingText10" msgid="7434767033595769499">"Roaming: funcionalidad de servicio parcial"</string>
+ <string name="roamingText11" msgid="5245687407203281407">"Banner de roaming activado"</string>
+ <string name="roamingText12" msgid="673537506362152640">"Banner de roaming desactivado"</string>
<string name="roamingTextSearching" msgid="5323235489657753486">"Buscando servicio"</string>
<string name="wfcRegErrorTitle" msgid="3193072971584858020">"No se ha podido configurar la llamada por Wi‑Fi"</string>
<string-array name="wfcOperatorErrorAlertMessages">
@@ -412,13 +412,13 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Permite que la aplicación envíe emisiones que permanecen en el dispositivo una vez finalizadas. Si esta función se utiliza en exceso, podría ralentizar tu dispositivo Android TV o volverlo inestable al hacer que se ocupe demasiada memoria."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Permite que la aplicación envíe emisiones que permanecen en el dispositivo una vez que la emisión ha finalizado. Un uso excesivo podría ralentizar el teléfono o volverlo inestable al hacer que use demasiada memoria."</string>
<string name="permlab_readContacts" msgid="8776395111787429099">"consultar tus contactos"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permite que la aplicación lea datos de los contactos almacenados en tu tablet. Las aplicaciones también podrán acceder a las cuentas de tu tablet que hayan creado contactos, y quizá tengan acceso a las cuentas creadas por aplicaciones que hayas descargado. Las aplicaciones con este permiso este permiso pueden guardar los datos de tus contactos, y las aplicaciones maliciosas puede que compartan estos datos sin que lo sepas."</string>
- <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permite que la aplicación lea datos de los contactos almacenados en tu dispositivo Android TV. Las aplicaciones también podrán acceder a las cuentas de tu dispositivo Android TV que hayan creado contactos, y quizá tengan acceso a las cuentas creadas por aplicaciones que hayas descargado. Las aplicaciones con este permiso este permiso pueden guardar los datos de tus contactos, y las aplicaciones maliciosas puede que compartan estos datos sin que lo sepas."</string>
- <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permite que la aplicación lea datos de los contactos almacenados en tu teléfono. Las aplicaciones también podrán acceder a las cuentas de tu teléfono que hayan creado contactos, y quizá tengan acceso a las cuentas creadas por aplicaciones que hayas descargado. Las aplicaciones con este permiso este permiso pueden guardar los datos de tus contactos, y las aplicaciones maliciosas puede que compartan estos datos sin que lo sepas."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permite que la aplicación lea datos de los contactos almacenados en tu tablet. Las aplicaciones también podrán acceder a las cuentas de tu tablet que hayan creado contactos, y quizá tengan acceso a las cuentas creadas por aplicaciones que hayas descargado. Las aplicaciones con este permiso pueden guardar los datos de tus contactos, y las aplicaciones maliciosas puede que compartan estos datos sin que lo sepas."</string>
+ <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permite que la aplicación lea datos de los contactos almacenados en tu dispositivo Android TV. Las aplicaciones también podrán acceder a las cuentas de tu dispositivo Android TV que hayan creado contactos, y quizá tengan acceso a las cuentas creadas por aplicaciones que hayas descargado. Las aplicaciones con este permiso pueden guardar los datos de tus contactos, y las aplicaciones maliciosas puede que compartan estos datos sin que lo sepas."</string>
+ <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permite que la aplicación lea datos de los contactos almacenados en tu teléfono. Las aplicaciones también podrán acceder a las cuentas de tu teléfono que hayan creado contactos, y quizá tengan acceso a las cuentas creadas por aplicaciones que hayas descargado. Las aplicaciones con este permiso pueden guardar los datos de tus contactos, y las aplicaciones maliciosas puede que compartan estos datos sin que lo sepas."</string>
<string name="permlab_writeContacts" msgid="8919430536404830430">"modificar tus contactos"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permite que la aplicación cambie los datos de los contactos almacenados en tu tablet. Las aplicaciones con este permiso este permiso pueden eliminar datos de contactos."</string>
- <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permite que la aplicación cambie los datos de los contactos almacenados en tu dispositivo Android TV. Las aplicaciones con este permiso este permiso pueden eliminar datos de contactos."</string>
- <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permite que la aplicación cambie los datos de los contactos almacenados en tu teléfono. Las aplicaciones con este permiso este permiso pueden eliminar datos de contactos."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permite que la aplicación cambie los datos de los contactos almacenados en tu tablet. Las aplicaciones con este permiso pueden eliminar datos de contactos."</string>
+ <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permite que la aplicación cambie los datos de los contactos almacenados en tu dispositivo Android TV. Las aplicaciones con este permiso pueden eliminar datos de contactos."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permite que la aplicación cambie los datos de los contactos almacenados en tu teléfono. Las aplicaciones con este permiso pueden eliminar datos de contactos."</string>
<string name="permlab_readCallLog" msgid="1739990210293505948">"leer el registro de llamadas"</string>
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Esta aplicación puede leer tu historial de llamadas."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"escribir en el registro de llamadas"</string>
@@ -521,25 +521,25 @@
<string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Permite que la aplicación reciba paquetes enviados a través de una red Wi-Fi y mediante direcciones de multidifusión a todos los dispositivos, no solo a tu dispositivo Android TV. Consume más batería que el modo sin multidifusión."</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Permite que la aplicación reciba paquetes enviados a todos los dispositivos de una red Wi-Fi que utilicen direcciones de multidifusión, no solo al teléfono. Utiliza más batería que el modo de no multidifusión."</string>
<string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"acceder a los ajustes de Bluetooth"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Permite que la aplicación configure el tablet Bluetooth local y que detecte dispositivos remotos y se vincule con ellos."</string>
- <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Permite que la aplicación configure el Bluetooth en tu dispositivo Android TV, detecte dispositivos remotos y se vincule con ellos."</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Permite que la aplicación configure el teléfono Bluetooth local y que detecte dispositivos remotos y se vincule con ellos."</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Permite que la aplicación configure el tablet Bluetooth local y que detecte dispositivos remotos y se empareje con ellos."</string>
+ <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Permite que la aplicación configure el Bluetooth en tu dispositivo Android TV, detecte dispositivos remotos y se empareje con ellos."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Permite que la aplicación configure el teléfono Bluetooth local y que detecte dispositivos remotos y se empareje con ellos."</string>
<string name="permlab_accessWimaxState" msgid="7029563339012437434">"conectarse a WiMAX y desconectarse de esta red"</string>
<string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Permite que la aplicación determine si está habilitada la conexión WiMAX y obtenga información sobre las redes WiMAX que están conectadas."</string>
<string name="permlab_changeWimaxState" msgid="6223305780806267462">"cambiar estado de WiMAX"</string>
<string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"Permite que la aplicación conecte el tablet a redes WiMAX y lo desconecte de ellas."</string>
<string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"Permite que la aplicación active y desactive la conexión entre tu dispositivo Android TV y las redes WiMAX."</string>
<string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"Permite que la aplicación conecte el teléfono a redes WiMAX y lo desconecte de ellas."</string>
- <string name="permlab_bluetooth" msgid="586333280736937209">"vincular con dispositivos Bluetooth"</string>
+ <string name="permlab_bluetooth" msgid="586333280736937209">"emparejar con dispositivos Bluetooth"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permite que la aplicación acceda a la configuración de Bluetooth del tablet y que establezca y acepte conexiones con los dispositivos sincronizados."</string>
<string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permite que la aplicación vea la configuración de Bluetooth de tu dispositivo Android TV y que cree y acepte conexiones con los dispositivos vinculados."</string>
<string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permite que la aplicación acceda a la configuración de Bluetooth del teléfono y que establezca y acepte conexiones con los dispositivos sincronizados."</string>
- <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"detectar y vincular dispositivos Bluetooth cercanos"</string>
- <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que la aplicación detecte y vincule dispositivos Bluetooth cercanos"</string>
+ <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"detectar y emparejar dispositivos Bluetooth cercanos"</string>
+ <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que la aplicación detecte y empareje dispositivos Bluetooth cercanos"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"conectarse a dispositivos Bluetooth vinculados"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que la aplicación se conecte a dispositivos Bluetooth vinculados"</string>
- <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"mostrar anuncios a dispositivos Bluetooth cercanos"</string>
- <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que la aplicación muestre anuncios a dispositivos Bluetooth cercanos"</string>
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"emitir a dispositivos Bluetooth cercanos"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que la aplicación emita a dispositivos Bluetooth cercanos"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"calcular posición de dispositivos de banda ultraancha cercanos"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite que la aplicación determine la posición relativa de los dispositivos de banda ultraancha cercanos"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información sobre el servicio de pago por NFC preferido"</string>
@@ -1335,7 +1335,7 @@
<string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"No permitir nunca"</string>
<string name="sim_removed_title" msgid="5387212933992546283">"Tarjeta SIM retirada"</string>
<string name="sim_removed_message" msgid="9051174064474904617">"La red móvil no estará disponible hasta que reinicies el dispositivo con una tarjeta SIM válida."</string>
- <string name="sim_done_button" msgid="6464250841528410598">"Listo"</string>
+ <string name="sim_done_button" msgid="6464250841528410598">"Hecho"</string>
<string name="sim_added_title" msgid="7930779986759414595">"Tarjeta SIM añadida"</string>
<string name="sim_added_message" msgid="6602906609509958680">"Reinicia el dispositivo para acceder a la red móvil."</string>
<string name="sim_restart_button" msgid="8481803851341190038">"Reiniciar"</string>
@@ -1348,7 +1348,7 @@
<string name="time_picker_dialog_title" msgid="9053376764985220821">"Establecer hora"</string>
<string name="date_picker_dialog_title" msgid="5030520449243071926">"Establecer fecha"</string>
<string name="date_time_set" msgid="4603445265164486816">"Establecer"</string>
- <string name="date_time_done" msgid="8363155889402873463">"Listo"</string>
+ <string name="date_time_done" msgid="8363155889402873463">"Hecho"</string>
<string name="perms_new_perm_prefix" msgid="6984556020395757087"><font size="12" fgcolor="#ff33b5e5">"NUEVO:"</font></string>
<string name="perms_description_app" msgid="2747752389870161996">"Proporcionado por <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="no_permissions" msgid="5729199278862516390">"No es necesario ningún permiso"</string>
@@ -1366,7 +1366,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Se ha detectado un accesorio de audio analógico"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"El dispositivo adjunto no es compatible con este teléfono. Toca para obtener más información."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"Depuración USB habilitada"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"Toca aquí para desactivar la depuración USB"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"Toca para desactivar la depuración USB"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Seleccionar para inhabilitar la depuración USB"</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Depuración inalámbrica conectada"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Toca para desactivar la depuración inalámbrica"</string>
@@ -1438,7 +1438,7 @@
<string name="ext_media_status_removed" msgid="241223931135751691">"Extraído"</string>
<string name="ext_media_status_unmounted" msgid="8145812017295835941">"Expulsado"</string>
<string name="ext_media_status_checking" msgid="159013362442090347">"Comprobando..."</string>
- <string name="ext_media_status_mounted" msgid="3459448555811203459">"Listo"</string>
+ <string name="ext_media_status_mounted" msgid="3459448555811203459">"Hecho"</string>
<string name="ext_media_status_mounted_ro" msgid="1974809199760086956">"Solo lectura"</string>
<string name="ext_media_status_bad_removal" msgid="508448566481406245">"Extraído de forma no segura"</string>
<string name="ext_media_status_unmountable" msgid="7043574843541087748">"Dañado"</string>
@@ -1463,7 +1463,7 @@
<string name="ime_action_search" msgid="4501435960587287668">"Buscar"</string>
<string name="ime_action_send" msgid="8456843745664334138">"Enviar"</string>
<string name="ime_action_next" msgid="4169702997635728543">"Siguiente"</string>
- <string name="ime_action_done" msgid="6299921014822891569">"Listo"</string>
+ <string name="ime_action_done" msgid="6299921014822891569">"Hecho"</string>
<string name="ime_action_previous" msgid="6548799326860401611">"Anterior"</string>
<string name="ime_action_default" msgid="8265027027659800121">"Ejecutar"</string>
<string name="dial_number_using" msgid="6060769078933953531">"Marcar número\ncon <xliff:g id="NUMBER">%s</xliff:g>"</string>
@@ -1510,7 +1510,7 @@
<item quantity="other"><xliff:g id="INDEX">%d</xliff:g> de <xliff:g id="TOTAL">%d</xliff:g></item>
<item quantity="one">1 coincidencia</item>
</plurals>
- <string name="action_mode_done" msgid="2536182504764803222">"Listo"</string>
+ <string name="action_mode_done" msgid="2536182504764803222">"Hecho"</string>
<string name="progress_erasing" msgid="6891435992721028004">"Borrando almacenamiento compartido…"</string>
<string name="share" msgid="4157615043345227321">"Compartir"</string>
<string name="find" msgid="5015737188624767706">"Buscar"</string>
@@ -1551,7 +1551,7 @@
<string name="keyboardview_keycode_alt" msgid="8997420058584292385">"Alt"</string>
<string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"Cancelar"</string>
<string name="keyboardview_keycode_delete" msgid="2661117313730098650">"Eliminar"</string>
- <string name="keyboardview_keycode_done" msgid="2524518019001653851">"Listo"</string>
+ <string name="keyboardview_keycode_done" msgid="2524518019001653851">"Hecho"</string>
<string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"Cambio de modo"</string>
<string name="keyboardview_keycode_shift" msgid="3026509237043975573">"Mayús"</string>
<string name="keyboardview_keycode_enter" msgid="168054869339091055">"Intro"</string>
@@ -1704,7 +1704,7 @@
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Selecciona qué funciones usar con la tecla de volumen"</string>
<string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"Se ha desactivado <xliff:g id="SERVICE_NAME">%s</xliff:g>"</string>
<string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar accesos directos"</string>
- <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Listo"</string>
+ <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Hecho"</string>
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactivar acceso directo"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar acceso directo"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de color"</string>
@@ -1834,7 +1834,7 @@
<string name="immersive_cling_title" msgid="2307034298721541791">"Modo de pantalla completa"</string>
<string name="immersive_cling_description" msgid="7092737175345204832">"Para salir, desliza el dedo de arriba abajo."</string>
<string name="immersive_cling_positive" msgid="7047498036346489883">"Entendido"</string>
- <string name="done_label" msgid="7283767013231718521">"Listo"</string>
+ <string name="done_label" msgid="7283767013231718521">"Hecho"</string>
<string name="hour_picker_description" msgid="5153757582093524635">"Control deslizante circular de horas"</string>
<string name="minute_picker_description" msgid="9029797023621927294">"Control deslizante circular de minutos"</string>
<string name="select_hours" msgid="5982889657313147347">"Seleccionar horas"</string>
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Actualizado por el administrador"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminado por el administrador"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Ahorro de batería activa el tema oscuro y limita o desactiva la actividad en segundo plano, algunos efectos visuales y funciones como \"Hey Google\"\n\n"<annotation id="url">"Más información"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Ahorro de batería activa el tema oscuro y limita o desactiva la actividad en segundo plano, algunos efectos visuales y funciones como \"Hey Google\"."</string>
<string name="data_saver_description" msgid="4995164271550590517">"El modo Ahorro de datos evita que algunas aplicaciones envíen o reciban datos en segundo plano, lo que puede reducir el uso de datos. Una aplicación activa puede acceder a los datos, aunque con menos frecuencia. Esto significa que es posible que, por ejemplo, algunas imágenes no se muestren hasta que las toques."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"¿Activar Ahorro de datos?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Activar"</string>
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Cerrar"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Responder"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Rechazar"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Colgar"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Llamada entrante"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"La importancia de esta notificación ha disminuido a Silencio. Toca para enviar comentarios."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Esta notificación aparecerá en una posición más alta. Toca para enviar comentarios."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Esta notificación aparecerá en una posición más baja. Toca para enviar comentarios."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Probar notificaciones mejoradas"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Para seguir recibiendo sugerencias de acciones, respuestas y más, activa las notificaciones mejoradas. Las notificaciones adaptativas de Android ya no están disponibles."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Activar"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Ahora no"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Más información"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Las notificaciones mejoradas pueden leer todo el contenido de las notificaciones, incluidas las relacionadas con información personal, como nombres y mensajes de tus contactos. Esta función también puede cerrar notificaciones o utilizar los botones de las notificaciones, por ejemplo, para responder llamadas telefónicas.\n\nAdemás, puede activar o desactivar el modo Prioridad y cambiar ajustes relacionados con él."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificación sobre el modo rutina"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Quizás se agote la batería antes de lo habitual"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Se ha activado el modo Ahorro de batería para aumentar la duración de la batería"</string>
@@ -2275,7 +2269,7 @@
<string name="dismiss_action" msgid="1728820550388704784">"Cerrar"</string>
<string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Desbloquea el micrófono del dispositivo"</string>
<string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Desbloquea la cámara del dispositivo"</string>
- <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Para que <b><xliff:g id="APP">%s</xliff:g></b> y todos los servicios y las aplicaciones puedan acceder"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Para <b><xliff:g id="APP">%s</xliff:g></b> y todos los servicios y las aplicaciones"</string>
<string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Desbloquear"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidad del sensor"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icono de aplicación"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 9672e84..1e58aed 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Administraator on seda värskendanud"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Administraator on selle kustutanud"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Akusäästja lülitab sisse tumeda teema ning piirab taustategevusi, teatud visuaalseid efekte ja funktsioone, nagu „Ok Google“ (või lülitab need välja)\n\n"<annotation id="url">"Lisateave"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Akusäästja lülitab sisse tumeda teema ning piirab taustategevusi, teatud visuaalseid efekte ja funktsioone, nagu „Ok Google“ (või lülitab need välja)."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Andmekasutuse vähendamiseks keelab andmemahu säästja mõne rakenduse puhul andmete taustal saatmise ja vastuvõtmise. Rakendus, mida praegu kasutate, pääseb andmesidele juurde, kuid võib seda teha väiksema sagedusega. Seetõttu võidakse näiteks pildid kuvada alles siis, kui neid puudutate."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Lülitada andmemahu säästja sisse?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Lülita sisse"</string>
@@ -1896,7 +1894,7 @@
<string name="zen_mode_alarm" msgid="7046911727540499275">"Kuni <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (järgmine äratus)"</string>
<string name="zen_mode_forever" msgid="740585666364912448">"Kuni välja lülitate"</string>
<string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Kuni lülitate välja valiku Mitte segada"</string>
- <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
+ <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="8009920446193610996">"Ahendamine"</string>
<string name="zen_mode_feature_name" msgid="3785547207263754500">"Mitte segada"</string>
<string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Puhkeaeg"</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Sule"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Vasta"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Keeldu"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Lõpeta kõne"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Sissetulev kõne"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Sellele märguandele määrati prioriteet Vaikne. Puudutage tagasiside andmiseks."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Sellele märguandele määrati kõrgem prioriteet. Puudutage tagasiside andmiseks."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Sellele märguandele määrati madalam prioriteet. Puudutage tagasiside andmiseks."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Proovige täiustatud märguandeid"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Soovitatud toimingute, vastuste ja muu nägemiseks ka edaspidi lülitage sisse täiustatud märguanded. Androidi kohanduvaid märguandeid enam ei toetata."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Lülita sisse"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Mitte praegu"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Lisateave"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Täiustatud märguanded saavad lugeda kogu märguande sisu, sh isiklikku teavet, nagu kontaktide nimed ja sõnumid. Samuti saab selle funktsiooniga märguannetest loobuda või märguannetes nuppude abil toiminguid teha (nt vastata telefonikõnedele).\n\nLisaks saab selle funktsiooniga sisse või välja lülitada režiimi Prioriteetne ja muuta seotud seadeid."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rutiinirežiimi teabe märguanne"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Aku võib enne tavapärast laadimist tühjaks saada"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Akusäästja aktiveeriti aku tööea pikendamiseks"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 08c4c06..3d2eda9 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -315,7 +315,7 @@
<string name="permgroupdesc_storage" msgid="6351503740613026600">"atzitu gailuko argazkiak, multimedia-edukia eta fitxategiak"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofonoa"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"grabatu audioa"</string>
- <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Jarduera fisiko"</string>
+ <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Jarduera fisikoa"</string>
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"jarduera fisikoa atzitu"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"atera argazkiak eta grabatu bideoak"</string>
@@ -362,11 +362,11 @@
<string name="permlab_receiveMms" msgid="4000650116674380275">"jaso testu-mezuak (MMSak)"</string>
<string name="permdesc_receiveMms" msgid="958102423732219710">"MMS mezuak jasotzeko eta prozesatzeko baimena ematen die aplikazioei. Horrela, aplikazioak gailura bidalitako mezuak kontrola eta ezaba ditzake zuri erakutsi gabe."</string>
<string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"desbideratu sare mugikor bidezko igorpen-mezuak"</string>
- <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Sare mugikor bidezko igorpen-modulura lotzeko baimena ematen die aplikazioei, sare mugikor bidezko igorpen-mezuak jaso ahala desbideratu ahal izateko. Sare mugikor bidezko igorpen-alertak kokapen batzuetan entregatzen dira larrialdi-egoeren berri emateko. Sare mugikor bidezko larrialdi-igorpenak jasotzean, asmo txarreko aplikazioek gailuaren errendimenduari edota funtzionamenduari eragin diezaiokete."</string>
+ <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Sare mugikor bidezko iragarpen-modulura lotzeko baimena ematen die aplikazioei, sare mugikor bidezko iragarpen-mezuak jaso ahala desbideratu ahal izateko. Sare mugikor bidezko iragarpen-alertak kokapen batzuetan entregatzen dira larrialdi-egoeren berri emateko. Sare mugikor bidezko larrialdi-iragarpenak jasotzean, asmo txarreko aplikazioek gailuaren errendimenduari edota funtzionamenduari eragin diezaiokete."</string>
<string name="permlab_manageOngoingCalls" msgid="281244770664231782">"Kudeatu abian dauden deiak"</string>
<string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"Gailuak jasotzen dituen deiei buruzko xehetasunak ikusteko eta dei horiek kontrolatzeko baimena ematen die aplikazioei."</string>
<string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"irakurri sare mugikor bidezko igorpen-mezuak"</string>
- <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Gailuak jasotako sare mugikor bidezko igorpenen mezuak irakurtzeko baimena ematen die aplikazioei. Sare mugikor bidezko igorpen-alertak kokapen batzuetan ematen dira larrialdi-egoeren berri emateko. Asmo txarreko aplikazioek gailuaren errendimendua edo funtzionamendua oztopa dezakete larrialdi-igorpen horietako bat jasotzen denean."</string>
+ <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Gailuak jasotako sare mugikor bidezko igorpen-mezuak irakurtzeko baimena ematen die aplikazioei. Sare mugikor bidezko igorpen-alertak kokapen batzuetan ematen dira larrialdi-egoeren berri emateko. Asmo txarreko aplikazioek gailuaren errendimendua edo funtzionamendua oztopa dezakete larrialdi-igorpen horietako bat jasotzen denean."</string>
<string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"irakurri harpidetutako jarioak"</string>
<string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"Une horretan sinkronizatutako jarioei buruzko xehetasunak lortzeko baimena ematen die aplikazioei."</string>
<string name="permlab_sendSms" msgid="7757368721742014252">"bidali eta ikusi SMS mezuak"</string>
@@ -451,8 +451,8 @@
<string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Aplikazioak edonoiz erabil dezake mikrofonoa audioa grabatzeko."</string>
<string name="permlab_sim_communication" msgid="176788115994050692">"bidali aginduak SIM txartelera"</string>
<string name="permdesc_sim_communication" msgid="4179799296415957960">"SIM txartelera aginduak bidaltzeko aukera ematen die aplikazioei. Oso arriskutsua da."</string>
- <string name="permlab_activityRecognition" msgid="1782303296053990884">"hauteman jarduera fisiko"</string>
- <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Aplikazioak jarduera fisiko hauteman dezake."</string>
+ <string name="permlab_activityRecognition" msgid="1782303296053990884">"hauteman jarduera fisikoa"</string>
+ <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Aplikazioak jarduera fisikoa hauteman dezake."</string>
<string name="permlab_camera" msgid="6320282492904119413">"atera argazkiak eta grabatu bideoak"</string>
<string name="permdesc_camera" msgid="5240801376168647151">"Aplikazioak abian den bitartean erabil dezake kamera argazkiak ateratzeko eta bideoak grabatzeko."</string>
<string name="permlab_backgroundCamera" msgid="7549917926079731681">"Argazkiak atera eta bideoak grabatu atzeko planoan."</string>
@@ -538,10 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Inguruko Bluetooth bidezko gailuak hautemateko eta haiekin parekatzeko baimena ematen die aplikazioei"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"parekatutako Bluetooth bidezko gailuetara konektatu"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Parekatutako Bluetooth bidezko gailuetara konektatzeko baimena ematen die aplikazioei"</string>
- <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"inguruko Bluetooth bidezko gailuei publizitatea erakutsi"</string>
- <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Inguruko Bluetooth bidezko gailuei publizitatea erakusteko baimena ematen die aplikazioei"</string>
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"inguruko Bluetooth bidezko gailuetan informazioa iragarri"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Inguruko Bluetooth bidezko gailuetan informazioa iragartzeko baimena ematen die aplikazioei"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"banda ultrazabala darabilten inguruko gailuen arteko distantzia erlatiboa zehaztu"</string>
- <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Banda ultrazabala darabilten inguruko gailuen arteko distantzia erlatiboa zehazteko baimena ematen die aplikazioei"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Banda ultrazabala darabilten inguruko gailuen arteko distantzia erlatiboa zehazteko baimena ematen dio aplikazioari"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Aplikazioari baimena ematen dio NFC bidezko ordainketa-zerbitzu lehenetsiari buruzko informazioa jasotzeko, hala nola erregistratutako laguntzaileak eta ibilbidearen helmuga."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrolatu Near Field Communication komunikazioa"</string>
@@ -1852,11 +1852,9 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Administratzaileak eguneratu du"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Administratzaileak ezabatu du"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Ados"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
- <string name="data_saver_description" msgid="4995164271550590517">"Datuen erabilera murrizteko, atzeko planoan datuak bidaltzea eta jasotzea galarazten die datu-aurrezleak aplikazio batzuei. Une honetan erabiltzen ari zaren aplikazioak atzitu egin ahal izango ditu datuak, baina baliteke maiztasun txikiagoarekin atzitzea. Horrela, adibidez, baliteke irudiak ez erakustea haiek sakatu arte."</string>
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Bateria-aurrezleak gai iluna aktibatzen du, eta murriztu edo desaktibatu egiten ditu atzeko planoko jarduerak, zenbait efektu bisual eta beste eginbide batzuk, hala nola \"Ok Google\".\n\n"<annotation id="url">"Lortu informazio gehiago"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Bateria-aurrezleak gai iluna aktibatzen du, eta murriztu edo desaktibatu egiten ditu atzeko planoko jarduerak, zenbait efektu bisual eta beste eginbide batzuk, hala nola \"Ok Google\"."</string>
+ <string name="data_saver_description" msgid="4995164271550590517">"Datuen 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>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Itxi"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Erantzun"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Baztertu"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Amaitu deia"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Jasotako deia"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Isilarazi da jakinarazpena. Sakatu hau oharrak bidaltzeko."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Mailaz igo da jakinarazpena. Sakatu hau oharrak bidaltzeko."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Mailaz jaitsi da jakinarazpena. Sakatu hau oharrak bidaltzeko."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Probatu jakinarazpen hobetuak"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Iradokitako ekintzak, erantzunak eta abar jasotzen jarraitzeko, aktibatu jakinarazpen hobetuak. Android-en jakinarazpen egokituak ez dira onartzen jada."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Aktibatu"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Orain ez"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Lortu informazio gehiago"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Jakinarazpen hobetuek jakinarazpenen eduki osoa irakur dezakete, informazio pertsonala barne (esaterako, kontaktuen izenak eta mezuak). Halaber, jakinarazpenak baztertu edo jakinarazpenetako botoiak erabil ditzake eginbideak; adibidez, telefono-deiak erantzun.\n\nHorretaz gain, lehentasunezko modua aktibatu edo desaktiba dezake, eta erlazionatutako ezarpenak aldatu."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Ohitura moduaren informazio-jakinarazpena"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baliteke bateria ohi baino lehenago agortzea"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Bateria-aurrezlea aktibatuta dago bateriaren iraupena luzatzeko"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index fc9162a..ae3f79a 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -84,7 +84,7 @@
<string name="RestrictedStateContent" msgid="7693575344608618926">"شرکت مخابراتی شما موقتاً آن را خاموش کرده است"</string>
<string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"شرکت مخابراتیتان موقتاً آن را برای سیمکارت <xliff:g id="SIMNUMBER">%d</xliff:g> خاموش کرده است"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"شبکه تلفن همراه دردسترس نیست"</string>
- <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"تغییر شبکه برگزیده را امتحان کنید. برای تغییر ضربه بزنید."</string>
+ <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"تغییر شبکه ترجیحی را امتحان کنید. برای تغییر، ضربه بزنید."</string>
<string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"تماس اضطراری امکانپذیر نیست"</string>
<string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"تماس اضطراری ازطریق Wi‑Fi امکانپذیر نیست"</string>
<string name="notification_channel_network_alert" msgid="4788053066033851841">"هشدارها"</string>
@@ -113,7 +113,7 @@
<string name="roamingText2" msgid="2834048284153110598">"نشانگر چشمک زن فراگردی"</string>
<string name="roamingText3" msgid="831690234035748988">"خارج از محله"</string>
<string name="roamingText4" msgid="2171252529065590728">"خارج از ساختمان"</string>
- <string name="roamingText5" msgid="4294671587635796641">"فراگردی - سیستم برگزیده"</string>
+ <string name="roamingText5" msgid="4294671587635796641">"فراگردی - سیستم ترجیحی"</string>
<string name="roamingText6" msgid="5536156746637992029">"فراگردی - سیستم موجود"</string>
<string name="roamingText7" msgid="1783303085512907706">"فراگردی - شریک"</string>
<string name="roamingText8" msgid="7774800704373721973">"فراگردی - شریک ویژه"</string>
@@ -1322,7 +1322,7 @@
<string name="select_character" msgid="3352797107930786979">"درج نویسه"</string>
<string name="sms_control_title" msgid="4748684259903148341">"درحال ارسال پیامکها"</string>
<string name="sms_control_message" msgid="6574313876316388239">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> درحال ارسال تعداد زیادی پیامک است. آیا اجازه میدهید این برنامه همچنان پیامک ارسال کند؟"</string>
- <string name="sms_control_yes" msgid="4858845109269524622">"مجاز است"</string>
+ <string name="sms_control_yes" msgid="4858845109269524622">"مجاز بودن"</string>
<string name="sms_control_no" msgid="4845717880040355570">"مجاز نبودن"</string>
<string name="sms_short_code_confirm_message" msgid="1385416688897538724">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> مایل است پیامی به <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> ارسال کند."</string>
<string name="sms_short_code_details" msgid="2723725738333388351">"این مورد "<b>"شاید هزینهای"</b>" را به حساب دستگاه همراهتان بگذارد."</string>
@@ -1852,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"«بهینهسازی باتری» «طرح زمینه تیره» را روشن میکند و فعالیت پسزمینه، برخی از جلوههای بصری، و ویژگیهایی مثل «Ok Google» را محدود یا خاموش میکند.\n\n"<annotation id="url">"بیشتر بدانید"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"«بهینهسازی باتری» «طرح زمینه تیره» را روشن میکند و فعالیت پسزمینه، برخی از جلوههای بصری، و ویژگیهایی مثل «Ok Google» را محدود یا خاموش میکند."</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>
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"بستن"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"پاسخ"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"رد کردن"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"قطع تماس"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"تماس ورودی"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"این اعلان به «بیصدا» تنزل داده شد. برای ارائه بازخورد، ضربه بزنید."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"این اعلان در رتبه بالاتری قرار گرفت. برای ارائه بازخورد، ضربه بزنید."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"این اعلان در رتبه پایینتری قرار گرفت. برای ارائه بازخورد، ضربه بزنید."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"امتحان کردن اعلانهای بهبودیافته"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"برای اینکه پاسخها و کنشهای پیشنهادی و موارد دیگر را همچنان دریافت کنید، اعلانهای بهبودیافته را روشن کنید. از «اعلانهای تطبیقی Android» دیگر پشتیبانی نمیشود."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"روشن کردن"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"الآن نه"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"بیشتر بدانید"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"اعلانهای بهبودیافته میتواند محتوای همه اعلانها، ازجمله اطلاعات شخصی مثل نام مخاطبین و پیامها را بخواند. این ویژگی همچنین میتواند اعلانها را ببندد یا بااستفاده از دکمههای موجود در اعلانها اقداماتی انجام دهد، مثلاً به تماسهای تلفنی پاسخ دهد.\n\nبهعلاوه، این ویژگی میتواند «حالت اولویت» را روشن یا خاموش کند و تنظیمات مربوطه را تغییر دهد."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"اعلان اطلاعات حالت روال معمول"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ممکن است شارژ باتری قبل از شارژ معمول تمام شود"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"جهت افزایش عمر باتری، «بهینهسازی باتری» فعال شد"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 4ff7593..7e6cb56 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -538,10 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Sallii sovelluksen löytää lähellä olevia Bluetooth-laitteita ja muodostaa niistä laitepareja"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"yhdistää pariliitettyihin Bluetooth-laitteisiin"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Sallii sovelluksen muodostaa yhteyden pariliitettyihin Bluetooth-laitteisiin"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"mainostaa lähellä oleville Bluetooth-laitteille"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Sallii sovelluksen mainostaa lähellä oleville Bluetooth-laitteille"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"määrittää UVB:ta käyttävien laitteiden suhteellisen sijainnin"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Sallii sovelluksen määrittää UVB-taajuutta käyttävien laitteiden sijainnin suhteessa toisiinsa"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Ensisijaiset NFC-maksupalvelutiedot"</string>
@@ -1854,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Järjestelmänvalvoja päivitti tämän."</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Järjestelmänvalvoja poisti tämän."</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Virransäästö laittaa tumman teeman päälle ja rajoittaa tai laittaa pois päältä taustatoimintoja, joitakin visuaalisia tehosteita ja muita ominaisuuksia (esim. Ok Google).\n\n"<annotation id="url">"Lue lisää"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Virransäästö laittaa tumman teeman päälle ja rajoittaa tai laittaa pois päältä taustatoimintoja, joitakin visuaalisia tehosteita ja muita ominaisuuksia (esim. Ok Google)."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Data Saver estää joitakin sovelluksia lähettämästä tai vastaanottamasta tietoja taustalla, jotta datan käyttöä voidaan vähentää. Käytössäsi oleva sovellus voi yhä käyttää dataa, mutta se saattaa tehdä niin tavallista harvemmin. Tämä voi tarkoittaa esimerkiksi sitä, että kuva ladataan vasta, kun kosketat sitä."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Otetaanko Data Saver käyttöön?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Ota käyttöön"</string>
@@ -1933,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Sulje"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Vastaa"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Hylkää"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Lopeta puhelu"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Saapuva puhelu"</string>
@@ -2076,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Tämä ilmoitus hiljennettiin. Lähetä palautetta napauttamalla."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Tämän ilmoituksen tasoa nostettiin. Lähetä palautetta napauttamalla."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Tämän ilmoituksen tasoa laskettiin. Lähetä palautetta napauttamalla."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Kokeile parann. ilmoituksia"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Jos haluat jatkossakin saada ehdotuksia toiminnoista, vastauksista ja muista, laita parannetut ilmoitukset päälle. Androidin mukautuvia ilmoituksia ei enää tueta."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Laita päälle"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Ei nyt"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Lue lisää"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Parannetut ilmoitukset voivat lukea kaikkea ilmoitussisältöä, myös henkilökohtaisia tietoja (esim. kontaktien nimet ja viestit). Ominaisuus voi myös ohittaa ilmoituksia tai käyttää niiden toimintopainikkeita, esim. vastata puheluihin.\n\nLisäksi ominaisuus voi laittaa Tärkeät-tilan päälle tai pois päältä ja muuttaa siihen liittyviä asetuksia."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Ohjelmatilan tietoilmoitus"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Akku saattaa loppua ennen normaalia latausaikaa"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Virransäästö otettu käyttöön akunkeston pidentämiseksi"</string>
@@ -2275,14 +2267,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Voit nyt suurentaa näytön osan"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Laita päälle asetuksista"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Hylkää"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Kumoa laitteen mikrofonin esto"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Kumoa laitteen kameran esto"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> sekä kaikki sovellukset ja palvelut"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Kumoa esto"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Anturin tietosuoja"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Sovelluskuvake"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Sovelluksen tuotemerkkikuva"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 20365d0..3d22748 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Mise à jour par votre administrateur"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Supprimé par votre administrateur"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"La fonctionnalité Économiseur de pile active le mode sombre et limite ou désactive l\'activité en arrière-plan, certains effets visuels et certaines fonctionnalités, comme « Ok Google »\n\n"<annotation id="url">"En savoir plus"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"La fonctionnalité Économiseur de pile active le mode sombre et limite ou désactive l\'activité en arrière-plan, certains effets visuels et certaines fonctionnalités, comme « Ok Google »."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Pour aider à diminuer l\'utilisation des données, la fonctionnalité Économiseur de données empêche certaines applications d\'envoyer ou de recevoir des données en arrière-plan. Une application que vous utilisez actuellement peut accéder à des données, mais peut le faire moins souvent. Cela peut signifier, par exemple, que les images ne s\'affichent pas jusqu\'à ce que vous les touchiez."</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>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Fermer"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g> : <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Répondre"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Vidéo"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Refuser"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Raccrocher"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Appel entrant"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Cette notification a été rétrogradée à Silencieuse. Touchez pour envoyer des commentaires."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Cette notification a été élevée d\'un niveau. Touchez pour envoyer des commentaires."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Cette notification a été abaissée d\'un niveau. Touchez pour envoyer des commentaires."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Essayer les notif. améliorées"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Pour continuer de recevoir des suggestions d\'actions, de réponses et plus encore, activez les notifications améliorées. Les notifications adaptatives Android ne sont plus prises en charge."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Activer"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Plus tard"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"En savoir plus"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Les notifications améliorées peuvent lire le contenu de toutes les notifications, y compris les renseignements personnels comme le nom des contacts et les messages. Cette fonctionnalité peut aussi fermer des notifications ou effectuer des actions sur les boutons dans les notifications, comme répondre aux appels entrants.\n\nElle peut aussi activer et désactiver le mode Prioritaire et modifier les paramètres connexes."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notification d\'information du mode Routine"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"La pile pourrait s\'épuiser avant la charge habituelle"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Le mode Économiseur de pile est activé afin de prolonger l\'autonomie"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 7afe476..5f762ff 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -196,7 +196,7 @@
<string name="network_logging_notification_text" msgid="1327373071132562512">"Votre organisation gère cet appareil et peut surveiller le trafic réseau. Appuyez ici pour obtenir plus d\'informations."</string>
<string name="location_changed_notification_title" msgid="3620158742816699316">"Des application peuvent accéder à votre position"</string>
<string name="location_changed_notification_text" msgid="7158423339982706912">"Contactez votre administrateur pour en savoir plus"</string>
- <string name="geofencing_service" msgid="3826902410740315456">"Service de gardiennage virtuel"</string>
+ <string name="geofencing_service" msgid="3826902410740315456">"Service de géorepérage"</string>
<string name="country_detector" msgid="7023275114706088854">"Détecteur de pays"</string>
<string name="location_service" msgid="2439187616018455546">"Service de localisation"</string>
<string name="gnss_service" msgid="8907781262179951385">"Service GNSS"</string>
@@ -538,10 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Autorise l\'appli à détecter et à associer les appareils Bluetooth à proximité"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"se connecter aux appareils Bluetooth associés"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Autorise l\'appli à se connecter à des appareils Bluetooth associés"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"diffuser sur les appareils Bluetooth à proximité"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permet à l\'appli de diffuser du contenu sur les appareils Bluetooth à proximité"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"déterminer position relative entre appareils ultra-wideband à proximité"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Autoriser l\'appli à déterminer la position relative entre des appareils ultra-wideband à proximité"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informations sur le service de paiement NFC préféré"</string>
@@ -1106,8 +1104,8 @@
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
</plurals>
<plurals name="duration_minutes_relative" formatted="false" msgid="6569851308583028344">
- <item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
- <item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
+ <item quantity="one">Il y a <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="other">Il y a <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
</plurals>
<plurals name="duration_hours_relative" formatted="false" msgid="420434788589102019">
<item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> heure</item>
@@ -1692,13 +1690,13 @@
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"Ne pas activer"</string>
<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 au service <xliff:g id="SERVICE">%1$s</xliff:g> ?"</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 applications."</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">"Cette fonctionnalité peut lire l\'intégralité du contenu à l\'écran et afficher du contenu par-dessus d\'autres applications."</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>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Afficher et effectuer des actions"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Cette fonctionnalité peut effectuer le suivi de vos interactions avec une application ou un capteur matériel, et interagir avec les applications en votre nom."</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Le service peut suivre vos interactions avec une application ou un capteur matériel, et interagir avec des applications de votre part."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Autoriser"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Refuser"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Appuyez sur une fonctionnalité pour commencer à l\'utiliser :"</string>
@@ -1854,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Mis à jour par votre administrateur"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Supprimé par votre administrateur"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"L\'économiseur de batterie active le thème sombre et limite ou désactive les activités en arrière-plan, certains effets visuels et d\'autres fonctionnalités comme \"Hey Google\"\n\n"<annotation id="url">"En savoir plus"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"L\'économiseur de batterie active le thème sombre et limite ou désactive les activités en arrière-plan, certains effets visuels et d\'autres fonctionnalités comme \"Hey Google\"."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Pour réduire la consommation de données, l\'économiseur de données empêche certaines applications d\'envoyer ou de recevoir des données en arrière-plan. Ainsi, les applications que vous utilisez peuvent toujours accéder aux données, mais pas en permanence. Par exemple, il se peut que les images ne s\'affichent pas tant que vous n\'appuyez 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>
@@ -1933,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Fermer"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g> : <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Répondre"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Refuser"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Raccrocher"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Appel entrant"</string>
@@ -2076,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Cette notification a été abaissée à la catégorie \"Silencieux\". Appuyez ici pour donner votre avis."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Cette notification a été élevée d\'un niveau. Appuyez ici pour donner votre avis."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Cette notification a été abaissée d\'un niveau. Appuyez ici pour donner votre avis."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Testez les notifications améliorées"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Activez les notifications améliorées pour continuer à recevoir des suggestions d\'actions, de réponses et plus encore. Les notifications intelligentes Android ne sont plus disponibles."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Activer"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Pas maintenant"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"En savoir plus"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Les notifications améliorées peuvent lire tout le contenu des notifications, y compris des informations personnelles comme le nom des contacts et les messages. Cette fonctionnalité peut aussi fermer des notifications ou effectuer des actions grâce aux boutons figurant dans ces notifications, par exemple répondre aux appels téléphoniques.\n\nElle peut aussi activer ou désactiver le mode Prioritaire et modifier les paramètres associés."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notification d\'information du mode Routine"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Vous risquez d\'être à court de batterie plus tôt que prévu"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Économiseur de batterie activé pour prolonger l\'autonomie"</string>
@@ -2275,14 +2267,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Vous pouvez désormais agrandir une partie de l\'écran"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activer dans les paramètres"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Fermer"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Débloquer le micro de l\'appareil"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Débloquer l\'appareil photo de l\'appareil"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Pour <b><xliff:g id="APP">%s</xliff:g></b> et tous les services et applis"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Débloquer"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Confidentialité du capteur"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icône de l\'application"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Image de branding de l\'application"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 123419b..12bb42d 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -342,7 +342,7 @@
<string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Facer captura de pantalla"</string>
<string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pode facer capturas de pantalla."</string>
<string name="permlab_statusBar" msgid="8798267849526214017">"desactivar ou modificar a barra de estado"</string>
- <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite á aplicación desactivar a barra de estado ou engadir e eliminar as iconas do sistema."</string>
+ <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite á aplicación desactivar a barra de estado ou engadir e quitar as iconas do sistema."</string>
<string name="permlab_statusBarService" msgid="2523421018081437981">"actuar como a barra de estado"</string>
<string name="permdesc_statusBarService" msgid="6652917399085712557">"Permite á aplicación ser a barra de estado."</string>
<string name="permlab_expandStatusBar" msgid="1184232794782141698">"ampliar/contraer a barra de estado"</string>
@@ -352,7 +352,7 @@
<string name="permlab_install_shortcut" msgid="7451554307502256221">"instalar atallos"</string>
<string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permite a unha aplicación engadir atallos na pantalla de inicio sen intervención do usuario."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"desinstalar atallos"</string>
- <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permite á aplicación eliminar atallos da pantalla de inicio sen a intervención do usuario."</string>
+ <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permite á aplicación quitar atallos da pantalla de inicio sen a intervención do usuario."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"redirixir as chamadas saíntes"</string>
<string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Permite á aplicación ver o número que se está marcando durante unha chamada saínte coa opción de redirixir a chamada a un número diferente ou abortar a chamada."</string>
<string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"responder chamadas telefónicas"</string>
@@ -709,8 +709,8 @@
<string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Permite a unha aplicación fornecer e utilizar certificados DRM. Non se deberían precisar nunca para as aplicacións normais."</string>
<string name="permlab_handoverStatus" msgid="7620438488137057281">"recibir o estado das transferencias de Android Beam"</string>
<string name="permdesc_handoverStatus" msgid="3842269451732571070">"Permite a esta aplicación recibir información acerca das transferencias actuais de Android Beam"</string>
- <string name="permlab_removeDrmCertificates" msgid="710576248717404416">"eliminar certificados DRM"</string>
- <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Permite a unha aplicación eliminar os certificados DRM. As aplicacións normais non o deberían precisar nunca."</string>
+ <string name="permlab_removeDrmCertificates" msgid="710576248717404416">"quitar certificados DRM"</string>
+ <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Permite a unha aplicación quitar os certificados DRM. As aplicacións normais non o deberían precisar nunca."</string>
<string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"vincular a un servizo de mensaxaría"</string>
<string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Permite ao propietario vincularse á interface de nivel superior dun servizo de mensaxaría. As aplicacións normais non deberían necesitar este permiso."</string>
<string name="permlab_bindCarrierServices" msgid="2395596978626237474">"vincular aos servizos do operador"</string>
@@ -1582,7 +1582,7 @@
<string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"Límite de datos wifi superado"</string>
<string name="data_usage_limit_snoozed_body" msgid="545146591766765678">"Pasácheste <xliff:g id="SIZE">%s</xliff:g> do límite establecido"</string>
<string name="data_usage_restricted_title" msgid="126711424380051268">"Datos en segundo plano limitados"</string>
- <string name="data_usage_restricted_body" msgid="5338694433686077733">"Toca para eliminar a restrición."</string>
+ <string name="data_usage_restricted_body" msgid="5338694433686077733">"Toca para quitar a restrición."</string>
<string name="data_usage_rapid_title" msgid="2950192123248740375">"Uso elevado de datos móbiles"</string>
<string name="data_usage_rapid_body" msgid="3886676853263693432">"As aplicacións utilizaron máis datos do normal"</string>
<string name="data_usage_rapid_app_body" msgid="5425779218506513861">"A aplicación <xliff:g id="APP">%s</xliff:g> utilizou máis datos do normal"</string>
@@ -1677,7 +1677,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Debuxaches incorrectamente o padrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear o dispositivo Android TV a través dunha conta de correo electrónico.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Debuxaches o padrón de desbloqueo incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear o teléfono a través dunha conta de correo electrónico.\n\n Téntao de novo dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
- <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Eliminar"</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Quitar"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Queres subir o volume máis do nivel recomendado?\n\nA reprodución de son a un volume elevado durante moito tempo pode provocar danos nos oídos."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Queres utilizar o atallo de accesibilidade?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Cando o atallo está activado, podes premer os dous botóns de volume durante 3 segundos para iniciar unha función de accesibilidade."</string>
@@ -1833,7 +1833,7 @@
<string name="restr_pin_try_later" msgid="5897719962541636727">"Téntao de novo máis tarde"</string>
<string name="immersive_cling_title" msgid="2307034298721541791">"Vendo pantalla completa"</string>
<string name="immersive_cling_description" msgid="7092737175345204832">"Para saír, pasa o dedo cara abaixo desde a parte superior."</string>
- <string name="immersive_cling_positive" msgid="7047498036346489883">"De acordo"</string>
+ <string name="immersive_cling_positive" msgid="7047498036346489883">"Entendido"</string>
<string name="done_label" msgid="7283767013231718521">"Feito"</string>
<string name="hour_picker_description" msgid="5153757582093524635">"Control desprazable circular das horas"</string>
<string name="minute_picker_description" msgid="9029797023621927294">"Control desprazable circular dos minutos"</string>
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Actualizado polo teu administrador"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminado polo teu administrador"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Coa función Aforro de batería actívase o tema escuro e restrínxense ou desactívanse a actividade en segundo plano, algúns efectos visuais e outras funcións, como “Hey Google”\n\n"<annotation id="url">"Máis información"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Coa función Aforro de batería actívase o tema escuro e restrínxense ou desactívanse a actividade en segundo plano, algúns efectos visuais e outras funcións, como “Hey Google”."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Para contribuír a reducir o uso de datos, o aforro de datos impide que algunhas aplicacións envíen ou reciban datos en segundo plano. Cando esteas utilizando unha aplicación, esta poderá acceder aos datos, pero é posible que o faga con menos frecuencia. Por exemplo, poida que as imaxes non se mostren ata que as toques."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Queres activar o aforro de datos?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Activar"</string>
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Pechar"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Resposta"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Rexeitar"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Colgar"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Chamada entrante"</string>
@@ -1948,7 +1948,7 @@
<string name="user_creation_adding" msgid="7305185499667958364">"Queres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario novo con <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="52674936078683285">"Engadir un idioma"</string>
<string name="country_selection_title" msgid="5221495687299014379">"Preferencia de rexión"</string>
- <string name="search_language_hint" msgid="7004225294308793583">"Nome do idioma"</string>
+ <string name="search_language_hint" msgid="7004225294308793583">"Escribe o nome do idioma"</string>
<string name="language_picker_section_suggested" msgid="6556199184638990447">"Suxeridos"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"Todos os idiomas"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"Todas as rexións"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"O nivel desta notificación diminuíu a Silenciosa. Toca para compartir a túa opinión."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Esta notificación clasificouse nun nivel superior. Toca para compartir a túa opinión."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Esta notificación clasificouse nun nivel inferior. Toca para compartir a túa opinión."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Proba notificacións melloradas"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Para seguir recibindo accións suxeridas, respostas e moito máis, activa as notificacións melloradas. As notificacións intelixentes de Android xa non son compatibles."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Activar"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Agora non"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Máis información"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Coas notificacións melloradas pódese ler todo o contido das notificacións, mesmo a información persoal (por exemplo, os nomes dos contactos e as mensaxes). Con esta función tamén se poden ignorar as notificacións ou realizar accións nos botóns que aparecen nelas, como responder chamadas telefónicas.\n\nAdemais, permite activar e desactivar o modo de prioridade e cambiar a configuración relacionada."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificación da información do modo de rutina"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"A batería pode esgotarse antes do habitual"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Para ampliar a duración da batería activouse a función Aforro de batería"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index f0e3f77..2f2df47 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -87,7 +87,7 @@
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"પસંદગીનું નેટવર્ક બદલવાનો પ્રયાસ કરો. બદલવા માટે ટૅપ કરો."</string>
<string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"કટોકટીની કૉલિંગ સેવા અનુપલબ્ધ"</string>
<string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"વાઇ-ફાઇ પરથી કટોકટીના કૉલ કરી શકાતા નથી"</string>
- <string name="notification_channel_network_alert" msgid="4788053066033851841">"ચેતવણીઓ"</string>
+ <string name="notification_channel_network_alert" msgid="4788053066033851841">"અલર્ટ"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"કૉલ ફૉર્વર્ડિંગ"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"કટોકટી કૉલબૅક મોડ"</string>
<string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"મોબાઇલ ડેટાની સ્થિતિ"</string>
@@ -288,7 +288,7 @@
<string name="notification_channel_network_available" msgid="6083697929214165169">"નેટવર્ક ઉપલબ્ધ છે"</string>
<string name="notification_channel_vpn" msgid="1628529026203808999">"VPN સ્થિતિ"</string>
<string name="notification_channel_device_admin" msgid="6384932669406095506">"તમારા IT વ્યવસ્થાપક તરફથી અલર્ટ"</string>
- <string name="notification_channel_alerts" msgid="5070241039583668427">"ચેતવણીઓ"</string>
+ <string name="notification_channel_alerts" msgid="5070241039583668427">"અલર્ટ"</string>
<string name="notification_channel_retail_mode" msgid="3732239154256431213">"રિટેલ ડેમો"</string>
<string name="notification_channel_usb" msgid="1528280969406244896">"USB કનેક્શન"</string>
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ઍપ ચાલી રહ્યું છે"</string>
@@ -303,7 +303,7 @@
<string name="android_system_label" msgid="5974767339591067210">"Android સિસ્ટમ"</string>
<string name="user_owner_label" msgid="8628726904184471211">"વ્યક્તિગત પ્રોફાઇલ પર સ્વિચ કરો"</string>
<string name="managed_profile_label" msgid="7316778766973512382">"કાર્યાલયની પ્રોફાઇલ પર સ્વિચ કરો"</string>
- <string name="permgrouplab_contacts" msgid="4254143639307316920">"Contacts"</string>
+ <string name="permgrouplab_contacts" msgid="4254143639307316920">"સંપર્કો"</string>
<string name="permgroupdesc_contacts" msgid="9163927941244182567">"તમારા સંપર્કોને ઍક્સેસ કરવાની"</string>
<string name="permgrouplab_location" msgid="1858277002233964394">"સ્થાન"</string>
<string name="permgroupdesc_location" msgid="1995955142118450685">"આ ઉપકરણના સ્થાનને ઍક્સેસ કરવાની"</string>
@@ -319,10 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"તમારી શારીરિક પ્રવૃત્તિને ઍક્સેસ કરવી"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"કૅમેરા"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ચિત્રો લેવાની અને વીડિઓ રેકોર્ડ કરવાની"</string>
- <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
- <skip />
- <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
- <skip />
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"નજીકના ડિવાઇસ"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"નજીકના ડિવાઇસ શોધો અને કનેક્ટ કરો"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"કૉલ લૉગ"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ફોન કૉલ લૉગ વાંચો અને લખો"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ફોન"</string>
@@ -540,14 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ઍપને આસપાસના બ્લૂટૂથ ડિવાઇસ શોધવાની અને તેની સાથે જોડી કરવાની મંજૂરી આપે છે"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"જોડી કરેલા બ્લૂટૂથ ડિવાઇસ સાથે કનેક્ટ કરો"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ઍપને જોડી કરેલા બ્લૂટૂથ ડિવાઇસ સાથે કનેક્ટ કરવાની મંજૂરી આપે છે"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"નજીકના બ્લૂટૂથ ડિવાઇસ પર જાહેરાત કરો"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"નજીકના બ્લૂટૂથ ડિવાઇસ પર ઍપને જાહેરાત કરવાની મંજૂરી આપે છે"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"અલ્ટ્રા-વાઇડબૅન્ડ ડિવાઇસની વચ્ચેનું અંતર નક્કી કરો"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ઍપને નજીકના અલ્ટ્રા-વાઇડબૅન્ડ ડિવાઇસની વચ્ચેનું સંબંધિત અંતર નક્કી કરવાની મંજૂરી આપો"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"પસંદગીની NFC ચુકવણીની સેવા વિશે માહિતી"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"આ મંજૂરીને આપવાથી, ઍપ તમારી પસંદગીની NFC ચુકવણીની સેવા વિશે માહિતી મેળવી શકે છે, જેમ કે રજિસ્ટર થયેલી સહાય અને નિર્ધારિત સ્થાન."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"નિઅર ફીલ્ડ કમ્યુનિકેશન નિયંત્રિત કરો"</string>
@@ -1683,7 +1677,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"તમે તમારી અનલૉક પૅટર્ન <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસ પછી, તમને ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને તમારા Android TV ડિવાઇસને અનલૉક કરવાનું કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"તમે તમારી અનલૉક પૅટર્ન <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી. હજી <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસ પછી, તમને ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને ફોનને અનલૉક કરવાનું કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
- <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"દૂર કરો"</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"કાઢી નાખો"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ભલામણ કરેલ સ્તરની ઉપર વૉલ્યૂમ વધાર્યો?\n\nલાંબા સમય સુધી ઊંચા અવાજે સાંભળવું તમારી શ્રવણક્ષમતાને નુકસાન પહોંચાડી શકે છે."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ઍક્સેસિબિલિટી શૉર્ટકટનો ઉપયોગ કરીએ?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"જ્યારે શૉર્ટકટ ચાલુ હોય, ત્યારે બન્ને વૉલ્યૂમ બટનને 3 સેકન્ડ સુધી દબાવી રાખવાથી ઍક્સેસિબિલિટી સુવિધા શરૂ થઈ જશે."</string>
@@ -1725,7 +1719,7 @@
<string name="accessibility_button_instructional_text" msgid="8853928358872550500">"કોઈ એક સુવિધાથી બીજી સુવિધા પર સ્વિચ કરવા માટે, ઍક્સેસિબિલિટી બટનને ટચ કરીને થોડીવાર દબાવી રાખો."</string>
<string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"કોઈ એક સુવિધાથી બીજી સુવિધા પર સ્વિચ કરવા માટે, બે આંગળીઓ વડે સ્ક્રીનની ઉપરની તરફ સ્વાઇપ કરીને દબાવી રાખો."</string>
<string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"કોઈ એક સુવિધાથી બીજી સુવિધા પર સ્વિચ કરવા માટે, ત્રણ આંગળીઓ વડે સ્ક્રીનની ઉપરની તરફ સ્વાઇપ કરીને દબાવી રાખો."</string>
- <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"વિસ્તૃતીકરણ"</string>
+ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"મોટું કરવું"</string>
<string name="user_switched" msgid="7249833311585228097">"વર્તમાન વપરાશકર્તા <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> પર સ્વિચ કરી રહ્યાં છે…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> લોગ આઉટ થઈ રહ્યાં છે…"</string>
@@ -1858,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"બૅટરી સેવર ઘેરી થીમની સુવિધા ચાલુ કરે છે અને બૅકગ્રાઉન્ડમાં થતી પ્રવૃત્તિ, કેટલીક વિઝ્યુઅલ ઇફેક્ટ અને “Ok Google” જેવી સુવિધાઓને મર્યાદિત કે બંધ કરે છે\n\n"<annotation id="url">"વધુ જાણો"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"બૅટરી સેવર ઘેરી થીમની સુવિધા ચાલુ કરે છે અને બૅકગ્રાઉન્ડમાં થતી પ્રવૃત્તિ, કેટલીક વિઝ્યુઅલ ઇફેક્ટ અને “Ok Google” જેવી સુવિધાઓને મર્યાદિત કે બંધ કરે છે."</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>
@@ -1937,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"બંધ કરો"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"જવાબ"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"નકારો"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"સમાપ્ત કરો"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"ઇનકમિંગ કૉલ"</string>
@@ -2034,7 +2028,7 @@
<string name="autofill_save_type_debit_card" msgid="3169397504133097468">"ડેબિટ કાર્ડ"</string>
<string name="autofill_save_type_payment_card" msgid="6555012156728690856">"ચુકવણી કાર્ડ"</string>
<string name="autofill_save_type_generic_card" msgid="1019367283921448608">"કાર્ડ"</string>
- <string name="autofill_save_type_username" msgid="1018816929884640882">"વપરાશકર્તાનામ"</string>
+ <string name="autofill_save_type_username" msgid="1018816929884640882">"વપરાશકર્તાનું નામ"</string>
<string name="autofill_save_type_email_address" msgid="1303262336895591924">"ઇમેઇલ સરનામું"</string>
<string name="etws_primary_default_message_earthquake" msgid="8401079517718280669">"શાંત રહો અને નજીકમાં આશ્રય લો."</string>
<string name="etws_primary_default_message_tsunami" msgid="5828171463387976279">"દરિયાકિનારાના પ્રદેશો તથા નદીકાંઠાના વિસ્તારો ખાલી કરીને તાત્કાલિક સુરક્ષિત ઊંચા સ્થાન પર જાઓ."</string>
@@ -2080,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"નોટિફિકેશનને સાઇલન્ટ પર અવનત કરવામાં આવ્યું. પ્રતિસાદ આપવા માટે ટૅપ કરો."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"આ નોટિફિકેશનને ઉપલી રેંક આપવામાં આવી. પ્રતિસાદ આપવા માટે ટૅપ કરો."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"આ નોટિફિકેશનને નીચલી રેંક આપવામાં આવી. પ્રતિસાદ આપવા માટે ટૅપ કરો."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"વધારાના નોટિફિકેશન અજમાવી જુઓ"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"સૂચવેલી ક્રિયાઓ, જવાબો અને બીજું ઘણું મેળવવા માટે, વધારાના નોટિફિકેશન ચાલુ કરો. Android માટે અનુકૂળ નોટિફિકેશનને હવેથી સપોર્ટ કરવામાં આવતો નથી."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"ચાલુ કરો"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"હમણાં નહીં"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"વધુ જાણો"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"વધારાના નોટિફિકેશન સંપર્કનું નામ અને સંદેશા જેવી વ્યક્તિગત માહિતી સહિત નોટિફિકેશનનું બધું કન્ટેન્ટ વાંચી શકે છે. આ સુવિધા નોટિફિકેશન છોડી પણ શકે છે અથવા નોટિફિકેશનમાં બટન પર ફોન કૉલનો જવાબ આપવા જેવી ક્રિયાઓ પણ કરી શકે છે.\n\nઆ સુવિધા પ્રાધાન્યતા મોડ ચાલુ કે બંધ પણ કરી શકે છે અને સંબંધિત સેટિંગ બદલી પણ શકે છે."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"રૂટિન મોડની માહિતીનું નોટિફિકેશન"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"સામાન્ય રીતે ચાર્જ કરવાના સમય પહેલાં બૅટરી સમાપ્ત થઈ શકે છે"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"બૅટરી આવરદા વધારવા માટે બૅટરી સેવર ચાલુ કર્યું"</string>
@@ -2279,14 +2267,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"હવે તમે તમારી સ્ક્રીનનો અમુક ભાગ મોટો કરી શકો છો"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"સેટિંગમાં ચાલુ કરો"</string>
<string name="dismiss_action" msgid="1728820550388704784">"છોડી દો"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"ડિવાઇસના માઇક્રોફોનને અનબ્લૉક કરો"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"ડિવાઇસના કૅમેરાને અનબ્લૉક કરો"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> અને બધી ઍપ અને સેવાઓ માટે"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"અનબ્લૉક કરો"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"સેન્સર પ્રાઇવસી સંબંધિત નોટિફિકેશન"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ઍપ્લિકેશનનું આઇકન"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ઍપ્લિકેશનની બ્રાંડિંગ છબી"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 8def350..190d561 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -103,7 +103,7 @@
<string name="serviceClassVoice" msgid="2065556932043454987">"Voice"</string>
<string name="serviceClassData" msgid="4148080018967300248">"डेटा"</string>
<string name="serviceClassFAX" msgid="2561653371698904118">"फ़ैक्स"</string>
- <string name="serviceClassSMS" msgid="1547664561704509004">"मैसेज (एसएमएस)"</string>
+ <string name="serviceClassSMS" msgid="1547664561704509004">"एसएमएस"</string>
<string name="serviceClassDataAsync" msgid="2029856900898545984">"Async"</string>
<string name="serviceClassDataSync" msgid="7895071363569133704">"समन्वयन"</string>
<string name="serviceClassPacket" msgid="1430642951399303804">"पैकेट"</string>
@@ -309,7 +309,7 @@
<string name="permgroupdesc_location" msgid="1995955142118450685">"इस डिवाइस की जगह तक पहुंचने दें"</string>
<string name="permgrouplab_calendar" msgid="6426860926123033230">"कैलेंडर"</string>
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"अपने कैलेंडर को ऐक्सेस करने"</string>
- <string name="permgrouplab_sms" msgid="795737735126084874">"मैसेज (एसएमएस)"</string>
+ <string name="permgrouplab_sms" msgid="795737735126084874">"एसएमएस"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"मैसेज (एसएमएस) भेजें और देखें"</string>
<string name="permgrouplab_storage" msgid="1938416135375282333">"फ़ाइलें और मीडिया"</string>
<string name="permgroupdesc_storage" msgid="6351503740613026600">"अपने डिवाइस पर मौजूद फ़ोटो, मीडिया और फ़ाइलें ऐक्सेस करने की"</string>
@@ -538,10 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"अनुमति देने पर, ऐप्लिकेशन, आस-पास मौजूद ब्लूटूथ डिवाइसों को खोज पाएगा और उनसे जुड़ पाएगा"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"जोड़े गए ब्लूटूथ डिवाइसों से कनेक्ट करें"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"अनुमति देने पर, ऐप्लिकेशन, जोड़े गए ब्लूटूथ डिवाइसों से कनेक्ट कर पाएगा"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"आस-पास मौजूद ब्लूटूथ डिवाइसों पर विज्ञापन दिखाएं"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"अनुमति मिलने पर, ऐप्लिकेशन, आस-पास मौजूद ब्लूटूथ डिवाइसों पर विज्ञापन दिखा पाएगा"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"आस-पास मौजूद Ultra-Wideband डिवाइसों के बीच की दूरी का पता लगाएं"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ऐप्लिकेशन को आस-पास मौजूद Ultra-Wideband डिवाइसों के बीच की दूरी का पता लगाने की अनुमति दें"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC का इस्तेमाल करने वाली पैसे चुकाने की पसंदीदा सेवा की जानकारी"</string>
@@ -1721,7 +1719,7 @@
<string name="accessibility_button_instructional_text" msgid="8853928358872550500">"एक सुविधा से दूसरी सुविधा पर जाने के लिए, सुलभता बटन दबाकर रखें."</string>
<string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"एक सुविधा से दूसरी सुविधा पर जाने के लिए, स्क्रीन पर दो उंगलियों से ऊपर की ओर स्वाइप करें और थोड़ी देर तक उंगलियां स्क्रीन पर रखे रहें."</string>
<string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"एक सुविधा से दूसरी सुविधा पर जाने के लिए, स्क्रीन पर तीन उंगलियों से ऊपर की ओर स्वाइप करें और थोड़ी देर तक उंगलियां स्क्रीन पर रखे रहें."</string>
- <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"बड़ा करना"</string>
+ <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ज़ूम करने की सुविधा"</string>
<string name="user_switched" msgid="7249833311585228097">"मौजूदा उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> पर स्विच किया जा रहा है…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> द्वारा प्रस्थान किया जा रहा है…"</string>
@@ -1854,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"बैटरी सेवर गहरे रंग वाली थीम को चालू कर देता है. साथ ही, यह बैकग्राउंड की गतिविधि, कुछ विज़ुअल इफ़ेक्ट, और \"Hey Google\" जैसी दूसरी सुविधाएं इस्तेमाल करने से डिवाइस को रोकता है या इन्हें बंद कर देता है\n\n"<annotation id="url">"ज़्यादा जानें"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"बैटरी सेवर गहरे रंग वाली थीम को चालू कर देता है. साथ ही, यह बैकग्राउंड की गतिविधि, कुछ विज़ुअल इफ़ेक्ट, और \"Hey Google\" जैसी दूसरी सुविधाएं इस्तेमाल करने से डिवाइस को रोकता है या इन्हें बंद कर देता है."</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>
@@ -1933,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"बंद करें"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"जवाब दें"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"वीडियो"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"अस्वीकार करें"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"कॉल काटें"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"आने वाला (इनकमिंग) कॉल"</string>
@@ -1994,7 +1991,7 @@
<string name="app_category_productivity" msgid="1844422703029557883">"उत्पादकता"</string>
<string name="app_category_accessibility" msgid="6643521607848547683">"सुलभता"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"डिवाइस में जगह"</string>
- <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB डीबग करना"</string>
+ <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"यूएसबी डीबग करना"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"घंटा"</string>
<string name="time_picker_minute_label" msgid="8307452311269824553">"मिनट"</string>
<string name="time_picker_header_text" msgid="9073802285051516688">"समय सेट करें"</string>
@@ -2076,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"इस सूचना के मिलने पर होने वाली आवाज़ बंद कर दी गई है. सुझाव/शिकायत/राय देने के लिए टैप करें."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"इस सूचना को रैंकिंग में ऊपर किया गया था. सुझाव/शिकायत/राय देने के लिए टैप करें."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"इस सूचना को रैंकिंग में नीचे किया गया था. सुझाव/शिकायत/राय देने के लिए टैप करें."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"\'बेहतर सूचनाएं\' सुविधा आज़माएं"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"कार्रवाई और जवाब वगैरह के लिए सुझाव पाना चाहते हैं, तो सूचनाएं पाने की सुविधा बेहतर करें. Android की, ज़रूरत के हिसाब से सूचनाएं पाने की सुविधा अब काम नहीं करती है."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"चालू करें"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"अभी नहीं"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ज़्यादा जानें"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"\'बेहतर सूचनाएं\' सुविधा, डिवाइस पर मिलने वाली सभी सूचनाओं का कॉन्टेंट पढ़ सकती है. इसमें आपकी निजी जानकारी, जैसे कि संपर्कों के नाम और मैसेज भी शामिल हैं. यह सुविधा, डिवाइस पर आने वाली सूचनाओं को रद्द कर सकती है या सूचनाओं में दिखने वाले बटन से कार्रवाइयां भी कर सकती है, जैसे कि फ़ोन कॉल का जवाब देना.\n\nयह सुविधा, प्राथमिकता मोड को चालू या बंद कर सकती है और इससे जुड़ी सेटिंग में बदलाव भी कर सकती है."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"रूटीन मोड जानकारी की सूचना"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"बैटरी आम तौर पर जितने समय चलती है, उससे पहले खत्म हो सकती है"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"बैटरी लाइफ़ बढ़ाने के लिए \'बैटरी सेवर\' चालू हो गया है"</string>
@@ -2271,18 +2262,14 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <string name="window_magnification_prompt_title" msgid="2876703640772778215">"ज़ूम करके देखने की नई सुविधा उपलब्ध है"</string>
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"ज़ूम करने की सुविधा वाली नई सेटिंग"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"अब आप अपनी स्क्रीन के किसी हिस्से को ज़ूम करके देख सकते हैं"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"सेटिंग में जाकर, इस सुविधा को चालू करें"</string>
<string name="dismiss_action" msgid="1728820550388704784">"खारिज करें"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"डिवाइस का माइक्रोफ़ोन अनब्लॉक करें"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"डिवाइस का कैमरा अनब्लॉक करें"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> के साथ-साथ, सभी ऐप्लिकेशन और सेवाओं के लिए"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"अनब्लॉक करें"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"सेंसर से जुड़ी निजता के बारे में सूचना"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ऐप्लिकेशन का आइकॉन"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ऐप्लिकेशन की ब्रैंड इमेज"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 8938dd2..28fb400 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -250,10 +250,10 @@
<string name="global_action_power_options" msgid="1185286119330160073">"Uključi"</string>
<string name="global_action_restart" msgid="4678451019561687074">"Ponovo pokreni"</string>
<string name="global_action_emergency" msgid="1387617624177105088">"Hitne službe"</string>
- <string name="global_action_bug_report" msgid="5127867163044170003">"Izvješće o bugovima"</string>
+ <string name="global_action_bug_report" msgid="5127867163044170003">"Izvješće o programskim pogreškama"</string>
<string name="global_action_logout" msgid="6093581310002476511">"Završi sesiju"</string>
<string name="global_action_screenshot" msgid="2610053466156478564">"Snimka zaslona"</string>
- <string name="bugreport_title" msgid="8549990811777373050">"Izvješće o bugovima"</string>
+ <string name="bugreport_title" msgid="8549990811777373050">"Izvješće o programskim pogreškama"</string>
<string name="bugreport_message" msgid="5212529146119624326">"Time će se prikupiti podaci o trenutačnom stanju vašeg uređaja koje ćete nam poslati u e-poruci. Za pripremu izvješća o programskoj pogrešci potrebno je nešto vremena pa vas molimo za strpljenje."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktivno izvješće"</string>
<string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"To možete upotrebljavati u većini slučajeva. Moći ćete pratiti izradu izvješća, unijeti više pojedinosti o problemu i izraditi snimke zaslona. Mogu se izostaviti neki odjeljci koji se upotrebljavaju rjeđe i produljuju izradu izvješća."</string>
@@ -1180,7 +1180,7 @@
<string name="redo" msgid="7231448494008532233">"Ponovi"</string>
<string name="autofill" msgid="511224882647795296">"Automatsko popunjavanje"</string>
<string name="textSelectionCABTitle" msgid="5151441579532476940">"Odabir teksta"</string>
- <string name="addToDictionary" msgid="8041821113480950096">"Dodaj u rječnik"</string>
+ <string name="addToDictionary" msgid="8041821113480950096">"Dodavanje u rječnik"</string>
<string name="deleteText" msgid="4200807474529938112">"Izbriši"</string>
<string name="inputMethod" msgid="1784759500516314751">"Način unosa"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"Radnje s tekstom"</string>
@@ -1406,7 +1406,7 @@
<string name="share_remote_bugreport_action" msgid="7630880678785123682">"DIJELI"</string>
<string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ODBIJ"</string>
<string name="select_input_method" msgid="3971267998568587025">"Odabir načina unosa"</string>
- <string name="show_ime" msgid="6406112007347443383">"Zadržava se na zaslonu dok je fizička tipkovnica aktivna"</string>
+ <string name="show_ime" msgid="6406112007347443383">"Zadrži na zaslonu dok je fizička tipkovnica aktivna"</string>
<string name="hardware" msgid="1800597768237606953">"Prikaži virtualnu tipkovnicu"</string>
<string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Konfigurirajte fizičku tipkovnicu"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dodirnite da biste odabrali jezik i raspored"</string>
@@ -1712,12 +1712,12 @@
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"Nemoj uključiti"</string>
<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 dopustiti usluzi <xliff:g id="SERVICE">%1$s</xliff:g> potpunu kontrolu nad uređajem?"</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">"Prikaz zaslona i upravljanje njime"</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>
- <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Prikaz i izvršavanje radnji"</string>
+ <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Pregled i izvršavanje radnji"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Može pratiti vaše interakcije s aplikacijama ili senzorom uređaja i stupati u interakciju s aplikacijama u vaše ime."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Dopusti"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Odbij"</string>
@@ -1730,7 +1730,7 @@
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Isključi prečac"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Upotrijebi prečac"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
- <string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcija boje"</string>
+ <string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcija boja"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatno zatamnjenje"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za glasnoću. Uključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za glasnoću. Isključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
@@ -1875,10 +1875,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Ažurirao administrator"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao administrator"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"U redu"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Štednja baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizualne efekte i značajke kao što je Hey Google\n\n"<annotation id="url">"Saznajte više"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Štednja baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizualne efekte i značajke kao što je Hey Google."</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_button" msgid="4399405762586419726">"Uključi"</string>
@@ -1962,6 +1960,7 @@
<string name="close_button_text" msgid="10603510034455258">"Zatvori"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Odgovori"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Videozapis"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Odbij"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Prekini"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Dolazni poziv"</string>
@@ -2107,18 +2106,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Obavijest je degradirana u bešumnu. Dodirnite da biste poslali povratne informacije."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Obavijest je više rangirana. Dodirnite da biste poslali povratne informacije."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Obavijest je niže rangirana. Dodirnite da biste poslali povratne informacije."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Proba poboljšanih obavijesti"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Da biste i dalje primali prijedloge za radnje, odgovore i druge informacije, uključite poboljšane obavijesti. Prilagodljive obavijesti za Android više nisu podržane."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Uključi"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Ne sad"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saznajte više"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Poboljšane obavijesti mogu čitati sadržaj svih obavijesti, uključujući osobne podatke kao što su imena kontakata i poruke. Ta značajka može i odbacivati obavijesti ili poduzimati radnje povezane s gumbima u obavijestima kao što je odgovaranje na telefonske pozive.\n\nZnačajka također može uključiti ili isključiti način prioritetnih obavijesti i promijeniti povezane postavke."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Obavještavanje o informacijama u Rutinskom načinu rada"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterija se može isprazniti prije uobičajenog vremena punjenja"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Štednja baterije aktivirana je kako bi se produljilo trajanje baterije"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 8a4cfab..4350d60 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"A rendszergazda által frissítve"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"A rendszergazda által törölve"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Az Akkumulátorkímélő mód bekapcsolja a Sötét témát, és korlátozza vagy kikapcsolja a háttérbeli tevékenységeket, bizonyos vizuális effekteket és olyan funkciókat, mint az „Ok Google”.\n\n"<annotation id="url">"További információ"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Az Akkumulátorkímélő mód bekapcsolja a Sötét témát, és korlátozza vagy kikapcsolja a háttérbeli tevékenységeket, bizonyos vizuális effekteket és olyan funkciókat, mint az „Ok Google”."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Az adatforgalom csökkentése érdekében az Adatforgalom-csökkentő megakadályozza, hogy egyes alkalmazások adatokat küldjenek vagy fogadjanak a háttérben. Az Ön által jelenleg használt alkalmazások hozzáférhetnek az adatokhoz, de csak ritkábban. Ez például azt jelentheti, hogy a képek csak rákoppintás után jelennek meg."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Bekapcsolja az Adatforgalom-csökkentőt?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Bekapcsolás"</string>
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Bezárás"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Fogadás"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Elutasítás"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Befejezés"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Bejövő hívás"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Ezt az értesítést némára állította a rendszer. Visszajelzés küldéséhez koppintson ide."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Ezt az értesítést előrébb sorolta a rendszer. Visszajelzés küldéséhez koppintson ide."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Ezt az értesítést hátrébb sorolta a rendszer. Visszajelzés küldéséhez koppintson ide."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Bővített értesítés kipróbálása"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Ha továbbra is szeretne kapni javasolt műveleteket, válaszokat és egyebeket, kapcsolja be a bővített értesítéseket. Az androidos alkalmazkodó értesítések már nem támogatottak."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Bekapcsolás"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Most nem"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"További információ"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"A bővített értesítések minden értesítéstartalmat olvashatnak (így a személyes adatokat, mint például a névjegyek nevét és az üzeneteket is). Ez a funkció emellett elvetheti az értesítéseket, valamint műveleteket végezhet az értesítésekben lévő gombokkal, például felveheti a telefonhívásokat.\n\nEz a funkció a Prioritásos módot is be- vagy kikapcsolhatja, és módosíthatja a kapcsolódó beállításokat."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Információs értesítés a rutinmódról"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Előfordulhat, hogy az akkumulátor lemerül a szokásos töltési időszak előtt"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Akkumulátorkímélő mód aktiválva az akkumulátor üzemidejének növelése érdekében"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index aebdbe6..bbf50a7 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -538,10 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Թույլ է տալիս հավելվածին հայտնաբերել և զուգակցել մոտակա Bluetooth սարքերը"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"միանալ զուգակցված Bluetooth սարքերի"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Թույլ է տալիս հավելվածին միանալ զուգակցված Bluetooth սարքերի"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"Գովազդ մոտակա Bluetooth սարքերում"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Թույլատրում է հավելվածին գովազդ փոխանցել մոտակա Bluetooth սարքերին"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"որոշել մոտակա UWB սարքերի միջև հարաբերական դիրքավորումը"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Թույլատրել հավելվածին որոշել գերլայնաշերտ կապի տեխնոլոգիան աջակցող մոտակա սարքերի միջև հարաբերական դիրքավորումը"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Տեղեկություններ NFC վճարային ծառայության մասին"</string>
@@ -1854,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Մարտկոցի տնտեսումը միացնում է մուգ թեման և սահմանափակում կամ անջատում է ֆոնային գործընթացները, որոշ վիզուալ էֆեկտներ և այլ գործառույթներ, օրինակ՝ «Ok Google» հրահանգի ճանաչումը։\n\n"<annotation id="url">"Իմանալ ավելին"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Մարտկոցի տնտեսումը միացնում է մուգ թեման և սահմանափակում կամ անջատում է ֆոնային գործընթացները, որոշ վիզուալ էֆեկտներ և այլ գործառույթներ, օրինակ՝ «Ok Google» հրահանգի ճանաչումը։"</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>
@@ -1933,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Փակել"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>՝ <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Պատասխանել"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Մերժել"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Ավարտել"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Մուտքային զանգ"</string>
@@ -1990,7 +1988,7 @@
<string name="app_category_image" msgid="7307840291864213007">"Լուսանկարներ և պատկերներ"</string>
<string name="app_category_social" msgid="2278269325488344054">"Սոցցանցեր և հաղորդակցություն"</string>
<string name="app_category_news" msgid="1172762719574964544">"Նորություններ և ամսագրեր"</string>
- <string name="app_category_maps" msgid="6395725487922533156">"Քարտեզներ և նավարկում"</string>
+ <string name="app_category_maps" msgid="6395725487922533156">"Քարտեզներ և նավիգացիա"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Արդյունավետություն"</string>
<string name="app_category_accessibility" msgid="6643521607848547683">"Հատուկ գործառույթներ"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Սարքի հիշողություն"</string>
@@ -2059,7 +2057,7 @@
<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>
<string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Զանգերի և ծանուցումների համար թրթռոցը միացված է"</string>
- <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Զանգերի և ծանուցումների համար ձայնն անջատած է"</string>
+ <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Զանգերի և ծանուցումների համար ձայնն անջատված է"</string>
<string name="notification_channel_system_changes" msgid="2462010596920209678">"Համակարգի փոփոխություններ"</string>
<string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Չանհանգստացնել"</string>
<string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Այժմ «Չանհանգստացնել» ռեժիմում ծանուցումները թաքցվում են"</string>
@@ -2076,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Այս ծանուցման կարևորության մակարդակը իջեցվել է և դարձել անձայն։ Հպեք՝ կարծիք հայտնելու համար։"</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Այս ծանուցման կարևորության մակարդակը բարձրացվել է։ Հպեք՝ կարծիք հայտնելու համար։"</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Այս ծանուցման կարևորության մակարդակն իջեցվել է։ Հպեք՝ կարծիք հայտնելու համար։"</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Փորձեք ընդլայնված ծանուցումները"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Միացրեք ընդլայնված ծանուցումները, որպեսզի այսուհետ ևս ստանաք գործողությունների, պատասխանների և այլ առաջարկներ։ Android-ի հարմարվող ծանուցումներն այլևս չեն աջակցվում։"</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Միացնել"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Ոչ հիմա"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Իմանալ ավելին"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Ընդլայնված ծանուցումներին հասանելի է բոլոր ծանուցումների պարունակությունը, ներառյալ անձնական տվյալները, օրինակ՝ կոնտակտների անուններն ու հաղորդագրությունները։ Այս գործառույթը կարող է նաև փակել ծանուցումները կամ ակտիվացնել դրանցում առկա կոճակները, այդ թվում՝ պատասխանել հեռախոսազանգերի։\n\nԱյս գործառույթը կարող է նաև միացնել/անջատել «Միայն կարևորները» ռեժիմը և փոխել համապատասխան կարգավորումները։"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Ծանուցում լիցքավորման մասին"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Մարտկոցը կարող է սովորականից շուտ սպառվել"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Մարտկոցի կյանքը երկարացնելու համար ակտիվացվել է մարտկոցի տնտեսման ռեժիմը"</string>
@@ -2275,14 +2267,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Դուք կարող եք խոշորացնել ձեր էկրանի մի մասը"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Միացնել կարգավորումներում"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Փակել"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Արգելահանել սարքի խոսափողը"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Արգելահանել սարքի տեսախցիկը"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> հավելվածի և մյուս բոլոր հավելվածների ու ծառայությունների համար"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Արգելահանել"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Տվիչների գաղտնիություն"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Հավելվածի պատկերակ"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Հավելվածի բրենդային պատկեր"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index bae2d48..222bbe8 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -538,10 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Mengizinkan aplikasi menemukan dan menyambungkan perangkat Bluetooth di sekitar"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"hubungkan ke perangkat Bluetooth yang disambungkan"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Mengizinkan aplikasi terhubung ke perangkat Bluetooth yang disambungkan"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"tampilkan iklan ke perangkat Bluetooth di sekitar"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Mengizinkan aplikasi untuk menampilkan iklan ke perangkat Bluetooth di sekitar"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"menentukan posisi relatif antar-perangkat Ultra-Wideband di sekitar"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Mengizinkan aplikasi menentukan posisi relatif antar-perangkat Ultra-Wideband di sekitar"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informasi Layanan Pembayaran NFC Pilihan"</string>
@@ -1049,8 +1047,8 @@
<string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Aktifkan Menjelajah dengan Sentuhan?"</string>
<string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mengaktifkan Menjelajah dengan Sentuhan. Saat Menjelajah dengan Sentuhan diaktifkan, Anda dapat melihat atau mendengar deskripsi dari apa yang ada di bawah jari Anda atau melakukan gerakan untuk berinteraksi dengan tablet."</string>
<string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mengaktifkan Menjelajah dengan Sentuhan. Saat Menjelajah dengan Sentuhan diaktifkan, Anda dapat mendengar atau melihat deskripsi dari apa yang ada di bawah jari Anda atau melakukan gerakan untuk berinteraksi dengan ponsel."</string>
- <string name="oneMonthDurationPast" msgid="4538030857114635777">"1 bulan yang lalu"</string>
- <string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Sebelum 1 bulan yang lalu"</string>
+ <string name="oneMonthDurationPast" msgid="4538030857114635777">"1 bulan lalu"</string>
+ <string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Sebelum 1 bulan lalu"</string>
<plurals name="last_num_days" formatted="false" msgid="687443109145393632">
<item quantity="other"> <xliff:g id="COUNT_1">%d</xliff:g> hari terakhir</item>
<item quantity="one"> <xliff:g id="COUNT_0">%d</xliff:g> hari terakhir</item>
@@ -1854,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Diupdate oleh admin Anda"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Dihapus oleh admin Anda"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Oke"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Penghemat Baterai mengaktifkan Tema gelap dan membatasi atau menonaktifkan aktivitas di latar belakang, beberapa efek visual, dan fitur seperti “Ok Google”\n\n"<annotation id="url">"Pelajari lebih lanjut"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Penghemat Baterai mengaktifkan Tema gelap dan membatasi atau menonaktifkan aktivitas di latar belakang, beberapa efek visual, dan fitur seperti “Ok Google”."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Untuk membantu mengurangi penggunaan data, Penghemat Data mencegah beberapa aplikasi mengirim atau menerima data di latar belakang. Aplikasi yang sedang digunakan dapat mengakses data, tetapi frekuensinya agak lebih jarang. Misalnya saja, gambar hanya akan ditampilkan setelah diketuk."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Aktifkan Penghemat Data?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Aktifkan"</string>
@@ -1933,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Tutup"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Jawab"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Tolak"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Tutup"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Panggilan masuk"</string>
@@ -2076,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Notifikasi ini didemosikan menjadi Senyap. Ketuk untuk memberikan masukan."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Notifikasi ini diberi peringkat lebih tinggi. Ketuk untuk memberikan masukan."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Notifikasi ini diberi peringkat lebih rendah. Ketuk untuk memberikan masukan."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Coba notifikasi yang disempurnakan"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Untuk terus mendapatkan saran tindakan, balasan, dan lainnya, aktifkan notifikasi yang disempurnakan. Notifikasi Adaptif Android tidak lagi didukung."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Aktifkan"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Lain kali"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Pelajari lebih lanjut"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Notifikasi yang disempurnakan dapat membaca semua isi notifikasi, termasuk informasi pribadi seperti nama kontak dan pesan. Fitur ini juga dapat menutup notifikasi atau memicu tindakan pada tombol di notifikasi, seperti menjawab panggilan telepon.\n\nFitur ini juga dapat mengaktifkan atau menonaktifkan mode Prioritas dan mengubah setelan terkait."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notifikasi info Mode Rutinitas"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterai mungkin habis sebelum pengisian daya biasanya"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Penghemat Baterai diaktifkan untuk memperpanjang masa pakai baterai"</string>
@@ -2275,14 +2267,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Sekarang Anda dapat memperbesar sebagian layar"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktifkan di Setelan"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Tutup"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Batalkan pemblokiran mikrofon perangkat"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Batalkan pemblokiran kamera perangkat"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Untuk <b><xliff:g id="APP">%s</xliff:g></b> serta semua aplikasi dan layanan"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Batalkan pemblokiran"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privasi Sensor"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikon aplikasi"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Brand image aplikasi"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index c23362e..47503ed 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Kerfisstjóri uppfærði"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Kerfisstjóri eyddi"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Í lagi"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Rafhlöðusparnaður kveikir á dökku þema og takmarkar eða slekkur á bakgrunnsvirkni, tilteknum myndbrellum og eiginleikum eins og „Ok Google“.\n\n"<annotation id="url">"Nánar"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Rafhlöðusparnaður kveikir á dökku þema og takmarkar eða slekkur á bakgrunnsvirkni, tilteknum myndbrellum og eiginleikum eins og „Ok Google“."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Gagnasparnaður getur hjálpað til við að draga úr gagnanotkun með því að hindra forrit í að senda eða sækja gögn í bakgrunni. Forrit sem er í notkun getur náð í gögn, en gerir það kannski sjaldnar. Niðurstaðan getur verið að myndir eru ekki birtar fyrr en þú ýtir á þær, svo dæmi sé tekið."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Kveikja á gagnasparnaði?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Kveikja"</string>
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Loka"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Svara"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Hafna"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Leggja á"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Símtal berst"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Þessi tilkynning var gerð þögul. Ýttu til að senda ábendingu."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Þessi tilkynning fékk hærri stöðu. Ýttu til að senda ábendingu."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Þessi tilkynning fékk lægri stöðu. Ýttu til að senda ábendingu."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Prófa auknar tilkynningar"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Kveiktu á auknum tilkynningum til að halda áfram að fá tillögur að aðgerðum, svörum og fleira. Breytilegar tilkynningar í Android eru ekki lengur studdar."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Kveikja"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Ekki núna"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Nánar"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Auknar tilkynningar geta lesið allt efni tilkynninga, þar á meðal persónuupplýsingar á borð við nöfn tengiliða og skilaboð. Þessi eiginleiki getur einnig hunsað tilkynningar eða notað hnappa í tilkynningum eins og að svara símtölum.\n\nÞessi eiginleiki getur einnig kveikt og slökkt á forgangsstillingu og breytt tengdum stillingum."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Upplýsingatilkynning aðgerðastillingar"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Rafhlaðan kann að tæmast áður en hún kemst í hleðslu"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Kveikt á rafhlöðusparnaði til að lengja endingu rafhlöðunnar"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 80aaa37..31096c7 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -538,8 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Consente all\'app di rilevare e accoppiare dispositivi Bluetooth nelle vicinanze"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"Connessione a dispositivi Bluetooth accoppiati"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Consente all\'app di connettersi ai dispositivi Bluetooth accoppiati"</string>
- <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"Pubblicità su dispositivi Bluetooth vicini"</string>
- <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Consente all\'app di fare pubblicità sui dispositivi Bluetooth nelle vicinanze"</string>
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"trasmettere annunci a dispositivi Bluetooth vicini"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Consente all\'app di trasmettere annunci ai dispositivi Bluetooth nelle vicinanze"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"Possibilità di stabilire la posizione relativa tra dispositivi a banda ultralarga nelle vicinanze"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Consenti all\'app di stabilire la posizione relativa tra dispositivi a banda ultralarga nelle vicinanze"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informazioni del servizio di pagamento NFC preferito"</string>
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Aggiornato dall\'amministratore"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminato dall\'amministratore"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"L\'opzione Risparmio energetico attiva il tema scuro e limita o disattiva l\'attività in background, alcuni effetti visivi e funzionalità come \"Hey Google\"\n\n"<annotation id="url">"Scopri di più"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"L\'opzione Risparmio energetico attiva il tema scuro e limita o disattiva l\'attività in background, alcuni effetti visivi e funzionalità come \"Hey Google\"."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Per contribuire a ridurre l\'utilizzo dei dati, la funzione Risparmio dati impedisce ad alcune app di inviare o ricevere dati in background. Un\'app in uso può accedere ai dati, ma potrebbe farlo con meno frequenza. Esempio: le immagini non vengono visualizzate finché non le tocchi."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Attivare Risparmio dati?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Attiva"</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Chiudi"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Rispondi"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Rifiuta"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Riaggancia"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Chiamata in arrivo"</string>
@@ -1955,7 +1954,7 @@
<string name="locale_search_menu" msgid="6258090710176422934">"Cerca"</string>
<string name="app_suspended_title" msgid="888873445010322650">"App non disponibile"</string>
<string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> non è al momento disponibile. Viene gestita tramite <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
- <string name="app_suspended_more_details" msgid="211260942831587014">"Ulteriori informazioni"</string>
+ <string name="app_suspended_more_details" msgid="211260942831587014">"Scopri di più"</string>
<string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Riattiva app"</string>
<string name="work_mode_off_title" msgid="5503291976647976560">"Attivare il profilo di lavoro?"</string>
<string name="work_mode_off_message" msgid="8417484421098563803">"Le tue app di lavoro, le notifiche, i dati e altri elementi del profilo di lavoro saranno attivati."</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Questa notifica è stata retrocessa a Silenziosa. Tocca per dare un feedback."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Questa notifica è stata posizionata più in alto. Tocca per dare un feedback."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Questa notifica è stata posizionata più in basso. Tocca per dare un feedback."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Prova le notifiche avanzate"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Per continuare a ricevere suggerimenti di azioni, risposte e altro, attiva le notifiche avanzate. Le notifiche adattive Android non sono più supportate."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Attiva"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Non ora"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Scopri di più"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Le notifiche avanzate possono accedere all\'intero contenuto di una notifica, incluse le informazioni personali, come i nomi dei contatti e i messaggi. Questa funzionalità può anche ignorare le notifiche o svolgere azioni sui pulsanti nelle notifiche, come rispondere alle telefonate.\n\nQuesta funzionalità può anche attivare o disattivare la modalità Priorità e modificare le relative impostazioni."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notifica di informazioni sulla modalità Routine"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"La batteria potrebbe esaurirsi prima della ricarica abituale"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Risparmio energetico attivo per far durare di più la batteria"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 734224c..b3134a7 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -325,7 +325,7 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"גישה לפעילות הגופנית שלך"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"מצלמה"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"צילום תמונות והקלטת וידאו"</string>
- <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"מכשירים קרובים"</string>
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"מכשירים בקרבת מקום"</string>
<string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"איתור מכשירים שנמצאים בקרבת מקום והתחברות אליהם"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"יומני שיחות"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"קריאה וכתיבה של יומן השיחות של הטלפון"</string>
@@ -1405,7 +1405,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>
@@ -1734,13 +1734,13 @@
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"לא להפעיל"</string>
<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_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_warning_description" msgid="291674995220940133">"האפשרות לשליטה מלאה במכשיר לא מתאימה לכל האפליקציות, אלא רק לאפליקציות שעוזרות עם צורכי הנגישות שלך."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"הצגת המסך ושליטה בו"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"אפשרות לקריאת כל התוכן במסך ולהצגת התוכן מעל אפליקציות אחרות."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"הצגה וביצוע של פעולות"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"זוהי אפשרות למעקב אחר האינטראקציות שלך עם אפליקציה או חיישן חומרה כלשהם, ולביצוע אינטראקציה בשמך."</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"אפשרות למעקב אחר האינטראקציה שלך עם אפליקציות או חיישני חומרה, וביצוע אינטראקציה בשמך."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"אישור"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"עדיף שלא"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"יש להקיש על תכונה כדי להתחיל להשתמש בה:"</string>
@@ -1898,10 +1898,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"התכונה \'חיסכון בסוללה\' מפעילה עיצוב כהה ומגבילה או מכבה פעילות ברקע, חלק מהאפקטים החזותיים ותכונות כמו \"Hey Google\"\n\n"<annotation id="url">"מידע נוסף"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"התכונה \'חיסכון בסוללה\' מפעילה עיצוב כהה ומגבילה או מכבה פעילות ברקע, חלק מהאפקטים החזותיים ותכונות כמו \"Hey Google\"."</string>
<string name="data_saver_description" msgid="4995164271550590517">"כדי לסייע בהפחתת השימוש בנתונים, חוסך הנתונים (Data Saver) מונע מאפליקציות מסוימות שליחה או קבלה של נתונים ברקע. אפליקציה שבה נעשה שימוש כרגע יכולה לגשת לנתונים, אבל בתדירות נמוכה יותר. המשמעות היא, למשל, שתמונות יוצגו רק לאחר שמקישים עליהן."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"להפעיל את חוסך הנתונים?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"הפעלה"</string>
@@ -1993,6 +1991,8 @@
<string name="close_button_text" msgid="10603510034455258">"סגירה"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"תשובה"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"דחייה"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"ניתוק"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"שיחה נכנסת"</string>
@@ -2012,7 +2012,7 @@
<string name="user_creation_adding" msgid="7305185499667958364">"לאפשר לאפליקציה <xliff:g id="APP">%1$s</xliff:g> ליצור משתמש חדש באמצעות <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
<string name="language_selection_title" msgid="52674936078683285">"הוספת שפה"</string>
<string name="country_selection_title" msgid="5221495687299014379">"העדפת אזור"</string>
- <string name="search_language_hint" msgid="7004225294308793583">"צריך להקליד את שם השפה"</string>
+ <string name="search_language_hint" msgid="7004225294308793583">"הקלדת שם השפה"</string>
<string name="language_picker_section_suggested" msgid="6556199184638990447">"הצעות"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"כל השפות"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"כל האזורים"</string>
@@ -2140,18 +2140,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"ההתראה הזו הורדה בדרגה ל\'שקטה\'. יש להקיש כדי לשלוח משוב."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"דירוג ההתראה הזו הוגבה. יש להקיש כדי לשלוח משוב."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"ההתראה הזו דורגה נמוך יותר. יש להקיש כדי לשלוח משוב."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"רוצה לנסות את ההתראות המשופרות?"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"כדי להמשיך לקבל הצעות לפעולות, לתשובות ועוד, יש להפעיל את ההתראות המשופרות. אין יותר תמיכה בהתראות מותאמות ל-Android."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"הפעלה"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"לא עכשיו"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"מידע נוסף"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"כשתכונת ההתראות המשופרות פועלת, המערכת יכולה לקרוא את כל תוכן ההתראות, כולל מידע אישי כמו שמות של אנשי קשר והודעות. כמו כן, התכונה תוכל לסגור התראות או לבצע פעולות שהן כוללות, כמו מענה לשיחות טלפון.\n\nהתכונה תוכל גם להפעיל או להשבית את מצב העדיפות ולשנות את ההגדרות הקשורות."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"התראת מידע לגבי מצב שגרתי"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"הסוללה עלולה להתרוקן לפני המועד הרגיל של הטעינה"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"תכונת החיסכון בסוללה הופעלה כדי להאריך את חיי הסוללה"</string>
@@ -2337,7 +2331,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <string name="window_magnification_prompt_title" msgid="2876703640772778215">"הגדרות חדשות להגדלה"</string>
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"הגדרות חדשות לתכונה \'הגדלה\'"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"עכשיו אפשר להגדיל חלק מהמסך"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"הפעלה בהגדרות"</string>
<string name="dismiss_action" msgid="1728820550388704784">"סגירה"</string>
@@ -2349,5 +2343,5 @@
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"סמל האפליקציה"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"תדמית המותג של האפליקציה"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"בדיקה של הגדרות הגישה"</string>
- <string name="view_and_control_notification_content" msgid="8003766498562604034">"לשירות <xliff:g id="SERVICE_NAME">%s</xliff:g> יהיו הרשאות לצפייה ולשליטה במסך. יש להקיש כדי לבדוק."</string>
+ <string name="view_and_control_notification_content" msgid="8003766498562604034">"לשירות <xliff:g id="SERVICE_NAME">%s</xliff:g> יש הרשאה להצגת המסך ושליטה בו. אפשר להקיש כדי לבדוק."</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index b38d9dc..a8d2f1a 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1852,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"バッテリー セーバーを有効にすると、ダークテーマが ON になり、バックグラウンド アクティビティ、一部の視覚効果や、「OK Google」などの機能が制限されるか OFF になります\n\n"<annotation id="url">"詳細"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"バッテリー セーバーを有効にすると、ダークテーマが ON になり、バックグラウンド アクティビティ、一部の視覚効果や、「OK Google」などの機能が制限されるか 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>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"閉じる"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"応答"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"ビデオ"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"拒否"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"通話終了"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"着信"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"この通知の重要度がサイレントに下がりました。タップしてフィードバックをお送りください。"</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"この通知の重要度が上がりました。タップしてフィードバックをお送りください。"</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"この通知の重要度が下がりました。タップしてフィードバックをお送りください。"</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"拡張通知を使ってみる"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"操作や返信の候補などを利用し続けるには、拡張通知を ON にしてください。Android 通知の自動調整はサポートを終了しました。"</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"ON にする"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"後で"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"詳細"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"拡張通知はすべての通知コンテンツにアクセスできます。これには、連絡先の名前などの個人情報やメッセージも含まれます。また、通知を非表示にしたり、電話に出るなど、通知内の操作ボタンを実行したりすることもできます。\n\nまた、この機能は、優先モードの設定を切り替えたり、関連する設定を変更したりすることもできます。"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ルーティン モード情報の通知"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"通常の充電を行う前に電池が切れる可能性があります"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"電池を長持ちさせるため、バッテリー セーバーが有効になりました"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index a14c551..ba7beac 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1852,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"ბატარეის დამზოგი ჩართავს მუქ თემას და შეზღუდავს ან გამორთავს ფონურ აქტივობას, ზოგიერთ ვიზუალურ ეფექტს და ისეთ ფუნქციებს, როგორიცაა „Ok Google“\n\n"<annotation id="url">"შეიტყვეთ მეტი"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"ბატარეის დამზოგი ჩართავს მუქ თემას და შეზღუდავს ან გამორთავს ფონურ აქტივობას, ზოგიერთ ვიზუალურ ეფექტს და ისეთ ფუნქციებს, როგორიცაა „Ok Google“."</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>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"დახურვა"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"პასუხი"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"ვიდეო"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"უარყოფა"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"გათიშვა"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"შემომავალი ზარი"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"ეს შეტყობინება ჩამოქვეითდა და გახდა „ჩუმი“. შეეხეთ გამოხმაურების მოსაწოდებლად."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"ეს შეტყობინება დაწინაურდა. შეეხეთ გამოხმაურების მოსაწოდებლად."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"ეს შეტყობინება ჩამოქვეითდა. შეეხეთ გამოხმაურების მოსაწოდებლად."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"გამოცადეთ გაფართოებული შეტყობინებები"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"შემოთავაზებული ქმედებების, პასუხების და სხვა მითითებების მიღების გასაგრძელებლად ჩართეთ გაფართოებული შეტყობინებები. Android-ის ადაპტაციური შეტყობინებები აღარაა მხარდაჭერილი."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"ჩართვა"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"ახლა არა"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"შეიტყვეთ მეტი"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"გაფართოებულ შეტყობინებებს შეუძლია ყველა შეტყობინების კონტენტის, მათ შორის, ისეთი პერსონალური ინფორმაციის წაკითხვა, როგორიცაა კონტაქტების სახელები და შეტყობინებები. ამ ფუნქციას ასევე შეუძლია შეტყობინებების დახურვა ან შეტყობინებათა ღილაკების ამოქმედება, მაგალითად, სატელეფონო ზარებზე პასუხი.\n\nამ ფუნქციას ასევე შეუძლია პრიორიტეტული რეჟიმის ჩართვა თუ გამორთვა და დაკავშირებული პარამეტრების შეცვლა."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"რუტინის რეჟიმის საინფორმაციო შეტყობინება"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ბატარეა შეიძლება დაჯდეს დატენის ჩვეულ დრომდე"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ბატარეის დამზოგი გააქტიურდა ბატარეის მუშაობის გასახანგრძლივლებლად"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 8dbe6ee..7d6bf12 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -305,7 +305,7 @@
<string name="managed_profile_label" msgid="7316778766973512382">"Жұмыс профиліне ауысу"</string>
<string name="permgrouplab_contacts" msgid="4254143639307316920">"Контактілер"</string>
<string name="permgroupdesc_contacts" msgid="9163927941244182567">"контактілерге кіру"</string>
- <string name="permgrouplab_location" msgid="1858277002233964394">"Геодерек"</string>
+ <string name="permgrouplab_location" msgid="1858277002233964394">"Локация"</string>
<string name="permgroupdesc_location" msgid="1995955142118450685">"бұл құрылғының орналасқан жерін көру"</string>
<string name="permgrouplab_calendar" msgid="6426860926123033230">"Күнтізбе"</string>
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"күнтізбеге кіру"</string>
@@ -538,12 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Қолданбаға маңайдағы Bluetooth құрылғыларын анықтап, жұптауға рұқсат береді."</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"жұпталған Bluetooth құрылғыларына қосылу"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Қолданбаға жұпталған Bluetooth құрылғыларына қосылуға рұқсат береді."</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
- <string name="permlab_uwb_ranging" msgid="8141915781475770665">"маңайдағы кеңжолақты құрылғылардың бір-біріне қатысты орнын анықтау"</string>
- <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Қолданбаға маңайдағы кеңжолақты құрылғылардың бір-біріне қатысты орнын анықтауға мүмкіндік береді."</string>
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"Жарнаманы маңайдағы Bluetooth құрылғыларына беру"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Қолданба жарнаманы маңайдағы Bluetooth құрылғыларына бере алады."</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"маңайдағы кең жолақты құрылғылардың бір-біріне қатысты орнын анықтау"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Қолданбаға маңайдағы кең жолақты құрылғылардың бір-біріне қатысты орнын анықтауға мүмкіндік береді."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Таңдаулы NFC төлеу қызметі туралы ақпарат"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Қолданба тіркелген көмектер және баратын жер маршруты сияқты таңдаулы NFC төлеу қызметі туралы ақпаратты ала алатын болады."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC функциясын басқару"</string>
@@ -1575,7 +1573,7 @@
<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="data_usage_warning_title" msgid="9034893717078325845">"Деректердің пайдаланылуы туралы ескерту"</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>
<string name="data_usage_wifi_limit_title" msgid="2069698056520812232">"Wi-Fi деректер шегіне жеттіңіз"</string>
@@ -1692,7 +1690,7 @@
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"Қосылмасын"</string>
<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_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>
@@ -1700,7 +1698,7 @@
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Әрекеттерді көру және орындау"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Ол қолданбамен немесе жабдық датчигімен істеген тапсырмаларыңызды бақылайды және қолданбаларды сіздің атыңыздан пайдаланады."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Рұқсат ету"</string>
- <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Қабылдамау"</string>
+ <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Тыйым салу"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Функцияны пайдалана бастау үшін түртіңіз:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"\"Арнайы мүмкіндіктер\" түймесімен қолданылатын функцияларды таңдаңыз"</string>
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Дыбыс деңгейі пернелері тіркесімімен қолданылатын функцияларды таңдаңыз"</string>
@@ -1711,7 +1709,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Төте жолды пайдалану"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Түстер инверсиясы"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Түсті түзету"</string>
- <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Аса күңгірт"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Экранды қарайту"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Пайдаланушы дыбыс деңгейі пернелерін басып ұстап тұрды. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қосулы."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дыбыс деңгейі пернелерін басып тұрған соң, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өшірілді."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін пайдалану үшін дыбыс деңгейін реттейтін екі түймені де 3 секунд басып тұрыңыз"</string>
@@ -1854,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Батареяны үнемдеу режимі қараңғы тақырыпты іске қосады және фондық әрекеттерге, кейбір визуалдық әсерлерге, \"Ok Google\" сияқты функцияларға шектеу қояды немесе оларды өшіреді.\n\n"<annotation id="url">"Толығырақ"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Батареяны үнемдеу режимі қараңғы тақырыпты іске қосады және фондық әрекеттерге, кейбір визуалдық әсерлерге, \"Ok Google\" сияқты функцияларға шектеу қояды немесе оларды өшіреді."</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>
@@ -1933,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Жабу"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Жауап"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Қабылдамау"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Тұтқаны қою"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Кіріс қоңырау"</string>
@@ -2076,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Бұл хабарландырудың маңыздылық деңгейі \"Үнсіз\" санатына төмендетілді. Пікір қалдыру үшін түртіңіз."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Бұл хабарландырудың маңыздылық деңгейі көтерілді. Пікір қалдыру үшін түртіңіз."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Бұл хабарландырудың маңыздылық деңгейі төмендетілді. Пікір қалдыру үшін түртіңіз."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Кеңейтілген хабарландыруларды пайдалану"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Ұсынылған әрекеттер, жауаптар және т.б. алып отыру үшін \"Кеңейтілген хабарландырулар\" функциясын қосыңыз. Android-тың \"Бейімделетін хабарландырулар\" функциясына бұдан былай қолдау көрсетілмейді."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Қосу"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Қазір емес"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Толығырақ"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"\"Кеңейтілген хабарландырулар\" функциясы барлық хабарландыру мазмұнын (контакт атаулары мен хабарлар сияқты жеке ақпаратты қоса алғанда) оқи алады. Сондай-ақ бұл функция арқылы хабарландыруларды жабуға немесе хабарландырулардағы түймелерді басқаруға (мысалы, телефон қоңырауларына жауап беру) болады.\n\nОл арқылы \"Маңызды\" режимін қосуға немесе өшіруге, қатысты параметрлерді өзгертуге де болады."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Режим туралы хабарландыру"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея заряды азаюы мүмкін"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Батарея ұзаққа жетуі үшін, Батареяны үнемдеу режимі іске қосылды"</string>
@@ -2275,17 +2267,13 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Енді экранның бір бөлігін ұлғайтуға болады."</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Параметрлер бөлімінен қосу"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Қабылдамау"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Құрылғы микрофонының бөгеуін алыңыз"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Құрылғы камерасының бөгеуін алыңыз"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> және барлық қолданбалар мен қызметтерге арналған."</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Бөгеуді алу"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Датчикке қатысты құпиялылық"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Қолданба белгішесі"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Қолданба брендін ілгері жылжыту кескіні"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"Пайдалану параметрлерін тексеріңіз"</string>
- <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> қызметі экраныңызды көріп, бақылай алады. Көру үшін түртіңіз."</string>
+ <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> экраныңызды көріп, оны басқара алады. Өту үшін түртіңіз."</string>
</resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index e294f38..370bb29 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -538,10 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"អនុញ្ញាតឱ្យកម្មវិធីស្វែងរក និងផ្គូផ្គងឧបករណ៍ប៊្លូធូសដែលនៅជិត"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ភ្ជាប់ទៅឧបករណ៍ប៊្លូធូសដែលបានផ្គូផ្គង"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"អនុញ្ញាតឱ្យកម្មវិធីភ្ជាប់ទៅឧបករណ៍ប៊្លូធូសដែលបានផ្គូផ្គង"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"ផ្សាយពាណិជ្ជកម្មទៅឧបករណ៍ប៊្លូធូសដែលនៅជិត"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"អនុញ្ញាតឱ្យកម្មវិធីផ្សាយពាណិជ្ជកម្មទៅឧបករណ៍ប៊្លូធូសដែលនៅជិត"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"កំណត់ចម្ងាយពាក់ព័ន្ធរវាងឧបករណ៍ Ultra-Wideband ដែលនៅជិត"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"អនុញ្ញាតឱ្យកម្មវិធីកំណត់ចម្ងាយពាក់ព័ន្ធរវាងឧបករណ៍ Ultra-Wideband ដែលនៅជិត"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ព័ត៌មានអំពីសេវាបង់ប្រាក់តាម NFC ជាអាទិភាព"</string>
@@ -1854,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"មុខងារសន្សំថ្មបើករចនាប័ទ្មងងឹត និងបិទឬដាក់កំហិតលើសកម្មភាពផ្ទៃខាងក្រោយ ឥទ្ធិពលរូបភាពមួយចំនួន និងមុខងារដូចជា “Ok Google” ជាដើម\n\n"<annotation id="url">"ស្វែងយល់បន្ថែម"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"មុខងារសន្សំថ្មបើករចនាប័ទ្មងងឹត និងបិទឬដាក់កំហិតលើសកម្មភាពផ្ទៃខាងក្រោយ ឥទ្ធិពលរូបភាពមួយចំនួន និងមុខងារដូចជា “Ok Google” ជាដើម។"</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>
@@ -1933,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"បិទ"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>៖ <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"ឆ្លើយ"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"វីដេអូ"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"បដិសេធ"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"ដាក់ចុះ"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"ការហៅចូល"</string>
@@ -2076,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"ការជូនដំណឹងនេះត្រូវបានបន្ទាបតំណែងទៅស្ងាត់។ សូមចុចដើម្បីផ្ដល់មតិកែលម្អ។"</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"ការជូនដំណឹងនេះត្រូវបានចាត់ថ្នាក់ខ្ពស់ជាងមុន។ សូមចុចដើម្បីផ្ដល់មតិកែលម្អ។"</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"ការជូនដំណឹងនេះត្រូវបានចាត់ថ្នាក់ទាបជាងមុន។ សូមចុចដើម្បីផ្ដល់មតិកែលម្អ។"</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"សាកល្បងប្រើការជូនដំណឹងប្រសើរជាងមុន"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"ដើម្បីបន្តទទួលបានការឆ្លើយតប សកម្មភាពដែលបានណែនាំ និងអ្វីៗជាច្រើនទៀត សូមបើកការជូនដំណឹងប្រសើរជាងមុន។ ការជូនដំណឺងដែលមានភាពបត់បែន Android មិនអាចប្រើបានទៀតទេ។"</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"បើក"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"កុំទាន់"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ស្វែងយល់បន្ថែម"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"ការជូនដំណឹងប្រសើរជាងមុនអាចអានខ្លឹមសារជូនដំណឹងទាំងអស់ រួមទាំងព័ត៌មានផ្ទាល់ខ្លួនដូចជា ឈ្មោះទំនាក់ទំនង និងសារជាដើម។ មុខងារនេះក៏អាចច្រានចោលការជូនដំណឹង ឬធ្វើសកម្មភាពលើប៊ូតុងនៅក្នុងការជូនដំណឹងផងដែរ ដូចជាការទទួលការហៅទូរសព្ទជាដើម។\n\nមុខងារនេះក៏អាចបើកឬបិទមុខងារអាទិភាព និងផ្លាស់ប្ដូរការកំណត់ដែលពាក់ព័ន្ធផងដែរ។"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ការជូនដំណឹងព័ត៌មានរបស់មុខងារទម្លាប់"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ថ្មអាចនឹងអស់ មុនពេលសាកថ្មធម្មតា"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"បានបើកដំណើរការមុខងារសន្សំថ្ម ដើម្បីបង្កើនកម្រិតថាមពលថ្ម"</string>
@@ -2275,14 +2266,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"ឥឡូវនេះ អ្នកអាចពង្រីកផ្នែកនៃអេក្រង់របស់អ្នកបានហើយ"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"បើកនៅក្នុងការកំណត់"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ច្រានចោល"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"ឈប់ទប់ស្កាត់មីក្រូហ្វូនរបស់ឧបករណ៍"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"ឈប់ទប់ស្កាត់កាមេរ៉ារបស់ឧបករណ៍"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"សម្រាប់ <b><xliff:g id="APP">%s</xliff:g></b> និង កម្មវិធីនិងសេវាកម្មទាំងអស់"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"ឈប់ទប់ស្កាត់"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ឯកជនភាពឧបករណ៍ចាប់សញ្ញា"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"រូបកម្មវិធី"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"រូបភាពផ្សព្វផ្សាយម៉ាកកម្មវិធី"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index a030715..0daa7fe 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -319,10 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ನಿಮ್ಮ ದೈಹಿಕ ಚಟುವಟಿಕೆಯನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"ಕ್ಯಾಮರಾ"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ಚಿತ್ರಗಳನ್ನು ತೆಗೆಯಲು, ವೀಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಲು"</string>
- <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
- <skip />
- <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
- <skip />
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಗಳು"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಗಳನ್ನು ಅನ್ವೇಷಿಸಿ ಮತ್ತು ಕನೆಕ್ಟ್ ಮಾಡಿ"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"ಕರೆಯ ಲಾಗ್"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ಪೋನ್ ಕರೆಯ ಲಾಗ್ ಅನ್ನು ಓದಿ ಮತ್ತು ಬರೆಯಿರಿ"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ಫೋನ್"</string>
@@ -540,14 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ಸಮೀಪದಲ್ಲಿರುವ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ಅನ್ವೇಷಿಸಲು ಮತ್ತು ಅವುಗಳಿಗೆ ಜೋಡಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸಿ"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ಜೋಡಿಸಿರುವ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳಿಗೆ ಕನೆಕ್ಟ್ ಮಾಡಿ"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ಜೋಡಿಸಲಾಗಿರುವ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳಿಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"ಸಮೀಪದ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳಿಗೆ ಜಾಹೀರಾತು ನೀಡಿ"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"ಸಮೀಪದ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳಿಗೆ ಜಾಹೀರಾತು ನೀಡಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"ಸಮೀಪದಲ್ಲಿರುವ ಅಲ್ಟ್ರಾ-ವೈಡ್ಬ್ಯಾಂಡ್ ಸಾಧನಗಳ ನಡುವೆ ಸಂಬಂಧಿತ ಸ್ಥಾನವನ್ನು ನಿರ್ಧರಿಸುತ್ತದೆ"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ಸಮೀಪದಲ್ಲಿರುವ ಅಲ್ಟ್ರಾ-ವೈಡ್ಬ್ಯಾಂಡ್ ಸಾಧನಗಳ ನಡುವೆ ಸಂಬಂಧಿತ ಸ್ಥಾನವನ್ನು ನಿರ್ಧರಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸಿ"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ಆದ್ಯತೆಯ NFC ಪಾವತಿ ಸೇವಾ ಮಾಹಿತಿ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ನೋಂದಾಯಿತ ಅಪ್ಲಿಕೇಶನ್ ಗುರುತಿಸುವಿಕೆಗಳು ಮತ್ತು ಮಾರ್ಗ ಗಮ್ಯಸ್ಥಾನಗಳಂತಹ ಆದ್ಯತೆಯ NFC ಪಾವತಿ ಸೇವೆಗಳ ಬಗ್ಗೆ ಮಾಹಿತಿಯನ್ನು ಪಡೆಯಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ಸಮೀಪ ಕ್ಷೇತ್ರ ಸಂವಹನವನ್ನು ನಿಯಂತ್ರಿಸಿ"</string>
@@ -1699,7 +1693,7 @@
<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_title" msgid="190017412626919776">"ಸ್ಕ್ರೀನ್ ವೀಕ್ಷಿಸಿ ಮತ್ತು ನಿಯಂತ್ರಿಸಿ"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"ಇದು ಪರದೆಯ ಮೇಲಿನ ಎಲ್ಲಾ ವಿಷಯವನ್ನು ಓದಬಹುದು ಮತ್ತು ಇತರ ಆ್ಯಪ್ಗಳ ಮೇಲೆ ವಿಷಯವನ್ನು ಪ್ರದರ್ಶಿಸಬಹುದು."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"ಕ್ರಿಯೆಗಳನ್ನು ವೀಕ್ಷಿಸಿ ಮತ್ತು ನಿರ್ವಹಿಸಿ"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ಇದು ಆ್ಯಪ್ ಅಥವಾ ಹಾರ್ಡ್ವೇರ್ ಸೆನ್ಸರ್ನ ಜೊತೆಗಿನ ನಿಮ್ಮ ಸಂವಹನಗಳನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಬಹುದು, ಮತ್ತು ನಿಮ್ಮ ಪರವಾಗಿ ಆ್ಯಪ್ಗಳ ಜೊತೆ ಸಂವಹನ ನಡೆಸಬಹುದು."</string>
@@ -1858,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"ಬ್ಯಾಟರಿ ಸೇವರ್ ಡಾರ್ಕ್ ಥೀಮ್ ಅನ್ನು ಆನ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ಹಿನ್ನೆಲೆ ಚಟುವಟಿಕೆ, ಕೆಲವು ವಿಷುವಲ್ ಎಫೆಕ್ಟ್ಗಳು ಮತ್ತು “Ok Google” ನಂತಹ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಮಿತಿಗೊಳಿಸುತ್ತದೆ ಅಥವಾ ಆಫ್ ಮಾಡುತ್ತದೆ.\n\n"<annotation id="url">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"ಬ್ಯಾಟರಿ ಸೇವರ್ ಡಾರ್ಕ್ ಥೀಮ್ ಅನ್ನು ಆನ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ಹಿನ್ನೆಲೆ ಚಟುವಟಿಕೆ, ಕೆಲವು ವಿಷುವಲ್ ಎಫೆಕ್ಟ್ಗಳು ಮತ್ತು “Ok Google” ನಂತಹ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಮಿತಿಗೊಳಿಸುತ್ತದೆ ಅಥವಾ ಆಫ್ ಮಾಡುತ್ತದೆ."</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>
@@ -1937,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"ಮುಚ್ಚು"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"ಉತ್ತರಿಸಿ"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"ನಿರಾಕರಿಸಿ"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"ಹ್ಯಾಂಗ್ ಅಪ್"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"ಒಳಬರುವ ಕರೆ"</string>
@@ -2080,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"ಈ ಅಧಿಸೂಚನೆಗೆ ಸೈಲೆಂಟ್ಗೆ ಹಿಂಬಡ್ತಿ ನೀಡಲಾಗಿದೆ. ಪ್ರತಿಕ್ರಿಯೆ ನೀಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"ಈ ಅಧಿಸೂಚನೆಗೆ ಮೇಲಿನ ಸ್ಥಾನವನ್ನು ನೀಡಲಾಗಿದೆ. ಪ್ರತಿಕ್ರಿಯೆ ನೀಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"ಈ ಅಧಿಸೂಚನೆಗೆ ಕೆಳಗಿನ ಸ್ಥಾನವನ್ನು ನೀಡಲಾಗಿದೆ. ಪ್ರತಿಕ್ರಿಯೆ ನೀಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"ವರ್ಧಿತ ಅಧಿಸೂಚನೆಗಳು ಪ್ರಯತ್ನಿಸಿ"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"ಸೂಚಿಸಲಾದ ಕ್ರಿಯೆಗಳು, ಪ್ರತ್ಯುತ್ತರಗಳು ಮತ್ತು ಹೆಚ್ಚಿನದನ್ನು ಪಡೆಯಲು, ವರ್ಧಿತ ಅಧಿಸೂಚನೆಗಳನ್ನು ಆನ್ ಮಾಡಿ. Android ಅಡಾಪ್ಟಿವ್ ಅಧಿಸೂಚನೆಗಳು ಇನ್ನು ಮುಂದೆ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"ಆನ್ ಮಾಡಿ"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"ಈಗ ಬೇಡ"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"ವರ್ಧಿತ ಅಧಿಸೂಚನೆಗಳು ಸಂಪರ್ಕ ಹೆಸರುಗಳು ಮತ್ತು ಸಂದೇಶಗಳಂತಹ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಂತೆ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆ ವಿಷಯವನ್ನು ಓದಬಹುದು. ಈ ವೈಶಿಷ್ಟ್ಯವು ಅಧಿಸೂಚನೆಗಳನ್ನು ವಜಾಗೊಳಿಸಬಹುದು ಅಥವಾ ಫೋನ್ ಕರೆಗಳಿಗೆ ಉತ್ತರಿಸುವಂತಹ ಅಧಿಸೂಚನೆಗಳಲ್ಲಿನ ಬಟನ್ಗಳಿಗೆ ಸಂಬಂಧಿಸಿದ ಕ್ರಮ ತೆಗೆದುಕೊಳ್ಳಬಹುದು.\n\nಈ ವೈಶಿಷ್ಟ್ಯವು ಆದ್ಯತಾ ಮೋಡ್ ಅನ್ನು ಆನ್ ಅಥವಾ ಆಫ್ ಮಾಡಬಹುದು ಮತ್ತು ಸಂಬಂಧಿತ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಬದಲಾಯಿಸಬಹುದು."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ದೈನಂದಿನ ಸ್ಥಿತಿಯ ಮಾಹಿತಿಯ ಅಧಿಸೂಚನೆ"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ಚಾರ್ಜ್ಗೆ ಮೊದಲೆ ಬ್ಯಾಟರಿ ಮುಗಿದು ಬಿಡಬಹುದು"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ಬ್ಯಾಟರಿ ಅವಧಿ ಹೆಚ್ಚಿಸಲು ಬ್ಯಾಟರಿ ಸೇವರ್ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
@@ -2279,14 +2267,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"ನೀವು ಇದೀಗ ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ನ ಭಾಗವನ್ನು ಹಿಗ್ಗಿಸಬಹುದು"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ಆನ್ ಮಾಡಿ"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ವಜಾಗೊಳಿಸಿ"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"ಸಾಧನದ ಮೈಕ್ರೋಫೋನ್ ನಿರ್ಬಂಧವನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"ಸಾಧನದ ಕ್ಯಾಮರಾ ನಿರ್ಬಂಧವನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> ಮತ್ತು ಎಲ್ಲಾ ಆ್ಯಪ್ಗಳು ಹಾಗೂ ಸೇವೆಗಳಿಗಾಗಿ"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"ನಿರ್ಬಂಧವನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ಸೆನ್ಸರ್ ಗೌಪ್ಯತೆ"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ಅಪ್ಲಿಕೇಶನ್ ಐಕಾನ್"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ಅಪ್ಲಿಕೇಶನ್ ಬ್ರ್ಯಾಂಡಿಂಗ್ ಚಿತ್ರ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index aa64179..da8f4ab 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -538,10 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"앱이 근처의 블루투스 기기를 찾고 페어링하도록 허용"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"페어링된 블루투스 기기에 연결"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"앱이 페어링된 블루투스 기기에 연결하도록 허용"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"근처의 블루투스 기기로 광고"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"앱에서 근처의 블루투스 기기로 광고하도록 허용"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"근처 초광대역 기기 간 상대적 위치 파악"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"앱이 근처의 초광대역 기기 간 상대적 위치를 파악하도록 허용"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"기본 NFC 결제 서비스 정보"</string>
@@ -1854,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"절전 기능은 어두운 테마를 사용 설정하고 백그라운드 활동, 일부 시각 효과, \'Hey Google\'과 같은 기능을 제한하거나 사용 중지합니다.\n\n"<annotation id="url">"자세히 알아보기"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"절전 기능은 어두운 테마를 사용 설정하고 백그라운드 활동, 일부 시각 효과, \'Hey Google\'과 같은 기능을 제한하거나 사용 중지합니다."</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>
@@ -1933,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"닫기"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"답변"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"동영상"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"거절"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"전화 끊기"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"수신 전화"</string>
@@ -2076,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"이 알림의 중요도가 무음으로 하향되었습니다. 의견을 보내려면 탭하세요."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"이전에 이 알림의 중요도는 더 높았습니다. 의견을 보내려면 탭하세요."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"이전에 이 알림의 중요도는 더 낮았습니다. 의견을 보내려면 탭하세요."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"개선된 알림 기능 사용해 보기"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"추천 작업, 답장 등을 계속 받으려면 개선된 알림 기능을 사용 설정하세요. Android 적응형 알림은 더 이상 지원되지 않습니다."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"사용 설정"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"나중에"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"자세히 알아보기"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"개선된 알림 기능은 연락처 이름과 메시지 등 개인 정보가 포함된 모든 알림 내용을 읽어줍니다. 알림을 닫거나 알림에 표시되는 버튼 관련 작업(예: 전화 받기)을 실행할 수도 있습니다.\n\n또한 이 기능은 우선순위 모드를 사용 또는 사용 중지하고 관련 설정을 변경할 수 있습니다."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"루틴 모드 정보 알림"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"평소에 충전하는 시간 전에 배터리가 소진될 수 있습니다."</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"배터리 수명을 연장하기 위해 절전 모드가 활성화되었습니다."</string>
@@ -2275,14 +2266,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"이제 화면 일부를 확대할 수 있습니다."</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"설정에서 사용 설정"</string>
<string name="dismiss_action" msgid="1728820550388704784">"닫기"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"기기 마이크 차단 해제"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"기기 카메라 차단 해제"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> 및 모든 앱 및 서비스 대상"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"차단 해제"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"센서 개인정보 보호"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"애플리케이션 아이콘"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"애플리케이션 브랜드 이미지"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 86aa419..de0acbe 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -538,10 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Колдонмого жакын жердеги Bluetooth түзмөктөрүн аныктап, жупташтырууга уруксат берет"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"жупташтырылган Bluetooth түзмөктөрү"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Колдонмого жупташтырылган Bluetooth түзмөктөрү менен байланышууга уруксат берет"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"жакын жердеги Bluetooth түзмөктөрүнө жарнамалоо"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Колдонмого жакын жердеги Bluetooth түзмөктөрүнө жарнама көрсөтүүгө мүмкүндүк берет"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"кең тилкелүү тармак аркылуу туташа турган жакын жердеги түзмөктөрдү аныктоо"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Колдонмо кең тилкелүү тармак аркылуу туташа турган жакын жердеги түзмөктөрдү аныктай алат"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Тандалган NFC төлөм кызматы жөнүндө маалымат"</string>
@@ -553,11 +551,11 @@
<string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"экранды бөгөттөөнүн татаалдык деңгээлин суроо"</string>
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Колдонмого экранды бөгөттөөнүн татаалдыгын (татаал, орточо, оңой же такыр жок) үйрөнүүгө мүмкүнчүлүк берет. Татаалдык деңгээли сырсөздүн узундугу жана экранды бөгөттөөнүн түрү боюнча айырмаланат. Колдонмо экранды бөгөттөөнү белгилүү деңгээлге тууралоону колдонуучуларга сунуштай да алат, бирок колдонуучулар ага көңүл бурбай койсо болот. Сырсөздү колдонмо билбеши үчүн, экранды бөгөттөө сырсөзүн кадимки текстте сактоого болбойт."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"биометрикалык аппаратты колдонуу"</string>
- <string name="permdesc_useBiometric" msgid="7502858732677143410">"Колдонмого аныктыгын текшерүү үчүн, биометрикалык аппаратты пайдалануу мүмкүндүгүн берет"</string>
+ <string name="permdesc_useBiometric" msgid="7502858732677143410">"Колдонмого аныктыгын текшерүү үчүн биометрикалык аппаратты пайдалануу мүмкүндүгүн берет"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"манжа изинин аппараттык камсыздоосун башкаруу"</string>
<string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Колдонмого пайдалануу үчүн манжа изинин үлгүлөрүн кошуу жана жок кылуу мүмкүндүгүн берет."</string>
<string name="permlab_useFingerprint" msgid="1001421069766751922">"манжа изинин аппараттык камсыздоосун колдонуу"</string>
- <string name="permdesc_useFingerprint" msgid="412463055059323742">"Колдонмого аныктыгын текшерүү үчүн, манжа изинин аппараттык камсыздоосун пайдалануу мүмкүндүгүн берет"</string>
+ <string name="permdesc_useFingerprint" msgid="412463055059323742">"Колдонмого аныктыгын текшерүү үчүн манжа изинин аппараттык камсыздоосун пайдалануу мүмкүндүгүн берет"</string>
<string name="permlab_audioWrite" msgid="8501705294265669405">"музыка жыйнагыңызды өчүрүү"</string>
<string name="permdesc_audioWrite" msgid="8057399517013412431">"Колдонмого музыка жыйнагыңызды өзгөртүүгө мүмкүнчүлүк берет."</string>
<string name="permlab_videoWrite" msgid="5940738769586451318">"видео жыйнагыңызды өзгөртүү"</string>
@@ -1374,7 +1372,7 @@
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Мүчүлүштүктөрдү зымсыз оңдоону өчүрүү үчүн таптап коюңуз"</string>
<string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Мүчүлүштүктөрдү Wi-Fi аркылуу оңдоону өчүрүңүз."</string>
<string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Сыноо программасынын режими иштетилди"</string>
- <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Сыноо программасынын режимин өчүрүү үчүн, баштапкы жөндөөлөргө кайтарыңыз."</string>
+ <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Сыноо программасынын режимин өчүрүү үчүн баштапкы жөндөөлөргө кайтарыңыз."</string>
<string name="console_running_notification_title" msgid="6087888939261635904">"Сериялык консоль иштетилди"</string>
<string name="console_running_notification_message" msgid="7892751888125174039">"Майнаптуулугуна таасири тиет. Аны өчүрүү үчүн операциялык тутумду жүктөгүчтү текшериңиз."</string>
<string name="usb_contaminant_detected_title" msgid="4359048603069159678">"USB портунда суюктук же урандылар бар"</string>
@@ -1679,12 +1677,12 @@
<string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Графикалык ачкычыңызды <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес чийдиңиз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин, Android TV түзмөгүңүздүн кулпусун электрондук почта аккаунтуңуз менен ачышыңыз керек болот.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайталап көрүңүз."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес көрсөттүңүз. <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес көрсөтүлгөндөн кийин, телефондун кулпусун ачуу үчүн Google аккаунтуңузга кирүүгө туура келет.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин кайталап көрсөңүз болот."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
- <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Алып салуу"</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Өчүрүү"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Сунушталган деңгээлден да катуулатып уккуңуз келеби?\n\nМузыканы узакка чейин катуу уксаңыз, угууңуз начарлап кетиши мүмкүн."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Ыкчам иштетесизби?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Атайын мүмкүнчүлүктөр функциясын пайдалануу үчүн ал күйгүзүлгөндө, үндү катуулатып/акырындаткан эки баскычты тең 3 секунддай коё бербей басып туруңуз."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Атайын мүмкүнчүлүктөрдүн ыкчам баскычын иштетесизби?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Атайын мүмкүнчүлүктөр функциясын иштетүү үчүн, үндү чоңойтуп/кичирейтүү баскычтарын бир нече секунд коё бербей басып туруңуз. Ушуну менен, түзмөгүңүз бир аз башкача иштеп калышы мүмкүн.\n\nУчурдагы функциялар:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nТандалган функцияларды өзгөртүү үчүн, Жөндөөлөр > Атайын мүмкүнчүлүктөр бөлүмүнө өтүңүз."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Атайын мүмкүнчүлүктөр функциясын иштетүү үчүн, үндү чоңойтуп/кичирейтүү баскычтарын бир нече секунд коё бербей басып туруңуз. Ушуну менен, түзмөгүңүз бир аз башкача иштеп калышы мүмкүн.\n\nУчурдагы функциялар:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nТандалган функцияларды өзгөртүү үчүн Жөндөөлөр > Атайын мүмкүнчүлүктөр бөлүмүнө өтүңүз."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"<xliff:g id="SERVICE">%1$s</xliff:g> ыкчам баскычын иштетесизби?"</string>
<string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"<xliff:g id="SERVICE">%1$s</xliff:g> кызматын иштетүү үчүн, үндү чоңойтуп/кичирейтүү баскычтарын бир нече секунд коё бербей басып туруңуз. Ушуну менен, түзмөгүңүз бир аз башкача иштеп калышы мүмкүн.\n\nБаскычтардын ушул айкалышын башка функцияга дайындоо үчүн, Жөндөөлөр > Атайын мүмкүнчүлүктөр бөлүмүнө өтүңүз."</string>
@@ -1854,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Батареяны үнөмдөгүч режиминде Караңгы тема күйгүзүлүп, фондогу аракеттер, айрым визуалдык эффекттер жана \"Окей, Google\" сыяктуу функциялар чектелип же өчүрүлөт\n\n"<annotation id="url">"Кеңири маалымат"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Батареяны үнөмдөгүч режиминде Караңгы тема күйгүзүлүп, фондогу аракеттер, айрым визуалдык эффекттер жана \"Окей, Google\" сыяктуу функциялар чектелип же өчүрүлөт."</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>
@@ -1933,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Жабуу"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Жооп берүү"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Видео"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Четке кагуу"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Чалууну бүтүрүү"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Кирүүчү чалуу"</string>
@@ -2076,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Бул билдирменин маанилүүлүгү Үнсүз болуп төмөндөтүлдү. Пикир билдирүү үчүн таптап коюңуз."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Бул билдирменин маанилүүлүгү жогорулатылды. Пикир билдирүү үчүн таптап коюңуз."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Бул билдирменин маанилүүлүгү төмөндөтүлдү. Пикир билдирүү үчүн таптап коюңуз."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Жакшыр-ган бил-ди байкап көрүү"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Сунушталган аракеттерди, жоопторду жана башка маалыматты ала берүү үчүн жакшыртылган билдирмелерди күйгүзүңүз. Android\'дин Ыңгайлаштырылуучу билдирмелери колдоого алынбай калды."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Күйгүзүү"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Азыр эмес"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Кененирээк"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Жакшыртылган билдирмелер бардык билдирмелердин мазмунун, ошондой эле байланыштардын аты-жөнү жана билдирүүлөр сыяктуу жеке маалыматты окуй алат. Мындан тышкары, билдирмелерди жаап же телефон чалууларына жооп берүү сыяктуу билдирмелердеги баскычтарды баса алат.\n\nБул функция Маанилүү жазышуулар режимин күйгүзүп же өчүрүп, ошондой эле анын жөндөөлөрүн өзгөртө алат."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Режимдин адаттагы билдирмеси"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея кубаттоого чейин отуруп калышы мүмкүн"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Батареянын отуруп калбашы үчүн Батареяны үнөмдөгүч режими иштетилди"</string>
@@ -2140,7 +2131,7 @@
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
<string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"сүрөт жөнөттү"</string>
<string name="conversation_title_fallback_one_to_one" msgid="1980753619726908614">"Жазышуу"</string>
- <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Топтук маек"</string>
+ <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Топтошуп жазышуу"</string>
<string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string>
<string name="resolver_personal_tab" msgid="2051260504014442073">"Жеке"</string>
<string name="resolver_work_tab" msgid="2690019516263167035">"Жумуш"</string>
@@ -2271,18 +2262,14 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Жаңы чоңойтуу жөндөөлөрү"</string>
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Чоңойтуу функциясынын жаңы жөндөөлөрү"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Эми экрандын бир бөлүгүн чоңойто аласыз"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Жөндөөлөрдөн күйгүзүү"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Жабуу"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Түзмөктүн микрофонунун кулпусун ачуу"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Түзмөктүн камерасынын кулпусун ачуу"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> жана башка бардык колдонмолор менен кызматтар үчүн"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Бөгөттөн чыгаруу"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Сенсордун купуялыгы"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Колдонмонун сүрөтчөсү"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Колдонмонун брендинин сүрөтү"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 0b53554..caa9154 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1852,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"ຕົວປະຢັດແບັດເຕີຣີຈະເປີດໃຊ້ຮູບແບບສີສັນມືດ ແລະ ຈຳກັດ ຫຼື ປິດການເຄື່ອນໄຫວໃນພື້ນຫຼັງ, ເອັບເຟັກດ້ານພາບບາງຢ່າງ ແລະ ຄຸນສົມບັດຕ່າງໆ ເຊັ່ນ: “Ok Google”\n\n"<annotation id="url">"ສຶກສາເພີ່ມເຕີມ"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"ຕົວປະຢັດແບັດເຕີຣີຈະເປີດໃຊ້ຮູບແບບສີສັນມືດ ແລະ ຈຳກັດ ຫຼື ປິດການເຄື່ອນໄຫວໃນພື້ນຫຼັງ, ເອັບເຟັກດ້ານພາບບາງຢ່າງ ແລະ ຄຸນສົມບັດຕ່າງໆ ເຊັ່ນ: “Ok Google”."</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>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"ປິດ"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"ຮັບສາຍ"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"ວິດີໂອ"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"ປະຕິເສດ"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"ວາງສາຍ"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"ສາຍໂທເຂົ້າ"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"ການແຈ້ງເຕືອນນີ້ຖືກຫຼຸດລະດັບເປັນປິດສຽງແລ້ວ. ແຕະເພື່ອສົ່ງຄຳຕິຊົມ."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"ການແຈ້ງເຕືອນນີ້ຖືກເລື່ອນລະດັບຂຶ້ນແລ້ວ. ແຕະເພື່ອສົ່ງຄຳຕິຊົມ."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"ການແຈ້ງເຕືອນນີ້ຖືກຫຼຸດລະດັບລົງແລ້ວ. ແຕະເພື່ອສົ່ງຄຳຕິຊົມ."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"ລອງໃຊ້ການແຈ້ງເຕືອນທີ່ປັບປຸງໃຫ້ດີຂຶ້ນ"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"ກະລຸນາເປີດໃຊ້ການແຈ້ງເຕືອນທີ່ປັບປຸງໃຫ້ດີຂຶ້ນເພື່ອສືບຕໍ່ຮັບຄຳສັ່ງທີ່ແນະນຳ, ການຕອບກັບ ແລະ ອື່ນໆ. ບໍ່ຮອງຮັບການແຈ້ງເຕືອນແບບປັບຕົວໄດ້ຂອງ Android ອີກຕໍ່ໄປແລ້ວ."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"ເປີດໃຊ້"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"ບໍ່ຟ້າວເທື່ອ"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ສຶກສາເພີ່ມເຕີມ"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"ການແຈ້ງເຕືອນທີ່ປັບປຸງໃຫ້ດີຂຶ້ນສາມາດອ່ານເນື້ອຫາການແຈ້ງເຕືອນທັງໝົດໄດ້, ຮວມທັງຂໍ້ມູນສ່ວນຕົວ ເຊັ່ນ: ຊື່ຜູ້ຕິດຕໍ່ ແລະ ຂໍ້ຄວາມຕ່າງໆ. ນອກຈາກນັ້ນ, ຄຸນສົມບັດນີ້ຍັງສາມາດປິດການແຈ້ງເຕືອນໄວ້ ຫຼື ໃຊ້ຄຳສັ່ງຕ່າງໆຢູ່ປຸ່ມໃນການແຈ້ງເຕືອນໄດ້ນຳ ເຊັ່ນ: ການຮັບສາຍໂທລະສັບ.\n\nຄຸນສົມບັດນີ້ສາມາດເປີດ ຫຼື ປິດໂໝດສຳຄັນ ແລະ ປ່ຽນການຕັ້ງຄ່າທີ່ກ່ຽວຂ້ອງໄດ້ນຳ."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ການແຈ້ງເຕືອນຂໍ້ມູນໂໝດກິດຈະວັດປະຈຳວັນ"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ແບັດເຕີຣີອາດໝົດກ່ອນການສາກຕາມປົກກະຕິ"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ເປີດຕົວປະຢັດແບັດເຕີຣີເພື່ອຂະຫຍາຍອາຍຸແບັດເຕີຣີ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 5a0b665..d06bc16 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1898,10 +1898,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Atnaujino administratorius"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Ištrynė administratorius"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Gerai"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Akumuliatoriaus tausojimo priemonė įjungia tamsiąją temą ir apriboja arba išjungia veiklą fone, kai kuriuos vizualinius efektus ir funkcijas, pvz., „Ok Google“\n\n"<annotation id="url">"Sužinokite daugiau"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Akumuliatoriaus tausojimo priemonė įjungia tamsiąją temą ir apriboja arba išjungia veiklą fone, kai kuriuos vizualinius efektus ir funkcijas, pvz., „Ok Google“."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Kad padėtų sumažinti duomenų naudojimą, Duomenų taupymo priemonė neleidžia kai kurioms programoms siųsti ar gauti duomenų fone. Šiuo metu naudojama programa gali pasiekti duomenis, bet tai bus daroma rečiau. Tai gali reikšti, kad, pvz., vaizdai nebus pateikiami, jei jų nepaliesite."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Įj. Duomenų taupymo priemonę?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Įjungti"</string>
@@ -1993,6 +1991,8 @@
<string name="close_button_text" msgid="10603510034455258">"Uždaryti"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Atsakyti"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Atmesti"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Baigti pok."</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Gaunamasis skambutis"</string>
@@ -2140,18 +2140,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Šio pranešimo svarba sumažinta iki begarsio lygio. Palieskite, kad pateiktumėte atsiliepimą."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Šio pranešimo svarba padidinta. Palieskite, kad pateiktumėte atsiliepimą."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Šio pranešimo svarba sumažinta. Palieskite, kad pateiktumėte atsiliepimą."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Išb. patobulintus pranešimus"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Norėdami toliau gauti siūlomus veiksmus, atsakymus ir daugiau, įjunkite patobulintus pranešimus. „Android“ prisitaikantys pranešimai nebepalaikomi."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Įjungti"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Ne dabar"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Sužinokite daugiau"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Patobulintų pranešimų funkcija gali skaityti visų pranešimų turinį, įskaitant asmens informaciją (pvz., kontaktų vardus ir pranešimus). Ši funkcija taip pat gali atsisakyti pranešimų ar imtis veiksmų su pranešimuose esančiais mygtukais, pvz., atsakyti į telefono skambučius.\n\nBe to, ši funkcija gali įjungti arba išjungti svarbiausių pokalbių režimą ir pakeisti susijusius nustatymus."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Veiksmų sekos režimo informacijos pranešimas"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Akumuliatoriaus energija gali išsekti prieš įprastą įkrovimą"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Akumuliatoriaus tausojimo priemonė suaktyvinta, kad akumuliatorius veiktų ilgiau"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index b4edfc6..7e54fb9 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1875,10 +1875,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Atjaunināja administrators"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Dzēsa administrators"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Labi"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Akumulatora enerģijas taupīšanas režīmā tiek ieslēgts tumšais motīvs un ierobežotas vai izslēgtas darbības fonā, konkrēti vizuālie efekti un tādas funkcijas kā īsinājumvārda “Hey Google” atpazīšana.\n\n"<annotation id="url">"Uzzināt vairāk"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Akumulatora enerģijas taupīšanas režīmā tiek ieslēgts tumšais motīvs un ierobežotas vai izslēgtas darbības fonā, konkrēti vizuālie efekti un tādas funkcijas kā īsinājumvārda “Hey Google” atpazīšana."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Lai samazinātu datu lietojumu, datu lietojuma samazinātājs neļauj dažām lietotnēm fonā nosūtīt vai saņemt datus. Lietotne, kuru pašlaik izmantojat, var piekļūt datiem, bet, iespējams, piekļūs tiem retāk (piemēram, attēli tiks parādīti tikai tad, kad tiem pieskarsieties)."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Vai ieslēgt datu lietojuma samazinātāju?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Ieslēgt"</string>
@@ -1962,6 +1960,8 @@
<string name="close_button_text" msgid="10603510034455258">"Aizvērt"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Atbildēt"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Noraidīt"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Pārtraukt"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Ienākošais zvans"</string>
@@ -2107,18 +2107,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Šī paziņojuma svarīgums tika pazemināts, un paziņojums tiks rādīts bez skaņas. Lai sniegtu atsauksmes, pieskarieties."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Šī paziņojuma rangs tika paaugstināts. Lai sniegtu atsauksmes, pieskarieties."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Šī paziņojuma rangs tika pazemināts. Lai sniegtu atsauksmes, pieskarieties."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Uzlabotie paziņojumi"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Lai arī turpmāk saņemtu darbību un atbilžu ieteikumus un citu saturu, ieslēdziet uzlabotos paziņojumus. Android adaptīvie paziņojumi vairs netiek atbalstīti."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Ieslēgt"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Vēlāk"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Uzzināt vairāk"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Funkcija “Uzlabotie paziņojumi” var lasīt visu paziņojumu saturu, tostarp personas informāciju, piemēram, kontaktpersonu vārdus un ziņojumus. Šī funkcija var arī noraidīt paziņojumus un izmantot paziņojumos esošās pogas darbību veikšanai, piemēram, atbildēt uz tālruņa zvaniem.\n\nTurklāt šī funkcija var ieslēgt un izslēgt režīmu Prioritāte un mainīt ar to saistītos iestatījumus."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Informatīvs paziņojums par akumulatoru"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Akumulators var izlādēties pirms parastā uzlādes laika"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Aktivizēts akumulatora enerģijas taupīšanas režīms, lai palielinātu akumulatora darbības ilgumu"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index fce03ff..1e4ede2 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -297,7 +297,7 @@
<string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Користење на пристапноста"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> користи батерија"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> апликации користат батерија"</string>
- <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Допрете за детали за батеријата и потрошениот сообраќај"</string>
+ <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Допрете за детали за батеријата и потрошениот интернет"</string>
<string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="8974401416068943888">"Безбеден режим"</string>
<string name="android_system_label" msgid="5974767339591067210">"Систем Android"</string>
@@ -1160,7 +1160,7 @@
<string name="redo" msgid="7231448494008532233">"Повтори"</string>
<string name="autofill" msgid="511224882647795296">"Автоматско пополнување"</string>
<string name="textSelectionCABTitle" msgid="5151441579532476940">"Избор на текст"</string>
- <string name="addToDictionary" msgid="8041821113480950096">"Додај во речник"</string>
+ <string name="addToDictionary" msgid="8041821113480950096">"Додајте во речникот"</string>
<string name="deleteText" msgid="4200807474529938112">"Избриши"</string>
<string name="inputMethod" msgid="1784759500516314751">"Метод на внес"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"Дејства со текст"</string>
@@ -1852,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"„Штедачот на батерија“ вклучува темна тема и исклучува или ограничува активност во заднина, некои визуелни ефекти и функции како „Ok Google“\n\n"<annotation id="url">"Дознајте повеќе"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"„Штедачот на батерија“ вклучува темна тема и исклучува или ограничува активност во заднина, некои визуелни ефекти и функции како „Ok Google“."</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>
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Затвори"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Одговори"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Одбиј"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Спушти"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Дојдовен повик"</string>
@@ -1948,7 +1948,7 @@
<string name="user_creation_adding" msgid="7305185499667958364">"Дозволувате <xliff:g id="APP">%1$s</xliff:g> да создаде нов корисник со <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="52674936078683285">"Додајте јазик"</string>
<string name="country_selection_title" msgid="5221495687299014379">"Претпочитувања за регион"</string>
- <string name="search_language_hint" msgid="7004225294308793583">"Внеси име на јазик"</string>
+ <string name="search_language_hint" msgid="7004225294308793583">"Внесете име на јазик"</string>
<string name="language_picker_section_suggested" msgid="6556199184638990447">"Предложени"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"Сите јазици"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"Сите региони"</string>
@@ -1992,7 +1992,7 @@
<string name="app_category_productivity" msgid="1844422703029557883">"Продуктивност"</string>
<string name="app_category_accessibility" msgid="6643521607848547683">"Пристапност"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Простор на уредот"</string>
- <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Отстранување грешки на USB"</string>
+ <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Отстранување грешки преку USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"час"</string>
<string name="time_picker_minute_label" msgid="8307452311269824553">"минута"</string>
<string name="time_picker_header_text" msgid="9073802285051516688">"Постави време"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Приоритетноста на известувањево е намалена на „Тивко“. Допрете за да дадете повратни информации."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Известувањево е рангирано повисоко. Допрете за да дадете повратни информации."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Известувањево е рангирано пониско. Допрете за да дадете повратни информации."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Пробај „Подобрени известувања“"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Вклучете ги „Подобрените известувања“ за да продолжите да добивате предлози за дејства, одговори и слично. „Приспособливите известувања на Android“ веќе не се достапни."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Вклучи"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Не сега"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Дознајте повеќе"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"„Подобрените известувања“ може да ги читаат сите содржини од известувањата, вклучително и личните податоци, како што се имињата на контактите и пораките. Функцијава ќе може и да отфрла известувања или да ги користи копчињата во известувањата, како на пр., да одговара на телефонски повици.\n\nФункцијава може и да го вклучува или исклучува „Приоритетниот режим“ и да ги менува поврзаните поставки."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Известување за информации за режимот за рутини"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батеријата може да се потроши пред вообичаеното време за полнење"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Активиран е „Штедачот на батерија“ за да се продолжи траењето на батеријата"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index e50fb7bd..1a27c20 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -307,7 +307,7 @@
<string name="permgroupdesc_contacts" msgid="9163927941244182567">"നിങ്ങളുടെ കോൺടാക്റ്റുകൾ ആക്സസ്സ് ചെയ്യുക"</string>
<string name="permgrouplab_location" msgid="1858277002233964394">"ലൊക്കേഷൻ"</string>
<string name="permgroupdesc_location" msgid="1995955142118450685">"ഈ ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ആക്സസ് ചെയ്യാൻ"</string>
- <string name="permgrouplab_calendar" msgid="6426860926123033230">"Calendar"</string>
+ <string name="permgrouplab_calendar" msgid="6426860926123033230">"കലണ്ടർ"</string>
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"നിങ്ങളുടെ കലണ്ടർ ആക്സസ്സ് ചെയ്യുക"</string>
<string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
<string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS സന്ദേശങ്ങൾ അയയ്ക്കുകയും കാണുകയും ചെയ്യുക"</string>
@@ -538,10 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"സമീപമുള്ള Bluetooth ഉപകരണങ്ങൾ കണ്ടെത്താനും ജോടിയാക്കാനും ആപ്പിനെ അനുവദിക്കുന്നു"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ജോടിയായ Bluetooth ഉപകരണങ്ങളിലേക്ക് കണക്റ്റ് ചെയ്യൂ"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ജോടിയാക്കിയ Bluetooth ഉപകരണങ്ങളിലേക്ക് കണക്റ്റ് ചെയ്യാൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"സമീപമുള്ള Bluetooth ഉപകരണങ്ങളിലേക്ക് പരസ്യം ചെയ്യൂ"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"സമീപമുള്ള Bluetooth ഉപകരണങ്ങളിലേക്ക് പരസ്യം ചെയ്യാൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"സമീപമുള്ള അൾട്രാ-വെെഡ്ബാൻഡ് ഉപകരണങ്ങൾ തമ്മിലുള്ള ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കൂ"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"സമീപമുള്ള അൾട്രാ-വെെഡ്ബാൻഡ് ഉപകരണങ്ങൾ തമ്മിലുള്ള ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കാൻ ആപ്പിനെ അനുവദിക്കുക"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"തിരഞ്ഞെടുത്ത NFC പേയ്മെന്റ് സേവനത്തെ സംബന്ധിച്ച വിവരങ്ങൾ"</string>
@@ -1854,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"ബാറ്ററി ലാഭിക്കൽ, ഡാർക്ക് തീം ഓണാക്കുന്നു, പശ്ചാത്തല പ്രവർത്തനവും ചില വിഷ്വൽ ഇഫക്റ്റുകളും “Ok Google” പോലുള്ള ഫീച്ചറുകളും നിയന്ത്രിക്കുകയോ ഓഫാക്കുകയോ ചെയ്യുന്നു\n\n"<annotation id="url">"കൂടുതലറിയുക"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"ബാറ്ററി ലാഭിക്കൽ, ഡാർക്ക് തീം ഓണാക്കുന്നു, പശ്ചാത്തല പ്രവർത്തനവും ചില വിഷ്വൽ ഇഫക്റ്റുകളും “Ok Google” പോലുള്ള ഫീച്ചറുകളും നിയന്ത്രിക്കുകയോ ഓഫാക്കുകയോ ചെയ്യുന്നു."</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>
@@ -1933,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"അവസാനിപ്പിക്കുക"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"മറുപടി നൽകുക"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"നിരസിക്കുക"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"കോൾ നിർത്തുക"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"ഇൻകമിംഗ് കോൾ"</string>
@@ -1950,7 +1948,7 @@
<string name="user_creation_adding" msgid="7305185499667958364">"<xliff:g id="ACCOUNT">%2$s</xliff:g> എന്ന അക്കൗണ്ട് ഉപയോഗിച്ച് പുതിയ ഉപയോക്താവിനെ സൃഷ്ടിക്കാൻ <xliff:g id="APP">%1$s</xliff:g> എന്നതിനെ അനുവദിക്കണോ?"</string>
<string name="language_selection_title" msgid="52674936078683285">"ഒരു ഭാഷ ചേർക്കുക"</string>
<string name="country_selection_title" msgid="5221495687299014379">"മേഖലാ മുൻഗണന"</string>
- <string name="search_language_hint" msgid="7004225294308793583">"ഭാഷയുടെ പേര് ടൈപ്പുചെയ്യുക"</string>
+ <string name="search_language_hint" msgid="7004225294308793583">"ഭാഷ ടൈപ്പ് ചെയ്യുക"</string>
<string name="language_picker_section_suggested" msgid="6556199184638990447">"നിര്ദ്ദേശിച്ചത്"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"എല്ലാ ഭാഷകളും"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"എല്ലാ പ്രദേശങ്ങളും"</string>
@@ -2076,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"ഈ അറിയിപ്പിനെ നിശബ്ദമാക്കി തരം താഴ്ത്തി. ഫീഡ്ബാക്ക് നൽകാൻ ടാപ്പ് ചെയ്യുക."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"ഈ അറിയിപ്പിന് ഉയർന്ന റാങ്ക് നൽകി. ഫീഡ്ബാക്ക് നൽകാൻ ടാപ്പ് ചെയ്യുക."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"ഈ അറിയിപ്പിന് താഴ്ന്ന റാങ്ക് നൽകി. ഫീഡ്ബാക്ക് നൽകാൻ ടാപ്പ് ചെയ്യുക."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"മെച്ചപ്പെടുത്തിയ അറിയിപ്പുകൾ പരീക്ഷിക്കൂ"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"നിർദ്ദേശിച്ച പ്രവർത്തനങ്ങളും മറുപടികളും മറ്റും ലഭിക്കുന്നത് തുടരാൻ, മെച്ചപ്പെടുത്തിയ അറിയിപ്പുകൾ ഓണാക്കുക. Android അഡാപ്റ്റീവ് അറിയിപ്പുകൾക്ക് ഇനി പിന്തുണയില്ല."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"ഓണാക്കുക"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"ഇപ്പോൾ വേണ്ട"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"കൂടുതലറിയുക"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"മെച്ചപ്പെടുത്തിയ അറിയിപ്പുകൾക്ക്, കോൺടാക്റ്റ് പേരുകളും സന്ദേശങ്ങളും പോലുള്ള വ്യക്തിപരമായ വിവരങ്ങൾ ഉൾപ്പെടെ എല്ലാ അറിയിപ്പ് ഉള്ളടക്കവും വായിക്കാനാകും. അറിയിപ്പുകൾ ഡിസ്മിസ് ചെയ്യാനോ ഫോൺ കോളുകൾക്ക് മറുപടി നൽകുന്നത് പോലെ അറിയിപ്പുകളിലെ ബട്ടണുകളിൽ നടപടിയെടുക്കാനോ ഈ ഫീച്ചറിന് കഴിയും.\n\nമുൻഗണനാ മോഡ് ഓണാക്കാനോ ഓഫാക്കാനോ ബന്ധപ്പെട്ട ക്രമീകരണം മാറ്റാനോ ഈ ഫീച്ചറിന് കഴിയും."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ദിനചര്യ മോഡ് വിവരത്തെ കുറിച്ചുള്ള അറിയിപ്പ്"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"സാധാരണയുള്ളതിലും നേരത്തെ ബാറ്ററിയുടെ ചാർജ് തീർന്നേക്കാം"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ബാറ്ററി ലൈഫ് വര്ദ്ധിപ്പിക്കാൻ, ബാറ്ററി ലാഭിക്കൽ സജീവമാക്കി"</string>
@@ -2275,14 +2267,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"നിങ്ങളുടെ സ്ക്രീനിന്റെ ഒരു ഭാഗം ഇപ്പോൾ മാഗ്നിഫൈ ചെയ്യാനാകും"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ക്രമീകരണത്തിൽ ഓണാക്കുക"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ഡിസ്മിസ് ചെയ്യുക"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"ഉപകരണ മൈക്രോഫോൺ അൺബ്ലോക്ക് ചെയ്യുക"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"ഉപകരണ ക്യാമറ അൺബ്ലോക്ക് ചെയ്യുക"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> എന്നതിനും എല്ലാ ആപ്പുകൾക്കും സേവനങ്ങൾക്കും"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"അൺബ്ലോക്ക് ചെയ്യുക"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"സെൻസർ സ്വകാര്യത"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ആപ്പ് ഐക്കൺ"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"അപ്ലിക്കേഷൻ ബ്രാൻഡിംഗ് ഇമേജ്"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 87ee801..a3a3cdb 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1693,7 +1693,7 @@
<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_title" msgid="190017412626919776">"Дэлгэцийг харах ба хянах"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Энэ нь дэлгэц дээрх бүх контентыг унших болон контентыг бусад аппад харуулах боломжтой."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Үйлдлийг харах болон гүйцэтгэх"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Энэ нь таны апп болон техник хангамжийн мэдрэгчтэй хийх харилцан үйлдлийг хянах болон таны өмнөөс апптай харилцан үйлдэл хийх боломжтой."</string>
@@ -1852,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Батарей хэмнэгч нь Бараан загварыг асааж, дэвсгэрийн үйл ажиллагаа, зарим визуал эффект болон “Hey Google” зэрэг онцлогуудыг хязгаарлаж эсвэл унтраана\n\n"<annotation id="url">"Нэмэлт мэдээлэл авах"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Батарей хэмнэгч нь Бараан загварыг асааж, дэвсгэрийн үйл ажиллагаа, зарим визуал эффект болон “Hey Google” зэрэг онцлогуудыг хязгаарлаж эсвэл унтраана."</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>
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Хаах"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Хариулах"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Татгалзах"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Таслах"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Ирсэн дуудлага"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Энэ мэдэгдлийг Чимээгүй болгож зэргийг нь бууруулсан байна. Санал хүсэлт өгөхийн тулд товшино уу."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Энэ мэдэгдлийг дээгүүр зэрэглэсэн байна. Санал хүсэлт өгөхийн тулд товшино уу."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Энэ мэдэгдлийг доогуур зэрэглэсэн байна. Санал хүсэлт өгөхийн тулд товшино уу."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Сайжруулсан мэдэгдлийг турших"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Санал болгосон үйлдэл, хариу болон илүү ихийг үргэлжлүүлэн авахын тулд сайжруулсан мэдэгдлийг асаана уу. Android-н Орчинтой тохирсон мэдэгдлийг дэмжихээ больсон байна."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Асаах"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Одоо биш"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Нэмэлт мэдээлэл авах"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Сайжруулсан мэдэгдэл нь харилцагчийн нэр, мессеж зэрэг хувийн мэдээллийг оруулаад бүх мэдэгдлийн контентыг унших боломжтой. Энэ онцлог мөн мэдэгдлийг хаах эсвэл утасны дуудлагад хариулах гэх мэт мэдэгдэл дэх товчлуур дээр үйлдэл хийх боломжтой.\n\nЭнэ онцлог мөн Чухал горимыг асаах, унтраах болон холбогдох тохиргоог өөрчлөх боломжтой."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Хэвшлийн горимын мэдээллийн мэдэгдэл"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарей ихэвчлэн цэнэглэдэг хугацаанаас өмнө дуусаж болзошгүй"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Батарейн ажиллах хугацааг уртасгахын тулд Батарей хэмнэгчийг идэвхжүүллээ"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 01b767e..24ed1b6 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -277,7 +277,7 @@
<string name="notification_hidden_text" msgid="2835519769868187223">"नवीन सूचना"</string>
<string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"व्हर्च्युअल कीबोर्ड"</string>
<string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"वास्तविक कीबोर्ड"</string>
- <string name="notification_channel_security" msgid="8516754650348238057">"सुरक्षितता"</string>
+ <string name="notification_channel_security" msgid="8516754650348238057">"सुरक्षा"</string>
<string name="notification_channel_car_mode" msgid="2123919247040988436">"कार मोड"</string>
<string name="notification_channel_account" msgid="6436294521740148173">"खाते स्थिती"</string>
<string name="notification_channel_developer" msgid="1691059964407549150">"डेव्हलपर मेसेज"</string>
@@ -538,10 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ॲपला जवळपासची ब्लूटूथ डिव्हाइस शोधण्यासाठी आणि ती पेअर करण्यासाठी अनुमती देते"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"पेअर केलेल्या ब्लूटूथ डिव्हाइसशी कनेक्ट करा"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"पेअर केलेल्या ब्लूटूथ डिव्हाइसशी कनेक्ट करण्यासाठी ॲपला अनुमती द्या"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"जवळपासच्या ब्लूटूथ डिव्हाइसवर जाहिरात करा"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"जवळपासच्या ब्लूटूथ डिव्हाइसवर जाहिरात करण्याची ॲपला परवानगी देते"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"जवळच्या अल्ट्रा-वाइडबँड डिव्हाइसदरम्यानचे संबंधित स्थान निर्धारित करा"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ॲपला जवळच्या अल्ट्रा-वाइडबँड डिव्हाइसदरम्यानचे संबंधित स्थान निर्धारित करण्याची अनुमती द्या"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"प्राधान्यकृत NFC पेमेंट सेवा माहिती"</string>
@@ -1854,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"बॅटरी सेव्हर गडद थीम सुरू करते आणि बॅकग्राउंड ॲक्टिव्हिटी, काही व्हिज्युअल इफेक्ट व “Ok Google” सारखी वैशिष्ट्ये मर्यादित किंवा बंद करते\n\n"<annotation id="url">"अधिक जाणून घ्या"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"बॅटरी सेव्हर गडद थीम सुरू करते आणि बॅकग्राउंड ॲक्टिव्हिटी, काही व्हिज्युअल इफेक्ट व “Ok Google” सारखी वैशिष्ट्ये मर्यादित किंवा बंद करते."</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>
@@ -1933,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"बंद करा"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"उत्तर द्या"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"नकार द्या"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"कॉल बंद करा"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"इनकमिंग कॉल"</string>
@@ -2076,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"ही सूचना सायलंट करण्यात आली आहे. फीडबॅक देण्यासाठी टॅप करा."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"हा सूचनेला उच्च रँक करण्यात आले. फीडबॅक देण्यासाठी टॅप करा."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"या सूचनेला कमी रँक करण्यात आले. फीडबॅक देण्यासाठी टॅप करा."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"वर्धित सूचना वापरून पहा"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"सुचवलेल्या कृती, उत्तरे आणि आणखी बरेच काही मिळवत राहण्यासाठी, वर्धित सूचना सुरू करा. Android अॅडॅप्टिव्ह सूचना यांना आता सपोर्ट नाही."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"सुरू करा"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"आता नको"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"अधिक जाणून घ्या"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"संपर्कांची नावे आणि मेसेज यांसारख्या वैयक्तिक माहितीच्या समावेशासह वर्धित सूचना या सर्व सूचनांचा आशय वाचू शकतात. हे वैशिष्ट्य सूचना डिसमिस करू शकते किंवा फोन कॉलना उत्तर देण्यासारख्या सूचनांमधील बटणवर कृतीदेखील करू शकते.\n\nहे वैशिष्ट्य प्राधान्य मोड सुरू किंवा बंद करू शकते आणि संबंधित सेटिंग्जदेखील बदलू शकते."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"दिनक्रम मोडची माहिती सूचना"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"चार्जिंगची सामान्य पातळी गाठेपर्यंत कदाचित बॅटरी संपू शकते"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"बॅटरी लाइफ वाढवण्यासाठी बॅटरी सेव्हर सुरू केला आहे"</string>
@@ -2275,14 +2267,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"आता तुम्ही तुमच्या स्क्रीनचा एखादा भाग मॅग्निफाय करू शकता"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"सेटिंग्ज मध्ये सुरू करा"</string>
<string name="dismiss_action" msgid="1728820550388704784">"डिसमिस करा"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"डिव्हाइसचा मायक्रोफोन अनब्लॉक करा"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"डिव्हाइसचा कॅमेरा अनब्लॉक करा"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"सर्व <b><xliff:g id="APP">%s</xliff:g></b> आणि सर्व ॲप्स व सेवांसाठी"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"अनब्लॉक करा"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"सेन्सरशी संबंधित गोपनीयतेबाबत सूचना"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ॲप्लिकेशन आयकन"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"अॅप्लिकेशन ब्रॅंडिंग इमेज"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index d5fe785..0afa2f9 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -538,10 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Membenarkan apl menemukan dan berganding dengan peranti Bluetooth yang berdekatan"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"sambung kepada peranti Bluetooth yang digandingkan"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Membenarkan apl untuk menyambung kepada peranti Bluetooth yang digandingkan"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"buat siaran kpd peranti Bluetooth yang berdekatan"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Membenarkan apl menyiarkan kandungan kepada peranti Bluetooth yang berdekatan"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"tentukan kedudukan relatif antara peranti Ultrajalur Lebar berdekatan"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Benarkan apl menentukan kedudukan relatif antara peranti Ultrajalur Lebar berdekatan"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Maklumat Perkhidmatan Pembayaran NFC Pilihan"</string>
@@ -1854,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Dikemas kini oleh pentadbir anda"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Dipadamkan oleh pentadbir anda"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Penjimat Bateri menghidupkan Tema gelap dan mengehadkan atau mematikan aktiviti latar, sesetengah kesan visual dan ciri seperti \"Ok Google\"\n\n"<annotation id="url">"Ketahui lebih lanjut"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Penjimat Bateri menghidupkan Tema gelap dan mengehadkan atau mematikan aktiviti latar, sesetengah kesan visual dan ciri seperti \"Ok Google\"."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Untuk membantu mengurangkan penggunaan data, Penjimat Data menghalang sesetengah apl daripada menghantar atau menerima data di latar. Apl yang sedang digunakan boleh mengakses data tetapi mungkin tidak secara kerap. Perkara ini mungkin bermaksud bahawa imej tidak dipaparkan sehingga anda mengetik pada imej itu, contohnya."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Hidupkan Penjimat Data?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Hidupkan"</string>
@@ -1933,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Tutup"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Jawapan"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Tolak"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Tamatkan Panggilan"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Panggilan masuk"</string>
@@ -2076,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Pemberitahuan ini telah diturun taraf kepada Senyap. Ketik untuk memberikan maklum balas."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Pemberitahuan ini berada di kedudukan lebih tinggi. Ketik untuk memberikan maklum balas."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Pemberitahuan ini berada di kedudukan lebih rendah. Ketik untuk memberikan maklum balas."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Cuba pemberitahuan dipertingkatkan"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Untuk terus mendapatkan tindakan yang dicadangkan, balasan dan banyak lagi, hidupkan pemberitahuan yang dipertingkatkan. Pemberitahuan Boleh Suai Android tidak disokong lagi."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Hidupkan"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Bukan sekarang"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Ketahui lebih lanjut"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Pemberitahuan yang dipertingkatkan dapat membaca semua kandungan pemberitahuan, termasuk maklumat peribadi seperti nama kenalan dan mesej. Ciri ini juga dapat mengetepikan pemberitahuan atau mengambil tindakan pada butang dalam pemberitahuan, seperti menjawab panggilan telefon.\n\nCiri ini juga dapat menghidupkan atau mematikan mod Keutamaan dan menukar tetapan yang berkaitan."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Pemberitahuan maklumat Mod Rutin"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Bateri mungkin habis sebelum pengecasan biasa"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Penjimat Bateri diaktifkan untuk memanjangkan hayat bateri"</string>
@@ -2275,14 +2267,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Kini anda boleh membesarkan sebahagian skrin anda"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Hidupkan dalam Tetapan"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Tolak"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Nyahsekat mikrofon peranti"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Nyahsekat kamera peranti"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Untuk <b><xliff:g id="APP">%s</xliff:g></b> dan semua apl serta perkhidmatan"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Nyahsekat"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privasi Penderia"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikon aplikasi"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imej jenama aplikasi"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 5f6a26a5..be4bf4fa 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1108,8 +1108,8 @@
<item quantity="one">ပြီးခဲ့သည့် <xliff:g id="COUNT_0">%d</xliff:g> မိနစ်က</item>
</plurals>
<plurals name="duration_hours_relative" formatted="false" msgid="420434788589102019">
- <item quantity="other">ပြီးခဲ့သည့် <xliff:g id="COUNT_1">%d</xliff:g> နာရီက</item>
- <item quantity="one">ပြီးခဲ့သည့် <xliff:g id="COUNT_0">%d</xliff:g> နာရီက</item>
+ <item quantity="other">ပြီးခဲ့သည့် <xliff:g id="COUNT_1">%d</xliff:g> နာရီ</item>
+ <item quantity="one">ပြီးခဲ့သည့် <xliff:g id="COUNT_0">%d</xliff:g> နာရီ</item>
</plurals>
<plurals name="duration_days_relative" formatted="false" msgid="6056425878237482431">
<item quantity="other">ပြီးခဲ့သည့် <xliff:g id="COUNT_1">%d</xliff:g> ရက်က</item>
@@ -1692,12 +1692,12 @@
<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_warning_description" msgid="291674995220940133">"အများသုံးစွဲနိုင်မှု လိုအပ်ချက်များအတွက် အထောက်အကူပြုသည့် အက်ပ်များအား အပြည့်အဝ ထိန်းချုပ်ခွင့်ပေးခြင်းသည် သင့်လျော်သော်လည်း အက်ပ်အများစုအတွက် မသင့်လျော်ပါ။"</string>
+ <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"ဖန်သားပြင်ကို ကြည့်ရှုထိန်းချုပ်ခြင်း"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"၎င်းသည် မျက်နှာပြင်ပေါ်ရှိ အကြောင်းအရာများအားလုံးကို ဖတ်နိုင်ပြီး အခြားအက်ပ်များအပေါ်တွင် ထိုအကြောင်းအရာကို ဖော်ပြနိုင်သည်။"</string>
- <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"လုပ်ဆောင်ချက်များကို ကြည့်ရှုလုပ်ဆောင်ပါ"</string>
+ <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"လုပ်ဆောင်ချက်များကို ကြည့်ရှုဆောင်ရွက်ခြင်း"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"၎င်းသည် အက်ပ်တစ်ခု သို့မဟုတ် အာရုံခံကိရိယာကို အသုံးပြု၍ သင့်ပြန်လှန်တုံ့ပြန်မှုများကို မှတ်သားနိုင်ပြီး သင့်ကိုယ်စား အက်ပ်များနှင့် ပြန်လှန်တုံ့ပြန်နိုင်သည်။"</string>
- <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"ခွင့်ပြု"</string>
+ <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"ခွင့်ပြုရန်"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"ပယ်ရန်"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"ဝန်ဆောင်မှုကို စတင်အသုံးပြုရန် တို့ပါ−"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"အများသုံးစွဲနိုင်မှု ခလုတ်ဖြင့် အသုံးပြုရန် ဝန်ဆောင်မှုများကို ရွေးပါ"</string>
@@ -1852,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"‘ဘက်ထရီ အားထိန်း’ က ‘မှောင်သည့် အပြင်အဆင်’ ကို ဖွင့်ပြီး နောက်ခံလုပ်ဆောင်ချက်၊ ပြသမှုဆိုင်ရာ အထူးပြုလုပ်ချက်အချို့နှင့် “Ok Google” ကဲ့သို့ ဝန်ဆောင်မှုများကို ကန့်သတ်သည် (သို့) ပိတ်သည်\n\n"<annotation id="url">"ပိုမိုလေ့လာရန်"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"‘ဘက်ထရီ အားထိန်း’ က ‘မှောင်သည့် အပြင်အဆင်’ ကို ဖွင့်ပြီး နောက်ခံလုပ်ဆောင်ချက်၊ ပြသမှုဆိုင်ရာ အထူးပြုလုပ်ချက်အချို့နှင့် “Ok Google” ကဲ့သို့ ဝန်ဆောင်မှုများကို ကန့်သတ်သည် (သို့) ပိတ်သည်။"</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>
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"ပိတ်ရန်"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>− <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"ဖုန်းကိုင်ရန်"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"ငြင်းပယ်ရန်"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"ဖုန်းချရန်"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"အဝင်ခေါ်ဆိုမှု"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"ဤအကြောင်းကြားချက်ကို \'အသံတိတ်ခြင်း\' သို့ ပြန်ချိန်ညှိထားသည်။ အကြံပြုချက်ပေးရန် တို့ပါ။"</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"ဤအကြောင်းကြားချက်ကို အဆင့်တိုးထားသည်။ အကြံပြုချက်ပေးရန် တို့ပါ။"</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"ဤအကြောင်းကြားချက်ကို အဆင့်လျှော့ထားသည်။ အကြံပြုချက်ပေးရန် တို့ပါ။"</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"အဆင့်မြင့် အကြောင်းကြားချက်များ စမ်းသုံးကြည့်ခြင်း"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"အကြံပြုထားသော လုပ်ဆောင်ချက်များ၊ ပြန်စာများ စသည်တို့ကို ဆက်လက်ရယူရန် အဆင့်မြင့် အကြောင်းကြားချက်များကို ဖွင့်ပါ။ ‘Android အလိုက်သင့် အကြောင်းကြားချက်များ’ ကို ပံ့ပိုးမထားတော့ပါ။"</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"ဖွင့်ရန်"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"ယခုမလုပ်ပါ"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ပိုမိုလေ့လာရန်"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"အဆင့်မြင့် အကြောင်းကြားချက်များသည် အဆက်အသွယ်အမည်နှင့် မက်ဆေ့ဂျ်များကဲ့သို့ ကိုယ်ရေးကိုယ်တာအချက်လက်များ အပါအဝင် အကြောင်းကြားချက် အကြောင်းအရာအားလုံးကို ဖတ်နိုင်သည်။ ဤဝန်ဆောင်မှုသည် အကြောင်းကြားချက်များကို ပယ်ခြင်း (သို့) ဖုန်းခေါ်ဆိုမှုများ ဖြေခြင်းကဲ့သို့ အကြောင်းကြားချက်များရှိ ခလုတ်များ နှိပ်ခြင်းကိုလည်း ပြုလုပ်နိုင်သည်။\n\nဤဝန်ဆောင်မှုသည် ‘ဦးစားပေးမုဒ်’ ကို ဖွင့်ခြင်း (သို့) ပိတ်ခြင်း ပြုလုပ်နိုင်ပြီး ဆက်စပ်နေသော ဆက်တင်များကိုလည်း ပြောင်းနိုင်သည်။"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ပုံမှန်မုဒ်အတွက် အချက်အလက်ပြသည့် အကြောင်းကြားချက်"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ပုံမှန်အားသွင်းမှုမပြုလုပ်မီ ဘက်ထရီကုန်သွားနိုင်သည်"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ဘက်ထရီသက်တမ်းကို တိုးမြှင့်ရန် \'ဘက်ထရီအားထိန်း\' စတင်ပြီးပါပြီ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index ec8d9d5..9c70fdf 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Oppdatert av administratoren din"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Slettet av administratoren din"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Batterisparing slår på mørkt tema og begrenser eller slår av bakgrunnsaktivitet, enkelte visuelle effekter og funksjoner, for eksempel «Hey Google»\n\n"<annotation id="url">"Finn ut mer"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Batterisparing slår på mørkt tema og begrenser eller slår av bakgrunnsaktivitet, enkelte visuelle effekter og funksjoner, for eksempel «Hey Google»."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Datasparing hindrer noen apper fra å sende og motta data i bakgrunnen, for å redusere dataforbruket. Aktive apper kan bruke data, men kanskje ikke så mye som ellers – for eksempel vises ikke bilder før du trykker på dem."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Vil du slå på Datasparing?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Slå på"</string>
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Lukk"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g><xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Svar"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Avvis"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Legg på"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Innkommende anrop"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Dette varselet ble nedgradert til lydløst. Trykk for å gi tilbakemelding."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Dette varselet ble rangert høyere. Trykk for å gi tilbakemelding."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Dette varselet ble rangert lavere. Trykk for å gi tilbakemelding."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Prøv forbedrede varsler"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"For å fortsette å få foreslåtte handlinger, svar med mer, slå på forbedrede varsler. Tilpassede Android-varsler støttes ikke lenger."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Slå på"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Ikke nå"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Finn ut mer"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Forbedrede varsler kan lese alt varselinnhold, inkludert personopplysninger som kontaktnavn og meldinger. Denne funksjonen kan også avvise varsler eller bruke knapper i varsler, for eksempel for å svare på telefonanrop.\n\nDenne funksjonen kan også slå prioriteringsmodus på eller av og endre relaterte innstillinger."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Varsel med informasjon om rutinemodus"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Batteriet kan gå tomt før den vanlige ladingen"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batterisparing er aktivert for å forlenge batterilevetiden"</string>
@@ -2269,7 +2263,7 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Nye forstørringsinnstillinger"</string>
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"Nye innstillinger for forstørring"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Nå kan du forstørre en del av skjermen"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Slå på i innstillingene"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Avvis"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 894edcf..ece2a53 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -71,7 +71,7 @@
<string name="RuacMmi" msgid="1876047385848991110">"नचाहिएका रिसउठ्दा कलहरूको अस्वीकार"</string>
<string name="CndMmi" msgid="185136449405618437">"कलिङ नम्बर प्रदान गर्ने"</string>
<string name="DndMmi" msgid="8797375819689129800">"बाधा नगर्नुहोस्"</string>
- <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"सीमति गर्न पूर्वनिर्धारित कलर ID, अर्को कल: सीमति गरिएको"</string>
+ <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"सीमति गर्न डिफल्ट कलर ID, अर्को कल: सीमति गरिएको"</string>
<string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"कलर ID पूर्वनिर्धारितको लागि रोकावट छ। अर्को कल: रोकावट छैन"</string>
<string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"कलर ID पूर्वनिर्धारितदेखि प्रतिबन्धित छैन। अर्को कल: प्रतिबन्धित छ"</string>
<string name="CLIRDefaultOffNextCallOff" msgid="2491576172356463443">"कलर ID पूर्वनिर्धारितको लागि रोकावट छैन। अर्को कल: रोकावट छैन"</string>
@@ -294,14 +294,13 @@
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"एप चलिरहेको छ"</string>
<string name="notification_channel_foreground_service" msgid="7102189948158885178">"एपहरूले ब्याट्री खपत गर्दै छन्"</string>
<string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"जुम इन गर्ने सुविधा"</string>
- <!-- no translation found for notification_channel_accessibility_security_policy (1727787021725251912) -->
- <skip />
+ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"सर्वसुलभतासम्बन्धी सेवाहरूको प्रयोग"</string>
<string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले ब्याट्री प्रयोग गर्दै छ"</string>
<string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> एपहरूले ब्याट्री प्रयोग गर्दै छन्"</string>
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"ब्याट्री र डेटाका प्रयोग सम्बन्धी विवरणहरूका लागि ट्याप गर्नुहोस्"</string>
<string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="8974401416068943888">"सुरक्षित मोड"</string>
- <string name="android_system_label" msgid="5974767339591067210">"एन्ड्रोइड प्रणाली"</string>
+ <string name="android_system_label" msgid="5974767339591067210">"Android सिस्टम"</string>
<string name="user_owner_label" msgid="8628726904184471211">"व्यक्तिगत प्रोफाइलमा बदल्नुहोस्"</string>
<string name="managed_profile_label" msgid="7316778766973512382">"कार्य प्रोफाइलमा बदल्नुहोस्"</string>
<string name="permgrouplab_contacts" msgid="4254143639307316920">"सम्पर्कहरू"</string>
@@ -320,10 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"आफ्नो शारीरिक क्रियाकलापको डेटामाथि पहुँच राख्नु"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"क्यामेरा"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"फोटो खिच्नुका साथै भिडियो रेकर्ड गर्नुहोस्"</string>
- <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
- <skip />
- <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
- <skip />
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"नजिकै रहेका डिभाइसहरू"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"नजिकै रहेका डिभाइसहरू फेला पार्ने तथा ती डिभाइसमा कनेक्ट गर्ने"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"कल लग"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"फोन कलको लग पढ्नुहोस् र लेख्नुहोस्"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"फोन"</string>
@@ -541,14 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"यो अनुमति दिइएमा एपले नजिकै रहेका ब्लुटुथ चल्ने डिभाइसहरू भेट्टाउन र ती यन्त्रहरूसँग कनेक्ट गर्न सक्छ"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"लिंक गरिएका ब्लुटुथ चल्ने यन्त्रहरूसँग कनेक्ट गर्ने"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"यो अनुमति दिइएमा एपले लिंक गरिएका ब्लुटुथ चल्ने यन्त्रहरूसँग कनेक्ट गर्न सक्छ"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"नजिकै रहेका ब्लुटुथ चल्ने डिभाइसमा विज्ञापन गर्ने"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"यो एपले नजिकै रहेका ब्लुटुथ चल्ने डिभाइसहरूमा विज्ञापन गर्न पाउँछ"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"नजिकै रहेका अल्ट्रा-वाइडब्यान्ड चल्ने डिभाइसहरूबिचको तुलनात्मक स्थान पत्ता लगाउने"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"यो एपलाई नजिकै रहेका अल्ट्रा-वाइडब्यान्ड चल्ने डिभाइसहरूबिचको तुलनात्मक स्थान पत्ता लगाउन दिनुहोस्"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"NFC भुक्तानी सेवासम्बन्धी रुचाइएको जानकारी"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"यसले एपलाई दर्ता गरिएका सहायता तथा मार्गको गन्तव्य जस्ता रुचाइएका NFC भुक्तानी सेवासम्बन्धी जानकारी प्राप्त गर्न दिन्छ।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"नजिक क्षेत्र संचार नियन्त्रणहरू"</string>
@@ -584,28 +577,21 @@
<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 (694598777291084823) -->
- <skip />
+ <string name="fingerprint_acquired_partial" msgid="694598777291084823">"फिंगरप्रिन्ट आंशिक रूपमा पत्ता लाग्यो"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"फिंगरप्रिन्ट प्रशोधन गर्न सकिएन। कृपया फेरि प्रयास गर्नुहोस्।"</string>
- <!-- no translation found for fingerprint_acquired_imager_dirty (5236744087471419479) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_fast (1254724478300787385) -->
- <skip />
+ <string name="fingerprint_acquired_imager_dirty" msgid="5236744087471419479">"सेन्सर सफा गर्नुहोस्"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1254724478300787385">"औँला धेरै छिटो सर्यो"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"औंला निकै सुस्त सारियो। कृपया फेरि प्रयास गर्नुहोस्।"</string>
- <!-- no translation found for fingerprint_acquired_already_enrolled (2285166003936206785) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_too_bright (3863560181670915607) -->
- <skip />
- <!-- no translation found for fingerprint_acquired_try_adjusting (3667006071003809364) -->
- <skip />
+ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"अर्को फिंगरप्रिन्ट प्रयोग गरी हेर्नुहोस्"</string>
+ <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ज्यादै उज्यालो छ"</string>
+ <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"सेन्सरमा सही तरिकाले औँला राखेर हेर्नुहोस्"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<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>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"औँठाछाप हार्डवेयर उपलब्ध छैन।"</string>
- <!-- no translation found for fingerprint_error_no_space (7285481581905967580) -->
- <skip />
+ <string name="fingerprint_error_no_space" msgid="7285481581905967580">"फिंगरप्रिन्ट सेटअप गर्न सकिएन"</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"फिंगरप्रिन्ट समय सकिएको छ। फेरि प्रयास गर्नुहोस्।"</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"फिंगरप्रिन्ट सञ्चालन रद्द गरियो।"</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"प्रयोगकर्ताले फिंगरप्रिन्टसम्बन्धी कारबाही रद्द गर्नुभयो।"</string>
@@ -723,7 +709,7 @@
<string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"DRM प्रमाणपत्रहरू प्रावधान र प्रयोग गर्ने निवेदनको अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै पनि आवश्यक पर्दैन।"</string>
<string name="permlab_handoverStatus" msgid="7620438488137057281">"Android Beam स्थानान्तरण अवस्था प्राप्त गर्नुहोस्"</string>
<string name="permdesc_handoverStatus" msgid="3842269451732571070">"यस आवेदनले वर्तमान Android Beam स्थानान्तरण बारेमा जानकारी प्राप्त गर्न अनुमति दिन्छ"</string>
- <string name="permlab_removeDrmCertificates" msgid="710576248717404416">"DRM प्रमाणपत्रहरू हटाउनुहोस्"</string>
+ <string name="permlab_removeDrmCertificates" msgid="710576248717404416">"DRM सर्टिफिकेट हटाउनुहोस्"</string>
<string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"DRM प्रमाणपत्रहरू हटाउन एपलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूको लागि कहिल्यै आवश्यकता पर्दैन।"</string>
<string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"वाहक मेसेजिङ सेवामा आबद्ध हुनुहोस्"</string>
<string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"धारकलाई वाहक मेसेजिङ सेवाको उच्च-स्तरको इन्टरफेसमा आबद्ध हुन अनुमति दिनुहोस्। सामान्य एपहरूको लागि कहिल्यै आवश्यकता पर्दैन।"</string>
@@ -930,10 +916,10 @@
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"तपाईंले आफ्नो अनलक शैली <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले कोर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> प्रयासहरू असफल भएपछि तपाईंलाई आफ्नो Google खाता मार्फत साइन इन गरेर आफ्नो Android टिभी यन्त्र अनलक गर्न अनुरोध गरिनेछ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डपछि फेरि प्रयास गर्नुहोस्।"</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"तपाईँले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले तपाईँको अनलक ढाँचालाई कोर्नु भएको छ। पछि <xliff:g id="NUMBER_1">%2$d</xliff:g> अरू धेरै असफल कोसिसहरूपछि, तपाईँलाई तपाईँको फोन Google साइन इन प्रयोग गरेर अनलक गर्नको लागि सोधिने छ। \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा पुनः प्रयास गर्नुहोस्।"</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"तपाईँले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक ट्याब्लेटलाई अनलक गर्नको लागि गलत तरिकाले कोशिस गर्नुभएको छ। <xliff:g id="NUMBER_1">%2$d</xliff:g> अरू धेरै असफल कोसिसहरूपछि, ट्याब्लेट फ्याट्रि पूर्वनिर्धारितमा रिसेट हुने छ र सबै प्रयोगकर्ता डेटा हराउने छन्।"</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"तपाईंले आफ्नो Android टिभी यन्त्र <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> प्रयासहरू असफल भएपछि तपाईंको Android टिभी यन्त्रलाई रिसेट गरेर पूर्वनिर्धारित फ्याक्ट्री सेटिङ लागू गरिने छ र प्रयोगकर्ताको सम्पूर्ण डेटा गुम्ने छ।"</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"तपाईंले आफ्नो Android टिभी यन्त्र <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> प्रयासहरू असफल भएपछि तपाईंको Android टिभी यन्त्रलाई रिसेट गरेर डिफल्ट फ्याक्ट्री सेटिङ लागू गरिने छ र प्रयोगकर्ताको सम्पूर्ण डेटा गुम्ने छ।"</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"तपाईंले गलत तरिकाले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक फोन अनलक गर्ने प्रयत्न गर्नुभयो। <xliff:g id="NUMBER_1">%2$d</xliff:g> बढी असफल प्रयत्नहरू पछि, फोन फ्याक्ट्रि पूर्वनिर्धारितमा रिसेट हुने छ र सबै प्रयोगकर्ता डेटा हराउने छन्।"</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"तपाईँले ट्यब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER">%d</xliff:g> पटक प्रयास गर्नु भएको छ। अब ट्याब्लेटलाई पूर्वनिर्धारित कार्यशालामा रिसेट गरिने छ।"</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"तपाईंले आफ्नो Android टिभी यन्त्र <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले अनलक गर्ने प्रयास गर्नुभएको छ। अब तपाईंको Android टिभी यन्त्रलाई रिसेट गरेर पूर्वनिर्धारित फ्याक्ट्री सेटिङ लागू गरिनेछ।"</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"तपाईँले ट्यब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER">%d</xliff:g> पटक प्रयास गर्नु भएको छ। अब ट्याब्लेटलाई डिफल्ट कार्यशालामा रिसेट गरिने छ।"</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"तपाईंले आफ्नो Android टिभी यन्त्र <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले अनलक गर्ने प्रयास गर्नुभएको छ। अब तपाईंको Android टिभी यन्त्रलाई रिसेट गरेर डिफल्ट फ्याक्ट्री सेटिङ लागू गरिनेछ।"</string>
<string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"तपाईंले गलत तरिकाले फोन <xliff:g id="NUMBER">%d</xliff:g> पटक अनलक गर्ने प्रयत्न गर्नुभयो। अब फोन फ्याक्ट्रि पूर्वनिर्धारितमा रिसेट हुने छ।"</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"<xliff:g id="NUMBER">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"ढाँचा बिर्सनु भयो?"</string>
@@ -1302,8 +1288,8 @@
<string name="volume_icon_description_incall" msgid="4491255105381227919">"कला मात्रा"</string>
<string name="volume_icon_description_media" msgid="4997633254078171233">"मिडियाको भोल्युम"</string>
<string name="volume_icon_description_notification" msgid="579091344110747279">"सूचना भोल्युम"</string>
- <string name="ringtone_default" msgid="9118299121288174597">"पूर्वनिर्धारित रिङटोन"</string>
- <string name="ringtone_default_with_actual" msgid="2709686194556159773">"पूर्वनिर्धारित (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+ <string name="ringtone_default" msgid="9118299121288174597">"डिफल्ट रिङटोन"</string>
+ <string name="ringtone_default_with_actual" msgid="2709686194556159773">"डिफल्ट (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="397111123930141876">"कुनै पनि होइन"</string>
<string name="ringtone_picker_title" msgid="667342618626068253">"रिङटोनहरू"</string>
<string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"अलार्मका आवाजहरू"</string>
@@ -1400,7 +1386,7 @@
<string name="share_remote_bugreport_action" msgid="7630880678785123682">"सेयर गर्नुहोस्"</string>
<string name="decline_remote_bugreport_action" msgid="4040894777519784346">"अस्वीकार गर्नुहोस्"</string>
<string name="select_input_method" msgid="3971267998568587025">"निवेश विधि छान्नुहोस्"</string>
- <string name="show_ime" msgid="6406112007347443383">"वास्तविक किबोर्ड सक्रिय हुँदा यसलाई स्क्रिनमा राख्नुहोस्"</string>
+ <string name="show_ime" msgid="6406112007347443383">"वास्तविक किबोर्ड सक्रिय हुँदा यसलाई स्क्रिनमा राखियोस्"</string>
<string name="hardware" msgid="1800597768237606953">"भर्चुअल किबोर्ड देखाउनुहोस्"</string>
<string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"फिजिकल किबोर्डलाई कन्फिगर गर्नुहोस्"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"भाषा र लेआउट चयन गर्न ट्याप गर्नुहोस्"</string>
@@ -1681,11 +1667,11 @@
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"तपाईँले गलत तरिकाले तपाईँको PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक टाइप गर्नु भएको छ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"तपाईँले तपाईँक पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत टाइप गर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"तपाईँले तपाईँको अनलक प्याटर्न गलत तरिकाले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक खिच्नु भएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"तपाईँले ट्याब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक कोसिस गर्नु भएको छ। <xliff:g id="NUMBER_1">%2$d</xliff:g> पछि थप असफल प्रयासहरू, ट्याब्लेट पूर्वनिर्धारित कार्यशालामा रिसेट गरिने छ र सबै प्रयोग डेटा हराउने छ।"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"तपाईंले आफ्नो Android टिभी यन्त्र <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> प्रयासहरू असफल भएपछि तपाईंको Android टिभी यन्त्रलाई रिसेट गरेर पूर्वनिर्धारित फ्याक्ट्री सेटिङ लागू गरिने छ र प्रयोगकर्ताको सम्पूर्ण डेटा गुम्ने छ।"</string>
- <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"तपाईँले गलतसँग फोनलाई अनलक गर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक कोसिस गर्नु भयो। <xliff:g id="NUMBER_1">%2$d</xliff:g> पछि थप असफल कोसिसहरू, फोनलाई पूर्वनिर्धारित कार्यशालामा रिसेट गरिने छ र सबै प्रयोग डेटा हराउने छ।"</string>
- <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"तपाईँले ट्यब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER">%d</xliff:g> पटक प्रयास गर्नु भएको छ। अब ट्याब्लेटलाई पूर्वनिर्धारित कार्यशालामा रिसेट गरिने छ।"</string>
- <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"तपाईंले आफ्नो Android टिभी यन्त्र <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले अनलक गर्ने प्रयास गर्नुभएको छ। अब तपाईंको Android टिभी यन्त्रलाई रिसेट गरेर पूर्वनिर्धारित फ्याक्ट्री सेटिङ लागू गरिनेछ।"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"तपाईँले ट्याब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक कोसिस गर्नु भएको छ। <xliff:g id="NUMBER_1">%2$d</xliff:g> पछि थप असफल प्रयासहरू, ट्याब्लेट डिफल्ट कार्यशालामा रिसेट गरिने छ र सबै प्रयोग डेटा हराउने छ।"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"तपाईंले आफ्नो Android टिभी यन्त्र <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> प्रयासहरू असफल भएपछि तपाईंको Android टिभी यन्त्रलाई रिसेट गरेर डिफल्ट फ्याक्ट्री सेटिङ लागू गरिने छ र प्रयोगकर्ताको सम्पूर्ण डेटा गुम्ने छ।"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"तपाईँले गलतसँग फोनलाई अनलक गर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक कोसिस गर्नु भयो। <xliff:g id="NUMBER_1">%2$d</xliff:g> पछि थप असफल कोसिसहरू, फोनलाई डिफल्ट कार्यशालामा रिसेट गरिने छ र सबै प्रयोग डेटा हराउने छ।"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"तपाईँले ट्यब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER">%d</xliff:g> पटक प्रयास गर्नु भएको छ। अब ट्याब्लेटलाई डिफल्ट कार्यशालामा रिसेट गरिने छ।"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"तपाईंले आफ्नो Android टिभी यन्त्र <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले अनलक गर्ने प्रयास गर्नुभएको छ। अब तपाईंको Android टिभी यन्त्रलाई रिसेट गरेर डिफल्ट फ्याक्ट्री सेटिङ लागू गरिनेछ।"</string>
<string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"तपाईंले गलत तरिकाले फोन <xliff:g id="NUMBER">%d</xliff:g> पटक अनलक गर्ने प्रयत्न गर्नुभयो। अब फोन फ्याक्ट्रि पूर्वनिर्धारितमा रिसेट हुने छ।"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"तपाईंले गलत तरिकाले आफ्नो अनलक प्याटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक कोर्नुभयो। <xliff:g id="NUMBER_1">%2$d</xliff:g> विफल प्रयत्नहरू पछि, तपाईंलाई आफ्नो ट्याब्लेट इमेल खाता प्रयोग गरेर अनलक गर्न सोधिने छ।\n\n फेरि प्रयास गर्नुहोस् <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डहरूमा।"</string>
<string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"तपाईंले आफ्नो अनलक शैली <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले कोर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> प्रयासहरू असफल भएपछि तपाईंलाई आफ्नो इमेल खाता प्रयोग गरेर आफ्नो Android टिभी यन्त्र अनलक गर्न अनुरोध गरिनेछ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डपछि फेरि प्रयास गर्नुहोस्।"</string>
@@ -1695,18 +1681,18 @@
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"सिफारिस तहभन्दा आवाज ठुलो गर्नुहुन्छ?\n\nलामो समय सम्म उच्च आवाजमा सुन्दा तपाईँको सुन्ने शक्तिलाई हानी गर्न सक्छ।"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"पहुँच सम्बन्धी सर्टकट प्रयोग गर्ने हो?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"यो सर्टकट सक्रिय हुँदा, ३ सेकेन्डसम्म दुवै भोल्युम बटन थिच्नुले पहुँचसम्बन्धी कुनै सुविधा सुरु गर्ने छ।"</string>
- <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"सर्वसुलभता कायम गर्ने सुविधाहरू प्रयोग गर्न सर्टकट अन गर्ने हो?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"केही सेकेन्डसम्म दुवै भोल्युम बटन थिचिराख्नुभयो भने पहुँचसम्बन्धी सुविधाहरू सक्रिय हुन्छ। यसले तपाईंको यन्त्रले काम गर्ने तरिका परिवर्तन गर्न सक्छ।\n\nहालका सुविधाहरू:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nतपाईं सेटिङ > पहुँचमा गएर चयन गरिएका सुविधाहरू परिवर्तन गर्न सक्नुहुन्छ।"</string>
+ <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"एक्सेसिबिलिटीसम्बन्धी सुविधा प्रयोग गर्न सर्टकट अन गर्ने हो?"</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"केही सेकेन्डसम्म दुवै भोल्युम की थिचिराख्नुभयो भने पहुँचसम्बन्धी सुविधाहरू सक्रिय हुन्छ। यसले तपाईंको यन्त्रले काम गर्ने तरिका परिवर्तन गर्न सक्छ।\n\nहालका सुविधाहरू:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nतपाईं सेटिङ > पहुँचमा गएर चयन गरिएका सुविधाहरू परिवर्तन गर्न सक्नुहुन्छ।"</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"<xliff:g id="SERVICE">%1$s</xliff:g> प्रयोग गर्न सर्टकट अन गर्ने हो?"</string>
- <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"केही सेकेन्डसम्म दुवै भोल्युम बटन थिचिराख्नुले <xliff:g id="SERVICE">%1$s</xliff:g> नामक पहुँचसम्बन्धी सुविधा सक्रिय गर्छ। यसले तपाईंको यन्त्रले काम गर्ने तरिका परिवर्तन गर्न सक्छ।\n\nतपाईं सेटिङ > पहुँचमा गई यो सर्टकटमार्फत अर्को सुविधा खुल्ने बनाउन सक्नुहुन्छ।"</string>
+ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"केही सेकेन्डसम्म दुवै भोल्युम की थिचिराख्नुले <xliff:g id="SERVICE">%1$s</xliff:g> नामक पहुँचसम्बन्धी सुविधा सक्रिय गर्छ। यसले तपाईंको यन्त्रले काम गर्ने तरिका परिवर्तन गर्न सक्छ।\n\nतपाईं सेटिङ > पहुँचमा गई यो सर्टकटमार्फत अर्को सुविधा खुल्ने बनाउन सक्नुहुन्छ।"</string>
<string name="accessibility_shortcut_on" msgid="5463618449556111344">"सक्रिय गरियोस्"</string>
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"सक्रिय नगरियोस्"</string>
<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_warning_description" msgid="291674995220940133">"एक्सेसिबिलिटीसम्बन्धी आवश्यकतामा सहयोग गर्ने एपको पूर्ण नियन्त्रण गर्नु उपयुक्त हुन्छ तर अधिकांश एपका हकमा यस्तो नियन्त्रण उपयुक्त हुँदैन।"</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"स्क्रिन हेर्नुहोस् र नियन्त्रण गर्नुहोस्"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"यसले स्क्रिनमा देखिने सबै सामग्री पढ्न सक्छ र अन्य एपहरूमा उक्त सामग्री देखाउन सक्छ।"</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"कारबाहीहरू हेर्नुहोस् र तिनमा कार्य गर्नुहोस्"</string>
@@ -1727,7 +1713,7 @@
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन भयो।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अफ भयो।"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> प्रयोग गर्न दुवै भोल्युम कुञ्जीहरूलाई तीन सेकेन्डसम्म थिचिराख्नुहोस्"</string>
- <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"तपाईंले पहुँचको बटन ट्याप गर्दा प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस्:"</string>
+ <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"तपाईंले एक्सेसिबिलिटी बटन ट्याप गर्दा प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस्:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"तपाईंले पहुँचको इसारामार्फत प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस् (दुईवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"तपाईंले पहुँचको इसारामार्फत प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस् (तीनवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
<string name="accessibility_button_instructional_text" msgid="8853928358872550500">"एउटा सुविधाबाट अर्को सुविधामा जान पहुँच बटन टच एण्ड होल्ड गर्नुहोस्।"</string>
@@ -1945,6 +1931,8 @@
<string name="close_button_text" msgid="10603510034455258">"बन्द गर्नुहोस्"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"कलको जवाफ दिनु…"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"अस्वीकार गर्नुहोस्"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"फोन राख्नुहोस्"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"आगमन कल"</string>
@@ -1963,7 +1951,7 @@
<string name="language_selection_title" msgid="52674936078683285">"भाषा थप्नुहोस्"</string>
<string name="country_selection_title" msgid="5221495687299014379">"क्षेत्रको प्राथमिकता"</string>
<string name="search_language_hint" msgid="7004225294308793583">"भाषाको नाम टाइप गर्नुहोस्"</string>
- <string name="language_picker_section_suggested" msgid="6556199184638990447">"सुझाव दिइयो"</string>
+ <string name="language_picker_section_suggested" msgid="6556199184638990447">"सिफारिस गरिएको"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"सम्पूर्ण भाषाहरू"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"सबै क्षेत्रहरू"</string>
<string name="locale_search_menu" msgid="6258090710176422934">"खोज"</string>
@@ -2084,7 +2072,7 @@
<string name="notification_appops_microphone_active" msgid="581333393214739332">"माइक्रोफोन"</string>
<string name="notification_appops_overlay_active" msgid="5571732753262836481">"तपाईंको स्क्रिनका अन्य एपहरूमा प्रदर्शन गरिँदै छ"</string>
<string name="notification_feedback_indicator" msgid="663476517711323016">"प्रतिक्रिया दिनुहोस्"</string>
- <string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"सिस्टमले स्वतः यस सूचनालाई महत्त्वपूर्ण ठानी यसका लागि पूर्वनिर्धारित मोड सेट गरिदिएको छ। प्रतिक्रिया दिन ट्याप गर्नुहोस्।"</string>
+ <string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"सिस्टमले स्वतः यस सूचनालाई महत्त्वपूर्ण ठानी यसका लागि डिफल्ट मोड सेट गरिदिएको छ। प्रतिक्रिया दिन ट्याप गर्नुहोस्।"</string>
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"यस सूचनालाई कम महत्त्वपूर्ण ठानी यसका लागि साइलेन्ट मोड सेट गरिएको छ। प्रतिक्रिया दिन ट्याप गर्नुहोस्।"</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"यस सूचनालाई धेरै महत्त्वपूर्ण सूचनाका रूपमा सेट गरिएको छ। प्रतिक्रिया दिन ट्याप गर्नुहोस्।"</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"यस सूचनालाई कम महत्त्वपूर्ण सूचनाका रूपमा सेट गरिएको छ। प्रतिक्रिया दिन ट्याप गर्नुहोस्।"</string>
@@ -2284,20 +2272,16 @@
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
<string name="window_magnification_prompt_title" msgid="2876703640772778215">"जुम इन गर्ने सुविधासम्बन्धी नयाँ सेटिङ"</string>
- <string name="window_magnification_prompt_content" msgid="8159173903032344891">"तपाईं अब स्क्रिनको जुनसुकै भाग जुम इन गर्न सक्नुहुन्छ"</string>
+ <string name="window_magnification_prompt_content" msgid="8159173903032344891">"तपाईं अब स्क्रिनको जुनसुकै भागमा जुम इन गर्न सक्नुहुन्छ"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"सेटिङमा गई यो सुविधा अन गर्नुहोस्"</string>
<string name="dismiss_action" msgid="1728820550388704784">"हटाउनुहोस्"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"डिभाइसको माइक्रोफोन अनब्लक गर्नुहोस्"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"डिभाइसको क्यामेरा अनब्लक गर्नुहोस्"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> का साथै सबै एप तथा सेवाहरूका लागि"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"अनब्लक गर्नुहोस्"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"सेन्सरसम्बन्धी गोपनीयता"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"एप जनाउने आइकन"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"एपको ब्रान्डिङ फोटो"</string>
- <string name="view_and_control_notification_title" msgid="4300765399209912240">"हेर्ने तथा नियन्त्रण गर्ने अनुमतिसम्बन्धी सेटिङ जाँच्नु…"</string>
- <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ले तपाईंको स्क्रिन हेर्न र नियन्त्रण गर्न सक्छ। समीक्षा गर्न ट्याप गर्नुहोस्।"</string>
+ <string name="view_and_control_notification_title" msgid="4300765399209912240">"हेराइ र नियन्त्रणसम्बन्धी सेटिङ जाँच्नुहोस्"</string>
+ <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> तपाईंको स्क्रिन हेर्न र नियन्त्रण गर्न सक्छ। सेटिङ मिलाउन ट्याप गर्नुहोस्।"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index a8e0c0e..0222f6f 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1108,8 +1108,8 @@
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> minuut geleden</item>
</plurals>
<plurals name="duration_hours_relative" formatted="false" msgid="420434788589102019">
- <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> uur geleden</item>
- <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> uur geleden</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> uur geleden, </item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> uur geleden, </item>
</plurals>
<plurals name="duration_days_relative" formatted="false" msgid="6056425878237482431">
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> dagen geleden</item>
@@ -1386,7 +1386,7 @@
<string name="share_remote_bugreport_action" msgid="7630880678785123682">"DELEN"</string>
<string name="decline_remote_bugreport_action" msgid="4040894777519784346">"WEIGEREN"</string>
<string name="select_input_method" msgid="3971267998568587025">"Invoermethode selecteren"</string>
- <string name="show_ime" msgid="6406112007347443383">"Op het scherm tonen terwijl het fysieke toetsenbord actief is"</string>
+ <string name="show_ime" msgid="6406112007347443383">"Toon op het scherm terwijl het fysieke toetsenbord actief is"</string>
<string name="hardware" msgid="1800597768237606953">"Virtueel toetsenbord tonen"</string>
<string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Fysiek toetsenbord instellen"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tik om een taal en indeling te selecteren"</string>
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Geüpdatet door je beheerder"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Verwijderd door je beheerder"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Batterijbesparing zet het donkere thema aan en beperkt achtergrondactiviteit, bepaalde visuele effecten en functies zoals Hey Google of zet dit uit\n\n"<annotation id="url">"Meer informatie"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Batterijbesparing zet het donkere thema aan en beperkt achtergrondactiviteit, bepaalde visuele effecten en functies zoals Hey Google of zet dit uit."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Databesparing beperkt het datagebruik door te voorkomen dat sommige apps gegevens sturen of ontvangen op de achtergrond. De apps die je open hebt, kunnen nog steeds data verbruiken, maar doen dit minder vaak. Afbeeldingen worden dan bijvoorbeeld niet weergegeven totdat je erop tikt."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Databesparing aanzetten?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Aanzetten"</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Sluiten"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Beantwoorden"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Weigeren"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Ophangen"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Inkomend gesprek"</string>
@@ -1946,9 +1945,9 @@
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Aangepaste app-melding"</string>
<string name="user_creation_account_exists" msgid="2239146360099708035">"Toestaan dat <xliff:g id="APP">%1$s</xliff:g> een nieuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> maakt (er is al een gebruiker met dit account)?"</string>
<string name="user_creation_adding" msgid="7305185499667958364">"Toestaan dat <xliff:g id="APP">%1$s</xliff:g> een nieuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> maakt?"</string>
- <string name="language_selection_title" msgid="52674936078683285">"Een taal toevoegen"</string>
+ <string name="language_selection_title" msgid="52674936078683285">"Taal toevoegen"</string>
<string name="country_selection_title" msgid="5221495687299014379">"Regiovoorkeur"</string>
- <string name="search_language_hint" msgid="7004225294308793583">"Typ een taalnaam"</string>
+ <string name="search_language_hint" msgid="7004225294308793583">"Typ de naam van een taal"</string>
<string name="language_picker_section_suggested" msgid="6556199184638990447">"Voorgesteld"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"Alle talen"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"Alle regio\'s"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Deze melding is verlaagd naar Stil. Tik om feedback te geven."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Deze melding is hoger geclassificeerd. Tik om feedback te geven."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Deze melding is lager geclassificeerd. Tik om feedback te geven."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Probeer verbeterde meldingen"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Activeer verbeterde meldingen om voorgestelde acties, antwoorden en meer te blijven ontvangen. Aanpasbare Android-meldingen worden niet meer ondersteund."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Aanzetten"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Niet nu"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Meer informatie"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Verbeterde meldingen kunnen alle meldingscontent lezen, waaronder persoonlijke informatie zoals contactnamen en berichten. Deze functie kan ook meldingen sluiten of acties uitvoeren voor knoppen in meldingen, zoals telefoongesprekken aannemen.\n\nDeze functie kan ook de prioriteitsmodus aan- of uitzetten en gerelateerde instellingen wijzigen."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Informatiemelding voor routinemodus"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"De batterij raakt mogelijk leeg voordat deze normaal gesproken wordt opgeladen"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batterijbesparing is geactiveerd om de batterijduur te verlengen"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 2536fa0..7948f64 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1160,7 +1160,7 @@
<string name="redo" msgid="7231448494008532233">"ପୁଣି କରନ୍ତୁ"</string>
<string name="autofill" msgid="511224882647795296">"ଅଟୋଫିଲ୍"</string>
<string name="textSelectionCABTitle" msgid="5151441579532476940">"ଟେକ୍ସଟ୍ ଚୟନ"</string>
- <string name="addToDictionary" msgid="8041821113480950096">"ଶବ୍ଦକୋଷରେ ଯୋଡ଼ନ୍ତୁ"</string>
+ <string name="addToDictionary" msgid="8041821113480950096">"ଶବ୍ଦକୋଷରେ ଯୋଗ କରନ୍ତୁ"</string>
<string name="deleteText" msgid="4200807474529938112">"ଡିଲିଟ୍ କରନ୍ତୁ"</string>
<string name="inputMethod" msgid="1784759500516314751">"ଇନପୁଟ୍ ପଦ୍ଧତି"</string>
<string name="editTextMenuTitle" msgid="857666911134482176">"ଟେକ୍ସଟ୍ କାର୍ଯ୍ୟ"</string>
@@ -1677,7 +1677,7 @@
<string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"ଆପଣ ଆପଣଙ୍କର ଅନଲକ୍ ପାଟର୍ନକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଆଙ୍କିଛନ୍ତି। <xliff:g id="NUMBER_1">%2$d</xliff:g> ଥର ଅସଫଳ ଚେଷ୍ଟା ପରେ, ଏକ ଇମେଲ୍ ଆକାଉଣ୍ଟ ବ୍ୟବହାର କରି ଆପଣଙ୍କର Android TV ଡିଭାଇସ୍କୁ ଅନ୍ଲକ୍ କରିବା ପାଇଁ କୁହାଯିବ। \n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> ସେକେଣ୍ଡ ମଧ୍ୟରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"ଆପଣଙ୍କ ଅନଲକ୍ ପାଟର୍ନକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଅଙ୍କନ କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ ପ୍ରୟାସ ପରେ ଏକ ଇମେଲ୍ ଆକାଉଣ୍ଟ ବ୍ୟବହାର କରି ନିଜ ଫୋନ୍କୁ ଅନଲକ୍ କରିବା ପାଇଁ କୁହାଯିବ।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
- <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"ବାହାର କରନ୍ତୁ"</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"କାଢ଼ି ଦିଅନ୍ତୁ"</string>
<string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ମାତ୍ରା ବଢ଼ାଇ ସୁପାରିଶ ସ୍ତର ବଢ଼ାଉଛନ୍ତି? \n\n ଲମ୍ବା ସମୟ ପର୍ଯ୍ୟନ୍ତ ଉଚ୍ଚ ଶବ୍ଦରେ ଶୁଣିଲେ ଆପଣଙ୍କ ଶ୍ରବଣ ଶକ୍ତି ଖରାପ ହୋଇପାରେ।"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ଆକ୍ସେସବିଲିଟି ଶର୍ଟକଟ୍ ବ୍ୟବହାର କରିବେ?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ସର୍ଟକଟ୍ ଚାଲୁ ଥିବା ବେଳେ, ଉଭୟ ଭଲ୍ୟୁମ୍ ବଟନ୍ 3 ସେକେଣ୍ଡ ପାଇଁ ଦବାଇବା ଦ୍ୱାରା ଏକ ଆକ୍ସେସବିଲିଟି ଫିଚର୍ ଆରମ୍ଭ ହେବ।"</string>
@@ -1852,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"ବ୍ୟାଟେରୀ ସେଭର୍ ଗାଢ଼ା ଥିମକୁ ଚାଲୁ କରେ ଏବଂ ପୃଷ୍ଠପଟ କାର୍ଯ୍ୟକଳାପ, କିଛି ଭିଜୁଆଲ୍ ଇଫେକ୍ଟ ଏବଂ “Hey Google” ପରି ଫିଚରଗୁଡ଼ିକୁ ସୀମିତ କିମ୍ବା ବନ୍ଦ କରେ\n\n"<annotation id="url">"ଅଧିକ ଜାଣନ୍ତୁ"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"ବ୍ୟାଟେରୀ ସେଭର୍ ଗାଢ଼ା ଥିମକୁ ଚାଲୁ କରେ ଏବଂ ପୃଷ୍ଠପଟ କାର୍ଯ୍ୟକଳାପ, କିଛି ଭିଜୁଆଲ୍ ଇଫେକ୍ଟ ଏବଂ “Hey Google” ପରି ଫିଚରଗୁଡ଼ିକୁ ସୀମିତ କିମ୍ବା ବନ୍ଦ କରେ।"</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>
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"ଉତ୍ତର ଦିଅନ୍ତୁ"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"ଅଗ୍ରାହ୍ୟ କର"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"ସମାପ୍ତ କରନ୍ତୁ"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"ଇନକମିଂ କଲ୍"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"ଏହି ବିଜ୍ଞପ୍ତିକୁ ନୀରବ ଭାବେ ଡିମୋଟ୍ କରାଯାଇଛି। ମତାମତ ପ୍ରଦାନ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"ଏହି ବିଜ୍ଞପ୍ତିର ରେଙ୍କ ଉପରକୁ କରାଯାଇଛି। ମତାମତ ପ୍ରଦାନ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"ଏହି ବିଜ୍ଞପ୍ତିର ରେଙ୍କ ତଳକୁ କରାଯାଇଛି। ମତାମତ ପ୍ରଦାନ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"ଉନ୍ନତ ବିଜ୍ଞପ୍ତି ବ୍ୟବହାରକରି ଦେଖ"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"ପ୍ରସ୍ତାବିତ କାର୍ଯ୍ୟ, ପ୍ରତ୍ୟୁତ୍ତର ଏବଂ ଆହୁରି ଅନେକ କିଛି ପାଇବା ଜାରି ରଖିବାକୁ, ଉନ୍ନତ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଚାଲୁ କରନ୍ତୁ। Android ଆଡେପ୍ଟିଭ୍ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଆଉ ସମର୍ଥିତ ନୁହେଁ।"</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"ଚାଲୁ କରନ୍ତୁ"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"ବର୍ତ୍ତମାନ ନୁହେଁ"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"ଉନ୍ନତ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଯୋଗାଯୋଗ ନାମ ଏବଂ ମେସେଜଗୁଡ଼ିକ ପରି ବ୍ୟକ୍ତିଗତ ସୂଚନା ସମେତ ସମସ୍ତ ବିଜ୍ଞପ୍ତି ବିଷୟବସ୍ତୁକୁ ପଢ଼ିପାରିବ। ଏହି ଫିଚର୍ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଖାରଜ କରିପାରିବ କିମ୍ବା ଫୋନ୍ କଲଗୁଡ଼ିକର ଉତ୍ତର ଦେବା ପରି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକରେ ଥିବା ବଟନଗୁଡ଼ିକ ଉପରେ ପଦକ୍ଷେପ ମଧ୍ୟ ନେଇପାରିବ।\n\nଏହି ଫିଚର୍ ପ୍ରାଥମିକତା ମୋଡକୁ ଚାଲୁ କିମ୍ବା ବନ୍ଦ କରିପାରିବ ଏବଂ ସମ୍ବନ୍ଧିତ ସେଟିଂସକୁ ପରିବର୍ତ୍ତନ ମଧ୍ୟ କରିପାରିବ।"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ନିୟମିତ ମୋଡ୍ ସୂଚନା ବିଜ୍ଞପ୍ତି"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ସାଧାରଣ ଭାବରେ ଚାର୍ଜ୍ କରିବା ପୂର୍ବରୁ ବ୍ୟାଟେରୀ ସରିଯାଇପାରେ"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ବ୍ୟାଟେରୀର ସମୟକୁ ବଢ଼ାଇବା ପାଇଁ ବ୍ୟଟେରୀ ସେଭର୍କୁ କାର୍ଯ୍ୟକାରୀ କରାଯାଇଛି"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index fc8a56b..ac5af41 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -319,10 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ਆਪਣੀ ਸਰੀਰਕ ਸਰਗਰਮੀ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"ਕੈਮਰਾ"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"ਤਸਵੀਰਾਂ ਲੈਣ ਅਤੇ ਵੀਡੀਓ ਰਿਕਾਰਡ ਕਰਨ"</string>
- <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
- <skip />
- <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
- <skip />
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸ"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸਾਂ ਨੂੰ ਖੋਜੋ ਅਤੇ ਉਹਨਾਂ ਨਾਲ ਕਨੈਕਟ ਕਰੋ"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"ਕਾਲ ਲੌਗ"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ਫ਼ੋਨ ਦੇ ਕਾਲ ਲੌਗ ਨੂੰ ਪੜ੍ਹੋ ਅਤੇ ਲਿਖੋ"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ਫ਼ੋਨ"</string>
@@ -540,14 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨੂੰ ਖੋਜਣ ਅਤੇ ਉਹਨਾਂ ਨਾਲ ਜੋੜਾਬੱਧ ਕਰਨ ਦਿੰਦੀ ਹੈ"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ਜੋੜਾਬੱਧ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਟ ਕਰੋ"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ਐਪਾਂ ਨੂੰ ਜੋੜਾਬੱਧ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਟ ਕਰਨ ਦਿੰਦੀ ਹੈ"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"ਨਜ਼ਦੀਕੀ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ \'ਤੇ ਵਿਗਿਆਪਨ ਦਿਓ"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ \'ਤੇ ਵਿਗਿਆਪਨ ਦੇਣ ਦੀ ਇਜਾਜ਼ਤ ਦਿੱਤੀ ਜਾਂਦੀ ਹੈ"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"ਨਜ਼ਦੀਕੀ ਅਲਟ੍ਰਾ-ਵਾਈਡਬੈਂਡ ਡੀਵਾਈਸਾਂ ਵਿਚਾਲੇ ਸੰਬੰਧਿਤ ਸਥਿਤੀ ਨਿਰਧਾਰਿਤ ਕਰੋ"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਅਲਟ੍ਰਾ-ਵਾਈਡਬੈਂਡ ਡੀਵਾਈਸਾਂ ਦੇ ਵਿਚਾਲੇ ਸੰਬੰਧਿਤ ਸਥਿਤੀ ਨੂੰ ਨਿਰਧਾਰਿਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ਤਰਜੀਹੀ NFC ਭੁਗਤਾਨਸ਼ੁਦਾ ਸੇਵਾ ਜਾਣਕਾਰੀ"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ਐਪ ਨੂੰ ਤਰਜੀਹੀ NFC ਭੁਗਤਾਨਸ਼ੁਦਾ ਸੇਵਾ ਜਾਣਕਾਰੀ ਪ੍ਰਾਪਤ ਕਰਨ ਦਿੰਦਾ ਹੈ ਜਿਵੇਂ ਕਿ ਰਜਿਸਟਰ ਕੀਤੇ ਸਾਧਨ ਅਤੇ ਮੰਜ਼ਿਲ ਰਸਤਾ।"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"ਨਜ਼ਦੀਕੀ ਖੇਤਰ ਸੰਚਾਰ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ"</string>
@@ -1700,7 +1694,7 @@
<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>
+ <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"ਇਹ ਸਕ੍ਰੀਨ \'ਤੇ ਸਾਰੀ ਸਮੱਗਰੀ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਸਮੱਗਰੀ ਨੂੰ ਦੂਜੀਆਂ ਐਪਾਂ ਦੇ ਉੱਪਰ ਦਿਖਾ ਸਕਦੀ ਹੈ।"</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"ਕਾਰਵਾਈਆਂ ਦੇਖੋ ਅਤੇ ਕਰੋ"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ਇਹ ਕਿਸੇ ਐਪ ਜਾਂ ਹਾਰਡਵੇਅਰ ਸੈਂਸਰ ਦੇ ਨਾਲ ਤੁਹਾਡੀਆਂ ਅੰਤਰਕਿਰਿਆਵਾਂ ਨੂੰ ਟਰੈਕ ਕਰ ਸਕਦੀ ਹੈ, ਅਤੇ ਤੁਹਾਡੀ ਤਰਫ਼ੋਂ ਐਪਾਂ ਦੇ ਨਾਲ ਅੰਤਰਕਿਰਿਆ ਕਰ ਸਕਦੀ ਹੈ।"</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"ਕਰਨ ਦਿਓ"</string>
@@ -1858,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"ਬੈਟਰੀ ਸੇਵਰ ਗੂੜ੍ਹੇ ਥੀਮ ਨੂੰ ਚਾਲੂ ਕਰਦਾ ਹੈ ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਸਰਗਰਮੀ, ਕੁਝ ਦ੍ਰਿਸ਼ਟੀਗਤ ਪ੍ਰਭਾਵਾਂ ਅਤੇ \"Ok Google\" ਵਰਗੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਸੀਮਤ ਕਰਦਾ ਹੈ ਜਾਂ ਬੰਦ ਕਰਦਾ ਹੈ\n\n"<annotation id="url">"ਹੋਰ ਜਾਣੋ"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"ਬੈਟਰੀ ਸੇਵਰ ਗੂੜ੍ਹੇ ਥੀਮ ਨੂੰ ਚਾਲੂ ਕਰਦਾ ਹੈ ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਸਰਗਰਮੀ, ਕੁਝ ਦ੍ਰਿਸ਼ਟੀਗਤ ਪ੍ਰਭਾਵਾਂ ਅਤੇ \"Ok Google\" ਵਰਗੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਸੀਮਤ ਕਰਦਾ ਹੈ ਜਾਂ ਬੰਦ ਕਰਦਾ ਹੈ।"</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>
@@ -1937,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"ਬੰਦ ਕਰੋ"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"ਜਵਾਬ ਦਿਓ"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"ਸਮਾਪਤ ਕਰੋ"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"ਇਨਕਮਿੰਗ ਕਾਲ"</string>
@@ -1954,7 +1948,7 @@
<string name="user_creation_adding" msgid="7305185499667958364">"ਕੀ <xliff:g id="APP">%1$s</xliff:g> ਨੂੰ <xliff:g id="ACCOUNT">%2$s</xliff:g> ਨਾਲ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣੀ ਹੈ?"</string>
<string name="language_selection_title" msgid="52674936078683285">"ਇੱਕ ਭਾਸ਼ਾ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="country_selection_title" msgid="5221495687299014379">"ਖੇਤਰ ਤਰਜੀਹ"</string>
- <string name="search_language_hint" msgid="7004225294308793583">"ਭਾਸ਼ਾ ਨਾਮ ਟਾਈਪ ਕਰੋ"</string>
+ <string name="search_language_hint" msgid="7004225294308793583">"ਭਾਸ਼ਾ ਦਾ ਨਾਮ ਟਾਈਪ ਕਰੋ"</string>
<string name="language_picker_section_suggested" msgid="6556199184638990447">"ਸੁਝਾਈਆਂ ਗਈਆਂ"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"ਸਾਰੀਆਂ ਭਾਸ਼ਾਵਾਂ"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"ਸਾਰੇ ਖੇਤਰ"</string>
@@ -2080,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"ਇਸ ਸੂਚਨਾ ਦਾ ਦਰਜਾ ਘਟਾ ਕੇ ਸ਼ਾਂਤ \'ਤੇ ਸੈੱਟ ਕੀਤਾ ਗਿਆ। ਵਿਚਾਰ ਮੁਹੱਈਆ ਕਰਵਾਉਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"ਇਸ ਸੂਚਨਾ ਦਾ ਦਰਜਾ ਵਧਾ ਦਿੱਤਾ ਗਿਆ। ਵਿਚਾਰ ਮੁਹੱਈਆ ਕਰਵਾਉਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"ਇਸ ਸੂਚਨਾ ਦਾ ਦਰਜਾ ਘਟਾ ਦਿੱਤਾ ਗਿਆ। ਵਿਚਾਰ ਮੁਹੱਈਆ ਕਰਵਾਉਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"ਵਿਸਤ੍ਰਿਤ ਸੂਚਨਾਵਾਂ ਅਜ਼ਮਾਓ"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"ਸੁਝਾਈਆਂ ਗਈਆਂ ਕਾਰਵਾਈਆਂ, ਜਵਾਬਾਂ ਅਤੇ ਹੋਰ ਬਹੁਤ ਕੁਝ ਨੂੰ ਪ੍ਰਾਪਤ ਕਰਦੇ ਰਹਿਣ ਲਈ, ਵਿਸਤ੍ਰਿਤ ਸੂਚਨਾਵਾਂ ਨੂੰ ਚਾਲੂ ਕਰੋ। Android ਅਡੈਪਟਿਵ ਸੂਚਨਾਵਾਂ ਹੁਣ ਸਮਰਥਿਤ ਨਹੀਂ ਹਨ।"</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"ਚਾਲੂ ਕਰੋ"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"ਹੁਣੇ ਨਹੀਂ"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ਹੋਰ ਜਾਣੋ"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"ਵਿਸਤ੍ਰਿਤ ਸੂਚਨਾਵਾਂ ਸਾਰੀ ਸੂਚਨਾ ਸਮੱਗਰੀ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀਆਂ ਹਨ, ਜਿਸ ਵਿੱਚ ਸੰਪਰਕ ਨਾਮ ਅਤੇ ਸੁਨੇਹੇ ਵਰਗੀ ਨਿੱਜੀ ਜਾਣਕਾਰੀ ਵੀ ਸ਼ਾਮਲ ਹੈ। ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਸੂਚਨਾਵਾਂ ਨੂੰ ਖਾਰਜ ਵੀ ਕਰ ਸਕਦੀ ਹੈ ਜਾਂ ਸੂਚਨਾਵਾਂ ਵਿੱਚ ਬਟਨਾਂ \'ਤੇ ਕਾਰਵਾਈਆਂ ਵੀ ਕਰ ਸਕਦੀ ਹੈ, ਜਿਵੇਂ ਕਿ ਫ਼ੋਨ ਕਾਲਾਂ ਦਾ ਜਵਾਬ ਦੇਣਾ।\n\nਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਤਰਜੀਹੀ ਮੋਡ ਨੂੰ ਚਾਲੂ ਜਾਂ ਬੰਦ ਵੀ ਕਰ ਸਕਦੀ ਹੈ ਅਤੇ ਸੰਬੰਧਿਤ ਸੈਟਿੰਗਾਂ ਨੂੰ ਬਦਲ ਸਕਦੀ ਹੈ।"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ਨਿਯਮਬੱਧ ਮੋਡ ਦੀ ਜਾਣਕਾਰੀ ਵਾਲੀ ਸੂਚਨਾ"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ਬੈਟਰੀ ਚਾਰਜ ਕਰਨ ਦੇ ਮਿੱਥੇ ਸਮੇਂ ਤੋਂ ਪਹਿਲਾਂ ਸ਼ਾਇਦ ਬੈਟਰੀ ਖਤਮ ਹੋ ਜਾਵੇ"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ਬੈਟਰੀ ਲਾਈਫ਼ ਵਧਾਉਣ ਲਈ ਬੈਟਰੀ ਸੇਵਰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
@@ -2276,17 +2264,13 @@
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
<string name="window_magnification_prompt_title" msgid="2876703640772778215">"ਨਵੀਆਂ ਵੱਡਦਰਸ਼ੀਕਰਨ ਸੈਟਿੰਗਾਂ"</string>
- <string name="window_magnification_prompt_content" msgid="8159173903032344891">"ਹੁਣ ਤੁਸੀਂ ਆਪਣੀ ਸਕ੍ਰੀਨ ਦਾ ਕੁਝ ਹਿੱਸਾ ਵੱਡਦਰਸ਼ੀ ਕਰ ਸਕਦੇ ਹੋ"</string>
+ <string name="window_magnification_prompt_content" msgid="8159173903032344891">"ਹੁਣ ਤੁਸੀਂ ਆਪਣੀ ਸਕ੍ਰੀਨ ਦਾ ਕੁਝ ਹਿੱਸਾ ਵੱਡਾ ਕਰ ਸਕਦੇ ਹੋ"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਚਾਲੂ ਕਰੋ"</string>
<string name="dismiss_action" msgid="1728820550388704784">"ਖਾਰਜ ਕਰੋ"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"ਡੀਵਾਈਸ ਦੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੂੰ ਅਣਬਲਾਕ ਕਰੋ"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"ਡੀਵਾਈਸ ਦੇ ਕੈਮਰੇ ਨੂੰ ਅਣਬਲਾਕ ਕਰੋ"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> ਅਤੇ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਲਈ"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"ਅਣਬਲਾਕ ਕਰੋ"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ਸੈਂਸਰ ਪਰਦੇਦਾਰੀ"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ਐਪਲੀਕੇਸ਼ਨ ਪ੍ਰਤੀਕ"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ਐਪਲੀਕੇਸ਼ਨ ਦਾ ਬ੍ਰਾਂਡ ਵਾਲਾ ਚਿੱਤਰ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 0d07cab..89279d4 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -544,10 +544,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Zezwala na wykrywanie i parowanie przez aplikację urządzeń Bluetooth w pobliżu"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"łączenie ze sparowanymi urządzeniami Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Zezwala na łączenie aplikacji ze sparowanymi urządzeniami Bluetooth"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"kierowanie informacji do urządzeń Bluetooth w pobliżu"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Zezwala na kierowanie przez aplikację informacji do urządzeń Bluetooth w pobliżu"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"określanie względnego położenia urządzeń ultraszerokopasmowych w pobliżu"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Zezwól na określanie przez aplikację względnego położenia urządzeń ultraszerokopasmowych w pobliżu"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacje o preferowanych usługach płatniczych NFC"</string>
@@ -1900,10 +1898,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Zaktualizowany przez administratora"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Usunięty przez administratora"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Oszczędzanie baterii uruchamia ciemny motyw oraz wyłącza lub ogranicza aktywność w tle, niektóre efekty wizualne i inne funkcje, np. „OK Google”\n\n"<annotation id="url">"Więcej informacji"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Oszczędzanie baterii uruchamia ciemny motyw oraz wyłącza lub ogranicza aktywność w tle, niektóre efekty wizualne i inne funkcje, np. „OK Google”."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Oszczędzanie danych uniemożliwia niektórym aplikacjom wysyłanie i odbieranie danych w tle, zmniejszając w ten sposób ich użycie. Aplikacja, z której w tej chwili korzystasz, może uzyskiwać dostęp do danych, ale rzadziej. Może to powodować, że obrazy będą się wyświetlać dopiero po kliknięciu."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Włączyć Oszczędzanie danych?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Włącz"</string>
@@ -1995,6 +1991,8 @@
<string name="close_button_text" msgid="10603510034455258">"Zamknij"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Odbierz"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Odrzuć"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Rozłącz"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Połączenie przychodzące"</string>
@@ -2142,18 +2140,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"To powiadomienie zostało zmienione na Ciche. Kliknij, by przesłać opinię."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Podniesiono ważność tego powiadomienia. Kliknij, by przesłać opinię."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Obniżono ważność tego powiadomienia. Kliknij, by przesłać opinię."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Wypróbuj ulepszone powiadomienia"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Aby nadal otrzymywać sugestie działań oraz odpowiedzi i inne podpowiedzi, włącz ulepszone powiadomienia. Powiadomienia adaptacyjne w Androidzie nie są już obsługiwane."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Włącz"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Nie teraz"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Więcej informacji"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Ulepszone powiadomienia mogą czytać wszystkie powiadomienia, w tym dane osobowe takie jak nazwy kontaktów i treść wiadomości. Funkcja będzie też mogła odrzucać powiadomienia oraz używać zawartych w nich przycisków, np. odbierać połączenia telefoniczne.\n\nMoże również włączać i wyłączać tryb Priorytet oraz zmieniać powiązane ustawienia."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Powiadomienie z informacją o trybie rutynowym"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Bateria może się wyczerpać przed zwykłą porą ładowania"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Włączono Oszczędzanie baterii, by wydłużyć czas pracy na baterii"</string>
@@ -2343,14 +2335,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Możesz teraz powiększyć część ekranu"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Włącz w Ustawieniach"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Odrzuć"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Odblokuj mikrofon urządzenia"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Odblokuj aparat urządzenia"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Dla aplikacji „<xliff:g id="APP">%s</xliff:g>” i wszystkich aplikacji oraz usług"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Odblokuj"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Poufność danych z czujników"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona aplikacji"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Wizerunek marki aplikacji"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 69da283..102073e 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Atualizado pelo seu administrador"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Excluído pelo seu administrador"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"A Economia de bateria ativa o tema escuro e limita ou desativa as atividades em segundo plano, alguns efeitos visuais e recursos como o \"Ok Google\"\n\n"<annotation id="url">"Saiba mais"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"A Economia de bateria ativa o tema escuro e limita ou desativa as atividades em segundo plano, alguns efeitos visuais e recursos como o \"Ok Google\"."</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 \"Economia de dados\"?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Ativar"</string>
@@ -1903,7 +1901,7 @@
<string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Durante a semana à noite"</string>
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fim de semana"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string>
- <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Dormindo"</string>
+ <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Dormir"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está silenciando alguns sons"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Há um problema interno com seu dispositivo. Ele pode ficar instável até que você faça a redefinição para configuração original."</string>
<string name="system_error_manufacturer" msgid="703545241070116315">"Há um problema interno com seu dispositivo. Entre em contato com o fabricante para saber mais detalhes."</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Fechar"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Atender"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Vídeo"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Recusar"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Desligar"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Chamada recebida"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Esta notificação foi rebaixada a Silenciosa. Toque para enviar seu feedback."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Esta notificação foi classificada com maior prioridade. Toque para enviar seu feedback."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Esta notificação foi classificada com menor prioridade. Toque para enviar seu feedback."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Testar notif. aprimoradas"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Para continuar a receber sugestões de ações, respostas e muito mais, ative as notificações aprimoradas. As Notificações adaptáveis do Android não estão mais disponíveis."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Ativar"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Agora não"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saiba mais"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"As notificações aprimoradas podem ler todo o conteúdo das notificações, incluindo informações pessoais como nomes de contatos e mensagens. Além disso, esse recurso pode dispensar notificações e usar os botões delas para, por exemplo, atender chamadas telefônicas.\n\nEle também pode ativar ou desativar o modo Prioridade e mudar as configurações relacionadas."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificação de informação do modo rotina"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"A bateria pode acabar antes da recarga normal"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"A Economia de bateria foi ativada para aumentar a duração da carga"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 04e282f..019107a 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -538,8 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que a app descubra e sincronize com dispositivos Bluetooth próximos"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"ligar-se a dispositivos Bluetooth sincronizados"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que a app se ligue a dispositivos Bluetooth sincronizados"</string>
- <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"mostrar anúncios a dispositivos Bluetooth próximos"</string>
- <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que a app apresente anúncios a dispositivos Bluetooth próximos"</string>
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"transmitir para dispositivos Bluetooth próximos"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que a app transmita para dispositivos Bluetooth próximos"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"determinar posição relativa dispos. de banda ultralarga próximos"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permita que a app determine a posição relativa entre os dispositivos de banda ultralarga próximos"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações de serviços de pagamento com NFC preferenciais"</string>
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Atualizado pelo seu gestor"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminado pelo seu gestor"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"A Poupança de bateria ativa o tema escuro e limita ou desativa a atividade em segundo plano, alguns efeitos visuais e funcionalidades como \"Ok Google\".\n\n"<annotation id="url">"Saiba mais"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"A Poupança de bateria ativa o tema escuro e limita ou desativa a atividade em segundo plano, alguns efeitos visuais e funcionalidades como \"Ok Google\"."</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 aplicações 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">"Pretende ativar a Poupança de dados?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Ativar"</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Fechar"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Atender"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Vídeo"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Recusar"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Desligar"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Chamada recebida"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Esta notificação foi despromovida para Silenciosa. Toque para fornecer feedback."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Esta notificação passou para uma classificação superior. Toque para fornecer feedback."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Esta notificação passou para uma classificação inferior. Toque para fornecer feedback."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Experimente as not. melhoradas"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Para continuar a obter sugestões de ações, respostas e muito mais, ative as notificações melhoradas. As notificações adaptáveis do Android já não são suportadas."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Ativar"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Agora não"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saber mais"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"As notificações melhoradas podem ler todo o conteúdo das notificações, incluindo informações pessoais como nomes de contactos e mensagens. Esta funcionalidade também pode ignorar notificações ou acionar botões em notificações, como atender chamadas telefónicas.\n\nAlém disso, esta funcionalidades pode ativar ou desativar o modo Prioridade e alterar as definições relacionadas."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificação de informações do Modo rotina"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Pode ficar sem bateria antes do carregamento habitual"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Poupança de bateria ativada para prolongar a duração da bateria"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 69da283..102073e 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Atualizado pelo seu administrador"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Excluído pelo seu administrador"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"A Economia de bateria ativa o tema escuro e limita ou desativa as atividades em segundo plano, alguns efeitos visuais e recursos como o \"Ok Google\"\n\n"<annotation id="url">"Saiba mais"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"A Economia de bateria ativa o tema escuro e limita ou desativa as atividades em segundo plano, alguns efeitos visuais e recursos como o \"Ok Google\"."</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 \"Economia de dados\"?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Ativar"</string>
@@ -1903,7 +1901,7 @@
<string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Durante a semana à noite"</string>
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fim de semana"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string>
- <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Dormindo"</string>
+ <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Dormir"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está silenciando alguns sons"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Há um problema interno com seu dispositivo. Ele pode ficar instável até que você faça a redefinição para configuração original."</string>
<string name="system_error_manufacturer" msgid="703545241070116315">"Há um problema interno com seu dispositivo. Entre em contato com o fabricante para saber mais detalhes."</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Fechar"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Atender"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Vídeo"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Recusar"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Desligar"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Chamada recebida"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Esta notificação foi rebaixada a Silenciosa. Toque para enviar seu feedback."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Esta notificação foi classificada com maior prioridade. Toque para enviar seu feedback."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Esta notificação foi classificada com menor prioridade. Toque para enviar seu feedback."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Testar notif. aprimoradas"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Para continuar a receber sugestões de ações, respostas e muito mais, ative as notificações aprimoradas. As Notificações adaptáveis do Android não estão mais disponíveis."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Ativar"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Agora não"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saiba mais"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"As notificações aprimoradas podem ler todo o conteúdo das notificações, incluindo informações pessoais como nomes de contatos e mensagens. Além disso, esse recurso pode dispensar notificações e usar os botões delas para, por exemplo, atender chamadas telefônicas.\n\nEle também pode ativar ou desativar o modo Prioridade e mudar as configurações relacionadas."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificação de informação do modo rotina"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"A bateria pode acabar antes da recarga normal"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"A Economia de bateria foi ativada para aumentar a duração da carga"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 8c145bf2..d54829a 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -541,10 +541,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite aplicației să descopere și să asocieze dispozitive Bluetooth din apropiere"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"să se conecteze la dispozitive Bluetooth asociate"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite aplicației să se conecteze la dispozitive Bluetooth asociate"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"să difuzeze anunțuri pe dispozitive Bluetooth din apropiere"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite aplicației să difuzeze anunțuri pe dispozitive Bluetooth din apropiere"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"să stabilească poziția relativă dintre dispozitivele Ultra-Wideband din apropiere"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permiteți-i aplicației să stabilească poziția relativă dintre dispozitivele Ultra-Wideband din apropiere"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informații despre serviciul de plăți NFC preferat"</string>
@@ -1877,10 +1875,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Actualizat de administratorul dvs."</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Șters de administratorul dvs."</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Economisirea bateriei activează Tema întunecată și limitează sau dezactivează activitatea din fundal, anumite efecte vizuale și funcții precum „Ok Google”\n\n"<annotation id="url">"Aflați mai multe"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Economisirea bateriei activează Tema întunecată și limitează sau dezactivează activitatea din fundal, anumite efecte vizuale și funcții precum „Ok Google”."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Pentru a contribui la reducerea utilizării de date, Economizorul de date împiedică unele aplicații să trimită sau să primească date în fundal. O aplicație pe care o folosiți poate accesa datele, însă mai rar. Aceasta poate însemna, de exemplu, că imaginile se afișează numai după ce le atingeți."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Activați Economizorul de date?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Activați"</string>
@@ -1964,6 +1960,8 @@
<string name="close_button_text" msgid="10603510034455258">"Închideți"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Răspundeți"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Respingeți"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Încheiați"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Apel primit"</string>
@@ -2109,18 +2107,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Notificarea a fost mutată în jos la Silențioasă. Atingeți pentru a oferi feedback."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Notificarea a fost mutată la un nivel superior. Atingeți pentru a oferi feedback."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Notificarea a fost mutată la un nivel inferior. Atingeți pentru a oferi feedback."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Încercați notificările optimizate"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Ca să primiți în continuare acțiuni sugerate, răspunsuri și altele, activați notificările optimizate. Notificările adaptive Android nu mai sunt acceptate."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Activați"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Nu acum"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Aflați mai multe"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Notificările optimizate pot citi tot conținutul notificărilor, inclusiv informații cu caracter personal, precum mesajele și numele persoanelor de contact. În plus, funcția poate să închidă notificări sau să acționeze asupra butoanelor din notificări, inclusiv să răspundă la apeluri telefonice.\n\nÎn plus, funcția poate să activeze sau să dezactiveze modul Cu prioritate și să schimbe setările asociate."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificare pentru informații despre modul Rutină"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Bateria se poate descărca înainte de încărcarea obișnuită"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Economisirea bateriei este activată pentru a prelungi durata de funcționare a bateriei"</string>
@@ -2309,14 +2301,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Acum puteți mări o parte a ecranului"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Activați din Setări"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Respingeți"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Deblocați microfonul dispozitivului"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Deblocați camera dispozitivului"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Pentru <b><xliff:g id="APP">%s</xliff:g></b> și toate aplicațiile și serviciile"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Deblocați"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Confidențialitatea privind senzorii"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Pictograma aplicației"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imaginea de branding a aplicației"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 4612662..76b3991 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1350,7 +1350,7 @@
<string name="network_switch_metered_detail" msgid="1358296010128405906">"Устройство использует <xliff:g id="NEW_NETWORK">%1$s</xliff:g>, если подключение к сети <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> недоступно. Может взиматься плата за передачу данных."</string>
<string name="network_switch_metered_toast" msgid="501662047275723743">"Устройство отключено от сети <xliff:g id="NEW_NETWORK">%2$s</xliff:g> и теперь использует <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>"</string>
<string-array name="network_switch_type_name">
- <item msgid="2255670471736226365">"мобильный Интернет"</item>
+ <item msgid="2255670471736226365">"мобильный интернет"</item>
<item msgid="5520925862115353992">"Wi-Fi"</item>
<item msgid="1055487873974272842">"Bluetooth"</item>
<item msgid="1616528372438698248">"Ethernet"</item>
@@ -1426,7 +1426,7 @@
<string name="share_remote_bugreport_action" msgid="7630880678785123682">"ПРЕДОСТАВИТЬ ДОСТУП"</string>
<string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ОТКЛОНИТЬ"</string>
<string name="select_input_method" msgid="3971267998568587025">"Выберите способ ввода"</string>
- <string name="show_ime" msgid="6406112007347443383">"Показывать на экране, когда физическая клавиатура включена"</string>
+ <string name="show_ime" msgid="6406112007347443383">"Не скрывать экранную клавиатуру, когда включена физическая"</string>
<string name="hardware" msgid="1800597768237606953">"Виртуальная клавиатура"</string>
<string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Настройка физической клавиатуры"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Нажмите, чтобы выбрать язык и раскладку"</string>
@@ -1898,10 +1898,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"В режиме энергосбережения включается тёмная тема. Кроме того, отключаются или ограничиваются фоновые процессы, некоторые визуальные эффекты и различные функции, например распознавание команды \"Окей, Google\".\n\n"<annotation id="url">"Подробнее…"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"В режиме энергосбережения включается тёмная тема. Кроме того, отключаются или ограничиваются фоновые процессы, некоторые визуальные эффекты и различные функции, например распознавание команды \"Окей, Google\"."</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>
@@ -1993,6 +1991,7 @@
<string name="close_button_text" msgid="10603510034455258">"Закрыть"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Ответить"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Видео"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Отклонить"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Завершить"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Входящий вызов"</string>
@@ -2010,9 +2009,9 @@
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Уведомление пользовательского приложения"</string>
<string name="user_creation_account_exists" msgid="2239146360099708035">"Разрешить приложению \"<xliff:g id="APP">%1$s</xliff:g>\" создать нового пользователя с аккаунтом <xliff:g id="ACCOUNT">%2$s</xliff:g> (пользователь с этим аккаунтом уже существует)?"</string>
<string name="user_creation_adding" msgid="7305185499667958364">"Разрешить приложению \"<xliff:g id="APP">%1$s</xliff:g>\" создать нового пользователя с аккаунтом <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
- <string name="language_selection_title" msgid="52674936078683285">"Добавьте язык"</string>
+ <string name="language_selection_title" msgid="52674936078683285">"Добавить язык"</string>
<string name="country_selection_title" msgid="5221495687299014379">"Региональные настройки"</string>
- <string name="search_language_hint" msgid="7004225294308793583">"Введите язык"</string>
+ <string name="search_language_hint" msgid="7004225294308793583">"Введите название языка"</string>
<string name="language_picker_section_suggested" msgid="6556199184638990447">"Рекомендуемые"</string>
<string name="language_picker_section_all" msgid="1985809075777564284">"Все языки"</string>
<string name="region_picker_section_all" msgid="756441309928774155">"Все регионы"</string>
@@ -2140,18 +2139,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Уровень важности этого уведомления был понижен до \"Без звука\". Нажмите, чтобы отправить отзыв."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Уровень важности этого уведомления был повышен. Нажмите, чтобы отправить отзыв."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Уровень важности этого уведомления был понижен. Нажмите, чтобы отправить отзыв."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Улучшенные уведомления"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Чтобы по-прежнему пользоваться рекомендуемыми действиями, ответами и другими подсказками, включите улучшенные уведомления. Адаптивные уведомления для Android больше не поддерживаются."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Включить"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Не сейчас"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Подробнее"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Улучшенным уведомлениям доступно содержимое всех уведомлений, в том числе личная информация, такая как имена контактов и сообщения. У этой функции также есть право закрывать уведомления и нажимать кнопки в них, например отвечать на звонки.\n\nКроме того, улучшенные уведомления могут включать и отключать режим \"Только важные\" и изменять связанные с ним настройки."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Уведомление о батарее"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея может разрядиться"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Чтобы увеличить время работы от батареи, был включен режим энергосбережения."</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 5523d8f..c0577d6 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1852,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"බැටරි සුරැකුම අඳුරු තේමාව ක්රියාත්මක කර පසුබිම් ක්රියාකාරකම්, සමහර දෘශ්ය ප්රයෝග සහ “Hey Google” වැනි විශේෂාංග සීමා කරයි\n\n"<annotation id="url">"තව දැන ගන්න"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"බැටරි සුරැකුම අඳුරු තේමාව ක්රියාත්මක කර පසුබිම් ක්රියාකාරකම්, සමහර දෘශ්ය ප්රයෝග සහ “Hey Google” වැනි විශේෂාංග සීමා කරයි."</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>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"වසන්න"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"පිළිතුරු දෙ."</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"වීඩියෝ"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"ප්රතික්ෂේප ක"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"විසන්ධි කරන්න"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"එන ඇමතුම"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"මෙම දැනුම්දීම නිහඬ වෙත පහත දමන ලදී. ප්රතිපෝෂණය ලබා දීමට තට්ටු කරන්න."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"මෙම දැනුම්දීම ඉහළට ශ්රේණිගත කරන ලදී. ප්රතිපෝෂණය ලබා දීමට තට්ටු කරන්න."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"මෙම දැනුම්දීම පහළට ශ්රේණිගත කරන ලදී. ප්රතිපෝෂණය ලබා දීමට තට්ටු කරන්න."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"දියුණු කළ දැනුම්දීම් උත්සාහ ක."</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"යෝජිත ක්රියා, පිළිතුරු සහ තවත් දේ ලබා ගැනීම සඳහා, වැඩි දියුණු කළ දැනුම්දීම් ක්රියාත්මක කරන්න. Android අනුවර්තී දැනුම්දීම් තවදුරටත් සහාය නොදක්වයි."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"ක්රියාත්මක කරන්න"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"දැන් නොවේ"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"තව දැන ගන්න"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"වැඩිදියුණු කළ දැනුම්දීම්වලට සම්බන්ධතා නම් සහ පණිවිඩ වැනි පුද්ගලික තොරතුරු ඇතුළුව, සියලු දැනුම්දීම් අන්තර්ගතය කියවිය හැකිය. මෙම විශේෂාංගයට දැනුම්දීම් ඉවත දැමීමට හෝ දුරකථන ඇමතුම්වලට පිළිතුරු දීම වැනි, දැනුම්දීම්වල බොත්තම් මත ක්රියා සිදු කිරීමටද හැකිය.\n\nමෙම විශේෂාංගයට ප්රමුඛතා ප්රකාරය ක්රියාත්මක හෝ ක්රියාවිරහිත කිරීමට සහ අදාළ සැකසීම් වෙනස් කිරීමටද හැකිය."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"දිනචරියා ප්රකාර තතු දැනුම්දීම"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"බැටරිය සුපුරුදු ආරෝපණයට පෙර ඉවර විය හැක"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"බැටරි සුරැකුම බැටරි ආයු කාලය දීර්ඝ කිරීමට සක්රිය කෙරිණි"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index b2ee98a..806e5a0 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1898,10 +1898,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Aktualizoval správca"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Odstránil správca"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Šetrič batérie zapne tmavý motív a obmedzí alebo vypne aktivitu na pozadí, niektoré vizuálne efekty a funkcie, napríklad „Hey Google“\n\n"<annotation id="url">"Ďalšie informácie"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Šetrič batérie zapne tmavý motív a obmedzí alebo vypne aktivitu na pozadí, niektoré vizuálne efekty a funkcie, napríklad „Hey Google“."</string>
<string name="data_saver_description" msgid="4995164271550590517">"S cieľom znížiť spotrebu dát bráni šetrič dát niektorým aplikáciám odosielať alebo prijímať dáta na pozadí. Aplikácia, ktorú práve používate, môže využívať dáta, ale možno to bude robiť menej často. Môže to napríklad znamenať, že sa obrázky zobrazia, až keď na ne klepnete."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Chcete zapnúť šetrič dát?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Zapnúť"</string>
@@ -1993,6 +1991,7 @@
<string name="close_button_text" msgid="10603510034455258">"Zavrieť"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Prijať"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Odmietnuť"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Zložiť"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Prichádzajúci hovor"</string>
@@ -2140,18 +2139,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Toto upozornenie bolo znížené na Tiché. Klepnutím nám poskytnite spätnú väzbu."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Toto upozornenie bolo preradené vyššie. Klepnutím nám poskytnite spätnú väzbu."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Toto upozornenie bolo preradené nižšie. Klepnutím nám poskytnite spätnú väzbu."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Skúste zlepšené upozornenia"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Ak chcete ďalej dostávať navrhované akcie, odpovede a ďalší obsah, zapnite zlepšené upozornenia. Adaptívne upozornenia Androidu už nie sú podporované."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Zapnúť"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Teraz nie"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Ďalšie informácie"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Zlepšené upozornenia môžu čítať všetok obsah upozornení vrátane osobných údajov, ako sú mená kontaktov a správy. Táto funkcia tiež môže rušiť upozornenia alebo aktivovať tlačidlá v upozorneniach, napríklad na prijatie telefonických hovorov.\n\nTáto funkcia môže tiež zapnúť alebo vypnúť režim priority a zmeniť súvisiace nastavenia."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Upozornenie s informáciami o rutinnom režime"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Batéria sa môže vybiť pred obvyklým nabitím"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Bol aktivovaný šetrič batérie na predĺženie výdrže batérie"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index d62aee7..b5a73ee 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -544,8 +544,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Aplikaciji omogoča odkrivanje naprav Bluetooth v bližini in seznanjanje z njimi."</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"povezovanje s seznanjenimi napravami Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Aplikaciji omogoča povezovanje s seznanjenimi napravami Bluetooth."</string>
- <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"oglaševanje v napravah Bluetooth v bližini"</string>
- <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Aplikaciji dovoljuje oglaševanje v napravah Bluetooth v bližini."</string>
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"oddajanje napravam Bluetooth v bližini"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Aplikaciji dovoljuje oddajanje napravam Bluetooth v bližini."</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"določanje relativne oddaljenosti med napravami UWB v bližini"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Aplikaciji dovoli, da določi relativno oddaljenost med napravami UWB v bližini."</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Podatki o prednostni storitvi za plačevanje prek povezave NFC"</string>
@@ -1898,10 +1898,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Posodobil skrbnik"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisal skrbnik"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"V redu"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Varčevanje z energijo baterije vklopi temno temo in omeji ali izklopi dejavnost v ozadju, nekatere vizualne učinke in druge funkcije, kot je »Hey Google«.\n\n"<annotation id="url">"Več o tem"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Varčevanje z energijo baterije vklopi temno temo in omeji ali izklopi dejavnost v ozadju, nekatere vizualne učinke in druge funkcije, kot je »Hey Google«."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Zaradi zmanjševanja prenesene količine podatkov funkcija varčevanja s podatki nekaterim aplikacijam preprečuje, da bi v ozadju pošiljale ali prejemale podatke. Aplikacija, ki jo trenutno uporabljate, lahko prenaša podatke, vendar to morda počne manj pogosto. To na primer pomeni, da se slike ne prikažejo, dokler se jih ne dotaknete."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Vklop varčevanja s podatki?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Vklop"</string>
@@ -1993,6 +1991,8 @@
<string name="close_button_text" msgid="10603510034455258">"Zapri"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Sprejmi"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Zavrni"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Prekini klic"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Dohodni klic"</string>
@@ -2140,18 +2140,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"To obvestilo je bilo uvrščeno nižje – med obvestila brez zvoka. Dotaknite se, če želite poslati povratne informacije."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"To obvestilo je bilo uvrščeno višje. Dotaknite se, če želite poslati povratne informacije."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"To obvestilo je bilo uvrščeno nižje. Dotaknite se, če želite poslati povratne informacije."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Preizkusite pametna obvestila"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Če želite še naprej prejemati predlagana dejanja, odgovore in drugo, vklopite pametna obvestila. Prilagodljiva obvestila Android niso več podprta."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Vklopi"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Ne zdaj"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Več o tem"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Pametna obvestila lahko preberejo vso vsebino obvestil, vključno z osebnimi podatki, kot so imena in sporočila stikov. Ta funkcija lahko tudi opusti obvestila in izvaja dejanja z gumbi v obvestilih, kot je sprejemanje telefonskih klicev.\n\nPoleg tega lahko ta funkcija vklopi ali izklopi prednostni način ter spremeni povezane nastavitve."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rutinsko informativno obvestilo o načinu delovanja"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterija se bo morda izpraznila, preden jo običajno priključite na polnjenje"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Vklopilo se je varčevanje z energijo baterije za podaljšanje časa delovanja baterije"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 5575f16..30bcbaf 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -319,10 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"qasje në aktivitetin tënd fizik"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"bëj fotografi dhe regjistro video"</string>
- <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
- <skip />
- <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
- <skip />
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Pajisjet në afërsi"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"të zbulojë dhe të lidhet me pajisjet në afërsi"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Evidencat e telefonatave"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"lexo dhe shkruaj evidencën e telefonatave"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefoni"</string>
@@ -540,14 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Lejon që aplikacioni të zbulojë dhe të çiftohet me pajisjet me Bluetooth në afërsi"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"të lidhet me pajisjet e çiftuara me Bluetooth"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Lejon që aplikacioni të lidhet me pajisjet e çiftuara me Bluetooth"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"të reklamojë në pajisjet me Bluetooth në afërsi"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Lejon që aplikacioni të reklamojë në pajisjet me Bluetooth në afërsi"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"të përcaktojë pozicionin e përafërt mes pajisjeve në afërsi me brezin ultra të gjerë"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Lejo që aplikacioni të përcaktojë pozicionin e përafërt mes pajisjeve në afërsi me brezin ultra të gjerë"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacionet për shërbimin e preferuar të pagesës me NFC"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Lejon aplikacionin të marrë informacione për shërbimin e preferuar të pagesës me NFC si p.sh. ndihmat e regjistruara dhe destinacionin e itinerarit."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"kontrollo \"Komunikimin e fushës në afërsi\" NFC"</string>
@@ -1273,12 +1267,12 @@
<string name="new_app_action" msgid="547772182913269801">"Hap <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
<string name="new_app_description" msgid="1958903080400806644">"<xliff:g id="OLD_APP">%1$s</xliff:g> do të mbyllet pa u ruajtur"</string>
<string name="dump_heap_notification" msgid="5316644945404825032">"<xliff:g id="PROC">%1$s</xliff:g> e ka kaluar kufirin e memories"</string>
- <string name="dump_heap_ready_notification" msgid="2302452262927390268">"Stiva e skedarëve fiktivë të <xliff:g id="PROC">%1$s</xliff:g> është gati"</string>
- <string name="dump_heap_notification_detail" msgid="8431586843001054050">"Stiva e skedarëve fiktivë është mbledhur. Trokit për t\'i ndarë."</string>
- <string name="dump_heap_title" msgid="4367128917229233901">"Të ndahet stiva e skedarëve fiktivë?"</string>
- <string name="dump_heap_text" msgid="1692649033835719336">"Procesi <xliff:g id="PROC">%1$s</xliff:g> ka kaluar kufirin e tij të memories prej <xliff:g id="SIZE">%2$s</xliff:g>. Ke një stivë të skedarësh fiktivë që mund ta ndash me zhvilluesin e tij. Ki kujdes pasi kjo stivë skedarësh fiktivë mund të përmbajë çdo informacion personal ku ka qasje aplikacioni."</string>
- <string name="dump_heap_system_text" msgid="6805155514925350849">"Procesi <xliff:g id="PROC">%1$s</xliff:g> e ka kaluar kufirin e tij të memories prej <xliff:g id="SIZE">%2$s</xliff:g>. Ke një stivë skedarësh fiktivë që mund ta ndash. Ki kujdes pasi kjo stivë skedarësh fiktivë mund të përmbajë çdo informacion personal delikat ku ka qasje procesi dhe mund të përfshijë gjërat që ke shkruar ti."</string>
- <string name="dump_heap_ready_text" msgid="5849618132123045516">"Ke një stivë skedarësh fiktivë të procesit <xliff:g id="PROC">%1$s</xliff:g> që mund ta ndash. Ki kujdes pasi kjo stivë skedarësh fiktivë mund të përmbajë çdo informacion personal delikat ku ka qasje procesi dhe mund të përfshijë gjërat që ke shkruar ti."</string>
+ <string name="dump_heap_ready_notification" msgid="2302452262927390268">"Grumbulli i skedarëve fiktivë të <xliff:g id="PROC">%1$s</xliff:g> është gati"</string>
+ <string name="dump_heap_notification_detail" msgid="8431586843001054050">"Grumbulli i skedarëve fiktivë është mbledhur. Trokit për t\'i ndarë."</string>
+ <string name="dump_heap_title" msgid="4367128917229233901">"Të ndahet grumbulli i skedarëve fiktivë?"</string>
+ <string name="dump_heap_text" msgid="1692649033835719336">"Procesi <xliff:g id="PROC">%1$s</xliff:g> ka kaluar kufirin e tij të memories prej <xliff:g id="SIZE">%2$s</xliff:g>. Ke një grumbull skedarësh fiktivë që mund ta ndash me zhvilluesin e tij. Ki kujdes pasi ky grumbull skedarësh fiktivë mund të përmbajë çdo informacion personal tëndin ku ka qasje aplikacioni."</string>
+ <string name="dump_heap_system_text" msgid="6805155514925350849">"Procesi <xliff:g id="PROC">%1$s</xliff:g> e ka kaluar kufirin e tij të memories prej <xliff:g id="SIZE">%2$s</xliff:g>. Ke një grumbull skedarësh fiktivë që mund ta ndash. Ki kujdes pasi ky grumbull skedarësh fiktivë mund të përmbajë çdo informacion personal delikat ku ka qasje procesi dhe mund të përfshijë gjërat që ke shkruar ti."</string>
+ <string name="dump_heap_ready_text" msgid="5849618132123045516">"Ke një grumbull skedarësh fiktivë të procesit <xliff:g id="PROC">%1$s</xliff:g> që mund ta ndash. Ki kujdes pasi ky grumbull skedarësh fiktivë mund të përmbajë çdo informacion personal delikat ku ka qasje procesi dhe mund të përfshijë gjërat që ke shkruar ti."</string>
<string name="sendText" msgid="493003724401350724">"Zgjidh një veprim për tekstin"</string>
<string name="volume_ringtone" msgid="134784084629229029">"Volumi i ziles"</string>
<string name="volume_music" msgid="7727274216734955095">"Volumi i medias"</string>
@@ -1713,7 +1707,7 @@
<string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"U krye"</string>
<string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Çaktivizo shkurtoren"</string>
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Përdor shkurtoren"</string>
- <string name="color_inversion_feature_name" msgid="326050048927789012">"Kthimi i ngjyrës"</string>
+ <string name="color_inversion_feature_name" msgid="326050048927789012">"Anasjellja e ngjyrës"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Korrigjimi i ngjyrës"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Shumë më i zbehtë"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tastet e volumit të mbajtura shtypur. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> i aktivizuar."</string>
@@ -1858,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Përditësuar nga administratori"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Fshirë nga administratori"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Në rregull"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"\"Kursyesi i baterisë\" aktivizon \"Temën e errët\" dhe kufizon ose çaktivizon aktivitetin në sfond, disa efekte vizuale dhe veçoritë si \"Ok Google\"\n\n"<annotation id="url">"Mëso më shumë"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"\"Kursyesi i baterisë\" aktivizon \"Temën e errët\" dhe kufizon ose çaktivizon aktivitetin në sfond, disa efekte vizuale dhe veçoritë si \"Ok Google\"."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Për të ndihmuar në reduktimin e përdorimit të të dhënave, \"Kursyesi i të dhënave\" pengon që disa aplikacione të dërgojnë apo të marrin të dhëna në sfond. Një aplikacion që po përdor aktualisht mund të ketë qasje te të dhënat, por këtë mund ta bëjë më rrallë. Kjo mund të nënkuptojë, për shembull, se imazhet nuk shfaqen kur troket mbi to."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Të aktivizohet \"Kursyesi i të dhënave\"?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Aktivizo"</string>
@@ -1937,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Mbyll"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Përgjigju"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Refuzo"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Mbyll"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Telefonatë hyrëse"</string>
@@ -2080,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Ky njoftim është ulur në nivel si në heshtje. Trokit për të dhënë komente."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Ky njoftim është renditur më lart. Trokit për të dhënë komente."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Ky njoftim është renditur më poshtë. Trokit për të dhënë komente."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Provo njoftimet e përmirësuara"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Për të vazhduar të marrësh sugjerime për veprimet, përgjigjet etj., aktivizo njoftimet e përmirësuara. \"Njoftimet me përshtatje të Android\" nuk mbështeten më."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Aktivizo"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Jo tani"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Mëso më shumë"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Njoftimet e përmirësuara mund të lexojnë të gjithë përmbajtjen e njoftimeve, duke përfshirë edhe informacionet personale si emrat e kontakteve dhe mesazhet. Kjo veçori mund të heqë po ashtu njoftimet ose të veprojë mbi butonat te njoftimet, si p.sh. t\'u përgjigjet telefonatave.\n\nKjo veçori mund të aktivizojë ose të çaktivizojë po ashtu modalitetin \"Me përparësi\" dhe të ndryshojë cilësimet përkatëse."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Njoftimi i informacionit të \"Modalitetit rutinë\""</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Bateria mund të mbarojë përpara ngarkimit të zakonshëm"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"\"Kursyesi i baterisë\" u aktivizua për të rritur kohëzgjatjen e baterisë"</string>
@@ -2279,14 +2267,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Tani mund të zmadhosh pjesë të ekranit tënd"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aktivizo te \"Cilësimet\""</string>
<string name="dismiss_action" msgid="1728820550388704784">"Hiq"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Zhblloko mikrofonin e pajisjes"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Zhblloko kamerën e pajisjes"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Për <b><xliff:g id="APP">%s</xliff:g></b> dhe të gjitha aplikacionet dhe shërbimet"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Zhblloko"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatësia e sensorit"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ikona e aplikacionit"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Imazhi i vendosjes së aplikacionit të markës"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index d404f8c..96fa82d 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1875,10 +1875,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Уштеда батерије укључује Тамну тему и ограничава или искључује активности у позадини, неке визуелне ефекте и функције, на пример, „Хеј Google“.\n\n"<annotation id="url">"Сазнајте више"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Уштеда батерије укључује Тамну тему и ограничава или искључује активности у позадини, неке визуелне ефекте и функције, на пример, „Хеј Google“."</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>
@@ -1962,6 +1960,7 @@
<string name="close_button_text" msgid="10603510034455258">"Затвори"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Одговори"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Видео"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Одбиј"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Прекини везу"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Долазни позив"</string>
@@ -2107,18 +2106,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Ово обавештење је деградирано у Нечујно. Додирните да бисте навели повратне информације."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Ово обавештење је рангирано више. Додирните да бисте навели повратне информације."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Ово обавештење је рангирано ниже. Додирните да бисте навели повратне информације."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Пробајте побољшана обавештења"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Укључите побољшана обавештења да бисте и даље добијали препоручене радње, одговоре и друго. Прилагодљива обавештења за Android више нису подржана."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Укључи"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Не сада"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Сазнајте више"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Побољшана обавештења могу да читају садржај свих обавештења, укључујући личне податке, попут имена контаката и порука. Ова функција може и да одбацује обавештења или активира дугмад у обавештењима, попут јављања на телефонске позиве.\n\nОва функција може и да укључи или искључи Приоритетни режим и да мења повезана подешавања."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Обавештење о информацијама Рутинског режима"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батерија ће се можда испразнити пре уобичајеног пуњења"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Уштеда батерије је активирана да би се продужило трајање батерије"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 4dc2ecf..b9efba0 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Administratören uppdaterade paketet"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Administratören raderade paketet"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"I batterisparläget aktiveras mörkt tema och bakgrundsaktivitet som vissa visuella effekter och funktioner som ”Hey Google” begränsas eller inaktiveras\n\n"<annotation id="url">"Läs mer"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"I batterisparläget aktiveras mörkt tema och bakgrundsaktivitet som vissa visuella effekter och funktioner som ”Hey Google” begränsas eller inaktiveras."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Med databesparing kan du minska dataanvändningen genom att hindra en del appar från att skicka eller ta emot data i bakgrunden. Appar som du använder kan komma åt data, men det sker kanske inte lika ofta. Detta innebär t.ex. att bilder inte visas förrän du trycker på dem."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Vill du aktivera Databesparing?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Aktivera"</string>
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Stäng"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Svara"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Avvisa"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Lägg på"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Inkommande samtal"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Den här aviseringen har ändrats till Tyst. Tryck för att lämna feedback."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Den här aviseringen har fått högre rankning. Tryck för att lämna feedback."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Den här aviseringen har fått lägre rankning. Tryck för att lämna feedback."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Testa förbättrade aviseringar"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Aktivera förbättrade aviseringar om du vill fortsätta att få rekommenderade åtgärder, svar och annat. Anpassade aviseringar för Android stöds inte längre."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Aktivera"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Inte nu"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Läs mer"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Förbättrade aviseringar kan läsa allt innehåll i aviseringar, inklusive personliga uppgifter som namn på kontakter och meddelanden. Funktionen kan även stänga aviseringar eller använda åtgärdsknappar i aviseringar, till exempel för att svara på telefonsamtal.\n\nFunktionen kan även aktivera och inaktivera prioritetsläget och ändra tillhörande inställningar."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Avisering om rutinläge"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Batteriet kan ta slut innan du brukar ladda det"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batterisparläget har aktiverats för att utöka batteritiden"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 0156787..ea069e1 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Imesasishwa na msimamizi wako"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Imefutwa na msimamizi wako"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Sawa"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Kiokoa Betri huwasha Mandhari meusi na kudhibiti au kuzima shughuli za chinichini, baadhi ya madoido yanayoonekana na vipengele kama vile \"Ok Google\"\n\n"<annotation id="url">"Pata maelezo zaidi"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Kiokoa Betri huwasha Mandhari meusi na kudhibiti au kuzima shughuli za chinichini, baadhi ya madoido yanayoonekana na vipengele kama vile \"Ok Google\"."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Ili kusaidia kupunguza matumizi ya data, Kiokoa Data huzuia baadhi ya programu kupokea na kutuma data chinichini. Programu ambayo unatumia sasa inaweza kufikia data, lakini si kila wakati. Kwa mfano, haitaonyesha picha hadi utakapozifungua."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Ungependa Kuwasha Kiokoa Data?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Washa"</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Funga"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Jibu"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Kataa"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Kata simu"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Simu uliyopigiwa"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Arifa hii ilishushwa hadhi kuwa Kimya. Gusa ili utoe maoni."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Arifa hii imeorodheshwa katika nafasi ya juu. Gusa ili utoe maoni."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Arifa hii imeorodheshwa katika nafasi ya chini. Gusa ili utoe maoni."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Jaribu arifa zilizoboreshwa"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Ili uendelee kupata vitendo, majibu na mambo mengine yanayopendekezwa, washa arifa zilizoboreshwa. Arifa Zinazojirekebisha za Android hazitumiki tena."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Washa"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Si sasa"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Pata maelezo zaidi"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Kipengele cha Arifa zilizoboreshwa kinaweza kusoma maudhui yote ya arifa, zikiwemo taarifa binafsi kama vile majina ya anwani na ujumbe. Kipengele hiki kinaweza pia kuondoa arifa au kuchukua hatua kwenye vitufe katika arifa, kama vile kujibu simu.\n\nKipengele hiki pia kinaweza kuwasha au kuzima hali ya Kipaumbele na kubadilisha mipangilio inayohusiana."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Arifa ya maelezo ya Hali ya Kawaida"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Huenda betri itakwisha chaji mapema"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Imewasha Kiokoa Betri ili kurefusha muda wa matumizi ya betri"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index e625c8bb..0b989c5 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1852,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"பேட்டரி சேமிப்பான் டார்க் தீமினை ஆன் செய்து பின்னணிச் செயல்பாடு, சில விஷுவல் எஃபெக்ட்கள், “Ok Google” போன்ற அம்சங்களை ஆஃப் செய்யும் அல்லது கட்டுப்படுத்தும்\n\n"<annotation id="url">"மேலும் அறிக"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"பேட்டரி சேமிப்பான் டார்க் தீமினை ஆன் செய்து பின்னணிச் செயல்பாடு, சில விஷுவல் எஃபெக்ட்கள், “Ok Google” போன்ற அம்சங்களை ஆஃப் செய்யும் அல்லது கட்டுப்படுத்தும்."</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>
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"மூடு"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"பதிலளி"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"நிராகரி"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"துண்டி"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"உள்வரும் அழைப்பு"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"இந்த அறிவிப்பின் முக்கியத்துவம் நிசப்த நிலைக்குக் குறைத்து அமைக்கப்பட்டது. கருத்து தெரிவிக்க தட்டவும்."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"இந்த அறிவிப்பின் முக்கியத்துவம் உயர்த்தப்பட்டது. கருத்து தெரிவிக்க தட்டவும்."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"இந்த அறிவிப்பின் முக்கியத்துவம் குறைக்கப்பட்டது. கருத்து தெரிவிக்க தட்டவும்."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"மேம்பட்ட அறிவிப்புகளை முயல்க"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"பரிந்துரைக்கப்பட்ட செயல்பாடுகள், பதில்கள் மற்றும் பலவற்றையும் தொடர்ந்து பெற மேம்பட்ட அறிவிப்புகளை ஆன் செய்யவும். Android சூழலுக்கேற்ற அறிவிப்புகள் இனி ஆதரிக்கப்படாது."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"ஆன் செய்"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"இப்போது வேண்டாம்"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"மேலும் அறிக"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"மேம்பட்ட அறிவிப்புகளால் அனைத்து அறிவிப்புகளின் உள்ளடக்கத்தையும் (தொடர்புகளின் பெயர்கள், மெசேஜ்கள் போன்ற தனிப்பட்ட தகவல்கள் உட்பட) படிக்க முடியும். இந்த அம்சத்தால் அறிவிப்புகளை நிராகரிக்கவோ அறிவிப்புகளிலுள்ள பட்டன்களை இயக்கவோ (அழைப்புகளுக்குப் பதிலளிப்பது போன்றவை) முடியும்.\n\nஇந்த அம்சத்தால் முன்னுரிமைப் பயன்முறையை இயக்கவோ முடக்கவோ முடியும் மற்றும் தொடர்புடைய அமைப்புகளை மாற்றவும் முடியும்."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"வழக்கமான பேட்டரி சேமிப்பானுக்கான விவர அறிவிப்பு"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"வழக்கமாகச் சார்ஜ் செய்வதற்கு முன்பே பேட்டரி தீர்ந்துபோகக்கூடும்"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"பேட்டரி நிலையை நீட்டிக்க பேட்டரி சேமிப்பான் இயக்கப்பட்டுள்ளது"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index faed275..882af55 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -251,7 +251,7 @@
<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>
- <string name="bugreport_title" msgid="8549990811777373050">"బగ్ నివేదిక"</string>
+ <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>
@@ -315,14 +315,12 @@
<string name="permgroupdesc_storage" msgid="6351503740613026600">"మీ పరికరంలోని ఫోటోలు, మీడియా మరియు ఫైల్లను యాక్సెస్ చేయడానికి"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"మైక్రోఫోన్"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"ఆడియోను రికార్డ్ చేయడానికి"</string>
- <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"భౌతిక కార్యకలాపం"</string>
+ <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ఫిజికల్ యాక్టివిటీ"</string>
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"భౌతిక కార్యకలాపాన్ని యాక్సెస్ చేయండి"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"కెమెరా"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"చిత్రాలను తీయడానికి మరియు వీడియోను రికార్డ్ చేయడానికి"</string>
- <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
- <skip />
- <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
- <skip />
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"సమీపంలోని పరికరాలు"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"సమీప పరికరాలను కనుగొనండి అలాగే కనెక్ట్ చేయండి"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"కాల్ లాగ్లు"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"ఫోన్ కాల్ లాగ్ని చదవండి మరియు రాయండి"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"ఫోన్"</string>
@@ -540,14 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"సమీపంలోని బ్లూటూత్ పరికరాలను కనుగొనడానికి, పెయిర్ చేయడానికి యాప్ను అనుమతిస్తుంది"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"పెయిర్ చేసిన బ్లూటూత్ పరికరాలకు కనెక్ట్ అవ్వండి"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"పెయిర్ చేసిన బ్లూటూత్ పరికరాలకు కనెక్ట్ అవ్వడానికి యాప్ను అనుమతిస్తుంది"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"సమీపంలోని బ్లూటూత్ పరికరాలలో అడ్వర్టయిజ్ చేయండి"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"సమీపంలోని బ్లూటూత్ పరికరాలలో అడ్వర్టయిజ్ చేయడానికి యాప్కు అనుమతిని ఇస్తుంది"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"సమీపంలోని అల్ట్రా-వైడ్బ్యాండ్ పరికరాల మధ్య సాపేక్ష స్థానాన్ని నిర్ణయించండి"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"సమీపంలోని అల్ట్రా-వైడ్బ్యాండ్ పరికరాల మధ్య సాపేక్ష స్థానాన్ని నిర్ణయించడానికి యాప్ను అనుమతించండి"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ప్రాధాన్యత ఇవ్వబడిన NFC చెల్లింపు సేవల సమాచారం"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ప్రాధాన్యత ఇవ్వబడిన NFC చెల్లింపు సేవల సమాచారాన్ని, అంటే రిజిస్టర్ చేయబడిన సహాయక సాధనాలు, మార్గం, గమ్యస్థానం వంటి వాటిని పొందేందుకు యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"సమీప క్షేత్ర కమ్యూనికేషన్ను నియంత్రించడం"</string>
@@ -1485,7 +1479,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>
@@ -1569,7 +1563,7 @@
<string name="description_target_unlock_tablet" msgid="7431571180065859551">"అన్లాక్ చేయడానికి స్వైప్ చేయండి."</string>
<string name="action_bar_home_description" msgid="1501655419158631974">"హోమ్కు నావిగేట్ చేయండి"</string>
<string name="action_bar_up_description" msgid="6611579697195026932">"పైకి నావిగేట్ చేయండి"</string>
- <string name="action_menu_overflow_description" msgid="4579536843510088170">"మరిన్ని ఎంపికలు"</string>
+ <string name="action_menu_overflow_description" msgid="4579536843510088170">"మరిన్ని ఆప్షన్లు"</string>
<string name="action_bar_home_description_format" msgid="5087107531331621803">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="4346835454749569826">"%1$s, %2$s, %3$s"</string>
<string name="storage_internal" msgid="8490227947584914460">"షేర్ చేయబడిన అంతర్గత నిల్వ"</string>
@@ -1696,13 +1690,13 @@
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"ఆన్ చేయకండి"</string>
<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_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_warning_description" msgid="291674995220940133">"అవసరమైన యాక్సెసిబిలిటీ కోసం యాప్లకు పూర్తి కంట్రోల్ ఇవ్వడం తగిన పనే అయినా, అన్ని యాప్లకు అలా ఇవ్వడం సరికాదు."</string>
+ <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"స్క్రీన్ను చూసి, కంట్రోల్ చేయడం"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"స్క్రీన్పై ఉండే కంటెంట్ మొత్తాన్ని చదవగలుగుతుంది మరియు ఇతర యాప్లలో కూడా ఈ కంటెంట్ను ప్రదర్శిస్తుంది."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"చర్యలను చూసి, అమలు చేయండి"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"మీరు యాప్తో చేసే పరస్పర చర్యలను లేదా హార్డ్వేర్ సెన్సార్ను ట్రాక్ చేస్తూ మీ తరఫున యాప్లతో పరస్పరం సమన్వయం చేస్తుంది."</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"మీరు ఒక యాప్తో చేసే ఇంటరాక్షన్లను లేదా హార్డ్వేర్ సెన్సార్ను ట్రాక్ చేస్తూ మీ తరఫున యాప్లతో ఇంటరాక్ట్ చేయగలదు."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"అనుమతించు"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"నిరాకరించు"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"ఫీచర్ని ఉపయోగించడం ప్రారంభించడానికి, దాన్ని ట్యాప్ చేయండి:"</string>
@@ -1715,7 +1709,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"సత్వరమార్గాన్ని ఉపయోగించు"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"కలర్ మార్పిడి"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"కలర్ సరిచేయడం"</string>
- <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"కాంతిని మరింత డిమ్ చేసే"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"కాంతిని మరింత డిమ్ చేయడం"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆన్ చేయబడింది"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆఫ్ చేయబడింది"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ని ఉపయోగించడానికి వాల్యూమ్ కీలు రెండింటినీ 3 సెకన్లు నొక్కి ఉంచండి"</string>
@@ -1858,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"బ్యాటరీ సేవర్ ముదురు రంగు రూపంను ఆన్ చేస్తుంది అలాగే బ్యాక్గ్రౌండ్ యాక్టివిటీని, కొన్ని విజువల్ ఎఫెక్ట్లు, అలాగే “Ok Google” వంటి ఫీచర్లను పరిమితం చేస్తుంది లేదా ఆఫ్ చేస్తుంది\n\n"<annotation id="url">"మరింత తెలుసుకోండి"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"బ్యాటరీ సేవర్ ముదురు రంగు రూపంను ఆన్ చేస్తుంది అలాగే బ్యాక్గ్రౌండ్ యాక్టివిటీని, కొన్ని విజువల్ ఎఫెక్ట్లు, అలాగే “Ok Google” వంటి ఫీచర్లను పరిమితం చేస్తుంది లేదా ఆఫ్ చేస్తుంది."</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>
@@ -1931,12 +1923,14 @@
<string name="usb_midi_peripheral_name" msgid="490523464968655741">"Android USB పెరిఫెరల్ పోర్ట్"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7557148557088787741">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="2836276258480904434">"USB పెరిఫెరల్ పోర్ట్"</string>
- <string name="floating_toolbar_open_overflow_description" msgid="2260297653578167367">"మరిన్ని ఎంపికలు"</string>
+ <string name="floating_toolbar_open_overflow_description" msgid="2260297653578167367">"మరిన్ని ఆప్షన్లు"</string>
<string name="floating_toolbar_close_overflow_description" msgid="3949818077708138098">"అతివ్యాప్తిని మూసివేస్తుంది"</string>
<string name="maximize_button_text" msgid="4258922519914732645">"గరిష్టీకరించు"</string>
<string name="close_button_text" msgid="10603510034455258">"మూసివేయి"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"సమాధానం ఇవ్వు"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"తిరస్కరించండి"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"కాల్ ముగించు"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"ఇన్కమింగ్ కాల్"</string>
@@ -1985,7 +1979,7 @@
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"డెమోను ప్రారంభిస్తోంది..."</string>
<string name="demo_restarting_message" msgid="1160053183701746766">"పరికరాన్ని రీసెట్ చేస్తోంది..."</string>
- <string name="suspended_widget_accessibility" msgid="6331451091851326101">"<xliff:g id="LABEL">%1$s</xliff:g> నిలిపివేయబడింది"</string>
+ <string name="suspended_widget_accessibility" msgid="6331451091851326101">"<xliff:g id="LABEL">%1$s</xliff:g> డిజేబుల్ చేయబడింది"</string>
<string name="conference_call" msgid="5731633152336490471">"కాన్ఫరెన్స్ కాల్"</string>
<string name="tooltip_popup_title" msgid="7863719020269945722">"సాధనం చిట్కా"</string>
<string name="app_category_game" msgid="4534216074910244790">"గేమ్లు"</string>
@@ -2080,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"ఈ నోటిఫికేషన్ స్థాయి నిశ్శబ్దంగా ఉండేలా తగ్గించబడింది. ఫీడ్బ్యాక్ను అందించడానికి ట్యాప్ చేయండి."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"ఈ నోటిఫికేషన్కు ఎక్కువ ర్యాంక్ ఇవ్వబడింది. ఫీడ్బ్యాక్ను అందించడానికి ట్యాప్ చేయండి."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"ఈ నోటిఫికేషన్కు తక్కువ ర్యాంక్ ఇవ్వబడింది. ఫీడ్బ్యాక్ను అందించడానికి ట్యాప్ చేయండి."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"మెరుగైన నోటిఫికేషన్ల ట్రై"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"సూచించిన చర్యలు, రిప్లయిలు, అలాగే మరిన్ని పొందడం కొనసాగించడానికి మెరుగైన నోటిఫికేషన్లను ఆన్ చేయండి. Android అనుకూల నోటిఫికేషన్లు ఇకపై సపోర్ట్ చేయవు."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"ఆన్ చేయి"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"ఇప్పుడు కాదు"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"మరింత తెలుసుకోండి"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"కాంటాక్ట్ పేర్లు, మెసేజ్లు వంటి వ్యక్తిగత సమాచారంతో సహా మెరుగైన నోటిఫికేషన్లు అన్ని నోటిఫికేషన్ కంటెంట్ను చదవగలవు. ఈ ఫీచర్ నోటిఫికేషన్లను తీసివేయవచ్చు లేదా ఫోన్ కాల్లకు సమాధానం ఇవ్వడం వంటి నోటిఫికేషన్లలోని బటన్లపై చర్యలు తీసుకోవచ్చు.\n\nఈ ఫీచర్ ప్రాధాన్యత మోడ్ను కూడా ఆన్ లేదా ఆఫ్ చేయవచ్చు, ఇది సంబంధిత సెట్టింగ్లను మార్చగలదు."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"రొటీన్ మోడ్ సమాచార నోటిఫికేషన్"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"మామూలుగా ఛార్జ్ చేసేలోపు బ్యాటరీ ఖాళీ కావచ్చు"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"బ్యాటరీ జీవితకాలాన్ని పెంచడానికి బ్యాటరీ సేవర్ యాక్టివేట్ చేయబడింది"</string>
@@ -2279,17 +2267,13 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"మీరు ఇప్పుడు మీ స్క్రీన్ కొంత భాగాన్ని మాగ్నిఫై చేయవచ్చు"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"సెట్టింగ్లలో ఆన్ చేయండి"</string>
<string name="dismiss_action" msgid="1728820550388704784">"విస్మరించు"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"పరికరం మైక్రోఫోన్ను అన్బ్లాక్ చేయండి"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"పరికరం కెమెరాను అన్బ్లాక్ చేయండి"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> యాప్, ఇతర యాప్లు, సర్వీస్ల కోసం"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"అన్బ్లాక్ చేయండి"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"సెన్సార్ గోప్యత"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"యాప్ చిహ్నం"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"యాప్ బ్రాండింగ్ ఇమేజ్"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"యాక్సెస్ సెట్టింగ్లను చెక్ చేయండి"</string>
- <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> మీ స్క్రీన్ను చూడవచ్చు, నియంత్రించవచ్చు. రివ్యూ చేయడానికి ట్యాప్ చేయండి."</string>
+ <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> మీ స్క్రీన్ను చూడవచ్చు, కంట్రోల్ చేయవచ్చు. రివ్యూ చేయడానికి ట్యాప్ చేయండి."</string>
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 1c00654..e0001c2 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1852,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"โหมดประหยัดแบตเตอรี่จะเปิดธีมมืดและจำกัดหรือปิดกิจกรรมในเบื้องหลัง เอฟเฟกต์ภาพบางอย่าง และฟีเจอร์อย่างเช่น \"Ok Google\"\n\n"<annotation id="url">"ดูข้อมูลเพิ่มเติม"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"โหมดประหยัดแบตเตอรี่จะเปิดธีมมืดและจำกัดหรือปิดกิจกรรมในเบื้องหลัง เอฟเฟกต์ภาพบางอย่าง และฟีเจอร์อย่างเช่น \"Ok Google\""</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>
@@ -1931,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"ปิด"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"รับสาย"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"ปฏิเสธ"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"วางสาย"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"สายเรียกเข้า"</string>
@@ -2074,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"การแจ้งเตือนนี้มีการลดระดับเป็นแบบปิดเสียง แตะเพื่อแสดงความคิดเห็น"</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"การแจ้งเตือนนี้มีการเพิ่มระดับ แตะเพื่อแสดงความคิดเห็น"</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"การแจ้งเตือนนี้มีการลดระดับ แตะเพื่อแสดงความคิดเห็น"</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"ลองใช้การแจ้งเตือนที่เพิ่มประสิทธิภาพ"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"หากต้องการรับการดําเนินการ การตอบ และอื่นๆ ที่แนะนําต่อไป ให้เปิดการแจ้งเตือนที่เพิ่มประสิทธิภาพ ไม่รองรับการแจ้งเตือนแบบปรับอัตโนมัติใน Android อีกต่อไป"</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"เปิด"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"ไว้ทีหลัง"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ดูข้อมูลเพิ่มเติม"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"การแจ้งเตือนที่เพิ่มประสิทธิภาพจะอ่านเนื้อหาการแจ้งเตือนทั้งหมดได้ รวมถึงข้อมูลส่วนบุคคล เช่น ชื่อผู้ติดต่อและข้อความ ฟีเจอร์นี้ยังปิดการแจ้งเตือนหรือดำเนินการกับปุ่มต่างๆ ในการแจ้งเตือนได้ด้วย เช่น การรับสายเรียกเข้า\n\nอีกทั้งสามารถเปิดหรือปิดโหมดลำดับความสำคัญสูงและเปลี่ยนแปลงการตั้งค่าที่เกี่ยวข้อง"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"การแจ้งเตือนข้อมูลโหมดกิจวัตร"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"แบตเตอรี่อาจหมดก่อนการชาร์จปกติ"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"เปิดใช้งานโหมดประหยัดแบตเตอรี่แล้วเพื่อยืดอายุการใช้งานแบตเตอรี่"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index c05fe90..adaa774 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Na-update ng iyong admin"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Na-delete ng iyong admin"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Ino-on ng Pantipid ng Baterya ang Madilim na tema at nililimitahan o ino-off nito ang aktibidad sa background, ilang visual effect, at mga feature gaya ng “Hey Google”\n\n"<annotation id="url">"Matuto pa"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Ino-on ng Pantipid ng Baterya ang Madilim na tema at nililimitahan o ino-off nito ang aktibidad sa background, ilang visual effect, at mga feature gaya ng “Hey Google.”"</string>
<string name="data_saver_description" msgid="4995164271550590517">"Upang makatulong na mabawasan ang paggamit ng data, pinipigilan ng Data Saver ang ilang app na magpadala o makatanggap ng data sa background. Maaaring mag-access ng data ang isang app na ginagamit mo sa kasalukuyan, ngunit mas bihira na nito magagawa iyon. Halimbawa, maaaring hindi lumabas ang mga larawan hangga\'t hindi mo nata-tap ang mga ito."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"I-on ang Data Saver?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"I-on"</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Isara"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Sagutin"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Tanggihan"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Ibaba"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Papasok na tawag"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Na-demote sa Naka-silent ang notification na ito. I-tap para magbigay ng feedback."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Itinaas ang ranggo ng notification na ito. I-tap para magbigay ng feedback."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Ibinaba ang ranggo ng notification na ito. I-tap para magbigay ng feedback."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Subukan ang enhanced notification"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Para patuloy na makakuha ng mga iminumungkahing pagkilos, sagot, at higit pa, i-on ang mga pinahusay na notification. Hindi na sinusuportahan ang Mga Adaptive na Notification ng Android."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"I-on"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Hindi ngayon"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Matuto pa"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Puwedeng basahin ng mga pinahusay na notification ang lahat ng notification, kabilang ang personal na impormasyon gaya ng mga pangalan ng contact at mga mensahe. Magagawa ring ng feature na ito na i-dismiss ang mga notification o gumawa ng mga pagkilos sa mga button sa mga notification, gaya ng pagsagot sa mga tawag sa telepono.\n\nPuwede ring i-on o i-off ng feature na ito ang Priority mode at baguhin ang mga kaugnay na setting."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notification ng impormasyon ng Routine Mode"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Maaaring maubos ang baterya bago ang karaniwang pag-charge"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Na-activate ang Pantipid ng Baterya para patagalin ang buhay ng baterya"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 87ca8e0..bd85322 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -324,7 +324,7 @@
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Arama kayıtları"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"telefon arama kaydını okuma ve yazma"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="270048070781478204">"telefon çağrıları yapma ve yönetme"</string>
+ <string name="permgroupdesc_phone" msgid="270048070781478204">"telefon aramaları yapma ve yönetme"</string>
<string name="permgrouplab_sensors" msgid="9134046949784064495">"Vücut sensörleri"</string>
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"hayati belirtilerinizle ilgili sensör verilerine erişme"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Pencere içeriğini alma"</string>
@@ -353,9 +353,9 @@
<string name="permdesc_install_shortcut" msgid="4476328467240212503">"Uygulamaya, kullanıcı müdahalesi olmadan kısayolları Ana Ekrana ekleme izni verir."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"kısayolların yüklemesini kaldırma"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Uygulamaya, kullanıcının müdahalesi olmadan kısayolları Ana Ekrandan kaldırma izni verir."</string>
- <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"giden çağrıları yeniden yönlendirme"</string>
+ <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"giden aramaları yeniden yönlendirme"</string>
<string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Uygulamaya, giden bir çağrının numarası çevrilirken çağrıyı farklı bir numaraya yönlendirme ya da tamamen kapatma seçeneğiyle birlikte numarayı görme izni verir."</string>
- <string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"telefon çağrılarını yanıtla"</string>
+ <string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"telefon aramalarını yanıtla"</string>
<string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"Uygulamanın gelen bir telefon çağrısına yanıt vermesine olanak tanır."</string>
<string name="permlab_receiveSms" msgid="505961632050451881">"kısa mesajları al (SMS)"</string>
<string name="permdesc_receiveSms" msgid="1797345626687832285">"Uygulamaya SMS iletilerini alma ve işleme izni verir. Bu izin, uygulamanın cihazınıza gönderilen iletileri takip edip size göstermeden silebileceği anlamına gelir."</string>
@@ -423,8 +423,8 @@
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Bu uygulama, çağrı geçmişinizi okuyabilir."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"çağrı günlüğüne yaz"</string>
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Uygulamaya tabletinizin çağrı günlüğünde (gelen ve giden çağrılarla ilgili veriler dahil olmak üzere) değişiklik yapma izni verir. Kötü amaçlı uygulamalar bu izni kullanarak çağrı günlüğünüzü silebilir veya değiştirebilir."</string>
- <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Uygulamaya, Android TV cihazınızın çağrı günlüğünde (gelen ve giden çağrılarla ilgili veriler dahil olmak üzere) değişiklik yapma izni verir. Kötü amaçlı uygulamalar bu izni kullanarak çağrı günlüğünüzü silebilir veya değiştirebilir."</string>
- <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Uygulamaya telefonunuzun çağrı günlüğünde (gelen ve giden çağrılarla ilgili veriler dahil olmak üzere) değişiklik yapma izni verir. Kötü amaçlı uygulamalar bu izni kullanarak çağrı günlüğünüzü silebilir veya değiştirebilir."</string>
+ <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Uygulamaya, Android TV cihazınızın arama günlüğünde (gelen ve giden aramalarla ilgili veriler dahil olmak üzere) değişiklik yapma izni verir. Kötü amaçlı uygulamalar bu izni kullanarak arama günlüğünüzü silebilir veya değiştirebilir."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Uygulamaya telefonunuzun arama günlüğünde (gelen ve giden aramalarla ilgili veriler dahil olmak üzere) değişiklik yapma izni verir. Kötü amaçlı uygulamalar bu izni kullanarak arama günlüğünüzü silebilir veya değiştirebilir."</string>
<string name="permlab_bodySensors" msgid="3411035315357380862">"vücut sensörlerine erişme (nabız takip cihazları gibi)"</string>
<string name="permdesc_bodySensors" product="default" msgid="2365357960407973997">"Uygulamanın, nabzınız gibi fiziksel durumunuzu izleyen sensörlerin gönderdiği verilere erişmesine izin verir."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Takvim etkinlikleri ve ayrıntılarını okuma"</string>
@@ -465,12 +465,12 @@
<string name="permdesc_vibrate" msgid="8733343234582083721">"Uygulamaya, titreşimi denetleme izni verir."</string>
<string name="permdesc_vibrator_state" msgid="7050024956594170724">"Uygulamanın titreşim durumuna erişimesine izni verir."</string>
<string name="permlab_callPhone" msgid="1798582257194643320">"telefon numaralarına doğrudan çağrı yap"</string>
- <string name="permdesc_callPhone" msgid="5439809516131609109">"Uygulamaya sizin müdahaleniz olmadan telefon numaralarına çağrı yapma izni verir. Bu durum beklenmeyen ödemelere veya çağrılara neden olabilir. Ancak bu iznin, uygulamanın acil numaralara çağrı yapmasına olanak sağlamadığını unutmayın. Kötü amaçlı uygulamalar onayınız olmadan çağrılar yaparak sizi zarara sokabilir."</string>
+ <string name="permdesc_callPhone" msgid="5439809516131609109">"Uygulamaya sizin müdahaleniz olmadan telefon numaralarını arama izni verir. Bu durum beklenmeyen ödemelere veya aramalara neden olabilir. Ancak bu iznin, uygulamanın acil numaraları aramasına olanak sağlamadığını unutmayın. Kötü amaçlı uygulamalar onayınız olmadan aramalar yaparak sizi zarara sokabilir."</string>
<string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS çağrı hizmetine erişme"</string>
<string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Uygulamanın, sizin müdahaleniz olmadan telefon etmek için IMS hizmetini kullanmasına izin verir."</string>
<string name="permlab_readPhoneState" msgid="8138526903259297969">"telefonun durumunu ve kimliğini okuma"</string>
<string name="permdesc_readPhoneState" msgid="7229063553502788058">"Uygulamaya cihazdaki telefon özelliklerine erişme izni verir. Bu izin, uygulamanın telefon numarasını ve cihaz kimliğini, etkin bir çağrı olup olmadığını ve çağrıda bağlanılan karşı tarafın numarasını öğrenmesine olanak sağlar."</string>
- <string name="permlab_manageOwnCalls" msgid="9033349060307561370">"çağrıları sistem üzerinden yönlendir"</string>
+ <string name="permlab_manageOwnCalls" msgid="9033349060307561370">"aramaları sistem üzerinden yönlendir"</string>
<string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Uygulamanın, çağrı deneyimini iyileştirmek için çağrılarını sistem üzerinden yönlendirmesine olanak tanır."</string>
<string name="permlab_callCompanionApp" msgid="3654373653014126884">"aramaları sistemde görüp denetleme."</string>
<string name="permdesc_callCompanionApp" msgid="8474168926184156261">"Uygulamanın cihazda devam eden aramaları görmesini ve denetlemesini sağlar. Bu bilgiler arasında aramaların yapıldığı numaralar ve aramaların durumu gibi bilgiler yer alır."</string>
@@ -671,8 +671,8 @@
<string name="permdesc_sdcardRead" msgid="6872973242228240382">"Uygulamaya, paylaşılan depolama alanınızın içeriğini okuma izni verir."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"paylaşılan depolama alanımın içeriğini değiştir veya sil"</string>
<string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Uygulamanın paylaşılan depolama alanınıza içerik yazmasına izin verir."</string>
- <string name="permlab_use_sip" msgid="8250774565189337477">"SIP çağrıları yapma/alma"</string>
- <string name="permdesc_use_sip" msgid="3590270893253204451">"Uygulamanın SIP çağrıları yapmasına ve almasına izin verir."</string>
+ <string name="permlab_use_sip" msgid="8250774565189337477">"SIP aramaları yapma/alma"</string>
+ <string name="permdesc_use_sip" msgid="3590270893253204451">"Uygulamanın SIP aramaları yapmasına ve almasına izin verir."</string>
<string name="permlab_register_sim_subscription" msgid="1653054249287576161">"yeni telekomünikasyon SIM bağlantılarını kaydettir"</string>
<string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"Uygulamanın yeni telekomünikasyon SIM bağlantıları kaydettirmesine izin verir."</string>
<string name="permlab_register_call_provider" msgid="6135073566140050702">"yeni telekomünikasyon bağlantıları kaydettir"</string>
@@ -903,7 +903,7 @@
<string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"Durdur"</string>
<string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"Geri sar"</string>
<string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"İleri sar"</string>
- <string name="emergency_calls_only" msgid="3057351206678279851">"Yalnızca acil çağrılar için"</string>
+ <string name="emergency_calls_only" msgid="3057351206678279851">"Yalnızca acil aramalar için"</string>
<string name="lockscreen_network_locked_message" msgid="2814046965899249635">"Ağ kilitli"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="6618356415831082174">"SIM kart PUK kilidi devrede."</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"Kullanıcı Rehberi\'ne bakın veya Müşteri Hizmetleri\'ne başvurun."</string>
@@ -1694,8 +1694,8 @@
<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>
- <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"İşlemleri görüntüleyin ve gerçekleştirin"</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>
+ <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"İşlemleri görüntüleme ve gerçekleştirme"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Bir uygulama veya donanım sensörüyle etkileşimlerinizi takip edebilir ve sizin adınıza uygulamalarla etkileşimde bulunabilir."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"İzin ver"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Reddet"</string>
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Yöneticiniz tarafından güncellendi"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Yöneticiniz tarafından silindi"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"Tamam"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Pil Tasarrufu, Koyu temayı açıp arka plan etkinliğini, bazı görsel efektleri ve \"Ok Google\" gibi özellikleri kapatır veya kısıtlar.\n\n"<annotation id="url">"Daha fazla bilgi"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Pil Tasarrufu, Koyu temayı açıp arka plan etkinliğini, bazı görsel efektleri ve \"Ok Google\" gibi özellikleri kapatır veya kısıtlar."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Veri kullanımını azaltmaya yardımcı olması için Veri Tasarrufu, bazı uygulamaların arka planda veri göndermesini veya almasını engeller. Şu anda kullandığınız bir uygulama veri bağlantısına erişebilir, ancak bunu daha seyrek yapabilir. Bu durumda örneğin, siz resimlere dokunmadan resimler görüntülenmez."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Veri Tasarrufu açılsın mı?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Aç"</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Kapat"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Yanıtla"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Reddet"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Kapat"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Gelen çağrı"</string>
@@ -2056,8 +2055,8 @@
<string name="harmful_app_warning_title" msgid="8794823880881113856">"Zararlı uygulama tespit edildi"</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>
- <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Çağrılar ve bildirimler titreşim yapacak"</string>
- <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Çağrılar ve bildirimlerin sesi kapalı olacak"</string>
+ <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Aramalar ve bildirimler titreşim yapacak"</string>
+ <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Aramalar ve bildirimlerin sesi kapalı olacak"</string>
<string name="notification_channel_system_changes" msgid="2462010596920209678">"Sistem değişiklikleri"</string>
<string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Rahatsız Etmeyin"</string>
<string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Yeni: Rahatsız Etmeyin ayarı bildirimleri gizliyor"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Bu bildirimin önem derecesi, \"Sessiz\" seviyesine düşürüldü. Geri bildirimde bulunmak için dokunun."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Bu bildirimin önem derecesi yükseltildi. Geri bildirimde bulunmak için dokunun."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Bu bildirimin önem derecesi düşürüldü. Geri bildirimde bulunmak için dokunun."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Gelişmiş bildirimleri deneyin"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Önerilen işlemleri, yanıtları ve diğer içerikleri almaya devam etmek için gelişmiş bildirimleri açın. Android Uyarlamalı Bildirimler artık desteklenmiyor."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Aç"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Şimdi değil"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Daha fazla bilgi"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Gelişmiş bildirimler, kişiler ve mesajlar gibi kişisel bilgiler dahil olmak üzere tüm bildirim içeriklerini okuyabilir. Bu özellik ayrıca bildirimleri kapatabilir veya bildirimlerdeki düğmeler üzerinde telefon çağrılarını yanıtlamak gibi işlemler yapabilir.\n\nBu özellik ayrıca Öncelik modunu açıp kapatabilir ve ilgili ayarları değiştirebilir."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rutin Modu bilgi bildirimi"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Pil normal şarjdan önce bitebilir"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Pilin ömrünü uzatmak için Pil Tasarrufu etkinleştirildi"</string>
@@ -2271,7 +2264,7 @@
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
<string name="window_magnification_prompt_title" msgid="2876703640772778215">"Yeni büyütme ayarları"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Artık ekranınızın bir bölümünü büyütebilirsiniz"</string>
- <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ayarlar\'da aç"</string>
+ <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Ayarlar\'da etkinleştir"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Kapat"</string>
<string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Cihaz mikrofonunun engellemesini kaldır"</string>
<string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Cihaz kamerasının engellemesini kaldır"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 7a74489..9401d50 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -544,10 +544,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Дозволяє додатку знаходити поблизу пристрої Bluetooth і створювати з ними пару"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"підключатися до пристроїв із Bluetooth, з якими є пара"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Дозволяє додатку підключатися до пристроїв із Bluetooth, з якими створено пару"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"показувати рекламу на пристроях із Bluetooth поблизу"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Додаток зможе показувати рекламу на пристроях із Bluetooth поблизу"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"визначення відстані між пристроями поблизу з надширокосмуговим зв’язком"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"З цим дозволом додаток може визначати відстань між розташованими поблизу пристроями з надширокосмуговим зв’язком"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Використання інформації з платіжного NFC-сервісу"</string>
@@ -1741,7 +1739,7 @@
<string name="accessibility_service_warning_description" msgid="291674995220940133">"Повний доступ доречний для додатків, які надають спеціальні можливості, але його не варто відкривати для більшості інших додатків."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Перегляд і контроль екрана"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Цей сервіс може переглядати всі дані на екрані й показувати вміст над іншими додатками."</string>
- <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Переглянути й виконати дії"</string>
+ <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Перегляд і виконання дій"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Цей сервіс може відстежувати вашу взаємодію з додатком чи апаратним датчиком, а також взаємодіяти з додатками від вашого імені."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Дозволити"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Заборонити"</string>
@@ -1900,10 +1898,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"У режимі енергозбереження вмикається темна тема й обмежуються чи вимикаються фонова робота додатків, деякі візуальні ефекти та інші функції, як-от \"Ok Google\"\n\n"<annotation id="url">"Докладніше"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"У режимі енергозбереження вмикається темна тема й обмежуються чи вимикаються фонова робота додатків, деякі візуальні ефекти та інші функції, як-от \"Ok Google\"."</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>
@@ -1995,6 +1991,8 @@
<string name="close_button_text" msgid="10603510034455258">"Закрити"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Відповісти"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Відхилити"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Завершити"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Вхідний виклик"</string>
@@ -2142,18 +2140,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Важливість цього сповіщення знижено до рівня \"Без звуку\". Натисніть, щоб надіслати відгук."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Важливість цього сповіщення підвищено. Натисніть, щоб надіслати відгук."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Важливість цього сповіщення знижено. Натисніть, щоб надіслати відгук."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Спробуйте покращені сповіщення"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Щоб і надалі отримувати пропозиції дій, відповідей тощо, увімкніть покращені сповіщення. Адаптивні сповіщення Android більше не підтримуються."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Увімкнути"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Не зараз"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Докладніше"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Покращені сповіщення дають змогу читати весь вміст сповіщень, зокрема особисту інформацію, як-от імена контактів і повідомлення. Крім того, ви зможете відхиляти сповіщення або натискати кнопки в них, щоб виконувати певні дії, наприклад відповідати на телефонні дзвінки.\n\nЦя функція також дає змогу вмикати й вимикати режим пріоритетності та змінювати відповідні налаштування."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Сповіщення про послідовнсть дій"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Акумулятор може розрядитися раніше ніж зазвичай"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Режим енергозбереження активовано для збільшення часу роботи акумулятора"</string>
@@ -2343,14 +2335,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Тепер можна збільшувати частину екрана"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Увімкнути в налаштуваннях"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Закрити"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Розблокуйте мікрофон пристрою"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Розблокуйте камеру пристрою"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Для <b><xliff:g id="APP">%s</xliff:g></b> та всіх додатків і сервісів"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Розблокувати"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Конфіденційність датчиків"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Значок додатка"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Зображення фірмової символіки додатка"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 854741b..9291cd2 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -319,10 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"اپنی جسمانی سرگرمی تک رسائی حاصل کریں"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"کیمرا"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"تصاویر لیں اور ویڈیو ریکارڈ کریں"</string>
- <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
- <skip />
- <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
- <skip />
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"قریبی آلات"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"قریبی آلات دریافت کریں اور ان سے منسلک ہوں"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"کال لاگز"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"فون کال لاگ پڑھ کر لکھیں"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"فون"</string>
@@ -540,14 +538,10 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"ایپ کو قریبی بلوٹوتھ آلات دریافت کرنے اور ان کا جوڑا بنانے کی اجازت دیں"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"جوڑا بنائے ہوئے بلوٹوتھ آلات سے منسلک کریں"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"ایپ کو جوڑا بنائے ہوئے بلوٹوتھ آلات سے منسلک کرنے کی اجازت دیں"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"قریبی بلوٹوتھ آلات پر تشہیر کریں"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"اس سے ایپ کو قریبی بلوٹوتھ آلات پر تشہیر کرنے کی اجازت ملتی ہے"</string>
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"قریبی الٹرا وائڈ بینڈ آلات کے مابین متعلقہ پوزیشن کا تعین کریں"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ایپ کو قریبی الٹرا وائڈ بینڈ آلات کے مابین متعلقہ پوزیشن کا تعین کرنے کی اجازت دیں"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ترجیح شدہ NFC ادائیگی کی سروس کی معلومات"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"ایپ کو رجسٹرشدہ ایڈز اور روٹ ڈسٹنیشن جیسی ترجیح شدہ nfc ادائیگی سروس کی معلومات حاصل کرنے کی اجازت دیتا ہے۔"</string>
<string name="permlab_nfc" msgid="1904455246837674977">"Near Field کمیونیکیشن کنٹرول کریں"</string>
@@ -1858,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"بیٹری سیور گہری تھیم کو آن کرتی ہے اور پس منظر کی سرگرمی، کچھ بصری اثرات اور \"Hey Google\" جیسی خصوصیات کو محدود یا آف کرتی ہے\n\n"<annotation id="url">"مزید جانیں"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"بیٹری سیور گہری تھیم کو آن کرتی ہے اور پس منظر کی سرگرمی، کچھ بصری اثرات اور \"Hey Google\" جیسی خصوصیات کو محدود یا آف کرتی ہے۔"</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>
@@ -1937,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"بند کریں"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"جواب"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"مسترد کریں"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"منقطع کر دیں"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"اِن کمنگ کال"</string>
@@ -2080,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"اس اطلاع کو خاموش پر ڈیموٹ کیا گيا۔ تاثرات فراہم کرنے کے ليے تھپتھپائیں۔"</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"اس اطلاع کو اعلی درجہ دیا گیا۔ تاثرات فراہم کرنے کے ليے تھپتھپائیں۔"</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"اس اطلاع کو کم درجہ دیا گیا۔ تاثرات فراہم کرنے کے ليے تھپتھپائیں۔"</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"بہتر کردہ اطلاعات آزمائیں"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"تجویز کردہ کارروائیاں، جوابات اور مزید بہت کچھ حاصل کرنا جاری رکھنے کے لیے بہتر کردہ اطلاعات آن کریں۔ Android اڈاپٹیو اطلاعات اب تعاون یافتہ نہیں ہیں۔"</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"آن کریں"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"ابھی نہیں"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"مزید جانیں"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"بہتر کردہ اطلاعات رابطوں کے نام اور پیغامات جیسی ذاتی معلومات سمیت تمام اطلاعی مواد پڑھ سکتی ہیں۔ یہ خصوصیت اطلاعات کو برخاست بھی کر سکتی ہے یا کالز کا جواب دینے جیسے اطلاعات میں نظر آنے والے بٹنوں سے کارروائیاں کر سکتی ہے۔\n\nیہ خصوصیت ترجیحی موڈ کو آن یا آف بھی کر سکتی ہے اور متعلقہ ترتیبات کو تبدیل کر سکتی ہے۔"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"روٹین موڈ معلومات کی اطلاع"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"معمول چارج سے پہلے بیٹری ختم ہو سکتی ہے"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"بیٹری لائف کو بڑھانے کے لیے بیٹری سیور کو فعال کر دیا گیا ہے"</string>
@@ -2279,17 +2267,13 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"اب آپ اپنی اسکرین کے حصے کو بڑا کر سکتے ہیں"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"ترتیبات میں آن کریں"</string>
<string name="dismiss_action" msgid="1728820550388704784">"برخاست کریں"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"آلے کا مائیکروفون غیر مسدود کریں"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"آلے کا کیمرا غیر مسدود کریں"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"<b><xliff:g id="APP">%s</xliff:g></b> اور سبھی ایپس اور سروسز کے لیے"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"غیر مسدود کریں"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"سینسر کی رازداری"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"ایپلیکیشن کا آئیکن"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ایپلیکیشن کی برانڈنگ تصویر"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"رسائی کی ترتیبات چیک کریں"</string>
- <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> آپ کی اسکرین کو دیکھ اور کنٹرول کر سکتی ہیں۔ جائزے کے لیے تھپتھپائیں۔"</string>
+ <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> آپ کی اسکرین کو دیکھ اور کنٹرول کر سکتی ہیں۔ جائزے کے لیے تھپتھپائیں۔"</string>
</resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index a40e083..3b135ec 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -319,10 +319,8 @@
<string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"jismoniy harakatlar axborotiga ruxsat"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"suratga olish va video yozib olish"</string>
- <!-- no translation found for permgrouplab_nearby_devices (5529147543651181991) -->
- <skip />
- <!-- no translation found for permgroupdesc_nearby_devices (3213561597116913508) -->
- <skip />
+ <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Yaqin-atrofdagi qurilmalar"</string>
+ <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"yaqin-atrofdagi qurilmalarni aniqlash va ulanish"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Chaqiruvlar jurnali"</string>
<string name="permgroupdesc_calllog" msgid="2026996642917801803">"telefon chaqiruvlari jurnalini o‘qish va unga yozish"</string>
<string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string>
@@ -542,10 +540,8 @@
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Ilovaga juftlangan Bluetooth qurilmalariga ulanish uchun ruxsat beradi"</string>
<string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"atrofdagi Bluetooth qurilmalariga reklama berish"</string>
<string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Ilovaga yaqin-atrofdagi Bluetooth qurilmalariga reklama yuborish imkonini beradi"</string>
- <!-- no translation found for permlab_uwb_ranging (8141915781475770665) -->
- <skip />
- <!-- no translation found for permdesc_uwb_ranging (2519723069604307055) -->
- <skip />
+ <string name="permlab_uwb_ranging" msgid="8141915781475770665">"yaqin atrofdagi ultra keng polosali qurilmalarining nisbiy joylashishini aniqlash"</string>
+ <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Ilovaga yaqin atrofdagi ultra keng polosali qurilmalarining nisbiy joylashishini aniqlashga ruxsat beradi"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Asosiy NFC toʻlov xizmati haqidagi axborot"</string>
<string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Bu ilovaga asosiy NFC toʻlov xizmati haqidagi axborotni olish imkonini beradi (masalan, qayd qilingan AID identifikatorlari va marshrutning yakuniy manzili)."</string>
<string name="permlab_nfc" msgid="1904455246837674977">"NFC modulini boshqarish"</string>
@@ -1856,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Administrator tomonidan yangilangan"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Administrator tomonidan o‘chirilgan"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Quvvat tejash funksiyasi Tungi mavzuni va cheklovlarni yoqadi va fondagi harakatlar, vizual effektlar va “Ok Google” kabi boshqa funksiyalarni faolsizlantiradi yoki cheklaydi.\n\n"<annotation id="url">"Batafsil"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Quvvat tejash funksiyasi Tungi mavzuni va cheklovlarni yoqadi va fondagi harakatlar, vizual effektlar va “Ok Google” kabi boshqa funksiyalarni faolsizlantiradi yoki cheklaydi."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Trafik tejash rejimida ayrim ilovalar uchun orqa fonda internetdan foydalanish imkoniyati cheklanadi. Siz ishlatayotgan ilova zaruratga qarab internet-trafik sarflashi mumkin, biroq cheklangan miqdorda. Masalan, rasmlar ustiga bosmaguningizcha ular yuklanmaydi."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Trafik tejash yoqilsinmi?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Yoqish"</string>
@@ -1935,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"Yopish"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Javob berish"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"Rad etish"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Tugatish"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Kiruvchi chaqiruv"</string>
@@ -2078,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Bu bildirishnoma darajasi Tovushsiz darajaga tushirildi Fikr-mulohaza bildirish uchun bosing."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Bu bildirishnoma darajasi oshirildi. Fikr-mulohaza bildirish uchun bosing."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Bu bildirishnoma darajasi pasaytirildi. Fikr-mulohaza bildirish uchun bosing."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Yangicha bildirishnomalar"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Amallar, javoblar va boshqa takliflarni olishda davom etish uchun yaxshilangan bildirishnomalarni yoqing. Android moslashuvchan bildirishnomalari endi ishlamaydi."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Yoqish"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Hozir emas"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Batafsil"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Yangicha bildirishnomalar funksiyasi barcha bildirishnomalarni, jumladan, shaxsiy maʼlumotlarni (kontakt nomlari va xabarlar) oʻqiy oladi. Shuningdek, bu funksiya bildirishnomalarni yopishi yoki telefon chaqiruvlariga javob berish kabi bildirishnomalarda tugmalar bilan amallar bajarishi mumkin.\n\nBu funksiya Faqat muhim rejimini yoqishi va faolsizlantirishi yoki unga aloqador sozlamalarni oʻzgartirishi ham mumkin."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Kun tartibi rejimi haqidagi bildirishnoma"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Batareya quvvati odatdagidan ertaroq tugashi mumkin"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batareya quvvatini uzoqroq vaqtga yetkazish uchun quvvat tejash rejimi yoqildi"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 41edab4..77d81d8 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -531,17 +531,15 @@
<string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"Cho phép ứng dụng kết nối và ngắt kết nối thiết bị Android TV khỏi mạng WiMAX."</string>
<string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"Cho phép ứng dụng kết nối điện thoại và ngắt kết nối điện thoại khỏi mạng WiMAX."</string>
<string name="permlab_bluetooth" msgid="586333280736937209">"ghép nối với thiết bị Bluetooth"</string>
- <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Cho phép ứng dụng xem cấu hình của Bluetooth trên máy tính bảng và tạo và chấp nhận các kết nối với các thiết bị được ghép nối."</string>
- <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Cho phép ứng dụng xem cấu hình của Bluetooth trên thiết bị Android TV, đồng thời tạo và chấp nhận các kết nối với thiết bị được ghép nối."</string>
- <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Cho phép ứng dụng xem cấu hình của Bluetooth trên điện thoại, tạo và chấp nhận các kết nối với các thiết bị được ghép nối."</string>
+ <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Cho phép ứng dụng xem cấu hình của Bluetooth trên máy tính bảng và tạo và chấp nhận các kết nối với các thiết bị đã ghép nối."</string>
+ <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Cho phép ứng dụng xem cấu hình của Bluetooth trên thiết bị Android TV, đồng thời tạo và chấp nhận các kết nối với thiết bị đã ghép nối."</string>
+ <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Cho phép ứng dụng xem cấu hình của Bluetooth trên điện thoại, tạo và chấp nhận các kết nối với các thiết bị đã ghép nối."</string>
<string name="permlab_bluetooth_scan" msgid="5402587142833124594">"khám phá và ghép nối với thiết bị Bluetooth ở gần"</string>
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Cho phép ứng dụng khám phá và ghép nối với các thiết bị Bluetooth ở gần"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"kết nối với các thiết bị Bluetooth đã ghép nối"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Cho phép ứng dụng kết nối với thiết bị Bluetooth đã ghép nối"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"quảng cáo trên các thiết bị Bluetooth ở gần"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Cho phép ứng dụng quảng cáo trên các thiết bị Bluetooth ở gần"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"xác định khoảng cách tương đối giữa các thiết bị ở gần dùng Băng tần siêu rộng"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Cho phép ứng dụng xác định khoảng cách tương đối giữa các thiết bị ở gần dùng Băng tần siêu rộng"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Thông tin về dịch vụ thanh toán qua công nghệ giao tiếp tầm gần (NFC) được ưu tiên"</string>
@@ -1388,8 +1386,8 @@
<string name="share_remote_bugreport_action" msgid="7630880678785123682">"CHIA SẺ"</string>
<string name="decline_remote_bugreport_action" msgid="4040894777519784346">"TỪ CHỐI"</string>
<string name="select_input_method" msgid="3971267998568587025">"Chọn phương thức nhập"</string>
- <string name="show_ime" msgid="6406112007347443383">"Hiển thị bàn phím ảo trên màn hình trong khi bàn phím vật lý đang hoạt động"</string>
- <string name="hardware" msgid="1800597768237606953">"Hiển thị bàn phím ảo"</string>
+ <string name="show_ime" msgid="6406112007347443383">"Hiện bàn phím ảo trên màn hình trong khi bàn phím vật lý đang hoạt động"</string>
+ <string name="hardware" msgid="1800597768237606953">"Hiện bàn phím ảo"</string>
<string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Định cấu hình bàn phím vật lý"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Nhấn để chọn ngôn ngữ và bố cục"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1854,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Do quản trị viên của bạn cập nhật"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Do quản trị viên của bạn xóa"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Tính năng Tiết kiệm pin sẽ bật Giao diện tối, đồng thời tắt hoặc hạn chế hoạt động chạy trong nền, một số hiệu ứng hình ảnh và các tính năng như lệnh “Ok Google”\n\n"<annotation id="url">"Tìm hiểu thêm"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Tính năng Tiết kiệm pin sẽ bật Giao diện tối, đồng thời tắt hoặc hạn chế hoạt động chạy trong nền, một số hiệu ứng hình ảnh và các tính năng như lệnh “Ok Google”."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Để giúp giảm mức sử dụng dữ liệu, Trình tiết kiệm dữ liệu sẽ chặn một số ứng dụng gửi hoặc nhận dữ liệu trong nền. Ứng dụng mà bạn hiện sử dụng có thể dùng dữ liệu nhưng tần suất sẽ giảm. Ví dụ: hình ảnh sẽ không hiển thị cho đến khi bạn nhấn vào hình ảnh đó."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Bật Trình tiết kiệm dữ liệu?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Bật"</string>
@@ -1933,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Đóng"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Trả lời"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Video"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Từ chối"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Kết thúc"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Cuộc gọi đến"</string>
@@ -2076,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Hệ thống đã hạ mức ưu tiên của thông báo này xuống thành Im lặng. Hãy nhấn để chia sẻ ý kiến phản hồi."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Hệ thống đã nâng mức ưu tiên của thông báo này. Hãy nhấn để chia sẻ ý kiến phản hồi."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Hệ thống đã hạ mức ưu tiên của thông báo này. Hãy nhấn để chia sẻ ý kiến phản hồi."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Dùng thử thông báo nâng cao"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Để tiếp tục nhận các thao tác đề xuất, câu trả lời và nhiều nội dung khác, hãy bật thông báo nâng cao. Thông báo thích ứng trên Android không được hỗ trợ nữa."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Bật"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Để sau"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Tìm hiểu thêm"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Thông báo nâng cao có thể đọc mọi nội dung thông báo, bao gồm cả thông tin cá nhân như tên liên hệ và tin nhắn. Tính năng này cũng có thể đóng các thông báo hoặc thực hiện thao tác đối với các nút trong thông báo, chẳng hạn như trả lời cuộc gọi điện thoại.\n\nTính năng này cũng có thể bật hoặc tắt Chế độ ưu tiên và thay đổi các chế độ cài đặt liên quan."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Thông báo cung cấp thông tin về chế độ sạc thông thường"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Pin có thể hết trước khi sạc bình thường"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Trình tiết kiệm pin được kích hoạt để kéo dài thời lượng pin"</string>
@@ -2275,14 +2266,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"Giờ đây, bạn có thể phóng to một phần màn hình"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Bật trong phần Cài đặt"</string>
<string name="dismiss_action" msgid="1728820550388704784">"Đóng"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Bỏ chặn micrô của thiết bị"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Bỏ chặn máy ảnh của thiết bị"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Cho <b><xliff:g id="APP">%s</xliff:g></b> cũng như mọi ứng dụng và dịch vụ"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Bỏ chặn"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Quyền riêng tư khi sử dụng cảm biến"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"Biểu tượng ứng dụng"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Hình ảnh thương hiệu của ứng dụng"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 8d8485d..1d4ee44 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -538,10 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"允许该应用发现附近的蓝牙设备并与其配对"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"连接到已配对的蓝牙设备"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"允许该应用连接到已配对的蓝牙设备"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"向附近的蓝牙设备广播"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"允许该应用向附近的蓝牙设备广播"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"确定附近超宽带设备之间的相对位置"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"允许应用确定附近超宽带设备之间的相对位置"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"首选 NFC 付款服务信息"</string>
@@ -1388,7 +1386,7 @@
<string name="share_remote_bugreport_action" msgid="7630880678785123682">"分享"</string>
<string name="decline_remote_bugreport_action" msgid="4040894777519784346">"拒绝"</string>
<string name="select_input_method" msgid="3971267998568587025">"选择输入法"</string>
- <string name="show_ime" msgid="6406112007347443383">"在连接到实体键盘时保持显示"</string>
+ <string name="show_ime" msgid="6406112007347443383">"开启后,连接到实体键盘时,它会一直显示在屏幕上"</string>
<string name="hardware" msgid="1800597768237606953">"显示虚拟键盘"</string>
<string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"配置实体键盘"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"点按即可选择语言和布局"</string>
@@ -1854,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"省电模式会开启深色主题,并限制或关闭后台活动、部分视觉效果和“Ok Google”等功能\n\n"<annotation id="url">"了解详情"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"省电模式会开启深色主题,并限制或关闭后台活动、部分视觉效果和“Ok Google”等功能。"</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>
@@ -1933,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"关闭"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>:<xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"接听"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"拒接"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"挂断"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"来电"</string>
@@ -2076,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"系统已将此通知的重要性降低为“静音”。点按即可提供反馈。"</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"系统已提升此通知的重要性。点按即可提供反馈。"</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"系统已降低此通知的重要性。点按即可提供反馈。"</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"试用增强型通知"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"如需继续接收建议的操作、回复等内容,请开启增强型通知功能。系统不再支持 Android 自动调节通知功能。"</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"开启"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"以后再说"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"了解详情"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"增强型通知功能可以读取所有通知内容,包括联系人姓名和消息等个人信息。该功能也能关闭通知或触发通知中的按钮,例如接听来电。\n\n此外,该功能还能开启或关闭“优先”模式,以及更改相关设置。"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"日常安排模式信息通知"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"电池电量可能会在您平时的充电时间之前耗尽"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"已启用省电模式以延长电池续航时间"</string>
@@ -2275,14 +2267,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"现在您可以放大屏幕上的部分内容"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"在“设置”中开启"</string>
<string name="dismiss_action" msgid="1728820550388704784">"关闭"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"取消禁用设备麦克风"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"取消禁用设备摄像头"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"针对<b><xliff:g id="APP">%s</xliff:g></b>及所有应用和服务"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"取消禁用"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"传感器隐私权"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"应用图标"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"应用品牌图片"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 68e06b13..9c6b851 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -445,7 +445,7 @@
<string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"即使您不使用此應用程式,它仍可隨時存取位置。"</string>
<string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"更改音效設定"</string>
<string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"允許應用程式修改全域音頻設定,例如音量和用於輸出的喇叭。"</string>
- <string name="permlab_recordAudio" msgid="1208457423054219147">"錄製音效"</string>
+ <string name="permlab_recordAudio" msgid="1208457423054219147">"錄音"</string>
<string name="permdesc_recordAudio" msgid="5857246765327514062">"此應用程式在使用期間可使用麥克風錄音。"</string>
<string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"在背景錄音"</string>
<string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"此應用程式可隨時使用麥克風錄音。"</string>
@@ -538,10 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"允許應用程式探索並配對附近的藍牙裝置"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"連接附近的藍牙裝置"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"允許應用程式連接已配對的藍牙裝置"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"向附近的藍牙裝置宣傳"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"允許應用程式向附近的藍牙裝置宣傳"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"判斷附近超寬頻裝置之間的相對位置"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"允許應用程式判斷附近超寬頻裝置之間的相對位置"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"由用戶允許授權的 NFC 付款服務資訊"</string>
@@ -1854,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"「省電模式」會開啟深色主題背景並限制或關閉背景活動、部分視覺效果,以及「Ok Google」啟動字詞等功能。\n\n"<annotation id="url">"瞭解詳情"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"「省電模式」會開啟深色主題背景並限制或關閉背景活動、部分視覺效果,以及「Ok Google」啟動字詞等功能。"</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>
@@ -1933,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"關閉"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>:<xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"接聽"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"視像"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"拒接"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"掛斷"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"來電"</string>
@@ -2076,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"此通知的重要性已降低為「靜音」。輕按即可提供意見。"</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"此通知的重要性已提升。輕按即可提供意見。"</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"此通知的重要性已降級。輕按即可提供意見。"</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"試用強化通知"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"如要繼續收到建議操作和回覆等內容,請開啟強化通知功能。系統已不再支援 Android 自動調整通知功能。"</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"開啟"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"暫時不要"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"瞭解詳情"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"強化通知功能可讀取所有通知內容 (包括聯絡人姓名和訊息等個人資料),以及關閉通知或針對通知中的按鈕採取行動,例如接聽來電。\n\n此功能亦可開啟或關閉「優先」模式及變更相關設定。"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"「日常安排模式」資料通知"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"電量可能會在日常充電前耗盡"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"「省電模式」已啟用,以便延長電池壽命"</string>
@@ -2275,14 +2266,10 @@
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"您現在可以放大部分畫面"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"在「設定」中開啟"</string>
<string name="dismiss_action" msgid="1728820550388704784">"關閉"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"解除封鎖裝置麥克風"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"解除封鎖裝置相機"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"適用於「<b><xliff:g id="APP">%s</xliff:g></b>」和所有應用程式及服務"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"解除封鎖"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"感應器私隱"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"應用程式圖示"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"應用程式品牌形象"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 78f326b..60cfa7e 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -350,9 +350,9 @@
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"在已鎖定的裝置上以全螢幕活動的形式顯示通知"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"允許應用程式在已鎖定的裝置上以全螢幕活動的形式顯示通知"</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"安裝捷徑"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"允許應用程式自動新增主螢幕捷徑。"</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"允許應用程式自動新增主畫面捷徑。"</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"解除安裝捷徑"</string>
- <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"允許應用程式自動移除主螢幕捷徑。"</string>
+ <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"允許應用程式自動移除主畫面捷徑。"</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"重設撥號路徑"</string>
<string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"允許應用程式在撥打電話期間查看撥出的電話號碼,並可選擇改撥其他號碼或中斷通話。"</string>
<string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"接聽電話"</string>
@@ -538,10 +538,8 @@
<string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"允許應用程式探索鄰近藍牙裝置並進行配對"</string>
<string name="permlab_bluetooth_connect" msgid="6657463246355003528">"與已配對的藍牙裝置連線"</string>
<string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"允許應用程式與已配對的藍牙裝置連線"</string>
- <!-- no translation found for permlab_bluetooth_advertise (2781147747928853177) -->
- <skip />
- <!-- no translation found for permdesc_bluetooth_advertise (6085174451034210183) -->
- <skip />
+ <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"向附近的藍牙裝置廣播"</string>
+ <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"允許應用程式向附近的藍牙裝置廣播"</string>
<string name="permlab_uwb_ranging" msgid="8141915781475770665">"判斷附近超寬頻裝置間的相對位置"</string>
<string name="permdesc_uwb_ranging" msgid="2519723069604307055">"允許應用程式判斷附近超寬頻裝置間的相對位置"</string>
<string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"首選 NFC 付費服務資訊"</string>
@@ -1204,7 +1202,7 @@
<string name="whichSendToApplicationNamed" msgid="3385686512014670003">"透過「%1$s」傳送"</string>
<string name="whichSendToApplicationLabel" msgid="3543240188816513303">"傳送"</string>
<string name="whichHomeApplication" msgid="8276350727038396616">"選取主畫面應用程式"</string>
- <string name="whichHomeApplicationNamed" msgid="5855990024847433794">"使用「%1$s」做為主螢幕"</string>
+ <string name="whichHomeApplicationNamed" msgid="5855990024847433794">"使用「%1$s」做為主畫面"</string>
<string name="whichHomeApplicationLabel" msgid="8907334282202933959">"擷取圖片"</string>
<string name="whichImageCaptureApplication" msgid="2737413019463215284">"使用以下應用程式擷取圖片:"</string>
<string name="whichImageCaptureApplicationNamed" msgid="8820702441847612202">"使用「%1$s」擷取圖片"</string>
@@ -1718,7 +1716,7 @@
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"輕觸無障礙工具按鈕後,選擇你想使用的功能:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"選擇要搭配無障礙手勢 (用兩指從螢幕底部向上滑動) 使用的功能:"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"選擇要搭配無障礙手勢 (用三指從螢幕底部向上滑動) 使用的功能:"</string>
- <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"如要切換不同的功能,請輕觸並按住無障礙工具按鈕。"</string>
+ <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"如要切換不同的功能,請按住無障礙工具按鈕。"</string>
<string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"如要切換不同的功能,請用兩指向上滑動並按住。"</string>
<string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"如要切換不同的功能,請用三指向上滑動並按住。"</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大"</string>
@@ -1854,10 +1852,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>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"省電模式會開啟深色主題並限制或關閉背景活動、部分視覺效果,以及「Ok Google」啟動字詞等功能\n\n"<annotation id="url">"瞭解詳情"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"省電模式會開啟深色主題並限制或關閉背景活動、部分視覺效果,以及「Ok Google」啟動字詞等功能。"</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>
@@ -1933,6 +1929,8 @@
<string name="close_button_text" msgid="10603510034455258">"關閉"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>:<xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"接聽"</string>
+ <!-- no translation found for call_notification_answer_video_action (2086030940195382249) -->
+ <skip />
<string name="call_notification_decline_action" msgid="3700345945214000726">"拒接"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"掛斷"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"來電"</string>
@@ -2076,18 +2074,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"這則通知的重要性已降低為「靜音」。輕觸即可提供意見。"</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"這則通知的重要性順序已調高。輕觸即可提供意見。"</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"這則通知的重要性順序已調降。輕觸即可提供意見。"</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"試試看加強型通知"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"如要繼續收到建議的操作、回覆等內容,請開啟加強型通知功能。系統已不再支援 Android 自動調整通知功能。"</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"開啟"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"暫時不要"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"瞭解詳情"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"加強型通知功能可讀取所有通知內容,包括聯絡人名稱和訊息內文等個人資訊。這項功能也能關閉通知或操作通知中的按鈕,例如接聽來電。\n\n此外,這項功能還可以開啟或關閉「優先」模式及變更相關設定。"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"日常安排模式資訊通知"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"電池電力可能會在你平常的充電時間前耗盡"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"已啟用省電模式以延長電池續航力"</string>
@@ -2123,7 +2115,7 @@
<string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"沒有建議的分享對象"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"應用程式清單"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"這個應用程式未取得錄製內容的權限,但可以透過這部 USB 裝置錄製音訊。"</string>
- <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"主螢幕"</string>
+ <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"主畫面"</string>
<string name="accessibility_system_action_back_label" msgid="4205361367345537608">"返回"</string>
<string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"最近使用的應用程式"</string>
<string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"通知"</string>
@@ -2271,18 +2263,14 @@
<string name="config_pdp_reject_user_authentication_failed" msgid="4531693033885744689"></string>
<string name="config_pdp_reject_service_not_subscribed" msgid="8190338397128671588"></string>
<string name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" msgid="6024904218067254186"></string>
- <string name="window_magnification_prompt_title" msgid="2876703640772778215">"放大功能推出新設定"</string>
+ <string name="window_magnification_prompt_title" msgid="2876703640772778215">"支援新的放大功能"</string>
<string name="window_magnification_prompt_content" msgid="8159173903032344891">"你現在可以放大局部畫面了"</string>
<string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"在「設定」中開啟"</string>
<string name="dismiss_action" msgid="1728820550388704784">"關閉"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_notification_content_title (2420858361276370367) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_notification_content_title (7287720213963466672) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_notification_content_text (7595608891015777346) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_dialog_turn_on_button (7089318886628390827) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"將裝置麥克風解除封鎖"</string>
+ <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"將裝置相機解除封鎖"</string>
+ <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"允許「<xliff:g id="APP">%s</xliff:g>」<b></b>及所有應用程式和服務使用"</string>
+ <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"解除封鎖"</string>
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"感應器隱私權"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"應用程式圖示"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"應用程式品牌圖片"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 1eb8438..e2a52f1 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1852,10 +1852,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"Kubuyekezwe umlawuli wakho"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"Kususwe umlawuli wakho"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"KULUNGILE"</string>
- <!-- no translation found for battery_saver_description_with_learn_more (7963058670863485450) -->
- <skip />
- <!-- no translation found for battery_saver_description (7695751399533397741) -->
- <skip />
+ <string name="battery_saver_description_with_learn_more" msgid="7963058670863485450">"Isilondolozi Sebhethri sivula Itimu Emnyama futhi sikhawulele noma sivale umsebenzi wendawo engemuva, izakhi ezithile ezibonakalayo, nezakhi ezinjenge-\"Ok Google\"\n\n"<annotation id="url">"Funda kabanzi"</annotation></string>
+ <string name="battery_saver_description" msgid="7695751399533397741">"Isilondolozi Sebhethri sivula Itimu Emnyama futhi sikhawulele noma sivale umsebenzi wendawo engemuva, izakhi ezithile ezibonakalayo, nezakhi ezinjenge-\"Ok Google\"."</string>
<string name="data_saver_description" msgid="4995164271550590517">"Ukusiza ukwehlisa ukusetshenziswa kwedatha, iseva yedatha igwema ezinye izinhlelo zokusebenza ukuthi zithumele noma zamukele idatha ngasemuva. Uhlelo lokusebenza olisebenzisa okwamanje lingafinyelela idatha, kodwa lingenza kanjalo kancane. Lokhu kungachaza, isibonelo, ukuthi izithombe azibonisi uze uzithephe."</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"Vula iseva yedatha?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"Vula"</string>
@@ -1931,6 +1929,7 @@
<string name="close_button_text" msgid="10603510034455258">"Vala"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"Phendula"</string>
+ <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Ividiyo"</string>
<string name="call_notification_decline_action" msgid="3700345945214000726">"Yenqaba"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"Vala Ucingo"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"Ikholi engenayo"</string>
@@ -1946,7 +1945,7 @@
<string name="notification_history_title_placeholder" msgid="7748630986182249599">"Isaziso sohlelo lokusebenza olungokwezifiso"</string>
<string name="user_creation_account_exists" msgid="2239146360099708035">"Vumela i-<xliff:g id="APP">%1$s</xliff:g> ukuthi idale umsebenzisi omusha nge-<xliff:g id="ACCOUNT">%2$s</xliff:g> (Umsebenzisi onale akhawunti usevele ukhona) ?"</string>
<string name="user_creation_adding" msgid="7305185499667958364">"Vumela i-<xliff:g id="APP">%1$s</xliff:g> ukuthi idale umsebenzisi omusha nge-<xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
- <string name="language_selection_title" msgid="52674936078683285">"Engeza ulwimi"</string>
+ <string name="language_selection_title" msgid="52674936078683285">"Engeza ulimi"</string>
<string name="country_selection_title" msgid="5221495687299014379">"Okuncamelayo kwesifunda"</string>
<string name="search_language_hint" msgid="7004225294308793583">"Thayipha igama lolimi"</string>
<string name="language_picker_section_suggested" msgid="6556199184638990447">"Okuphakanyisiwe"</string>
@@ -2074,18 +2073,12 @@
<string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Lesi saziso sehliselwe esikhundleni Sokuthula. Thepha ukuze unikeze impendulo."</string>
<string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Lesi saziso sibekwe ezingeni eliphakeme. Thepha ukuze unikeze impendulo."</string>
<string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Lesi saziso sibekwe ezingeni eliphansi. Thepha ukuze unikeze impendulo."</string>
- <!-- no translation found for nas_upgrade_notification_title (4224351129445073051) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_content (7036860187157134706) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_enable_action (4823652531622744798) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_disable_action (7561210256700811433) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_action (7011130656195423947) -->
- <skip />
- <!-- no translation found for nas_upgrade_notification_learn_more_content (6276343083934111208) -->
- <skip />
+ <string name="nas_upgrade_notification_title" msgid="4224351129445073051">"Zama izaziso ezigqanyisiwe"</string>
+ <string name="nas_upgrade_notification_content" msgid="7036860187157134706">"Ukuze uqhubeke nokuthola izenzo eziphakanyisiwe, izimpendulo nokuningi, vula izaziso ezigqanyisiwe. Izaziso ze-Androin Ezivumelana Nezimo azisasekelwe."</string>
+ <string name="nas_upgrade_notification_enable_action" msgid="4823652531622744798">"Vula"</string>
+ <string name="nas_upgrade_notification_disable_action" msgid="7561210256700811433">"Hhayi manje"</string>
+ <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Funda kabanzi"</string>
+ <string name="nas_upgrade_notification_learn_more_content" msgid="6276343083934111208">"Izaziso ezigqanyisiwe zingafunda konke okuqukethwe yizaziso zakho, kuhlanganise nolwazi lomuntu siqu njengamagama oxhumana nabo nemilayezo. Lesi sakhi singacashisa izaziso noma sithathe izinyathelo ezinkinobheni ezisezazisweni, njengokuphendula amakholi wefoni.\n\nLesi sici singavula noma sivale nemodi Yokubalulekile futhi sishintshe amasethingi ahambisanayo."</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Isaziso solwazi lwe-Routine Mode"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Ibhethri lingaphela ngaphambi kokushaja okuvamile"</string>
<string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Isilondolozi sebhethri siyasebenza ngaphandle kwempilo yebhethri"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index bd1d848..1d532fc 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -9577,7 +9577,7 @@
<!-- Perceptual luminance of a color, in accessibility friendly color space. From 0 to 100. -->
<attr name="lStar" format="float"/>
- <declare-styleable name="DisplayHasherService">
+ <declare-styleable name="DisplayHashingService">
<!-- The throttle duration for display hash requests
@hide @SystemApi -->
<attr name="throttleDurationMillis" format="integer" />
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 0213c60..3ad20c6 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -231,7 +231,8 @@
<color name="chooser_gradient_background">@color/loading_gradient_background_color_light</color>
<color name="chooser_gradient_highlight">@color/loading_gradient_highlight_color_light</color>
- <color name="GM2_grey_800">#ff3C4043</color>
+ <color name="GM2_grey_700">#5F6368</color>
+ <color name="GM2_grey_800">#3C4043</color>
<!-- Resolver/Chooser -->
<color name="resolver_text_color_secondary_dark">#ffC4C6C6</color>
diff --git a/core/res/res/values/colors_device_defaults.xml b/core/res/res/values/colors_device_defaults.xml
index bec0ad1..4c5a008 100644
--- a/core/res/res/values/colors_device_defaults.xml
+++ b/core/res/res/values/colors_device_defaults.xml
@@ -17,9 +17,9 @@
<!-- Colors specific to DeviceDefault themes. These are mostly pass-throughs to enable
overlaying new theme colors. -->
<resources>
- <color name="primary_device_default_dark">@color/system_neutral1_800</color>
+ <color name="primary_device_default_dark">@color/system_neutral1_900</color>
<color name="primary_device_default_light">@color/system_neutral1_50</color>
- <color name="primary_device_default_settings">@color/system_neutral1_800</color>
+ <color name="primary_device_default_settings">@color/system_neutral1_900</color>
<color name="primary_device_default_settings_light">@color/primary_device_default_light</color>
<color name="primary_dark_device_default_dark">@color/primary_device_default_dark</color>
<color name="primary_dark_device_default_light">@color/primary_device_default_light</color>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 0e436e3..062b080 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -570,6 +570,12 @@
<!-- Width of the outline stroke used by the accessibility focus rectangle -->
<dimen name="accessibility_focus_highlight_stroke_width">4dp</dimen>
+ <!-- The size of the Accessibility icon -->
+ <dimen name="accessibility_icon_size">32dp</dimen>
+
+ <!-- The size of the Accessibility icon foreground part -->
+ <dimen name="accessibility_icon_foreground_size">18dp</dimen>
+
<!-- Margin around the various security views -->
<dimen name="keyguard_muliuser_selector_margin">8dp</dimen>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5715fab..60383be 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3389,6 +3389,7 @@
<java-symbol type="drawable" name="ic_accessibility_color_inversion" />
<java-symbol type="drawable" name="ic_accessibility_color_correction" />
<java-symbol type="drawable" name="ic_accessibility_magnification" />
+ <java-symbol type="drawable" name="ic_accessibility_reduce_bright_colors" />
<java-symbol type="string" name="reduce_bright_colors_feature_name" />
diff --git a/core/tests/coretests/src/android/app/time/TimeZoneCapabilitiesTest.java b/core/tests/coretests/src/android/app/time/TimeZoneCapabilitiesTest.java
index dd93997..0082728 100644
--- a/core/tests/coretests/src/android/app/time/TimeZoneCapabilitiesTest.java
+++ b/core/tests/coretests/src/android/app/time/TimeZoneCapabilitiesTest.java
@@ -20,6 +20,8 @@
import static android.app.time.Capabilities.CAPABILITY_POSSESSED;
import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
@@ -157,4 +159,60 @@
assertNull(capabilities.tryApplyConfigChanges(oldConfiguration, configChange));
}
+
+ @Test
+ public void copyBuilder_copiesAllFields() {
+ TimeZoneCapabilities capabilities = new TimeZoneCapabilities.Builder(TEST_USER_HANDLE)
+ .setConfigureAutoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED)
+ .setConfigureGeoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED)
+ .setSuggestManualTimeZoneCapability(CAPABILITY_NOT_ALLOWED)
+ .build();
+
+ {
+ TimeZoneCapabilities updatedCapabilities =
+ new TimeZoneCapabilities.Builder(capabilities)
+ .setConfigureAutoDetectionEnabledCapability(CAPABILITY_POSSESSED)
+ .build();
+ TimeZoneCapabilities expectedCapabilities =
+ new TimeZoneCapabilities.Builder(TEST_USER_HANDLE)
+ .setConfigureAutoDetectionEnabledCapability(CAPABILITY_POSSESSED)
+ .setConfigureGeoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED)
+ .setSuggestManualTimeZoneCapability(CAPABILITY_NOT_ALLOWED)
+ .build();
+
+ assertThat(updatedCapabilities).isEqualTo(expectedCapabilities);
+ }
+
+ {
+ TimeZoneCapabilities updatedCapabilities =
+ new TimeZoneCapabilities.Builder(capabilities)
+ .setConfigureGeoDetectionEnabledCapability(CAPABILITY_POSSESSED)
+ .build();
+
+ TimeZoneCapabilities expectedCapabilities =
+ new TimeZoneCapabilities.Builder(TEST_USER_HANDLE)
+ .setConfigureAutoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED)
+ .setConfigureGeoDetectionEnabledCapability(CAPABILITY_POSSESSED)
+ .setSuggestManualTimeZoneCapability(CAPABILITY_NOT_ALLOWED)
+ .build();
+
+ assertThat(updatedCapabilities).isEqualTo(expectedCapabilities);
+ }
+
+ {
+ TimeZoneCapabilities updatedCapabilities =
+ new TimeZoneCapabilities.Builder(capabilities)
+ .setSuggestManualTimeZoneCapability(CAPABILITY_POSSESSED)
+ .build();
+
+ TimeZoneCapabilities expectedCapabilities =
+ new TimeZoneCapabilities.Builder(TEST_USER_HANDLE)
+ .setConfigureAutoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED)
+ .setConfigureGeoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED)
+ .setSuggestManualTimeZoneCapability(CAPABILITY_POSSESSED)
+ .build();
+
+ assertThat(updatedCapabilities).isEqualTo(expectedCapabilities);
+ }
+ }
}
diff --git a/core/tests/coretests/src/android/graphics/FontListParserTest.java b/core/tests/coretests/src/android/graphics/FontListParserTest.java
index bef1a4e..b2df98d 100644
--- a/core/tests/coretests/src/android/graphics/FontListParserTest.java
+++ b/core/tests/coretests/src/android/graphics/FontListParserTest.java
@@ -59,7 +59,7 @@
+ "</family>";
FontConfig.FontFamily expected = new FontConfig.FontFamily(
Arrays.asList(
- new FontConfig.Font(new File("test.ttf"), null,
+ new FontConfig.Font(new File("test.ttf"), null, "test",
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
0, "", null)),
"sans-serif", LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT);
@@ -77,10 +77,10 @@
+ "</family>";
FontConfig.FontFamily expected = new FontConfig.FontFamily(
Arrays.asList(
- new FontConfig.Font(new File("test.ttf"), null,
+ new FontConfig.Font(new File("test.ttf"), null, "test",
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
0, "", null),
- new FontConfig.Font(new File("test.ttf"), null,
+ new FontConfig.Font(new File("test.ttf"), null, "test",
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
0, "", "serif")),
null, LocaleList.forLanguageTags("en"), VARIANT_DEFAULT);
@@ -97,7 +97,7 @@
+ "</family>";
FontConfig.FontFamily expected = new FontConfig.FontFamily(
Arrays.asList(
- new FontConfig.Font(new File("test.ttf"), null,
+ new FontConfig.Font(new File("test.ttf"), null, "test",
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
0, "", null)),
null, LocaleList.forLanguageTags("en"), VARIANT_COMPACT);
@@ -114,7 +114,7 @@
+ "</family>";
FontConfig.FontFamily expected = new FontConfig.FontFamily(
Arrays.asList(
- new FontConfig.Font(new File("test.ttf"), null,
+ new FontConfig.Font(new File("test.ttf"), null, "test",
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
0, "", null)),
null, LocaleList.forLanguageTags("en"), VARIANT_ELEGANT);
@@ -133,13 +133,13 @@
+ "</family>";
FontConfig.FontFamily expected = new FontConfig.FontFamily(
Arrays.asList(
- new FontConfig.Font(new File("normal.ttf"), null,
+ new FontConfig.Font(new File("normal.ttf"), null, "test",
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
0, "", null),
- new FontConfig.Font(new File("weight.ttf"), null,
+ new FontConfig.Font(new File("weight.ttf"), null, "test",
new FontStyle(100, FONT_SLANT_UPRIGHT),
0, "", null),
- new FontConfig.Font(new File("italic.ttf"), null,
+ new FontConfig.Font(new File("italic.ttf"), null, "test",
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_ITALIC),
0, "", null)),
"sans-serif", LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT);
@@ -162,10 +162,10 @@
+ "</family>";
FontConfig.FontFamily expected = new FontConfig.FontFamily(
Arrays.asList(
- new FontConfig.Font(new File("test-VF.ttf"), null,
+ new FontConfig.Font(new File("test-VF.ttf"), null, "test",
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
0, "'wdth' 100.0,'wght' 200.0", null),
- new FontConfig.Font(new File("test-VF.ttf"), null,
+ new FontConfig.Font(new File("test-VF.ttf"), null, "test",
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
0, "'wdth' 400.0,'wght' 700.0", null)),
"sans-serif", LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT);
@@ -182,10 +182,30 @@
+ "</family>";
FontConfig.FontFamily expected = new FontConfig.FontFamily(
Arrays.asList(
- new FontConfig.Font(new File("test.ttc"), null,
+ new FontConfig.Font(new File("test.ttc"), null, "test",
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
0, "", null),
- new FontConfig.Font(new File("test.ttc"), null,
+ new FontConfig.Font(new File("test.ttc"), null, "test",
+ new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
+ 1, "", null)),
+ "sans-serif", LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT);
+ FontConfig.FontFamily family = readFamily(xml);
+ assertThat(family).isEqualTo(expected);
+ }
+
+ @Test
+ public void psName() throws Exception {
+ String xml = "<?xml version='1.0' encoding='UTF-8'?>"
+ + "<family name='sans-serif'>"
+ + " <font index='0' postScriptName='foo'>test.ttc</font>"
+ + " <font index='1'>test.ttc</font>"
+ + "</family>";
+ FontConfig.FontFamily expected = new FontConfig.FontFamily(
+ Arrays.asList(
+ new FontConfig.Font(new File("test.ttc"), null, "foo",
+ new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
+ 0, "", null),
+ new FontConfig.Font(new File("test.ttc"), null, "test",
new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
1, "", null)),
"sans-serif", LocaleList.getEmptyLocaleList(), VARIANT_DEFAULT);
diff --git a/core/tests/coretests/src/android/graphics/TypefaceTest.java b/core/tests/coretests/src/android/graphics/TypefaceTest.java
index d12f495..6defe91 100644
--- a/core/tests/coretests/src/android/graphics/TypefaceTest.java
+++ b/core/tests/coretests/src/android/graphics/TypefaceTest.java
@@ -27,6 +27,7 @@
import android.graphics.fonts.SystemFonts;
import android.os.SharedMemory;
import android.text.FontConfig;
+import android.util.ArrayMap;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;
@@ -200,8 +201,9 @@
Map<String, Typeface> systemFontMap = SystemFonts.buildSystemTypefaces(fontConfig,
fallbackMap);
SharedMemory sharedMemory = Typeface.serializeFontMap(systemFontMap);
- Map<String, Typeface> copiedFontMap =
- Typeface.deserializeFontMap(sharedMemory.mapReadOnly().order(ByteOrder.BIG_ENDIAN));
+ Map<String, Typeface> copiedFontMap = new ArrayMap<>();
+ Typeface.deserializeFontMap(sharedMemory.mapReadOnly().order(ByteOrder.BIG_ENDIAN),
+ copiedFontMap);
assertEquals(systemFontMap.size(), copiedFontMap.size());
for (String key : systemFontMap.keySet()) {
assertTrue(copiedFontMap.containsKey(key));
diff --git a/core/tests/coretests/src/android/view/ScrollCaptureConnectionTest.java b/core/tests/coretests/src/android/view/ScrollCaptureConnectionTest.java
index 22c71b52..e7b88c8 100644
--- a/core/tests/coretests/src/android/view/ScrollCaptureConnectionTest.java
+++ b/core/tests/coretests/src/android/view/ScrollCaptureConnectionTest.java
@@ -32,6 +32,7 @@
import android.graphics.Rect;
import android.os.Handler;
import android.os.ICancellationSignal;
+import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
@@ -189,4 +190,15 @@
verifyNoMoreInteractions(mRemote);
}
+ @Test
+ public void testClose_whileActive() throws RemoteException {
+ mConnection.startCapture(mSurface, mRemote);
+
+ mCallback.completeStartRequest();
+ assertTrue(mConnection.isActive());
+
+ mConnection.close();
+ mCallback.completeEndRequest();
+ assertFalse(mConnection.isActive());
+ }
}
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationTest.java
index c393d68..8225afc 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationTest.java
@@ -244,7 +244,8 @@
PendingIntent.getActivity(
context, 0, new Intent("action1"), FLAG_IMMUTABLE)))
.addAction(new RemoteAction(icon1, "title2", "desc2",
- PendingIntent.getActivity(context, 0, new Intent("action2"), 0)))
+ PendingIntent.getActivity(context, 0, new Intent("action2"),
+ FLAG_IMMUTABLE)))
.setEntityType(TextClassifier.TYPE_EMAIL, 0.5f)
.setEntityType(TextClassifier.TYPE_PHONE, 0.4f)
.build();
diff --git a/core/tests/coretests/src/com/android/internal/view/RecyclerViewCaptureHelperTest.java b/core/tests/coretests/src/com/android/internal/view/RecyclerViewCaptureHelperTest.java
index 88bbcc2..a6b26be 100644
--- a/core/tests/coretests/src/com/android/internal/view/RecyclerViewCaptureHelperTest.java
+++ b/core/tests/coretests/src/com/android/internal/view/RecyclerViewCaptureHelperTest.java
@@ -145,7 +145,9 @@
ScrollResult scrollResult = rvc.onScrollRequested(mTarget, scrollBounds, request);
assertThat(request).isEqualTo(scrollResult.requestedArea);
assertThat(request).isEqualTo(scrollResult.availableArea);
- assertThat(scrollResult.scrollDelta).isEqualTo(CAPTURE_HEIGHT);
+ // Capture height centered in the window
+ assertThat(scrollResult.scrollDelta).isEqualTo(
+ CAPTURE_HEIGHT + (WINDOW_HEIGHT - CAPTURE_HEIGHT) / 2);
assertAvailableAreaCompletelyVisible(scrollResult, mTarget);
}
@@ -163,7 +165,8 @@
ScrollResult scrollResult = helper.onScrollRequested(mTarget, scrollBounds, request);
assertThat(request).isEqualTo(scrollResult.requestedArea);
assertThat(request).isEqualTo(scrollResult.availableArea);
- assertThat(scrollResult.scrollDelta).isEqualTo(-CAPTURE_HEIGHT);
+ assertThat(scrollResult.scrollDelta).isEqualTo(
+ -CAPTURE_HEIGHT - (WINDOW_HEIGHT - CAPTURE_HEIGHT) / 2);
assertAvailableAreaCompletelyVisible(scrollResult, mTarget);
}
@@ -182,7 +185,8 @@
ScrollResult scrollResult = helper.onScrollRequested(mTarget, scrollBounds, request);
assertThat(request).isEqualTo(scrollResult.requestedArea);
assertThat(request).isEqualTo(scrollResult.availableArea);
- assertThat(scrollResult.scrollDelta).isEqualTo(CAPTURE_HEIGHT);
+ assertThat(scrollResult.scrollDelta).isEqualTo(
+ CAPTURE_HEIGHT + (WINDOW_HEIGHT - CAPTURE_HEIGHT) / 2);
assertAvailableAreaCompletelyVisible(scrollResult, mTarget);
}
@@ -200,7 +204,8 @@
ScrollResult scrollResult = helper.onScrollRequested(mTarget, scrollBounds, request);
assertThat(request).isEqualTo(scrollResult.requestedArea);
assertThat(request).isEqualTo(scrollResult.availableArea);
- assertThat(scrollResult.scrollDelta).isEqualTo(-CAPTURE_HEIGHT);
+ assertThat(scrollResult.scrollDelta).isEqualTo(
+ -CAPTURE_HEIGHT - (WINDOW_HEIGHT - CAPTURE_HEIGHT) / 2);
assertAvailableAreaCompletelyVisible(scrollResult, mTarget);
}
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 5f34426..9f1d943 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -417,6 +417,8 @@
<permission name="android.permission.SET_WALLPAPER" />
<permission name="android.permission.SET_WALLPAPER_COMPONENT" />
<permission name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" />
+ <!-- Permissions required for Incremental CTS tests -->
+ <permission name="com.android.permission.USE_INSTALLER_V2"/>
<permission name="android.permission.LOADER_USAGE_STATS"/>
<!-- Permission required to test system only camera devices. -->
<permission name="android.permission.SYSTEM_CAMERA" />
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index 2db4c5d..1163536 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -223,7 +223,7 @@
<alias name="sans-serif-condensed-medium" to="sans-serif-condensed" weight="500" />
<family name="serif">
- <font weight="400" style="normal">NotoSerif-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSerif">NotoSerif-Regular.ttf</font>
<font weight="700" style="normal">NotoSerif-Bold.ttf</font>
<font weight="400" style="italic">NotoSerif-Italic.ttf</font>
<font weight="700" style="italic">NotoSerif-BoldItalic.ttf</font>
@@ -245,7 +245,7 @@
<alias name="monaco" to="monospace" />
<family name="serif-monospace">
- <font weight="400" style="normal">CutiveMono.ttf</font>
+ <font weight="400" style="normal" postScriptName="CutiveMono-Regular">CutiveMono.ttf</font>
</family>
<alias name="courier" to="serif-monospace" />
<alias name="courier new" to="serif-monospace" />
@@ -255,7 +255,8 @@
</family>
<family name="cursive">
- <font weight="400" style="normal">DancingScript-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="DancingScript">DancingScript-Regular.ttf
+ </font>
<font weight="700" style="normal">DancingScript-Bold.ttf</font>
</family>
@@ -271,148 +272,195 @@
<font weight="700" style="normal">SourceSansPro-Bold.ttf</font>
<font weight="700" style="italic">SourceSansPro-BoldItalic.ttf</font>
</family>
- <alias name="source-sans-pro-semi-bold" to="source-sans-pro" weight="600" />
+ <alias name="source-sans-pro-semi-bold" to="source-sans-pro" weight="600"/>
<!-- fallback fonts -->
<family lang="und-Arab" variant="elegant">
- <font weight="400" style="normal">NotoNaskhArabic-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoNaskhArabic">
+ NotoNaskhArabic-Regular.ttf
+ </font>
<font weight="700" style="normal">NotoNaskhArabic-Bold.ttf</font>
</family>
<family lang="und-Arab" variant="compact">
- <font weight="400" style="normal">NotoNaskhArabicUI-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoNaskhArabicUI">
+ NotoNaskhArabicUI-Regular.ttf
+ </font>
<font weight="700" style="normal">NotoNaskhArabicUI-Bold.ttf</font>
</family>
<family lang="und-Ethi">
- <font weight="400" style="normal">NotoSansEthiopic-VF.ttf
- <axis tag="wght" stylevalue="400"/>
- </font>
- <font weight="500" style="normal">NotoSansEthiopic-VF.ttf
- <axis tag="wght" stylevalue="500"/>
- </font>
- <font weight="600" style="normal">NotoSansEthiopic-VF.ttf
- <axis tag="wght" stylevalue="600"/>
- </font>
- <font weight="700" style="normal">NotoSansEthiopic-VF.ttf
- <axis tag="wght" stylevalue="700"/>
- </font>
- <font weight="400" style="normal" fallbackFor="serif">NotoSerifEthiopic-VF.ttf
- <axis tag="wght" stylevalue="400"/>
- </font>
- <font weight="500" style="normal" fallbackFor="serif">NotoSerifEthiopic-VF.ttf
- <axis tag="wght" stylevalue="500"/>
- </font>
- <font weight="600" style="normal" fallbackFor="serif">NotoSerifEthiopic-VF.ttf
- <axis tag="wght" stylevalue="600"/>
- </font>
- <font weight="700" style="normal" fallbackFor="serif">NotoSerifEthiopic-VF.ttf
- <axis tag="wght" stylevalue="700"/>
- </font>
+ <font weight="400" style="normal" postScriptName="NotoSansEthiopic-Regular">
+ NotoSansEthiopic-VF.ttf
+ <axis tag="wght" stylevalue="400"/>
+ </font>
+ <font weight="500" style="normal" postScriptName="NotoSansEthiopic-Regular">
+ NotoSansEthiopic-VF.ttf
+ <axis tag="wght" stylevalue="500"/>
+ </font>
+ <font weight="600" style="normal" postScriptName="NotoSansEthiopic-Regular">
+ NotoSansEthiopic-VF.ttf
+ <axis tag="wght" stylevalue="600"/>
+ </font>
+ <font weight="700" style="normal" postScriptName="NotoSansEthiopic-Regular">
+ NotoSansEthiopic-VF.ttf
+ <axis tag="wght" stylevalue="700"/>
+ </font>
+ <font weight="400" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifEthiopic-Regular">NotoSerifEthiopic-VF.ttf
+ <axis tag="wght" stylevalue="400"/>
+ </font>
+ <font weight="500" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifEthiopic-Regular">NotoSerifEthiopic-VF.ttf
+ <axis tag="wght" stylevalue="500"/>
+ </font>
+ <font weight="600" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifEthiopic-Regular">NotoSerifEthiopic-VF.ttf
+ <axis tag="wght" stylevalue="600"/>
+ </font>
+ <font weight="700" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifEthiopic-Regular">NotoSerifEthiopic-VF.ttf
+ <axis tag="wght" stylevalue="700"/>
+ </font>
</family>
<family lang="und-Hebr">
- <font weight="400" style="normal">NotoSansHebrew-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansHebrew">
+ NotoSansHebrew-Regular.ttf
+ </font>
<font weight="700" style="normal">NotoSansHebrew-Bold.ttf</font>
<font weight="400" style="normal" fallbackFor="serif">NotoSerifHebrew-Regular.ttf</font>
<font weight="700" style="normal" fallbackFor="serif">NotoSerifHebrew-Bold.ttf</font>
</family>
<family lang="und-Thai" variant="elegant">
- <font weight="400" style="normal">NotoSansThai-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansThai">NotoSansThai-Regular.ttf
+ </font>
<font weight="700" style="normal">NotoSansThai-Bold.ttf</font>
- <font weight="400" style="normal" fallbackFor="serif">NotoSerifThai-Regular.ttf</font>
+ <font weight="400" style="normal" fallbackFor="serif" postScriptName="NotoSerifThai">
+ NotoSerifThai-Regular.ttf
+ </font>
<font weight="700" style="normal" fallbackFor="serif">NotoSerifThai-Bold.ttf</font>
</family>
<family lang="und-Thai" variant="compact">
- <font weight="400" style="normal">NotoSansThaiUI-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansThaiUI">
+ NotoSansThaiUI-Regular.ttf
+ </font>
<font weight="700" style="normal">NotoSansThaiUI-Bold.ttf</font>
</family>
<family lang="und-Armn">
- <font weight="400" style="normal">NotoSansArmenian-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansArmenian-Regular">
+ NotoSansArmenian-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansArmenian-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansArmenian-Regular">
+ NotoSansArmenian-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansArmenian-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansArmenian-Regular">
+ NotoSansArmenian-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansArmenian-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansArmenian-Regular">
+ NotoSansArmenian-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
- <font weight="400" style="normal" fallbackFor="serif">NotoSerifArmenian-VF.ttf
+ <font weight="400" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifArmenian-Regular">NotoSerifArmenian-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal" fallbackFor="serif">NotoSerifArmenian-VF.ttf
+ <font weight="500" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifArmenian-Regular">NotoSerifArmenian-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal" fallbackFor="serif">NotoSerifArmenian-VF.ttf
+ <font weight="600" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifArmenian-Regular">NotoSerifArmenian-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal" fallbackFor="serif">NotoSerifArmenian-VF.ttf
+ <font weight="700" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifArmenian-Regular">NotoSerifArmenian-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Geor,und-Geok">
- <font weight="400" style="normal">NotoSansGeorgian-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansGeorgian-Regular">
+ NotoSansGeorgian-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansGeorgian-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansGeorgian-Regular">
+ NotoSansGeorgian-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansGeorgian-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansGeorgian-Regular">
+ NotoSansGeorgian-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansGeorgian-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansGeorgian-Regular">
+ NotoSansGeorgian-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
- <font weight="400" style="normal" fallbackFor="serif">NotoSerifGeorgian-VF.ttf
+ <font weight="400" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifGeorgian-Regular">NotoSerifGeorgian-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal" fallbackFor="serif">NotoSerifGeorgian-VF.ttf
+ <font weight="500" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifGeorgian-Regular">NotoSerifGeorgian-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal" fallbackFor="serif">NotoSerifGeorgian-VF.ttf
+ <font weight="600" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifGeorgian-Regular">NotoSerifGeorgian-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal" fallbackFor="serif">NotoSerifGeorgian-VF.ttf
+ <font weight="700" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifGeorgian-Regular">NotoSerifGeorgian-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Deva" variant="elegant">
- <font weight="400" style="normal">NotoSansDevanagari-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansDevanagari-Regular">
+ NotoSansDevanagari-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansDevanagari-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansDevanagari-Regular">
+ NotoSansDevanagari-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansDevanagari-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansDevanagari-Regular">
+ NotoSansDevanagari-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansDevanagari-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansDevanagari-Regular">
+ NotoSansDevanagari-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
- <font weight="400" style="normal" fallbackFor="serif">NotoSerifDevanagari-VF.ttf
+ <font weight="400" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifDevanagari-Regular">NotoSerifDevanagari-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal" fallbackFor="serif">NotoSerifDevanagari-VF.ttf
+ <font weight="500" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifDevanagari-Regular">NotoSerifDevanagari-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal" fallbackFor="serif">NotoSerifDevanagari-VF.ttf
+ <font weight="600" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifDevanagari-Regular">NotoSerifDevanagari-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal" fallbackFor="serif">NotoSerifDevanagari-VF.ttf
+ <font weight="700" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifDevanagari-Regular">NotoSerifDevanagari-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Deva" variant="compact">
- <font weight="400" style="normal">NotoSansDevanagariUI-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansDevanagariUI-Regular">
+ NotoSansDevanagariUI-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansDevanagariUI-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansDevanagariUI-Regular">
+ NotoSansDevanagariUI-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansDevanagariUI-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansDevanagariUI-Regular">
+ NotoSansDevanagariUI-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansDevanagariUI-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansDevanagariUI-Regular">
+ NotoSansDevanagariUI-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
@@ -421,347 +469,451 @@
danda characters.
-->
<family lang="und-Gujr" variant="elegant">
- <font weight="400" style="normal">NotoSansGujarati-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansGujarati">
+ NotoSansGujarati-Regular.ttf
+ </font>
<font weight="700" style="normal">NotoSansGujarati-Bold.ttf</font>
- <font weight="400" style="normal" fallbackFor="serif">NotoSerifGujarati-VF.ttf
+ <font weight="400" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifGujarati-Regular">NotoSerifGujarati-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal" fallbackFor="serif">NotoSerifGujarati-VF.ttf
+ <font weight="500" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifGujarati-Regular">NotoSerifGujarati-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal" fallbackFor="serif">NotoSerifGujarati-VF.ttf
+ <font weight="600" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifGujarati-Regular">NotoSerifGujarati-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal" fallbackFor="serif">NotoSerifGujarati-VF.ttf
+ <font weight="700" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifGujarati-Regular">NotoSerifGujarati-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Gujr" variant="compact">
- <font weight="400" style="normal">NotoSansGujaratiUI-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansGujaratiUI">
+ NotoSansGujaratiUI-Regular.ttf
+ </font>
<font weight="700" style="normal">NotoSansGujaratiUI-Bold.ttf</font>
</family>
<family lang="und-Guru" variant="elegant">
- <font weight="400" style="normal">NotoSansGurmukhi-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansGurmukhi-Regular">
+ NotoSansGurmukhi-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansGurmukhi-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansGurmukhi-Regular">
+ NotoSansGurmukhi-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansGurmukhi-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansGurmukhi-Regular">
+ NotoSansGurmukhi-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansGurmukhi-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansGurmukhi-Regular">
+ NotoSansGurmukhi-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
- <font weight="400" style="normal" fallbackFor="serif">NotoSerifGurmukhi-VF.ttf
+ <font weight="400" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifGurmukhi-Regular">NotoSerifGurmukhi-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal" fallbackFor="serif">NotoSerifGurmukhi-VF.ttf
+ <font weight="500" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifGurmukhi-Regular">NotoSerifGurmukhi-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal" fallbackFor="serif">NotoSerifGurmukhi-VF.ttf
+ <font weight="600" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifGurmukhi-Regular">NotoSerifGurmukhi-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal" fallbackFor="serif">NotoSerifGurmukhi-VF.ttf
+ <font weight="700" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifGurmukhi-Regular">NotoSerifGurmukhi-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Guru" variant="compact">
- <font weight="400" style="normal">NotoSansGurmukhiUI-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansGurmukhiUI-Regular">
+ NotoSansGurmukhiUI-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansGurmukhiUI-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansGurmukhiUI-Regular">
+ NotoSansGurmukhiUI-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansGurmukhiUI-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansGurmukhiUI-Regular">
+ NotoSansGurmukhiUI-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansGurmukhiUI-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansGurmukhiUI-Regular">
+ NotoSansGurmukhiUI-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Taml" variant="elegant">
- <font weight="400" style="normal">NotoSansTamil-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansTamil-Regular">
+ NotoSansTamil-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansTamil-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansTamil-Regular">
+ NotoSansTamil-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansTamil-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansTamil-Regular">
+ NotoSansTamil-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansTamil-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansTamil-Regular">
+ NotoSansTamil-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
- <font weight="400" style="normal" fallbackFor="serif">NotoSerifTamil-VF.ttf
+ <font weight="400" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifTamil-Regular">NotoSerifTamil-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal" fallbackFor="serif">NotoSerifTamil-VF.ttf
+ <font weight="500" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifTamil-Regular">NotoSerifTamil-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal" fallbackFor="serif">NotoSerifTamil-VF.ttf
+ <font weight="600" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifTamil-Regular">NotoSerifTamil-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal" fallbackFor="serif">NotoSerifTamil-VF.ttf
+ <font weight="700" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifTamil-Regular">NotoSerifTamil-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Taml" variant="compact">
- <font weight="400" style="normal">NotoSansTamilUI-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansTamilUI-Regular">
+ NotoSansTamilUI-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansTamilUI-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansTamilUI-Regular">
+ NotoSansTamilUI-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansTamilUI-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansTamilUI-Regular">
+ NotoSansTamilUI-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansTamilUI-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansTamilUI-Regular">
+ NotoSansTamilUI-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Mlym" variant="elegant">
- <font weight="400" style="normal">NotoSansMalayalam-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansMalayalam-Regular">
+ NotoSansMalayalam-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansMalayalam-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansMalayalam-Regular">
+ NotoSansMalayalam-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansMalayalam-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansMalayalam-Regular">
+ NotoSansMalayalam-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansMalayalam-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansMalayalam-Regular">
+ NotoSansMalayalam-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
- <font weight="400" style="normal" fallbackFor="serif">NotoSerifMalayalam-VF.ttf
+ <font weight="400" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifMalayalam-Regular">NotoSerifMalayalam-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal" fallbackFor="serif">NotoSerifMalayalam-VF.ttf
+ <font weight="500" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifMalayalam-Regular">NotoSerifMalayalam-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal" fallbackFor="serif">NotoSerifMalayalam-VF.ttf
+ <font weight="600" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifMalayalam-Regular">NotoSerifMalayalam-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal" fallbackFor="serif">NotoSerifMalayalam-VF.ttf
+ <font weight="700" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifMalayalam-Regular">NotoSerifMalayalam-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Mlym" variant="compact">
- <font weight="400" style="normal">NotoSansMalayalamUI-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansMalayalamUI-Regular">
+ NotoSansMalayalamUI-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansMalayalamUI-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansMalayalamUI-Regular">
+ NotoSansMalayalamUI-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansMalayalamUI-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansMalayalamUI-Regular">
+ NotoSansMalayalamUI-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansMalayalamUI-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansMalayalamUI-Regular">
+ NotoSansMalayalamUI-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Beng" variant="elegant">
- <font weight="400" style="normal">NotoSansBengali-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansBengali-Regular">
+ NotoSansBengali-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansBengali-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansBengali-Regular">
+ NotoSansBengali-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansBengali-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansBengali-Regular">
+ NotoSansBengali-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansBengali-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansBengali-Regular">
+ NotoSansBengali-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
- <font weight="400" style="normal" fallbackFor="serif">NotoSerifBengali-VF.ttf
+ <font weight="400" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifBengali-Regular">NotoSerifBengali-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal" fallbackFor="serif">NotoSerifBengali-VF.ttf
+ <font weight="500" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifBengali-Regular">NotoSerifBengali-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal" fallbackFor="serif">NotoSerifBengali-VF.ttf
+ <font weight="600" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifBengali-Regular">NotoSerifBengali-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal" fallbackFor="serif">NotoSerifBengali-VF.ttf
+ <font weight="700" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifBengali-Regular">NotoSerifBengali-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Beng" variant="compact">
- <font weight="400" style="normal">NotoSansBengaliUI-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansBengaliUI-Regular">
+ NotoSansBengaliUI-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansBengaliUI-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansBengaliUI-Regular">
+ NotoSansBengaliUI-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansBengaliUI-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansBengaliUI-Regular">
+ NotoSansBengaliUI-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansBengaliUI-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansBengaliUI-Regular">
+ NotoSansBengaliUI-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Telu" variant="elegant">
- <font weight="400" style="normal">NotoSansTelugu-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansTelugu-Regular">
+ NotoSansTelugu-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansTelugu-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansTelugu-Regular">
+ NotoSansTelugu-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansTelugu-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansTelugu-Regular">
+ NotoSansTelugu-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansTelugu-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansTelugu-Regular">
+ NotoSansTelugu-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
- <font weight="400" style="normal" fallbackFor="serif">NotoSerifTelugu-VF.ttf
+ <font weight="400" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifTelugu-Regular">NotoSerifTelugu-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal" fallbackFor="serif">NotoSerifTelugu-VF.ttf
+ <font weight="500" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifTelugu-Regular">NotoSerifTelugu-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal" fallbackFor="serif">NotoSerifTelugu-VF.ttf
+ <font weight="600" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifTelugu-Regular">NotoSerifTelugu-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal" fallbackFor="serif">NotoSerifTelugu-VF.ttf
+ <font weight="700" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifTelugu-Regular">NotoSerifTelugu-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Telu" variant="compact">
- <font weight="400" style="normal">NotoSansTeluguUI-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansTeluguUI-Regular">
+ NotoSansTeluguUI-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansTeluguUI-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansTeluguUI-Regular">
+ NotoSansTeluguUI-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansTeluguUI-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansTeluguUI-Regular">
+ NotoSansTeluguUI-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansTeluguUI-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansTeluguUI-Regular">
+ NotoSansTeluguUI-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Knda" variant="elegant">
- <font weight="400" style="normal">NotoSansKannada-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansKannada-Regular">
+ NotoSansKannada-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansKannada-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansKannada-Regular">
+ NotoSansKannada-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansKannada-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansKannada-Regular">
+ NotoSansKannada-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansKannada-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansKannada-Regular">
+ NotoSansKannada-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
- <font weight="400" style="normal" fallbackFor="serif">NotoSerifKannada-VF.ttf
+ <font weight="400" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifKannada-Regular">NotoSerifKannada-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal" fallbackFor="serif">NotoSerifKannada-VF.ttf
+ <font weight="500" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifKannada-Regular">NotoSerifKannada-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal" fallbackFor="serif">NotoSerifKannada-VF.ttf
+ <font weight="600" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifKannada-Regular">NotoSerifKannada-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal" fallbackFor="serif">NotoSerifKannada-VF.ttf
+ <font weight="700" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifKannada-Regular">NotoSerifKannada-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Knda" variant="compact">
- <font weight="400" style="normal">NotoSansKannadaUI-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansKannadaUI-Regular">
+ NotoSansKannadaUI-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansKannadaUI-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansKannadaUI-Regular">
+ NotoSansKannadaUI-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansKannadaUI-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansKannadaUI-Regular">
+ NotoSansKannadaUI-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansKannadaUI-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansKannadaUI-Regular">
+ NotoSansKannadaUI-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Orya" variant="elegant">
- <font weight="400" style="normal">NotoSansOriya-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansOriya">NotoSansOriya-Regular.ttf
+ </font>
<font weight="700" style="normal">NotoSansOriya-Bold.ttf</font>
</family>
<family lang="und-Orya" variant="compact">
- <font weight="400" style="normal">NotoSansOriyaUI-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansOriyaUI">
+ NotoSansOriyaUI-Regular.ttf
+ </font>
<font weight="700" style="normal">NotoSansOriyaUI-Bold.ttf</font>
</family>
<family lang="und-Sinh" variant="elegant">
- <font weight="400" style="normal">NotoSansSinhala-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansSinhala-Regular">
+ NotoSansSinhala-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansSinhala-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansSinhala-Regular">
+ NotoSansSinhala-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansSinhala-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansSinhala-Regular">
+ NotoSansSinhala-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansSinhala-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansSinhala-Regular">
+ NotoSansSinhala-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
- <font weight="400" style="normal" fallbackFor="serif">NotoSerifSinhala-VF.ttf
+ <font weight="400" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifSinhala-Regular">NotoSerifSinhala-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal" fallbackFor="serif">NotoSerifSinhala-VF.ttf
+ <font weight="500" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifSinhala-Regular">NotoSerifSinhala-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal" fallbackFor="serif">NotoSerifSinhala-VF.ttf
+ <font weight="600" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifSinhala-Regular">NotoSerifSinhala-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal" fallbackFor="serif">NotoSerifSinhala-VF.ttf
+ <font weight="700" style="normal" fallbackFor="serif"
+ postScriptName="NotoSerifSinhala-Regular">NotoSerifSinhala-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Sinh" variant="compact">
- <font weight="400" style="normal">NotoSansSinhalaUI-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansSinhalaUI-Regular">
+ NotoSansSinhalaUI-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansSinhalaUI-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansSinhalaUI-Regular">
+ NotoSansSinhalaUI-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansSinhalaUI-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansSinhalaUI-Regular">
+ NotoSansSinhalaUI-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansSinhalaUI-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansSinhalaUI-Regular">
+ NotoSansSinhalaUI-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Khmr" variant="elegant">
- <font weight="100" style="normal">NotoSansKhmer-VF.ttf
+ <font weight="100" style="normal" postScriptName="NotoSansKhmer-Regular">
+ NotoSansKhmer-VF.ttf
<axis tag="wdth" stylevalue="100.0"/>
<axis tag="wght" stylevalue="26.0"/>
</font>
- <font weight="200" style="normal">NotoSansKhmer-VF.ttf
+ <font weight="200" style="normal" postScriptName="NotoSansKhmer-Regular">
+ NotoSansKhmer-VF.ttf
<axis tag="wdth" stylevalue="100.0"/>
<axis tag="wght" stylevalue="39.0"/>
</font>
- <font weight="300" style="normal">NotoSansKhmer-VF.ttf
+ <font weight="300" style="normal" postScriptName="NotoSansKhmer-Regular">
+ NotoSansKhmer-VF.ttf
<axis tag="wdth" stylevalue="100.0"/>
<axis tag="wght" stylevalue="58.0"/>
</font>
- <font weight="400" style="normal">NotoSansKhmer-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansKhmer-Regular">
+ NotoSansKhmer-VF.ttf
<axis tag="wdth" stylevalue="100.0"/>
<axis tag="wght" stylevalue="90.0"/>
</font>
- <font weight="500" style="normal">NotoSansKhmer-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansKhmer-Regular">
+ NotoSansKhmer-VF.ttf
<axis tag="wdth" stylevalue="100.0"/>
<axis tag="wght" stylevalue="108.0"/>
</font>
- <font weight="600" style="normal">NotoSansKhmer-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansKhmer-Regular">
+ NotoSansKhmer-VF.ttf
<axis tag="wdth" stylevalue="100.0"/>
<axis tag="wght" stylevalue="128.0"/>
</font>
- <font weight="700" style="normal">NotoSansKhmer-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansKhmer-Regular">
+ NotoSansKhmer-VF.ttf
<axis tag="wdth" stylevalue="100.0"/>
<axis tag="wght" stylevalue="151.0"/>
</font>
- <font weight="800" style="normal">NotoSansKhmer-VF.ttf
+ <font weight="800" style="normal" postScriptName="NotoSansKhmer-Regular">
+ NotoSansKhmer-VF.ttf
<axis tag="wdth" stylevalue="100.0"/>
<axis tag="wght" stylevalue="169.0"/>
</font>
- <font weight="900" style="normal">NotoSansKhmer-VF.ttf
+ <font weight="900" style="normal" postScriptName="NotoSansKhmer-Regular">
+ NotoSansKhmer-VF.ttf
<axis tag="wdth" stylevalue="100.0"/>
<axis tag="wght" stylevalue="190.0"/>
</font>
@@ -769,17 +921,23 @@
<font weight="700" style="normal" fallbackFor="serif">NotoSerifKhmer-Bold.otf</font>
</family>
<family lang="und-Khmr" variant="compact">
- <font weight="400" style="normal">NotoSansKhmerUI-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansKhmerUI">
+ NotoSansKhmerUI-Regular.ttf
+ </font>
<font weight="700" style="normal">NotoSansKhmerUI-Bold.ttf</font>
</family>
<family lang="und-Laoo" variant="elegant">
- <font weight="400" style="normal">NotoSansLao-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansLao">NotoSansLao-Regular.ttf
+ </font>
<font weight="700" style="normal">NotoSansLao-Bold.ttf</font>
- <font weight="400" style="normal" fallbackFor="serif">NotoSerifLao-Regular.ttf</font>
+ <font weight="400" style="normal" fallbackFor="serif" postScriptName="NotoSerifLao">
+ NotoSerifLao-Regular.ttf
+ </font>
<font weight="700" style="normal" fallbackFor="serif">NotoSerifLao-Bold.ttf</font>
</family>
<family lang="und-Laoo" variant="compact">
- <font weight="400" style="normal">NotoSansLaoUI-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansLaoUI">NotoSansLaoUI-Regular.ttf
+ </font>
<font weight="700" style="normal">NotoSansLaoUI-Bold.ttf</font>
</family>
<family lang="und-Mymr" variant="elegant">
@@ -795,56 +953,78 @@
<font weight="700" style="normal">NotoSansMyanmarUI-Bold.otf</font>
</family>
<family lang="und-Thaa">
- <font weight="400" style="normal">NotoSansThaana-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansThaana">
+ NotoSansThaana-Regular.ttf
+ </font>
<font weight="700" style="normal">NotoSansThaana-Bold.ttf</font>
</family>
<family lang="und-Cham">
- <font weight="400" style="normal">NotoSansCham-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansCham">NotoSansCham-Regular.ttf
+ </font>
<font weight="700" style="normal">NotoSansCham-Bold.ttf</font>
</family>
<family lang="und-Ahom">
<font weight="400" style="normal">NotoSansAhom-Regular.otf</font>
</family>
<family lang="und-Adlm">
- <font weight="400" style="normal">NotoSansAdlam-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansAdlam-Regular">
+ NotoSansAdlam-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansAdlam-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansAdlam-Regular">
+ NotoSansAdlam-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansAdlam-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansAdlam-Regular">
+ NotoSansAdlam-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansAdlam-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansAdlam-Regular">
+ NotoSansAdlam-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Avst">
- <font weight="400" style="normal">NotoSansAvestan-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansAvestan">
+ NotoSansAvestan-Regular.ttf
+ </font>
</family>
<family lang="und-Bali">
- <font weight="400" style="normal">NotoSansBalinese-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansBalinese">
+ NotoSansBalinese-Regular.ttf
+ </font>
</family>
<family lang="und-Bamu">
- <font weight="400" style="normal">NotoSansBamum-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansBamum">NotoSansBamum-Regular.ttf
+ </font>
</family>
<family lang="und-Batk">
- <font weight="400" style="normal">NotoSansBatak-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansBatak">NotoSansBatak-Regular.ttf
+ </font>
</family>
<family lang="und-Brah">
- <font weight="400" style="normal">NotoSansBrahmi-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansBrahmi">
+ NotoSansBrahmi-Regular.ttf
+ </font>
</family>
<family lang="und-Bugi">
- <font weight="400" style="normal">NotoSansBuginese-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansBuginese">
+ NotoSansBuginese-Regular.ttf
+ </font>
</family>
<family lang="und-Buhd">
- <font weight="400" style="normal">NotoSansBuhid-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansBuhid">NotoSansBuhid-Regular.ttf
+ </font>
</family>
<family lang="und-Cans">
- <font weight="400" style="normal">NotoSansCanadianAboriginal-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansCanadianAboriginal">
+ NotoSansCanadianAboriginal-Regular.ttf
+ </font>
</family>
<family lang="und-Cari">
- <font weight="400" style="normal">NotoSansCarian-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansCarian">
+ NotoSansCarian-Regular.ttf
+ </font>
</family>
<family lang="und-Cakm">
<font weight="400" style="normal">NotoSansChakma-Regular.otf</font>
@@ -853,164 +1033,255 @@
<font weight="400" style="normal">NotoSansCherokee-Regular.ttf</font>
</family>
<family lang="und-Copt">
- <font weight="400" style="normal">NotoSansCoptic-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansCoptic">
+ NotoSansCoptic-Regular.ttf
+ </font>
</family>
<family lang="und-Xsux">
- <font weight="400" style="normal">NotoSansCuneiform-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansCuneiform">
+ NotoSansCuneiform-Regular.ttf
+ </font>
</family>
<family lang="und-Cprt">
- <font weight="400" style="normal">NotoSansCypriot-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansCypriot">
+ NotoSansCypriot-Regular.ttf
+ </font>
</family>
<family lang="und-Dsrt">
- <font weight="400" style="normal">NotoSansDeseret-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansDeseret">
+ NotoSansDeseret-Regular.ttf
+ </font>
</family>
<family lang="und-Egyp">
- <font weight="400" style="normal">NotoSansEgyptianHieroglyphs-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansEgyptianHieroglyphs">
+ NotoSansEgyptianHieroglyphs-Regular.ttf
+ </font>
</family>
<family lang="und-Elba">
<font weight="400" style="normal">NotoSansElbasan-Regular.otf</font>
</family>
<family lang="und-Glag">
- <font weight="400" style="normal">NotoSansGlagolitic-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansGlagolitic">
+ NotoSansGlagolitic-Regular.ttf
+ </font>
</family>
<family lang="und-Goth">
- <font weight="400" style="normal">NotoSansGothic-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansGothic">
+ NotoSansGothic-Regular.ttf
+ </font>
</family>
<family lang="und-Hano">
- <font weight="400" style="normal">NotoSansHanunoo-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansHanunoo">
+ NotoSansHanunoo-Regular.ttf
+ </font>
</family>
<family lang="und-Armi">
- <font weight="400" style="normal">NotoSansImperialAramaic-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansImperialAramaic">
+ NotoSansImperialAramaic-Regular.ttf
+ </font>
</family>
<family lang="und-Phli">
- <font weight="400" style="normal">NotoSansInscriptionalPahlavi-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansInscriptionalPahlavi">
+ NotoSansInscriptionalPahlavi-Regular.ttf
+ </font>
</family>
<family lang="und-Prti">
- <font weight="400" style="normal">NotoSansInscriptionalParthian-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansInscriptionalParthian">
+ NotoSansInscriptionalParthian-Regular.ttf
+ </font>
</family>
<family lang="und-Java">
<font weight="400" style="normal">NotoSansJavanese-Regular.otf</font>
</family>
<family lang="und-Kthi">
- <font weight="400" style="normal">NotoSansKaithi-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansKaithi">
+ NotoSansKaithi-Regular.ttf
+ </font>
</family>
<family lang="und-Kali">
- <font weight="400" style="normal">NotoSansKayahLi-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansKayahLi">
+ NotoSansKayahLi-Regular.ttf
+ </font>
</family>
<family lang="und-Khar">
- <font weight="400" style="normal">NotoSansKharoshthi-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansKharoshthi">
+ NotoSansKharoshthi-Regular.ttf
+ </font>
</family>
<family lang="und-Lepc">
- <font weight="400" style="normal">NotoSansLepcha-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansLepcha">
+ NotoSansLepcha-Regular.ttf
+ </font>
</family>
<family lang="und-Limb">
- <font weight="400" style="normal">NotoSansLimbu-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansLimbu">NotoSansLimbu-Regular.ttf
+ </font>
</family>
<family lang="und-Linb">
- <font weight="400" style="normal">NotoSansLinearB-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansLinearB">
+ NotoSansLinearB-Regular.ttf
+ </font>
</family>
<family lang="und-Lisu">
- <font weight="400" style="normal">NotoSansLisu-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansLisu">NotoSansLisu-Regular.ttf
+ </font>
</family>
<family lang="und-Lyci">
- <font weight="400" style="normal">NotoSansLycian-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansLycian">
+ NotoSansLycian-Regular.ttf
+ </font>
</family>
<family lang="und-Lydi">
- <font weight="400" style="normal">NotoSansLydian-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansLydian">
+ NotoSansLydian-Regular.ttf
+ </font>
</family>
<family lang="und-Mand">
- <font weight="400" style="normal">NotoSansMandaic-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansMandaic">
+ NotoSansMandaic-Regular.ttf
+ </font>
</family>
<family lang="und-Mtei">
- <font weight="400" style="normal">NotoSansMeeteiMayek-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansMeeteiMayek">
+ NotoSansMeeteiMayek-Regular.ttf
+ </font>
</family>
<family lang="und-Talu">
- <font weight="400" style="normal">NotoSansNewTaiLue-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansNewTaiLue">
+ NotoSansNewTaiLue-Regular.ttf
+ </font>
</family>
<family lang="und-Nkoo">
- <font weight="400" style="normal">NotoSansNKo-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansNKo">NotoSansNKo-Regular.ttf
+ </font>
</family>
<family lang="und-Ogam">
- <font weight="400" style="normal">NotoSansOgham-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansOgham">NotoSansOgham-Regular.ttf
+ </font>
</family>
<family lang="und-Olck">
- <font weight="400" style="normal">NotoSansOlChiki-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansOlChiki">
+ NotoSansOlChiki-Regular.ttf
+ </font>
</family>
<family lang="und-Ital">
- <font weight="400" style="normal">NotoSansOldItalic-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansOldItalic">
+ NotoSansOldItalic-Regular.ttf
+ </font>
</family>
<family lang="und-Xpeo">
- <font weight="400" style="normal">NotoSansOldPersian-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansOldPersian">
+ NotoSansOldPersian-Regular.ttf
+ </font>
</family>
<family lang="und-Sarb">
- <font weight="400" style="normal">NotoSansOldSouthArabian-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansOldSouthArabian">
+ NotoSansOldSouthArabian-Regular.ttf
+ </font>
</family>
<family lang="und-Orkh">
- <font weight="400" style="normal">NotoSansOldTurkic-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansOldTurkic">
+ NotoSansOldTurkic-Regular.ttf
+ </font>
</family>
<family lang="und-Osge">
<font weight="400" style="normal">NotoSansOsage-Regular.ttf</font>
</family>
<family lang="und-Osma">
- <font weight="400" style="normal">NotoSansOsmanya-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansOsmanya">
+ NotoSansOsmanya-Regular.ttf
+ </font>
</family>
<family lang="und-Phnx">
- <font weight="400" style="normal">NotoSansPhoenician-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansPhoenician">
+ NotoSansPhoenician-Regular.ttf
+ </font>
</family>
<family lang="und-Rjng">
- <font weight="400" style="normal">NotoSansRejang-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansRejang">
+ NotoSansRejang-Regular.ttf
+ </font>
</family>
<family lang="und-Runr">
- <font weight="400" style="normal">NotoSansRunic-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansRunic">NotoSansRunic-Regular.ttf
+ </font>
</family>
<family lang="und-Samr">
- <font weight="400" style="normal">NotoSansSamaritan-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansSamaritan">
+ NotoSansSamaritan-Regular.ttf
+ </font>
</family>
<family lang="und-Saur">
- <font weight="400" style="normal">NotoSansSaurashtra-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansSaurashtra">
+ NotoSansSaurashtra-Regular.ttf
+ </font>
</family>
<family lang="und-Shaw">
- <font weight="400" style="normal">NotoSansShavian-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansShavian">
+ NotoSansShavian-Regular.ttf
+ </font>
</family>
<family lang="und-Sund">
- <font weight="400" style="normal">NotoSansSundanese-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansSundanese">
+ NotoSansSundanese-Regular.ttf
+ </font>
</family>
<family lang="und-Sylo">
- <font weight="400" style="normal">NotoSansSylotiNagri-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansSylotiNagri">
+ NotoSansSylotiNagri-Regular.ttf
+ </font>
</family>
<!-- Esrangela should precede Eastern and Western Syriac, since it's our default form. -->
<family lang="und-Syre">
- <font weight="400" style="normal">NotoSansSyriacEstrangela-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansSyriacEstrangela">
+ NotoSansSyriacEstrangela-Regular.ttf
+ </font>
</family>
<family lang="und-Syrn">
- <font weight="400" style="normal">NotoSansSyriacEastern-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansSyriacEastern">
+ NotoSansSyriacEastern-Regular.ttf
+ </font>
</family>
<family lang="und-Syrj">
- <font weight="400" style="normal">NotoSansSyriacWestern-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansSyriacWestern">
+ NotoSansSyriacWestern-Regular.ttf
+ </font>
</family>
<family lang="und-Tglg">
- <font weight="400" style="normal">NotoSansTagalog-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansTagalog">
+ NotoSansTagalog-Regular.ttf
+ </font>
</family>
<family lang="und-Tagb">
- <font weight="400" style="normal">NotoSansTagbanwa-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansTagbanwa">
+ NotoSansTagbanwa-Regular.ttf
+ </font>
</family>
<family lang="und-Lana">
- <font weight="400" style="normal">NotoSansTaiTham-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansTaiTham">
+ NotoSansTaiTham-Regular.ttf
+ </font>
</family>
<family lang="und-Tavt">
- <font weight="400" style="normal">NotoSansTaiViet-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansTaiViet">
+ NotoSansTaiViet-Regular.ttf
+ </font>
</family>
<family lang="und-Tibt">
- <font weight="400" style="normal">NotoSerifTibetan-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSerifTibetan-Regular">
+ NotoSerifTibetan-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSerifTibetan-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSerifTibetan-Regular">
+ NotoSerifTibetan-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSerifTibetan-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSerifTibetan-Regular">
+ NotoSerifTibetan-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSerifTibetan-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSerifTibetan-Regular">
+ NotoSerifTibetan-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
@@ -1018,29 +1289,48 @@
<font weight="400" style="normal">NotoSansTifinagh-Regular.otf</font>
</family>
<family lang="und-Ugar">
- <font weight="400" style="normal">NotoSansUgaritic-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansUgaritic">
+ NotoSansUgaritic-Regular.ttf
+ </font>
</family>
<family lang="und-Vaii">
- <font weight="400" style="normal">NotoSansVai-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansVai">NotoSansVai-Regular.ttf
+ </font>
</family>
<family>
<font weight="400" style="normal">NotoSansSymbols-Regular-Subsetted.ttf</font>
</family>
<family lang="zh-Hans">
- <font weight="400" style="normal" index="2">NotoSansCJK-Regular.ttc</font>
- <font weight="400" style="normal" index="2" fallbackFor="serif">NotoSerifCJK-Regular.ttc</font>
+ <font weight="400" style="normal" index="2" postScriptName="NotoSansCJKjp-Regular">
+ NotoSansCJK-Regular.ttc
+ </font>
+ <font weight="400" style="normal" index="2" fallbackFor="serif"
+ postScriptName="NotoSerifCJKjp-Regular">NotoSerifCJK-Regular.ttc
+ </font>
</family>
<family lang="zh-Hant,zh-Bopo">
- <font weight="400" style="normal" index="3">NotoSansCJK-Regular.ttc</font>
- <font weight="400" style="normal" index="3" fallbackFor="serif">NotoSerifCJK-Regular.ttc</font>
+ <font weight="400" style="normal" index="3" postScriptName="NotoSansCJKjp-Regular">
+ NotoSansCJK-Regular.ttc
+ </font>
+ <font weight="400" style="normal" index="3" fallbackFor="serif"
+ postScriptName="NotoSerifCJKjp-Regular">NotoSerifCJK-Regular.ttc
+ </font>
</family>
<family lang="ja">
- <font weight="400" style="normal" index="0">NotoSansCJK-Regular.ttc</font>
- <font weight="400" style="normal" index="0" fallbackFor="serif">NotoSerifCJK-Regular.ttc</font>
+ <font weight="400" style="normal" index="0" postScriptName="NotoSansCJKjp-Regular">
+ NotoSansCJK-Regular.ttc
+ </font>
+ <font weight="400" style="normal" index="0" fallbackFor="serif"
+ postScriptName="NotoSerifCJKjp-Regular">NotoSerifCJK-Regular.ttc
+ </font>
</family>
<family lang="ko">
- <font weight="400" style="normal" index="1">NotoSansCJK-Regular.ttc</font>
- <font weight="400" style="normal" index="1" fallbackFor="serif">NotoSerifCJK-Regular.ttc</font>
+ <font weight="400" style="normal" index="1" postScriptName="NotoSansCJKjp-Regular">
+ NotoSansCJK-Regular.ttc
+ </font>
+ <font weight="400" style="normal" index="1" fallbackFor="serif"
+ postScriptName="NotoSerifCJKjp-Regular">NotoSerifCJK-Regular.ttc
+ </font>
</family>
<family lang="und-Zsye">
<font weight="400" style="normal">NotoColorEmoji.ttf</font>
@@ -1053,16 +1343,21 @@
override the East Asian punctuation for Chinese.
-->
<family lang="und-Tale">
- <font weight="400" style="normal">NotoSansTaiLe-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansTaiLe">NotoSansTaiLe-Regular.ttf
+ </font>
</family>
<family lang="und-Yiii">
- <font weight="400" style="normal">NotoSansYi-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansYi">NotoSansYi-Regular.ttf</font>
</family>
<family lang="und-Mong">
- <font weight="400" style="normal">NotoSansMongolian-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansMongolian">
+ NotoSansMongolian-Regular.ttf
+ </font>
</family>
<family lang="und-Phag">
- <font weight="400" style="normal">NotoSansPhagsPa-Regular.ttf</font>
+ <font weight="400" style="normal" postScriptName="NotoSansPhagsPa">
+ NotoSansPhagsPa-Regular.ttf
+ </font>
</family>
<family lang="und-Hluw">
<font weight="400" style="normal">NotoSansAnatolianHieroglyphs-Regular.otf</font>
@@ -1152,72 +1447,92 @@
<font weight="400" style="normal">NotoSerifDogra-Regular.ttf</font>
</family>
<family lang="und-Medf">
- <font weight="400" style="normal">NotoSansMedefaidrin-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansMedefaidrin-Regular">
+ NotoSansMedefaidrin-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansMedefaidrin-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansMedefaidrin-Regular">
+ NotoSansMedefaidrin-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansMedefaidrin-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansMedefaidrin-Regular">
+ NotoSansMedefaidrin-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansMedefaidrin-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansMedefaidrin-Regular">
+ NotoSansMedefaidrin-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Soyo">
- <font weight="400" style="normal">NotoSansSoyombo-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansSoyombo-Regular">
+ NotoSansSoyombo-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansSoyombo-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansSoyombo-Regular">
+ NotoSansSoyombo-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansSoyombo-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansSoyombo-Regular">
+ NotoSansSoyombo-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansSoyombo-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansSoyombo-Regular">
+ NotoSansSoyombo-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Takr">
- <font weight="400" style="normal">NotoSansTakri-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSansTakri-Regular">
+ NotoSansTakri-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSansTakri-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSansTakri-Regular">
+ NotoSansTakri-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSansTakri-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSansTakri-Regular">
+ NotoSansTakri-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSansTakri-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSansTakri-Regular">
+ NotoSansTakri-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Hmnp">
- <font weight="400" style="normal">NotoSerifNyiakengPuachueHmong-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSerifHmongNyiakeng-Regular">
+ NotoSerifNyiakengPuachueHmong-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSerifNyiakengPuachueHmong-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSerifHmongNyiakeng-Regular">
+ NotoSerifNyiakengPuachueHmong-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSerifNyiakengPuachueHmong-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSerifHmongNyiakeng-Regular">
+ NotoSerifNyiakengPuachueHmong-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSerifNyiakengPuachueHmong-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSerifHmongNyiakeng-Regular">
+ NotoSerifNyiakengPuachueHmong-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
<family lang="und-Yezi">
- <font weight="400" style="normal">NotoSerifYezidi-VF.ttf
+ <font weight="400" style="normal" postScriptName="NotoSerifYezidi-Regular">
+ NotoSerifYezidi-VF.ttf
<axis tag="wght" stylevalue="400"/>
</font>
- <font weight="500" style="normal">NotoSerifYezidi-VF.ttf
+ <font weight="500" style="normal" postScriptName="NotoSerifYezidi-Regular">
+ NotoSerifYezidi-VF.ttf
<axis tag="wght" stylevalue="500"/>
</font>
- <font weight="600" style="normal">NotoSerifYezidi-VF.ttf
+ <font weight="600" style="normal" postScriptName="NotoSerifYezidi-Regular">
+ NotoSerifYezidi-VF.ttf
<axis tag="wght" stylevalue="600"/>
</font>
- <font weight="700" style="normal">NotoSerifYezidi-VF.ttf
+ <font weight="700" style="normal" postScriptName="NotoSerifYezidi-Regular">
+ NotoSerifYezidi-VF.ttf
<axis tag="wght" stylevalue="700"/>
</font>
</family>
diff --git a/errorprone/java/android/annotation/RequiresNoPermission.java b/errorprone/java/android/annotation/RequiresNoPermission.java
new file mode 100644
index 0000000..6ff4d6e3
--- /dev/null
+++ b/errorprone/java/android/annotation/RequiresNoPermission.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Denotes that the annotated element requires no permissions.
+ *
+ * @hide
+ */
+@Retention(CLASS)
+@Target({ANNOTATION_TYPE,METHOD,CONSTRUCTOR,FIELD,PARAMETER})
+public @interface RequiresNoPermission {
+}
diff --git a/errorprone/java/android/annotation/RequiresPermission.java b/errorprone/java/android/annotation/RequiresPermission.java
new file mode 100644
index 0000000..303ab41
--- /dev/null
+++ b/errorprone/java/android/annotation/RequiresPermission.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2015 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.annotation;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Denotes that the annotated element requires (or may require) one or more permissions.
+ * <p/>
+ * Example of requiring a single permission:
+ * <pre>{@code
+ * {@literal @}RequiresPermission(Manifest.permission.SET_WALLPAPER)
+ * public abstract void setWallpaper(Bitmap bitmap) throws IOException;
+ *
+ * {@literal @}RequiresPermission(ACCESS_COARSE_LOCATION)
+ * public abstract Location getLastKnownLocation(String provider);
+ * }</pre>
+ * Example of requiring at least one permission from a set:
+ * <pre>{@code
+ * {@literal @}RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+ * public abstract Location getLastKnownLocation(String provider);
+ * }</pre>
+ * Example of requiring multiple permissions:
+ * <pre>{@code
+ * {@literal @}RequiresPermission(allOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+ * public abstract Location getLastKnownLocation(String provider);
+ * }</pre>
+ * Example of requiring separate read and write permissions for a content provider:
+ * <pre>{@code
+ * {@literal @}RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))
+ * {@literal @}RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
+ * public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
+ * }</pre>
+ * <p>
+ * When specified on a parameter, the annotation indicates that the method requires
+ * a permission which depends on the value of the parameter. For example, consider
+ * {@link android.app.Activity#startActivity(android.content.Intent)
+ * Activity#startActivity(Intent)}:
+ * <pre>{@code
+ * public void startActivity(@RequiresPermission Intent intent) { ... }
+ * }</pre>
+ * Notice how there are no actual permission names listed in the annotation. The actual
+ * permissions required will depend on the particular intent passed in. For example,
+ * the code may look like this:
+ * <pre>{@code
+ * Intent intent = new Intent(Intent.ACTION_CALL);
+ * startActivity(intent);
+ * }</pre>
+ * and the actual permission requirement for this particular intent is described on
+ * the Intent name itself:
+ * <pre>{@code
+ * {@literal @}RequiresPermission(Manifest.permission.CALL_PHONE)
+ * public static final String ACTION_CALL = "android.intent.action.CALL";
+ * }</pre>
+ *
+ * @hide
+ */
+@Retention(CLASS)
+@Target({ANNOTATION_TYPE,METHOD,CONSTRUCTOR,FIELD,PARAMETER})
+public @interface RequiresPermission {
+ /**
+ * The name of the permission that is required, if precisely one permission
+ * is required. If more than one permission is required, specify either
+ * {@link #allOf()} or {@link #anyOf()} instead.
+ * <p>
+ * If specified, {@link #anyOf()} and {@link #allOf()} must both be null.
+ */
+ String value() default "";
+
+ /**
+ * Specifies a list of permission names that are all required.
+ * <p>
+ * If specified, {@link #anyOf()} and {@link #value()} must both be null.
+ */
+ String[] allOf() default {};
+
+ /**
+ * Specifies a list of permission names where at least one is required
+ * <p>
+ * If specified, {@link #allOf()} and {@link #value()} must both be null.
+ */
+ String[] anyOf() default {};
+
+ /**
+ * If true, the permission may not be required in all cases (e.g. it may only be
+ * enforced on certain platforms, or for certain call parameters, etc.
+ */
+ boolean conditional() default false;
+
+ /**
+ * Specifies that the given permission is required for read operations.
+ * <p>
+ * When specified on a parameter, the annotation indicates that the method requires
+ * a permission which depends on the value of the parameter (and typically
+ * the corresponding field passed in will be one of a set of constants which have
+ * been annotated with a <code>@RequiresPermission</code> annotation.)
+ */
+ @Target({FIELD, METHOD, PARAMETER})
+ @interface Read {
+ RequiresPermission value() default @RequiresPermission;
+ }
+
+ /**
+ * Specifies that the given permission is required for write operations.
+ * <p>
+ * When specified on a parameter, the annotation indicates that the method requires
+ * a permission which depends on the value of the parameter (and typically
+ * the corresponding field passed in will be one of a set of constants which have
+ * been annotated with a <code>@RequiresPermission</code> annotation.)
+ */
+ @Target({FIELD, METHOD, PARAMETER})
+ @interface Write {
+ RequiresPermission value() default @RequiresPermission;
+ }
+}
diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/BluetoothPermissionChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/BluetoothPermissionChecker.java
new file mode 100644
index 0000000..9d1cf87
--- /dev/null
+++ b/errorprone/java/com/google/errorprone/bugpatterns/android/BluetoothPermissionChecker.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.errorprone.bugpatterns.android;
+
+import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
+import static com.google.errorprone.bugpatterns.android.RequiresPermissionChecker.simpleNameMatches;
+import static com.google.errorprone.matchers.Matchers.allOf;
+import static com.google.errorprone.matchers.Matchers.anyOf;
+import static com.google.errorprone.matchers.Matchers.enclosingClass;
+import static com.google.errorprone.matchers.Matchers.isStatic;
+import static com.google.errorprone.matchers.Matchers.isSubtypeOf;
+import static com.google.errorprone.matchers.Matchers.methodHasVisibility;
+import static com.google.errorprone.matchers.Matchers.methodIsConstructor;
+import static com.google.errorprone.matchers.Matchers.methodIsNamed;
+import static com.google.errorprone.matchers.Matchers.not;
+import static com.google.errorprone.matchers.Matchers.packageStartsWith;
+
+import android.annotation.RequiresNoPermission;
+import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
+
+import com.google.auto.service.AutoService;
+import com.google.errorprone.BugPattern;
+import com.google.errorprone.VisitorState;
+import com.google.errorprone.bugpatterns.BugChecker;
+import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher;
+import com.google.errorprone.matchers.Description;
+import com.google.errorprone.matchers.Matcher;
+import com.google.errorprone.matchers.MethodVisibility.Visibility;
+import com.google.errorprone.util.ASTHelpers;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Symbol.MethodSymbol;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.regex.Pattern;
+
+/**
+ * Verifies that all Bluetooth APIs have consistent permissions.
+ */
+@AutoService(BugChecker.class)
+@BugPattern(
+ name = "AndroidFrameworkBluetoothPermission",
+ summary = "Verifies that all Bluetooth APIs have consistent permissions",
+ severity = WARNING)
+public final class BluetoothPermissionChecker extends BugChecker implements MethodTreeMatcher {
+ private static final Matcher<MethodTree> BLUETOOTH_API = allOf(
+ packageStartsWith("android.bluetooth"),
+ methodHasVisibility(Visibility.PUBLIC),
+ not(isStatic()),
+ not(methodIsConstructor()),
+ not(enclosingClass(isInsideParcelable())),
+ not(enclosingClass(simpleNameMatches(Pattern.compile(".+Callback$")))),
+ not(enclosingClass(isSubtypeOf("android.bluetooth.BluetoothProfileConnector"))),
+ not(enclosingClass(isSubtypeOf("android.app.PropertyInvalidatedCache"))));
+
+ private static final Matcher<ClassTree> PARCELABLE_CLASS =
+ isSubtypeOf("android.os.Parcelable");
+ private static final Matcher<MethodTree> BINDER_METHOD = enclosingClass(
+ isSubtypeOf("android.os.IInterface"));
+
+ private static final Matcher<MethodTree> BINDER_INTERNALS = allOf(
+ enclosingClass(isSubtypeOf("android.os.IInterface")),
+ anyOf(
+ methodIsNamed("onTransact"),
+ methodIsNamed("dump"),
+ enclosingClass(simpleNameMatches(Pattern.compile("^(Stub|Default|Proxy)$")))));
+
+ private static final Matcher<MethodTree> GENERIC_INTERNALS = anyOf(
+ methodIsNamed("close"),
+ methodIsNamed("finalize"),
+ methodIsNamed("equals"),
+ methodIsNamed("hashCode"),
+ methodIsNamed("toString"));
+
+ private static final String PERMISSION_ADVERTISE = "android.permission.BLUETOOTH_ADVERTISE";
+ private static final String PERMISSION_CONNECT = "android.permission.BLUETOOTH_CONNECT";
+ private static final String PERMISSION_SCAN = "android.permission.BLUETOOTH_SCAN";
+
+ private static final String ANNOTATION_ADVERTISE =
+ "android.bluetooth.annotations.RequiresBluetoothAdvertisePermission";
+ private static final String ANNOTATION_CONNECT =
+ "android.bluetooth.annotations.RequiresBluetoothConnectPermission";
+ private static final String ANNOTATION_SCAN =
+ "android.bluetooth.annotations.RequiresBluetoothScanPermission";
+
+ @Override
+ public Description matchMethod(MethodTree tree, VisitorState state) {
+ // Ignore methods outside Bluetooth area
+ if (!BLUETOOTH_API.matches(tree, state)) return Description.NO_MATCH;
+
+ // Ignore certain types of generated or internal code
+ if (BINDER_INTERNALS.matches(tree, state)) return Description.NO_MATCH;
+ if (GENERIC_INTERNALS.matches(tree, state)) return Description.NO_MATCH;
+
+ // Skip abstract methods, except for binder interfaces
+ if (tree.getBody() == null && !BINDER_METHOD.matches(tree, state)) {
+ return Description.NO_MATCH;
+ }
+
+ // Ignore callbacks which don't need permission enforcement
+ final MethodSymbol symbol = ASTHelpers.getSymbol(tree);
+ if (isCallbackOrWrapper(symbol)) return Description.NO_MATCH;
+
+ // Ignore when suppressed
+ if (isSuppressed(symbol)) return Description.NO_MATCH;
+
+ final RequiresPermission requiresPerm = ASTHelpers.getAnnotation(tree,
+ RequiresPermission.class);
+ final RequiresNoPermission requiresNoPerm = ASTHelpers.getAnnotation(tree,
+ RequiresNoPermission.class);
+
+ final boolean requiresValid = requiresPerm != null
+ && (requiresPerm.value() != null || requiresPerm.allOf() != null);
+ final boolean requiresNoValid = requiresNoPerm != null;
+ if (!requiresValid && !requiresNoValid) {
+ return buildDescription(tree)
+ .setMessage("Method " + symbol.name.toString()
+ + "() must be protected by at least one permission")
+ .build();
+ }
+
+ // No additional checks needed for Binder generated code
+ if (BINDER_METHOD.matches(tree, state)) return Description.NO_MATCH;
+
+ if (ASTHelpers.hasAnnotation(tree, ANNOTATION_ADVERTISE,
+ state) != isPermissionReferenced(requiresPerm, PERMISSION_ADVERTISE)) {
+ return buildDescription(tree)
+ .setMessage("Method " + symbol.name.toString()
+ + "() has inconsistent annotations for " + PERMISSION_ADVERTISE)
+ .build();
+ }
+ if (ASTHelpers.hasAnnotation(tree, ANNOTATION_CONNECT,
+ state) != isPermissionReferenced(requiresPerm, PERMISSION_CONNECT)) {
+ return buildDescription(tree)
+ .setMessage("Method " + symbol.name.toString()
+ + "() has inconsistent annotations for " + PERMISSION_CONNECT)
+ .build();
+ }
+ if (ASTHelpers.hasAnnotation(tree, ANNOTATION_SCAN,
+ state) != isPermissionReferenced(requiresPerm, PERMISSION_SCAN)) {
+ return buildDescription(tree)
+ .setMessage("Method " + symbol.name.toString()
+ + "() has inconsistent annotations for " + PERMISSION_SCAN)
+ .build();
+ }
+
+ return Description.NO_MATCH;
+ }
+
+ private static boolean isPermissionReferenced(RequiresPermission anno, String perm) {
+ if (anno == null) return false;
+ if (perm.equals(anno.value())) return true;
+ return anno.allOf() != null && Arrays.asList(anno.allOf()).contains(perm);
+ }
+
+ private static boolean isCallbackOrWrapper(Symbol symbol) {
+ if (symbol == null) return false;
+ final String name = symbol.name.toString();
+ return isCallbackOrWrapper(ASTHelpers.enclosingClass(symbol))
+ || name.endsWith("Callback")
+ || name.endsWith("Wrapper");
+ }
+
+ public boolean isSuppressed(Symbol symbol) {
+ if (symbol == null) return false;
+ return isSuppressed(ASTHelpers.enclosingClass(symbol))
+ || isSuppressed(ASTHelpers.getAnnotation(symbol, SuppressWarnings.class))
+ || isSuppressed(ASTHelpers.getAnnotation(symbol, SuppressLint.class));
+ }
+
+ private boolean isSuppressed(SuppressWarnings anno) {
+ return (anno != null) && !Collections.disjoint(Arrays.asList(anno.value()), allNames());
+ }
+
+ private boolean isSuppressed(SuppressLint anno) {
+ return (anno != null) && !Collections.disjoint(Arrays.asList(anno.value()), allNames());
+ }
+
+ private static Matcher<ClassTree> isInsideParcelable() {
+ return new Matcher<ClassTree>() {
+ @Override
+ public boolean matches(ClassTree tree, VisitorState state) {
+ final TreePath path = state.getPath();
+ for (Tree node : path) {
+ if (node instanceof ClassTree
+ && PARCELABLE_CLASS.matches((ClassTree) node, state)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ };
+ }
+}
diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java
index 3b5a58c..f54782d 100644
--- a/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java
+++ b/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java
@@ -143,8 +143,11 @@
final ParsedRequiresPermission nodePerm = parseRequiresPermissionRecursively(
node, state);
if (!expectedPerm.containsAll(nodePerm)) {
- return buildDescription(node).setMessage("Annotated " + expectedPerm
- + " but too narrow; invokes method requiring " + nodePerm).build();
+ return buildDescription(node)
+ .setMessage("Method " + method.name.toString() + "() annotated "
+ + expectedPerm
+ + " but too narrow; invokes method requiring " + nodePerm)
+ .build();
} else {
actualPerm.addAll(nodePerm);
}
@@ -162,8 +165,10 @@
// Second, determine if we actually used all permissions that we claim
// to require; yell if we're too broad
if (!actualPerm.containsAll(expectedPerm)) {
- return buildDescription(tree).setMessage("Annotated " + expectedPerm
- + " but too wide; only invokes methods requiring " + actualPerm).build();
+ return buildDescription(tree)
+ .setMessage("Method " + method.name.toString() + "() annotated " + expectedPerm
+ + " but too wide; only invokes methods requiring " + actualPerm)
+ .build();
}
return Description.NO_MATCH;
@@ -316,7 +321,7 @@
return (anno != null) && !Collections.disjoint(Arrays.asList(anno.value()), allNames());
}
- private static Matcher<ClassTree> simpleNameMatches(Pattern pattern) {
+ static Matcher<ClassTree> simpleNameMatches(Pattern pattern) {
return new Matcher<ClassTree>() {
@Override
public boolean matches(ClassTree tree, VisitorState state) {
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index 6fdf552..13e2692 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -56,6 +56,7 @@
// XML constants for Font.
public static final String ATTR_INDEX = "index";
public static final String ATTR_WEIGHT = "weight";
+ public static final String ATTR_POSTSCRIPT_NAME = "postScriptName";
public static final String ATTR_STYLE = "style";
public static final String ATTR_FALLBACK_FOR = "fallbackFor";
public static final String STYLE_ITALIC = "italic";
@@ -209,6 +210,7 @@
int weight = weightStr == null ? FontStyle.FONT_WEIGHT_NORMAL : Integer.parseInt(weightStr);
boolean isItalic = STYLE_ITALIC.equals(parser.getAttributeValue(null, ATTR_STYLE));
String fallbackFor = parser.getAttributeValue(null, ATTR_FALLBACK_FOR);
+ String postScriptName = parser.getAttributeValue(null, ATTR_POSTSCRIPT_NAME);
StringBuilder filename = new StringBuilder();
while (keepReading(parser)) {
if (parser.getEventType() == XmlPullParser.TEXT) {
@@ -242,8 +244,18 @@
axes.toArray(new FontVariationAxis[0]));
}
- return new FontConfig.Font(new File(filePath),
+ File file = new File(filePath);
+
+ if (postScriptName == null) {
+ // If post script name was not provided, assume the file name is same to PostScript
+ // name.
+ String name = file.getName();
+ postScriptName = name.substring(0, name.length() - 4);
+ }
+
+ return new FontConfig.Font(file,
originalPath == null ? null : new File(originalPath),
+ postScriptName,
new FontStyle(
weight,
isItalic ? FontStyle.FONT_SLANT_ITALIC : FontStyle.FONT_SLANT_UPRIGHT
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index f3dba82..8f1223b 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -754,6 +754,11 @@
}
/** @hide */
+ public void setASurfaceTransactionCallback(ASurfaceTransactionCallback callback) {
+ nSetASurfaceTransactionCallback(mNativeProxy, callback);
+ }
+
+ /** @hide */
public void setFrameCallback(FrameDrawingCallback callback) {
nSetFrameCallback(mNativeProxy, callback);
}
@@ -868,6 +873,23 @@
}
/**
+ * Interface used to receive callbacks when a transaction needs to be merged.
+ *
+ * @hide
+ */
+ public interface ASurfaceTransactionCallback {
+ /**
+ * Invoked during a frame drawing.
+ *
+ * @param aSurfaceTranactionNativeObj the ASurfaceTransaction native object handle
+ * @param aSurfaceControlNativeObj ASurfaceControl native object handle
+ * @param frame The id of the frame being drawn.
+ */
+ void onMergeTransaction(long aSurfaceTranactionNativeObj,
+ long aSurfaceControlNativeObj, long frame);
+ }
+
+ /**
* Interface used to receive callbacks when a frame is being drawn.
*
* @hide
@@ -1342,6 +1364,9 @@
private static native void nSetPictureCaptureCallback(long nativeProxy,
PictureCapturedCallback callback);
+ private static native void nSetASurfaceTransactionCallback(long nativeProxy,
+ ASurfaceTransactionCallback callback);
+
private static native void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback);
private static native void nSetFrameCompleteCallback(long nativeProxy,
diff --git a/graphics/java/android/graphics/RecordingCanvas.java b/graphics/java/android/graphics/RecordingCanvas.java
index 6c03ddc..e9e58c6 100644
--- a/graphics/java/android/graphics/RecordingCanvas.java
+++ b/graphics/java/android/graphics/RecordingCanvas.java
@@ -226,10 +226,12 @@
*/
public void drawRipple(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
CanvasProperty<Float> radius, CanvasProperty<Paint> paint,
- CanvasProperty<Float> progress, RuntimeShader shader) {
+ CanvasProperty<Float> progress, CanvasProperty<Float> turbulencePhase,
+ RuntimeShader shader) {
nDrawRipple(mNativeCanvasWrapper, cx.getNativeContainer(), cy.getNativeContainer(),
radius.getNativeContainer(), paint.getNativeContainer(),
- progress.getNativeContainer(), shader.getNativeShaderBuilder());
+ progress.getNativeContainer(), turbulencePhase.getNativeContainer(),
+ shader.getNativeShaderBuilder());
}
/**
@@ -290,7 +292,7 @@
long propCy, long propRadius, long propPaint);
@CriticalNative
private static native void nDrawRipple(long renderer, long propCx, long propCy, long propRadius,
- long propPaint, long propProgress, long runtimeEffect);
+ long propPaint, long propProgress, long turbulencePhase, long runtimeEffect);
@CriticalNative
private static native void nDrawRoundRect(long renderer, long propLeft, long propTop,
long propRight, long propBottom, long propRx, long propRy, long propPaint);
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index c48fd8b..b88751a 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -1259,20 +1259,21 @@
* @hide
*/
@TestApi
- public static @NonNull Map<String, Typeface> deserializeFontMap(@NonNull ByteBuffer buffer)
+ public static @NonNull long[] deserializeFontMap(
+ @NonNull ByteBuffer buffer, @NonNull Map<String, Typeface> out)
throws IOException {
- Map<String, Typeface> fontMap = new ArrayMap<>();
int typefacesBytesCount = buffer.getInt();
long[] nativePtrs = nativeReadTypefaces(buffer.slice());
if (nativePtrs == null) {
throw new IOException("Could not read typefaces");
}
+ out.clear();
buffer.position(buffer.position() + typefacesBytesCount);
for (long nativePtr : nativePtrs) {
String name = readString(buffer);
- fontMap.put(name, new Typeface(nativePtr));
+ out.put(name, new Typeface(nativePtr));
}
- return fontMap;
+ return nativePtrs;
}
private static String readString(ByteBuffer buffer) {
@@ -1330,7 +1331,14 @@
return;
}
sSystemFontMapBuffer = sharedMemory.mapReadOnly().order(ByteOrder.BIG_ENDIAN);
- Map<String, Typeface> systemFontMap = deserializeFontMap(sSystemFontMapBuffer);
+ Map<String, Typeface> systemFontMap = new ArrayMap<>();
+ long[] nativePtrs = deserializeFontMap(sSystemFontMapBuffer, systemFontMap);
+
+ // Initialize native font APIs. The native font API will read fonts.xml by itself if
+ // Typeface is initialized with loadPreinstalledSystemFontMap.
+ for (long ptr : nativePtrs) {
+ nativeAddFontCollections(ptr);
+ }
setSystemFontMap(systemFontMap);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
@@ -1528,5 +1536,8 @@
private static native void nativeForceSetStaticFinalField(String fieldName, Typeface typeface);
+ @CriticalNative
+ private static native void nativeAddFontCollections(long nativePtr);
+
private static native void nativeWarmUpCache(String fileName);
}
diff --git a/graphics/java/android/graphics/drawable/RippleAnimationSession.java b/graphics/java/android/graphics/drawable/RippleAnimationSession.java
index c317831..1cd4cf1 100644
--- a/graphics/java/android/graphics/drawable/RippleAnimationSession.java
+++ b/graphics/java/android/graphics/drawable/RippleAnimationSession.java
@@ -40,6 +40,8 @@
private static final String TAG = "RippleAnimationSession";
private static final int ENTER_ANIM_DURATION = 450;
private static final int EXIT_ANIM_DURATION = 300;
+ private static final long NOISE_ANIMATION_DURATION = 7000;
+ private static final long MAX_NOISE_PHASE = NOISE_ANIMATION_DURATION / 120;
private static final TimeInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
private static final Interpolator FAST_OUT_SLOW_IN =
new PathInterpolator(0.4f, 0f, 0.2f, 1f);
@@ -49,7 +51,7 @@
private Runnable mOnUpdate;
private long mStartTime;
private boolean mForceSoftware;
- private boolean mAnimateSparkle;
+ private Animator mLoopAnimation;
RippleAnimationSession(@NonNull AnimationProperties<Float, Paint> properties,
boolean forceSoftware) {
@@ -88,16 +90,6 @@
return this;
}
- public boolean shouldAnimateSparkle() {
- return mAnimateSparkle && ValueAnimator.getDurationScale() > 0;
- }
-
- public float getSparklePhase() {
- final long now = AnimationUtils.currentAnimationTimeMillis();
- final long elapsed = now - mStartTime;
- return (float) elapsed / 800;
- }
-
private boolean isHwAccelerated(Canvas canvas) {
return canvas.isHardwareAccelerated() && !mForceSoftware;
}
@@ -114,7 +106,7 @@
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
- mAnimateSparkle = false;
+ if (mLoopAnimation != null) mLoopAnimation.cancel();
Consumer<RippleAnimationSession> onEnd = mOnSessionEnd;
if (onEnd != null) onEnd.accept(RippleAnimationSession.this);
}
@@ -148,7 +140,7 @@
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
- mAnimateSparkle = false;
+ if (mLoopAnimation != null) mLoopAnimation.cancel();
Consumer<RippleAnimationSession> onEnd = mOnSessionEnd;
if (onEnd != null) onEnd.accept(RippleAnimationSession.this);
}
@@ -167,24 +159,42 @@
RenderNodeAnimator expand =
new RenderNodeAnimator(props.getProgress(), .5f);
expand.setTarget(canvas);
- startAnimation(expand);
+ RenderNodeAnimator loop = new RenderNodeAnimator(props.getNoisePhase(), MAX_NOISE_PHASE);
+ loop.setTarget(canvas);
+ startAnimation(expand, loop);
}
- private void startAnimation(Animator expand) {
+ private void startAnimation(Animator expand, Animator loop) {
expand.setDuration(ENTER_ANIM_DURATION);
expand.addListener(new AnimatorListener(this));
expand.setInterpolator(FAST_OUT_SLOW_IN);
expand.start();
- mAnimateSparkle = true;
+ loop.setDuration(NOISE_ANIMATION_DURATION);
+ loop.addListener(new AnimatorListener(this) {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ mLoopAnimation = null;
+ }
+ });
+ loop.setInterpolator(LINEAR_INTERPOLATOR);
+ loop.start();
+ if (mLoopAnimation != null) mLoopAnimation.cancel();
+ mLoopAnimation = loop;
}
private void enterSoftware() {
ValueAnimator expand = ValueAnimator.ofFloat(0f, 0.5f);
expand.addUpdateListener(updatedAnimation -> {
notifyUpdate();
- mProperties.getShader().setProgress((Float) expand.getAnimatedValue());
+ mProperties.getShader().setProgress((float) expand.getAnimatedValue());
});
- startAnimation(expand);
+ ValueAnimator loop = ValueAnimator.ofFloat(0f, MAX_NOISE_PHASE);
+ loop.addUpdateListener(updatedAnimation -> {
+ notifyUpdate();
+ mProperties.getShader().setNoisePhase((float) loop.getAnimatedValue());
+ });
+ startAnimation(expand, loop);
}
@NonNull AnimationProperties<Float, Paint> getProperties() {
@@ -198,6 +208,7 @@
CanvasProperty.createFloat(mProperties.getX()),
CanvasProperty.createFloat(mProperties.getY()),
CanvasProperty.createFloat(mProperties.getMaxRadius()),
+ CanvasProperty.createFloat(mProperties.getNoisePhase()),
CanvasProperty.createPaint(mProperties.getPaint()),
CanvasProperty.createFloat(mProperties.getProgress()),
mProperties.getShader());
@@ -236,16 +247,18 @@
static class AnimationProperties<FloatType, PaintType> {
private final FloatType mProgress;
private final FloatType mMaxRadius;
+ private final FloatType mNoisePhase;
private final PaintType mPaint;
private final RippleShader mShader;
private FloatType mX;
private FloatType mY;
- AnimationProperties(FloatType x, FloatType y, FloatType maxRadius,
+ AnimationProperties(FloatType x, FloatType y, FloatType maxRadius, FloatType noisePhase,
PaintType paint, FloatType progress, RippleShader shader) {
mY = y;
mX = x;
mMaxRadius = maxRadius;
+ mNoisePhase = noisePhase;
mPaint = paint;
mShader = shader;
mProgress = progress;
@@ -279,5 +292,9 @@
RippleShader getShader() {
return mShader;
}
+
+ FloatType getNoisePhase() {
+ return mNoisePhase;
+ }
}
}
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 0865332..c972a24 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -858,15 +858,6 @@
}
for (int i = 0; i < mRunningAnimations.size(); i++) {
RippleAnimationSession s = mRunningAnimations.get(i);
- if (s.shouldAnimateSparkle()) {
- final float phase = s.getSparklePhase();
- if (useCanvasProps) {
- s.getCanvasProperties().getShader().setNoisePhase(phase);
- } else {
- s.getProperties().getShader().setNoisePhase(phase);
- }
- invalidateSelf();
- }
if (useCanvasProps) {
RippleAnimationSession.AnimationProperties<CanvasProperty<Float>,
CanvasProperty<Paint>>
@@ -883,7 +874,7 @@
yProp = p.getY();
}
can.drawRipple(xProp, yProp, p.getMaxRadius(), p.getPaint(),
- p.getProgress(), p.getShader());
+ p.getProgress(), p.getNoisePhase(), p.getShader());
} else {
RippleAnimationSession.AnimationProperties<Float, Paint> p =
s.getProperties();
@@ -953,7 +944,7 @@
shader.setRadius(radius);
shader.setProgress(.0f);
properties = new RippleAnimationSession.AnimationProperties<>(
- cx, cy, radius, p, 0f, shader);
+ cx, cy, radius, 0f, p, 0f, shader);
if (mMaskShader == null) {
shader.setShader(null);
} else {
diff --git a/graphics/java/android/graphics/drawable/RippleShader.java b/graphics/java/android/graphics/drawable/RippleShader.java
index 4608d02..c1c6afc 100644
--- a/graphics/java/android/graphics/drawable/RippleShader.java
+++ b/graphics/java/android/graphics/drawable/RippleShader.java
@@ -167,6 +167,9 @@
final float turbulencePhase = (float) ((mProgress + mNoisePhase * 0.333f) * 5f * Math.PI);
setUniform("in_turbulencePhase", turbulencePhase);
+ //
+ // Keep in sync with: frameworks/base/libs/hwui/pipeline/skia/AnimatedDrawables.h
+ //
final float scale = 1.5f;
setUniform("in_tCircle1", new float[]{
(float) (scale * 0.5 + (turbulencePhase * 0.01 * Math.cos(scale * 0.55))),
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
index ecb082e..62fe54f 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
@@ -62,10 +62,8 @@
*/
@UnsupportedAppUsage
public static long getKeyStoreOperationHandle(Object cryptoPrimitive) {
- if (cryptoPrimitive == null) {
- throw new NullPointerException();
- }
- return 0;
+ return android.security.keystore2.AndroidKeyStoreProvider
+ .getKeyStoreOperationHandle(cryptoPrimitive);
}
/**
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index f3baad7..2207e62 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -43,10 +43,10 @@
<string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Superior 50%"</string>
<string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Superior 30%"</string>
<string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pantalla inferior completa"</string>
- <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Utilizar el modo una mano"</string>
+ <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Usar Modo una mano"</string>
<string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para salir, desliza el dedo hacia arriba desde la parte inferior de la pantalla o toca cualquier zona que haya encima de la aplicación"</string>
- <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar modo una mano"</string>
- <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Salir del modo una mano"</string>
+ <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar Modo una mano"</string>
+ <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Salir del Modo una mano"</string>
<string name="bubbles_settings_button_description" msgid="1301286017420516912">"Ajustes de las burbujas de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Menú adicional"</string>
<string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Volver a añadir a la pila"</string>
@@ -70,5 +70,5 @@
<string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionar"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbuja cerrada."</string>
<string name="restart_button_description" msgid="5887656107651190519">"Toca para reiniciar esta aplicación e ir a la pantalla completa."</string>
- <string name="got_it" msgid="4428750913636945527">"Listo"</string>
+ <string name="got_it" msgid="4428750913636945527">"Entendido"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index fed3ea9..a17f543 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -62,10 +62,10 @@
<string name="bubbles_user_education_title" msgid="2112319053732691899">"گپ بااستفاده از حبابکها"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"مکالمههای جدید بهصورت نمادهای شناور یا حبابکها نشان داده میشوند. برای باز کردن حبابکها ضربه بزنید. برای جابهجایی، آن را بکشید."</string>
<string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"کنترل حبابکها در هرزمانی"</string>
- <string name="bubbles_user_education_manage" msgid="3460756219946517198">"برای خاموش کردن «حبابکها» از این برنامه، روی «مدیریت» ضربه بزنید"</string>
+ <string name="bubbles_user_education_manage" msgid="3460756219946517198">"برای خاموش کردن حبابکها از این برنامه، روی «مدیریت» ضربه بزنید"</string>
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"متوجهام"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"هیچ حبابک جدیدی وجود ندارد"</string>
- <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"حبابکها اخیر و حبابکها ردشده اینجا ظاهر خواهند شد"</string>
+ <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"حبابکهای اخیر و حبابکهای ردشده اینجا ظاهر خواهند شد"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"حباب"</string>
<string name="manage_bubbles_text" msgid="7730624269650594419">"مدیریت"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"حبابک رد شد."</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index a969386..b2c0055 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -67,7 +67,7 @@
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"हाल ही के बबल्स मौजूद नहीं हैं"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"हाल ही के बबल्स और हटाए गए बबल्स यहां दिखेंगे"</string>
<string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
- <string name="manage_bubbles_text" msgid="7730624269650594419">"प्रबंधित करें"</string>
+ <string name="manage_bubbles_text" msgid="7730624269650594419">"मैनेज करें"</string>
<string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल खारिज किया गया."</string>
<string name="restart_button_description" msgid="5887656107651190519">"इस ऐप्लिकेशन को रीस्टार्ट करने और फ़ुल स्क्रीन पर देखने के लिए टैप करें."</string>
<string name="got_it" msgid="4428750913636945527">"ठीक है"</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings_tv.xml b/libs/WindowManager/Shell/res/values-iw/strings_tv.xml
index 8ca54e0..ef98a9c 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings_tv.xml
@@ -19,6 +19,6 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="notification_channel_tv_pip" msgid="2576686079160402435">"תמונה בתוך תמונה"</string>
<string name="pip_notification_unknown_title" msgid="2729870284350772311">"(תוכנית ללא כותרת)"</string>
- <string name="pip_close" msgid="9135220303720555525">"סגור PIP"</string>
+ <string name="pip_close" msgid="9135220303720555525">"סגירת PIP"</string>
<string name="pip_fullscreen" msgid="7278047353591302554">"מסך מלא"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 530d40a..0c64c76 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -62,7 +62,7 @@
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Калкып чыкма билдирмелер аркылуу маектешүү"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Жаңы жазышуулар калкыма сүрөтчөлөр же калкып чыкма билдирмелер түрүндө көрүнөт. Калкып чыкма билдирмелерди ачуу үчүн таптап коюңуз. Жылдыруу үчүн сүйрөңүз."</string>
<string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Калкып чыкма билдирмелерди каалаган убакта көзөмөлдөңүз"</string>
- <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Бул колдонмодогу калкып чыкма билдирмелерди өчүрүү үчүн, \"Башкарууну\" басыңыз"</string>
+ <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Бул колдонмодогу калкып чыкма билдирмелерди өчүрүү үчүн \"Башкарууну\" басыңыз"</string>
<string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Түшүндүм"</string>
<string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Азырынча эч нерсе жок"</string>
<string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Акыркы жана жабылган калкып чыкма билдирмелер ушул жерде көрүнөт"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 882ac37..dfa364a 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -30,7 +30,7 @@
<string name="accessibility_action_pip_resize" msgid="4623966104749543182">"आकार बदल्नुहोस्"</string>
<string name="dock_forced_resizable" msgid="1749750436092293116">"एप विभाजित स्क्रिनमा काम नगर्न सक्छ।"</string>
<string name="dock_non_resizeble_failed_to_dock_text" msgid="7408396418008948957">"अनुप्रयोगले विभाजित-स्क्रिनलाई समर्थन गर्दैन।"</string>
- <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"यो अनुप्रयोगले सहायक प्रदर्शनमा काम नगर्नसक्छ।"</string>
+ <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"यो एपले सहायक प्रदर्शनमा काम नगर्नसक्छ।"</string>
<string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"अनुप्रयोगले सहायक प्रदर्शनहरूमा लञ्च सुविधालाई समर्थन गर्दैन।"</string>
<string name="accessibility_divider" msgid="703810061635792791">"विभाजित-स्क्रिन छुट्याउने"</string>
<string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"बायाँ भाग फुल स्क्रिन"</string>
diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml
index 6698a01..a138fee 100644
--- a/libs/WindowManager/Shell/res/values/config.xml
+++ b/libs/WindowManager/Shell/res/values/config.xml
@@ -40,7 +40,7 @@
<integer name="long_press_dock_anim_duration">250</integer>
<!-- Animation duration for translating of one handed when trigger / dismiss. -->
- <integer name="config_one_handed_translate_animation_duration">300</integer>
+ <integer name="config_one_handed_translate_animation_duration">800</integer>
<!-- One handed mode default offset % of display size -->
<fraction name="config_one_handed_offset">40%</fraction>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java
index 125e322..25dd3ca 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java
@@ -22,8 +22,7 @@
import android.content.Context;
import android.graphics.Rect;
import android.view.SurfaceControl;
-import android.view.animation.Interpolator;
-import android.view.animation.OvershootInterpolator;
+import android.view.animation.BaseInterpolator;
import android.window.WindowContainerToken;
import androidx.annotation.VisibleForTesting;
@@ -54,7 +53,7 @@
public @interface TransitionDirection {
}
- private final Interpolator mOvershootInterpolator;
+ private final OneHandedInterpolator mInterpolator;
private final OneHandedSurfaceTransactionHelper mSurfaceTransactionHelper;
private final HashMap<WindowContainerToken, OneHandedTransitionAnimator> mAnimatorMap =
new HashMap<>();
@@ -64,7 +63,7 @@
*/
public OneHandedAnimationController(Context context) {
mSurfaceTransactionHelper = new OneHandedSurfaceTransactionHelper(context);
- mOvershootInterpolator = new OvershootInterpolator();
+ mInterpolator = new OneHandedInterpolator();
}
@SuppressWarnings("unchecked")
@@ -102,7 +101,7 @@
OneHandedTransitionAnimator setupOneHandedTransitionAnimator(
OneHandedTransitionAnimator animator) {
animator.setSurfaceTransactionHelper(mSurfaceTransactionHelper);
- animator.setInterpolator(mOvershootInterpolator);
+ animator.setInterpolator(mInterpolator);
animator.setFloatValues(FRACTION_START, FRACTION_END);
return animator;
}
@@ -112,6 +111,8 @@
*
* @param <T> Type of property to animate, either offset (float)
*/
+ // TODO: Refactoring to use SpringAnimation and DynamicAnimation instead of using ValueAnimator
+ // to implement One-Handed transition animation. (b/185129031)
public abstract static class OneHandedTransitionAnimator<T> extends ValueAnimator implements
ValueAnimator.AnimatorUpdateListener,
ValueAnimator.AnimatorListener {
@@ -297,4 +298,15 @@
};
}
}
+
+ /**
+ * An Interpolator for One-Handed transition animation.
+ */
+ public class OneHandedInterpolator extends BaseInterpolator {
+ @Override
+ public float getInterpolation(float input) {
+ return (float) (Math.pow(2, -10 * input) * Math.sin(((input - 4.0f) / 4.0f)
+ * (2.0f * Math.PI) / 4.0f) + 1);
+ }
+ }
}
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 19098fd..625f4b8 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
@@ -29,6 +29,7 @@
import android.content.om.OverlayInfo;
import android.content.res.Configuration;
import android.database.ContentObserver;
+import android.graphics.Rect;
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -61,7 +62,8 @@
/**
* Manages and manipulates the one handed states, transitions, and gesture for phones.
*/
-public class OneHandedController implements RemoteCallable<OneHandedController> {
+public class OneHandedController implements RemoteCallable<OneHandedController>,
+ OneHandedTransitionCallback {
private static final String TAG = "OneHandedController";
private static final String ONE_HANDED_MODE_OFFSET_PERCENTAGE =
@@ -73,6 +75,7 @@
private volatile boolean mIsOneHandedEnabled;
private volatile boolean mIsSwipeToNotificationEnabled;
+ private volatile boolean mIsTransitioning;
private boolean mTaskChangeToExit;
private boolean mLockedDisabled;
private int mUserId;
@@ -327,7 +330,7 @@
@VisibleForTesting
void startOneHanded() {
- if (isLockedDisabled()) {
+ if (isLockedDisabled() || mIsTransitioning) {
Slog.d(TAG, "Temporary lock disabled");
return;
}
@@ -337,13 +340,13 @@
return;
}
if (!mDisplayAreaOrganizer.isInOneHanded()) {
+ mIsTransitioning = true;
final int yOffSet = Math.round(
mDisplayAreaOrganizer.getDisplayLayout().height() * mOffSetFraction);
mOneHandedAccessibilityUtil.announcementForScreenReader(
mOneHandedAccessibilityUtil.getOneHandedStartDescription());
mDisplayAreaOrganizer.scheduleOffset(0, yOffSet);
mTimeoutHandler.resetTimer();
-
mOneHandedUiEventLogger.writeEvent(
OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_GESTURE_IN);
}
@@ -351,16 +354,12 @@
@VisibleForTesting
void stopOneHanded() {
- if (mDisplayAreaOrganizer.isInOneHanded()) {
- mOneHandedAccessibilityUtil.announcementForScreenReader(
- mOneHandedAccessibilityUtil.getOneHandedStopDescription());
- mDisplayAreaOrganizer.scheduleOffset(0, 0);
- mTimeoutHandler.removeTimer();
- }
+ stopOneHanded(OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_GESTURE_OUT);
}
private void stopOneHanded(int uiEvent) {
- if (mDisplayAreaOrganizer.isInOneHanded()) {
+ if (mDisplayAreaOrganizer.isInOneHanded() && !mIsTransitioning) {
+ mIsTransitioning = true;
mOneHandedAccessibilityUtil.announcementForScreenReader(
mOneHandedAccessibilityUtil.getOneHandedStopDescription());
mDisplayAreaOrganizer.scheduleOffset(0, 0);
@@ -389,6 +388,7 @@
mDisplayAreaOrganizer.registerTransitionCallback(mGestureHandler);
mDisplayAreaOrganizer.registerTransitionCallback(mTutorialHandler);
mDisplayAreaOrganizer.registerTransitionCallback(mBackgroundPanelOrganizer);
+ mDisplayAreaOrganizer.registerTransitionCallback(this);
if (mTaskChangeToExit) {
mTaskStackListener.addListener(mTaskStackListenerCallback);
}
@@ -615,6 +615,8 @@
pw.println(mLockedDisabled);
pw.print(innerPrefix + "mUserId=");
pw.println(mUserId);
+ pw.print(innerPrefix + "mIsTransitioning=");
+ pw.println(mIsTransitioning);
if (mBackgroundPanelOrganizer != null) {
mBackgroundPanelOrganizer.dump(pw);
@@ -661,6 +663,26 @@
}
/**
+ * TODO(b/185558765) To implement a state machine for One-Handed transition state machine.
+ * ONE_HANDDE_STATE_TRANSITION {
+ * STATE_DEFAULT,
+ * STATE_TRANSITIONING,
+ * STATE_ENTER_ONE_HANED,
+ * STATE_EXIT_ONE_HANDED
+ * }
+ * and we need to align the state to launcher3 quick steps through SysuiProxy.
+ */
+ @Override
+ public void onStartFinished(Rect bounds) {
+ mIsTransitioning = false;
+ }
+
+ @Override
+ public void onStopFinished(Rect bounds) {
+ mIsTransitioning = false;
+ }
+
+ /**
* The interface for calls from outside the Shell, within the host process.
*/
@ExternalThread
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
index a474831..dd7e294 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
@@ -50,6 +50,7 @@
// Referenced in com.android.systemui.util.NotificationChannels.
public static final String NOTIFICATION_CHANNEL = "TVPIP";
private static final String NOTIFICATION_TAG = "TvPip";
+ private static final String SYSTEMUI_PERMISSION = "com.android.systemui.permission.SELF";
private static final String ACTION_SHOW_PIP_MENU =
"com.android.wm.shell.pip.tv.notification.action.SHOW_PIP_MENU";
@@ -207,7 +208,8 @@
}
private static PendingIntent createPendingIntent(Context context, String action) {
- return PendingIntent.getBroadcast(context, 0, new Intent(action),
+ return PendingIntent.getBroadcast(context, 0,
+ new Intent(action).setPackage(context.getPackageName()),
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
}
@@ -223,7 +225,7 @@
void register() {
if (mRegistered) return;
- mContext.registerReceiverForAllUsers(this, mIntentFilter, null /* permission */,
+ mContext.registerReceiverForAllUsers(this, mIntentFilter, SYSTEMUI_PERMISSION,
mMainHandler);
mRegistered = true;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index 516dfd0..147f2e2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -16,6 +16,7 @@
package com.android.wm.shell.startingsurface;
+import static android.os.Process.THREAD_PRIORITY_TOP_APP_BOOST;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.os.UserHandle.getUserHandleForUid;
@@ -35,6 +36,8 @@
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerThread;
import android.os.Trace;
import android.util.Slog;
import android.view.SurfaceControl;
@@ -48,10 +51,11 @@
import com.android.wm.shell.common.TransactionPool;
import java.util.List;
+import java.util.function.Consumer;
/**
* Util class to create the view for a splash screen content.
- *
+ * Everything execute in this class should be post to mSplashscreenWorkerHandler.
* @hide
*/
public class SplashscreenContentDrawer {
@@ -78,6 +82,7 @@
private int mIconEarlyExitDistance;
private final TransactionPool mTransactionPool;
private final SplashScreenWindowAttrs mTmpAttrs = new SplashScreenWindowAttrs();
+ private final Handler mSplashscreenWorkerHandler;
SplashscreenContentDrawer(Context context, int maxAnimatableIconDuration,
int iconExitAnimDuration, int appRevealAnimDuration, TransactionPool pool) {
@@ -87,6 +92,45 @@
mAppRevealDuration = appRevealAnimDuration;
mIconExitDuration = iconExitAnimDuration;
mTransactionPool = pool;
+
+ // Initialize Splashscreen worker thread
+ // TODO(b/185288910) move it into WMShellConcurrencyModule and provide an executor to make
+ // it easier to test stuff that happens on that thread later.
+ final HandlerThread shellSplashscreenWorkerThread =
+ new HandlerThread("wmshell.splashworker", THREAD_PRIORITY_TOP_APP_BOOST);
+ shellSplashscreenWorkerThread.start();
+ mSplashscreenWorkerHandler = shellSplashscreenWorkerThread.getThreadHandler();
+ }
+
+ /**
+ * Create a SplashScreenView object.
+ *
+ * In order to speed up the splash screen view to show on first frame, preparing the
+ * view on background thread so the view and the drawable can be create and pre-draw in
+ * parallel.
+ *
+ * @param consumer Receiving the SplashScreenView object, which will also be executed
+ * on splash screen thread. Note that the view can be null if failed.
+ */
+ void createContentView(Context context, int splashScreenResId, ActivityInfo info,
+ int taskId, Consumer<SplashScreenView> consumer) {
+ mSplashscreenWorkerHandler.post(() -> {
+ SplashScreenView contentView;
+ try {
+ contentView = SplashscreenContentDrawer.makeSplashscreenContent(
+ context, splashScreenResId);
+ if (contentView == null) {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "makeSplashScreenContentView");
+ contentView = makeSplashScreenContentView(context, info);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ }
+ } catch (RuntimeException e) {
+ Slog.w(TAG, "failed creating starting window content at taskId: "
+ + taskId, e);
+ contentView = null;
+ }
+ consumer.accept(contentView);
+ });
}
private void updateDensity() {
@@ -146,7 +190,7 @@
}
}
- SplashScreenView makeSplashScreenContentView(Context context, ActivityInfo ai) {
+ private SplashScreenView makeSplashScreenContentView(Context context, ActivityInfo ai) {
updateDensity();
getWindowAttrs(context, mTmpAttrs);
@@ -199,7 +243,7 @@
}
}
- static class SplashScreenWindowAttrs {
+ private static class SplashScreenWindowAttrs {
private int mWindowBgResId = 0;
private int mWindowBgColor = Color.TRANSPARENT;
private Drawable mReplaceIcon = null;
@@ -271,9 +315,7 @@
if (DEBUG) {
Slog.d(TAG, "The icon is not an AdaptiveIconDrawable");
}
- mFinalIconDrawable = SplashscreenIconDrawableFactory.makeIconDrawable(
- mIconBackground != Color.TRANSPARENT
- ? mIconBackground : mThemeColor, mIconDrawable, mIconSize);
+ createIconDrawable(mIconDrawable, mIconSize);
}
final int iconSize = mFinalIconDrawable != null ? (int) (mIconSize * mScale) : 0;
mCachedResult = fillViewWithIcon(mContext, iconSize, mFinalIconDrawable);
@@ -283,8 +325,8 @@
private void createIconDrawable(Drawable iconDrawable, int iconSize) {
mFinalIconDrawable = SplashscreenIconDrawableFactory.makeIconDrawable(
- mIconBackground != Color.TRANSPARENT
- ? mIconBackground : mThemeColor, iconDrawable, iconSize);
+ mIconBackground != Color.TRANSPARENT ? mIconBackground : mThemeColor,
+ iconDrawable, iconSize, mSplashscreenWorkerHandler);
}
private boolean processAdaptiveIcon() {
@@ -399,7 +441,7 @@
return root < 0.1;
}
- static SplashScreenView makeSplashscreenContent(Context ctx,
+ private static SplashScreenView makeSplashscreenContent(Context ctx,
int splashscreenContentResId) {
// doesn't support windowSplashscreenContent after S
// TODO add an allowlist to skip some packages if needed
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java
index 4196d68..85845d0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java
@@ -37,6 +37,7 @@
import android.graphics.drawable.Animatable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.os.Handler;
import android.os.Trace;
import android.util.PathParser;
import android.window.SplashScreenView;
@@ -50,42 +51,61 @@
public class SplashscreenIconDrawableFactory {
static Drawable makeIconDrawable(@ColorInt int backgroundColor,
- @NonNull Drawable foregroundDrawable, int iconSize) {
+ @NonNull Drawable foregroundDrawable, int iconSize,
+ Handler splashscreenWorkerHandler) {
if (foregroundDrawable instanceof Animatable) {
return new AnimatableIconDrawable(backgroundColor, foregroundDrawable);
} else if (foregroundDrawable instanceof AdaptiveIconDrawable) {
- return new ImmobileIconDrawable((AdaptiveIconDrawable) foregroundDrawable, iconSize);
+ return new ImmobileIconDrawable((AdaptiveIconDrawable) foregroundDrawable, iconSize,
+ splashscreenWorkerHandler);
} else {
return new ImmobileIconDrawable(new AdaptiveIconDrawable(
- new ColorDrawable(backgroundColor), foregroundDrawable), iconSize);
+ new ColorDrawable(backgroundColor), foregroundDrawable), iconSize,
+ splashscreenWorkerHandler);
}
}
private static class ImmobileIconDrawable extends Drawable {
- private Shader mLayersShader;
+ private boolean mCacheComplete;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG
| Paint.FILTER_BITMAP_FLAG);
- ImmobileIconDrawable(AdaptiveIconDrawable drawable, int iconSize) {
- cachePaint(drawable, iconSize, iconSize);
+ ImmobileIconDrawable(AdaptiveIconDrawable drawable, int iconSize,
+ Handler splashscreenWorkerHandler) {
+ splashscreenWorkerHandler.post(() -> cachePaint(drawable, iconSize, iconSize));
}
private void cachePaint(AdaptiveIconDrawable drawable, int width, int height) {
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "cachePaint");
- final Bitmap layersBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- final Canvas canvas = new Canvas(layersBitmap);
- drawable.setBounds(0, 0, width, height);
- drawable.draw(canvas);
- mLayersShader = new BitmapShader(layersBitmap, Shader.TileMode.CLAMP,
- Shader.TileMode.CLAMP);
- mPaint.setShader(mLayersShader);
- Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ synchronized (mPaint) {
+ if (mCacheComplete) {
+ return;
+ }
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "cachePaint");
+ final Bitmap layersBitmap = Bitmap.createBitmap(width, height,
+ Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(layersBitmap);
+ drawable.setBounds(0, 0, width, height);
+ drawable.draw(canvas);
+ final Shader layersShader = new BitmapShader(layersBitmap, Shader.TileMode.CLAMP,
+ Shader.TileMode.CLAMP);
+ mPaint.setShader(layersShader);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ mCacheComplete = true;
+ }
}
@Override
public void draw(Canvas canvas) {
- final Rect bounds = getBounds();
- canvas.drawRect(bounds, mPaint);
+ synchronized (mPaint) {
+ if (mCacheComplete) {
+ final Rect bounds = getBounds();
+ canvas.drawRect(bounds, mPaint);
+ } else {
+ // this shouldn't happen, but if it really happen, invalidate self to wait
+ // for cachePaint finish.
+ invalidateSelf();
+ }
+ }
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index e95135a..7037d18 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -18,8 +18,10 @@
import static android.content.Context.CONTEXT_RESTRICTED;
import static android.content.res.Configuration.EMPTY;
+import static android.view.Choreographer.CALLBACK_INSETS_ANIMATION;
import static android.view.Display.DEFAULT_DISPLAY;
+import android.annotation.Nullable;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityTaskManager;
import android.content.Context;
@@ -29,16 +31,15 @@
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
-import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
-import android.graphics.drawable.ColorDrawable;
import android.hardware.display.DisplayManager;
import android.os.IBinder;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Slog;
import android.util.SparseArray;
+import android.view.Choreographer;
import android.view.Display;
import android.view.SurfaceControl;
import android.view.View;
@@ -54,9 +55,44 @@
import com.android.wm.shell.common.TransactionPool;
import java.util.function.Consumer;
+import java.util.function.Supplier;
/**
* A class which able to draw splash screen or snapshot as the starting window for a task.
+ *
+ * In order to speed up, there will use two threads to creating a splash screen in parallel.
+ * Right now we are still using PhoneWindow to create splash screen window, so the view is added to
+ * the ViewRootImpl, and those view won't be draw immediately because the ViewRootImpl will call
+ * scheduleTraversal to register a callback from Choreographer, so the drawing result of the view
+ * can synchronize on each frame.
+ *
+ * The bad thing is that we cannot decide when would Choreographer#doFrame happen, and drawing
+ * the AdaptiveIconDrawable object can be time consuming, so we use the splash-screen background
+ * thread to draw the AdaptiveIconDrawable object to a Bitmap and cache it to a BitmapShader after
+ * the SplashScreenView just created, once we get the BitmapShader then the #draw call can be very
+ * quickly.
+ *
+ * So basically we are using the spare time to prepare the SplashScreenView while splash screen
+ * thread is waiting for
+ * 1. WindowManager#addView(binder call to WM),
+ * 2. Choreographer#doFrame happen(uncertain time for next frame, depends on device),
+ * 3. Session#relayout(another binder call to WM which under Choreographer#doFrame, but will
+ * always happen before #draw).
+ * Because above steps are running on splash-screen thread, so pre-draw the BitmapShader on
+ * splash-screen background tread can make they execute in parallel, which ensure it is faster then
+ * to draw the AdaptiveIconDrawable when receive callback from Choreographer#doFrame.
+ *
+ * Here is the sequence to compare the difference between using single and two thread.
+ *
+ * Single thread:
+ * => makeSplashScreenContentView -> WM#addView .. waiting for Choreographer#doFrame -> relayout
+ * -> draw -> AdaptiveIconDrawable#draw
+ *
+ * Two threads:
+ * => makeSplashScreenContentView -> cachePaint(=AdaptiveIconDrawable#draw)
+ * => WM#addView -> .. waiting for Choreographer#doFrame -> relayout -> draw -> (draw the Paint
+ * directly).
+ *
* @hide
*/
public class StartingSurfaceDrawer {
@@ -68,7 +104,11 @@
private final DisplayManager mDisplayManager;
private final ShellExecutor mSplashScreenExecutor;
private final SplashscreenContentDrawer mSplashscreenContentDrawer;
+ private Choreographer mChoreographer;
+ /**
+ * @param splashScreenExecutor The thread used to control add and remove starting window.
+ */
public StartingSurfaceDrawer(Context context, ShellExecutor splashScreenExecutor,
TransactionPool pool) {
mContext = context;
@@ -82,6 +122,7 @@
com.android.wm.shell.R.integer.starting_window_app_reveal_anim_duration);
mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext,
maxAnimatableIconDuration, iconExitAnimDuration, appRevealAnimDuration, pool);
+ mSplashScreenExecutor.execute(() -> mChoreographer = Choreographer.getInstance());
}
private final SparseArray<StartingWindowRecord> mStartingWindowRecords = new SparseArray<>();
@@ -267,36 +308,91 @@
params.setTitle("Splash Screen " + activityInfo.packageName);
// TODO(b/173975965) tracking performance
- SplashScreenView sView = null;
+ // Prepare the splash screen content view on splash screen worker thread in parallel, so the
+ // content view won't be blocked by binder call like addWindow and relayout.
+ // 1. Trigger splash screen worker thread to create SplashScreenView before/while
+ // Session#addWindow.
+ // 2. Synchronize the SplashscreenView to splash screen thread before Choreographer start
+ // traversal, which will call Session#relayout on splash screen thread.
+ // 3. Pre-draw the BitmapShader if the icon is immobile on splash screen worker thread, at
+ // the same time the splash screen thread should be executing Session#relayout. Blocking the
+ // traversal -> draw on splash screen thread until the BitmapShader of the icon is ready.
+ final Runnable setViewSynchronized;
+ if (!emptyView) {
+ // Record whether create splash screen view success, notify to current thread after
+ // create splash screen view finished.
+ final SplashScreenViewSupplier viewSupplier = new SplashScreenViewSupplier();
+ setViewSynchronized = () -> {
+ // waiting for setContentView before relayoutWindow
+ SplashScreenView contentView = viewSupplier.get();
+ final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
+ // if record == null, either the starting window added fail or removed already.
+ if (record != null) {
+ // if view == null then creation of content view was failed.
+ if (contentView != null) {
+ try {
+ win.setContentView(contentView);
+ contentView.cacheRootWindow(win);
+ } catch (RuntimeException e) {
+ Slog.w(TAG, "failed set content view to starting window "
+ + "at taskId: " + taskId, e);
+ contentView = null;
+ }
+ }
+ record.setSplashScreenView(contentView);
+ }
+ };
+ mSplashscreenContentDrawer.createContentView(context,
+ splashscreenContentResId[0], activityInfo, taskId, viewSupplier::setView);
+ } else {
+ setViewSynchronized = null;
+ }
+
try {
final View view = win.getDecorView();
final WindowManager wm = mContext.getSystemService(WindowManager.class);
- if (!emptyView) {
- // splash screen content will be deprecated after S.
- sView = SplashscreenContentDrawer.makeSplashscreenContent(
- context, splashscreenContentResId[0]);
- final boolean splashscreenContentCompatible = sView != null;
- if (splashscreenContentCompatible) {
- win.setContentView(sView);
- } else {
- sView = mSplashscreenContentDrawer
- .makeSplashScreenContentView(context, activityInfo);
- win.setContentView(sView);
- win.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
- sView.cacheRootWindow(win);
- }
- }
postAddWindow(taskId, appToken, view, wm, params);
+
+ // all done
+ if (emptyView) {
+ return;
+ }
+ // We use the splash screen worker thread to create SplashScreenView while adding the
+ // window, as otherwise Choreographer#doFrame might be delayed on this thread.
+ // And since Choreographer#doFrame won't happen immediately after adding the window, if
+ // the view is not added to the PhoneWindow on the first #doFrame, the view will not be
+ // rendered on the first frame. So here we need to synchronize the view on the window
+ // before first round relayoutWindow, which will happen after insets animation.
+ mChoreographer.postCallback(CALLBACK_INSETS_ANIMATION, setViewSynchronized, null);
} catch (RuntimeException e) {
// don't crash if something else bad happens, for example a
// failure loading resources because we are loading from an app
// on external storage that has been unmounted.
- Slog.w(TAG, " failed creating starting window at taskId: " + taskId, e);
- sView = null;
- } finally {
- final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
- if (record != null) {
- record.setSplashScreenView(sView);
+ Slog.w(TAG, "failed creating starting window at taskId: " + taskId, e);
+ }
+ }
+
+ private static class SplashScreenViewSupplier implements Supplier<SplashScreenView> {
+ private SplashScreenView mView;
+ private boolean mIsViewSet;
+ void setView(SplashScreenView view) {
+ synchronized (this) {
+ mView = view;
+ mIsViewSet = true;
+ notify();
+ }
+ }
+
+ @Override
+ public @Nullable SplashScreenView get() {
+ synchronized (this) {
+ while (!mIsViewSet) {
+ try {
+ wait();
+ } catch (InterruptedException ignored) {
+ }
+ }
+ return mView;
}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
index 8a629bc..e336287 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
@@ -16,6 +16,7 @@
package com.android.wm.shell.startingsurface;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_NONE;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT;
@@ -30,11 +31,11 @@
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
import android.app.ActivityManager.RunningTaskInfo;
-import android.app.ActivityTaskManager;
import android.content.Context;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.Trace;
import android.util.Slog;
import android.view.SurfaceControl;
import android.window.StartingWindowInfo;
@@ -109,17 +110,9 @@
}
private static class StartingTypeChecker {
- TaskSnapshot mSnapshot;
-
- StartingTypeChecker() { }
-
- private void reset() {
- mSnapshot = null;
- }
private @StartingWindowInfo.StartingWindowType int
estimateStartingWindowType(StartingWindowInfo windowInfo) {
- reset();
final int parameter = windowInfo.startingWindowTypeParameter;
final boolean newTask = (parameter & TYPE_PARAMETER_NEW_TASK) != 0;
final boolean taskSwitch = (parameter & TYPE_PARAMETER_TASK_SWITCH) != 0;
@@ -159,7 +152,7 @@
}
}
if (taskSwitch && allowTaskSnapshot) {
- final TaskSnapshot snapshot = getTaskSnapshot(windowInfo.taskInfo.taskId);
+ final TaskSnapshot snapshot = windowInfo.mTaskSnapshot;
if (isSnapshotCompatible(windowInfo, snapshot)) {
return STARTING_WINDOW_TYPE_SNAPSHOT;
}
@@ -198,20 +191,6 @@
}
return taskRotation == snapshotRotation;
}
-
- private TaskSnapshot getTaskSnapshot(int taskId) {
- if (mSnapshot != null) {
- return mSnapshot;
- }
- try {
- mSnapshot = ActivityTaskManager.getService().getTaskSnapshot(taskId,
- false/* isLowResolution */);
- } catch (RemoteException e) {
- Slog.e(TAG, "Unable to get snapshot for task: " + taskId + ", from: " + e);
- return null;
- }
- return mSnapshot;
- }
}
/*
@@ -232,7 +211,9 @@
*/
public void addStartingWindow(StartingWindowInfo windowInfo, IBinder appToken) {
mSplashScreenExecutor.execute(() -> {
- final int suggestionType = mStartingTypeChecker.estimateStartingWindowType(windowInfo);
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "addStartingWindow");
+ final int suggestionType = mStartingTypeChecker.estimateStartingWindowType(
+ windowInfo);
final RunningTaskInfo runningTaskInfo = windowInfo.taskInfo;
if (mTaskLaunchingCallback != null && shouldSendToListener(suggestionType)) {
mTaskLaunchingCallback.accept(runningTaskInfo.taskId, suggestionType);
@@ -244,10 +225,12 @@
mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo, appToken,
true /* emptyView */);
} else if (suggestionType == STARTING_WINDOW_TYPE_SNAPSHOT) {
- final TaskSnapshot snapshot = mStartingTypeChecker.mSnapshot;
- mStartingSurfaceDrawer.makeTaskSnapshotWindow(windowInfo, appToken, snapshot);
+ final TaskSnapshot snapshot = windowInfo.mTaskSnapshot;
+ mStartingSurfaceDrawer.makeTaskSnapshotWindow(windowInfo, appToken,
+ snapshot);
}
// If prefer don't show, then don't show!
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
});
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
index 6e43741..e9ce2ad 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
@@ -19,6 +19,7 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.graphics.Color.WHITE;
import static android.graphics.Color.alpha;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
@@ -60,6 +61,7 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.os.Trace;
import android.util.MergedConfiguration;
import android.util.Slog;
import android.view.IWindowSession;
@@ -222,8 +224,10 @@
final InputChannel tmpInputChannel = new InputChannel();
mainExecutor.execute(() -> {
try {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "TaskSnapshot#addToDisplay");
final int res = session.addToDisplay(window, layoutParams, View.GONE, displayId,
mTmpInsetsState, tmpInputChannel, mTmpInsetsState, mTempControls);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
if (res < 0) {
Slog.w(TAG, "Failed to add snapshot starting window res=" + res);
return;
@@ -233,9 +237,11 @@
}
window.setOuter(snapshotSurface);
try {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "TaskSnapshot#relayout");
session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0, -1,
tmpFrames, tmpMergedConfiguration, surfaceControl, mTmpInsetsState,
mTempControls, TMP_SURFACE_SIZE);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
} catch (RemoteException e) {
snapshotSurface.clearWindowSynced();
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenDockActivity.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenDockActivity.kt
index e50bde2..6494f89 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenDockActivity.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenDockActivity.kt
@@ -23,7 +23,7 @@
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.LAUNCHER_TITLE
+import com.android.server.wm.flicker.HOME_WINDOW_TITLE
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.launchSplitScreen
import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
@@ -62,7 +62,7 @@
override val ignoredWindows: List<String>
get() = listOf(LAUNCHER_PACKAGE_NAME, LIVE_WALLPAPER_PACKAGE_NAME,
splitScreenApp.defaultWindowName, WindowManagerStateHelper.SPLASH_SCREEN_NAME,
- WindowManagerStateHelper.SNAPSHOT_WINDOW_NAME, *LAUNCHER_TITLE)
+ WindowManagerStateHelper.SNAPSHOT_WINDOW_NAME, *HOME_WINDOW_TITLE)
@FlakyTest(bugId = 169271943)
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
index d1d1313..2623535 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
@@ -77,9 +77,9 @@
int mAddWindowForTask = 0;
int mViewThemeResId;
- TestStartingSurfaceDrawer(Context context, ShellExecutor animExecutor,
+ TestStartingSurfaceDrawer(Context context, ShellExecutor splashScreenExecutor,
TransactionPool pool) {
- super(context, animExecutor, pool);
+ super(context, splashScreenExecutor, pool);
}
@Override
@@ -120,8 +120,9 @@
doReturn(metrics).when(mMockWindowManager).getMaximumWindowMetrics();
doNothing().when(mMockWindowManager).addView(any(), any());
- mStartingSurfaceDrawer = spy(new TestStartingSurfaceDrawer(context,
- new HandlerExecutor(new Handler(Looper.getMainLooper())),
+ final HandlerExecutor testExecutor =
+ new HandlerExecutor(new Handler(Looper.getMainLooper()));
+ mStartingSurfaceDrawer = spy(new TestStartingSurfaceDrawer(context, testExecutor,
mTransactionPool));
}
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 4c4a152..3056e97 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -820,10 +820,11 @@
uirenderer::CanvasPropertyPrimitive* radius,
uirenderer::CanvasPropertyPaint* paint,
uirenderer::CanvasPropertyPrimitive* progress,
+ uirenderer::CanvasPropertyPrimitive* turbulencePhase,
const SkRuntimeShaderBuilder& effectBuilder) {
sk_sp<uirenderer::skiapipeline::AnimatedRipple> drawable(
new uirenderer::skiapipeline::AnimatedRipple(x, y, radius, paint, progress,
- effectBuilder));
+ turbulencePhase, effectBuilder));
mCanvas->drawDrawable(drawable.get());
}
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index e0a0be5..995f00c 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -153,6 +153,7 @@
uirenderer::CanvasPropertyPrimitive* radius,
uirenderer::CanvasPropertyPaint* paint,
uirenderer::CanvasPropertyPrimitive* progress,
+ uirenderer::CanvasPropertyPrimitive* turbulencePhase,
const SkRuntimeShaderBuilder& effectBuilder) override;
virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) override;
diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp
index 671c66f..979678d 100644
--- a/libs/hwui/WebViewFunctorManager.cpp
+++ b/libs/hwui/WebViewFunctorManager.cpp
@@ -18,6 +18,7 @@
#include <private/hwui/WebViewFunctor.h>
#include "Properties.h"
+#include "renderthread/CanvasContext.h"
#include "renderthread/RenderThread.h"
#include <log/log.h>
@@ -115,11 +116,20 @@
ScopedCurrentFunctor currentFunctor(this);
WebViewOverlayData overlayParams = {
- // TODO:
.overlaysMode = OverlaysMode::Disabled,
.getSurfaceControl = currentFunctor.getSurfaceControl,
.mergeTransaction = currentFunctor.mergeTransaction,
};
+
+ if (!drawInfo.isLayer) {
+ renderthread::CanvasContext* activeContext =
+ renderthread::CanvasContext::getActiveContext();
+ if (activeContext != nullptr) {
+ ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
+ if (rootSurfaceControl) overlayParams.overlaysMode = OverlaysMode::Enabled;
+ }
+ }
+
mCallbacks.gles.draw(mFunctor, mData, drawInfo, overlayParams);
}
@@ -138,11 +148,12 @@
ScopedCurrentFunctor currentFunctor(this);
WebViewOverlayData overlayParams = {
- // TODO
.overlaysMode = OverlaysMode::Disabled,
.getSurfaceControl = currentFunctor.getSurfaceControl,
.mergeTransaction = currentFunctor.mergeTransaction,
};
+
+ // TODO, enable surface control once offscreen mode figured out
mCallbacks.vk.draw(mFunctor, mData, params, overlayParams);
}
@@ -166,15 +177,43 @@
void WebViewFunctor::removeOverlays() {
ScopedCurrentFunctor currentFunctor(this);
mCallbacks.removeOverlays(mFunctor, mData, currentFunctor.mergeTransaction);
+ if (mSurfaceControl) {
+ auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
+ funcs.releaseFunc(mSurfaceControl);
+ mSurfaceControl = nullptr;
+ }
}
ASurfaceControl* WebViewFunctor::getSurfaceControl() {
- // TODO
- return nullptr;
+ ATRACE_NAME("WebViewFunctor::getSurfaceControl");
+ if (mSurfaceControl != nullptr) return mSurfaceControl;
+
+ renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
+ LOG_ALWAYS_FATAL_IF(activeContext == nullptr, "Null active canvas context!");
+
+ ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
+ LOG_ALWAYS_FATAL_IF(rootSurfaceControl == nullptr, "Null root surface control!");
+
+ auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
+ mSurfaceControl = funcs.createFunc(rootSurfaceControl, "Webview Overlay SurfaceControl");
+ ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
+ funcs.transactionSetVisibilityFunc(transaction, mSurfaceControl,
+ ASURFACE_TRANSACTION_VISIBILITY_SHOW);
+ funcs.transactionApplyFunc(transaction);
+ funcs.transactionDeleteFunc(transaction);
+ return mSurfaceControl;
}
void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {
- // TODO
+ ATRACE_NAME("WebViewFunctor::mergeTransaction");
+ if (transaction == nullptr) return;
+ renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
+ LOG_ALWAYS_FATAL_IF(activeContext == nullptr, "Null active canvas context!");
+ bool done = activeContext->mergeTransaction(transaction, mSurfaceControl);
+ if (!done) {
+ auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
+ funcs.transactionApplyFunc(transaction);
+ }
}
WebViewFunctorManager& WebViewFunctorManager::instance() {
diff --git a/libs/hwui/WebViewFunctorManager.h b/libs/hwui/WebViewFunctorManager.h
index 17b936a..a84cda5 100644
--- a/libs/hwui/WebViewFunctorManager.h
+++ b/libs/hwui/WebViewFunctorManager.h
@@ -91,6 +91,7 @@
RenderMode mMode;
bool mHasContext = false;
bool mCreatedHandle = false;
+ ASurfaceControl* mSurfaceControl = nullptr;
};
class WebViewFunctorManager {
diff --git a/libs/hwui/canvas/CanvasOps.h b/libs/hwui/canvas/CanvasOps.h
index 855cd0d..173f394 100644
--- a/libs/hwui/canvas/CanvasOps.h
+++ b/libs/hwui/canvas/CanvasOps.h
@@ -152,32 +152,66 @@
sp<uirenderer::CanvasPropertyPrimitive> radius;
sp<uirenderer::CanvasPropertyPaint> paint;
sp<uirenderer::CanvasPropertyPrimitive> progress;
+ sp<uirenderer::CanvasPropertyPrimitive> turbulencePhase;
sk_sp<SkRuntimeEffect> effect;
+ const float PI = 3.1415926535897932384626;
+ const float PI_ROTATE_RIGHT = PI * 0.0078125;
+ const float PI_ROTATE_LEFT = PI * -0.0078125;
+ const float SCALE = 1.5;
+ const float CIRCLE_X_1 = 0.01 * cos(SCALE * 0.55);
+ const float CIRCLE_Y_1 = 0.01 * sin(SCALE * 0.55);
+ const float CIRCLE_X_2 = -0.0066 * cos(SCALE * 0.45);
+ const float CIRCLE_Y_2 = -0.0066 * sin(SCALE * 0.45);
+ const float CIRCLE_X_3 = -0.0066 * cos(SCALE * 0.35);
+ const float CIRCLE_Y_3 = -0.0066 * sin(SCALE * 0.35);
+
void draw(SkCanvas* canvas) const {
SkRuntimeShaderBuilder runtimeEffectBuilder(effect);
- SkRuntimeShaderBuilder::BuilderUniform center = runtimeEffectBuilder.uniform("in_origin");
- if (center.fVar != nullptr) {
- center = SkV2{x->value, y->value};
- }
+ setUniform2f(runtimeEffectBuilder, "in_origin", x->value, y->value);
+ setUniform(runtimeEffectBuilder, "in_radius", radius);
+ setUniform(runtimeEffectBuilder, "in_progress", progress);
+ setUniform(runtimeEffectBuilder, "in_turbulencePhase", turbulencePhase);
- SkRuntimeShaderBuilder::BuilderUniform radiusU =
- runtimeEffectBuilder.uniform("in_radius");
- if (radiusU.fVar != nullptr) {
- radiusU = radius->value;
- }
-
- SkRuntimeShaderBuilder::BuilderUniform progressU =
- runtimeEffectBuilder.uniform("in_progress");
- if (progressU.fVar != nullptr) {
- progressU = progress->value;
- }
+ //
+ // Keep in sync with:
+ // frameworks/base/graphics/java/android/graphics/drawable/RippleShader.java
+ //
+ const float turbulence = turbulencePhase->value;
+ setUniform2f(runtimeEffectBuilder, "in_tCircle1", SCALE * 0.5 + (turbulence * CIRCLE_X_1),
+ SCALE * 0.5 + (turbulence * CIRCLE_Y_1));
+ setUniform2f(runtimeEffectBuilder, "in_tCircle2", SCALE * 0.2 + (turbulence * CIRCLE_X_2),
+ SCALE * 0.2 + (turbulence * CIRCLE_Y_2));
+ setUniform2f(runtimeEffectBuilder, "in_tCircle3", SCALE + (turbulence * CIRCLE_X_3),
+ SCALE + (turbulence * CIRCLE_Y_3));
+ const float rotation1 = turbulence * PI_ROTATE_RIGHT + 1.7 * PI;
+ setUniform2f(runtimeEffectBuilder, "in_tRotation1", cos(rotation1), sin(rotation1));
+ const float rotation2 = turbulence * PI_ROTATE_LEFT + 2 * PI;
+ setUniform2f(runtimeEffectBuilder, "in_tRotation2", cos(rotation2), sin(rotation2));
+ const float rotation3 = turbulence * PI_ROTATE_RIGHT + 2.75 * PI;
+ setUniform2f(runtimeEffectBuilder, "in_tRotation3", cos(rotation3), sin(rotation3));
SkPaint paintMod = paint->value;
paintMod.setShader(runtimeEffectBuilder.makeShader(nullptr, false));
canvas->drawCircle(x->value, y->value, radius->value, paintMod);
}
+
+ void setUniform(SkRuntimeShaderBuilder& effect, std::string name,
+ sp<uirenderer::CanvasPropertyPrimitive> property) const {
+ SkRuntimeShaderBuilder::BuilderUniform uniform = effect.uniform(name.c_str());
+ if (uniform.fVar != nullptr) {
+ uniform = property->value;
+ }
+ }
+
+ void setUniform2f(SkRuntimeShaderBuilder effect, std::string name, float a, float b) const {
+ SkRuntimeShaderBuilder::BuilderUniform uniform = effect.uniform(name.c_str());
+ if (uniform.fVar != nullptr) {
+ uniform = SkV2{a, b};
+ }
+ }
+
ASSERT_DRAWABLE()
};
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index c1feb76..837b055 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -146,6 +146,7 @@
uirenderer::CanvasPropertyPrimitive* radius,
uirenderer::CanvasPropertyPaint* paint,
uirenderer::CanvasPropertyPrimitive* progress,
+ uirenderer::CanvasPropertyPrimitive* turbulencePhase,
const SkRuntimeShaderBuilder& effectBuilder) = 0;
virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) = 0;
diff --git a/libs/hwui/jni/Typeface.cpp b/libs/hwui/jni/Typeface.cpp
index 251323d..f928baa 100644
--- a/libs/hwui/jni/Typeface.cpp
+++ b/libs/hwui/jni/Typeface.cpp
@@ -373,6 +373,12 @@
makeSkDataCached(filePath.c_str(), false /* fs verity */);
}
+// Critical Native
+static void Typeface_addFontCollection(CRITICAL_JNI_PARAMS_COMMA jlong faceHandle) {
+ std::shared_ptr<minikin::FontCollection> collection = toTypeface(faceHandle)->fFontCollection;
+ minikin::SystemFonts::addFontMap(std::move(collection));
+}
+
///////////////////////////////////////////////////////////////////////////////
static const JNINativeMethod gTypefaceMethods[] = {
@@ -397,6 +403,7 @@
{"nativeGetFamilySize", "(J)I", (void*)Typeface_getFamilySize},
{"nativeGetFamily", "(JI)J", (void*)Typeface_getFamily},
{"nativeWarmUpCache", "(Ljava/lang/String;)V", (void*)Typeface_warmUpCache},
+ {"nativeAddFontCollections", "(J)V", (void*)Typeface_addFontCollection},
};
int register_android_graphics_Typeface(JNIEnv* env)
diff --git a/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp b/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp
index 855d56e..eb5a88a 100644
--- a/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp
+++ b/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp
@@ -141,20 +141,22 @@
canvas->drawCircle(xProp, yProp, radiusProp, paintProp);
}
-static void android_view_DisplayListCanvas_drawRippleProps(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
- jlong xPropPtr, jlong yPropPtr,
- jlong radiusPropPtr, jlong paintPropPtr,
- jlong progressPropPtr,
- jlong builderPtr) {
+static void android_view_DisplayListCanvas_drawRippleProps(
+ CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jlong xPropPtr, jlong yPropPtr,
+ jlong radiusPropPtr, jlong paintPropPtr, jlong progressPropPtr, jlong turbulencePhasePtr,
+ jlong builderPtr) {
Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr);
CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr);
CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr);
+ CanvasPropertyPrimitive* turbulencePhaseProp =
+ reinterpret_cast<CanvasPropertyPrimitive*>(turbulencePhasePtr);
CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
CanvasPropertyPrimitive* progressProp =
reinterpret_cast<CanvasPropertyPrimitive*>(progressPropPtr);
SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(builderPtr);
- canvas->drawRipple(xProp, yProp, radiusProp, paintProp, progressProp, *builder);
+ canvas->drawRipple(xProp, yProp, radiusProp, paintProp, progressProp, turbulencePhaseProp,
+ *builder);
}
static void android_view_DisplayListCanvas_drawWebViewFunctor(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jint functor) {
@@ -169,19 +171,22 @@
const char* const kClassPathName = "android/graphics/RecordingCanvas";
static JNINativeMethod gMethods[] = {
- // ------------ @CriticalNative --------------
- { "nCreateDisplayListCanvas", "(JII)J", (void*) android_view_DisplayListCanvas_createDisplayListCanvas },
- { "nResetDisplayListCanvas", "(JJII)V", (void*) android_view_DisplayListCanvas_resetDisplayListCanvas },
- { "nGetMaximumTextureWidth", "()I", (void*) android_view_DisplayListCanvas_getMaxTextureSize },
- { "nGetMaximumTextureHeight", "()I", (void*) android_view_DisplayListCanvas_getMaxTextureSize },
- { "nEnableZ", "(JZ)V", (void*) android_view_DisplayListCanvas_enableZ },
- { "nFinishRecording", "(JJ)V", (void*) android_view_DisplayListCanvas_finishRecording },
- { "nDrawRenderNode", "(JJ)V", (void*) android_view_DisplayListCanvas_drawRenderNode },
- { "nDrawTextureLayer", "(JJ)V", (void*) android_view_DisplayListCanvas_drawTextureLayer },
- { "nDrawCircle", "(JJJJJ)V", (void*) android_view_DisplayListCanvas_drawCircleProps },
- { "nDrawRoundRect", "(JJJJJJJJ)V",(void*) android_view_DisplayListCanvas_drawRoundRectProps },
- { "nDrawWebViewFunctor", "(JI)V", (void*) android_view_DisplayListCanvas_drawWebViewFunctor },
- { "nDrawRipple", "(JJJJJJJ)V", (void*) android_view_DisplayListCanvas_drawRippleProps },
+ // ------------ @CriticalNative --------------
+ {"nCreateDisplayListCanvas", "(JII)J",
+ (void*)android_view_DisplayListCanvas_createDisplayListCanvas},
+ {"nResetDisplayListCanvas", "(JJII)V",
+ (void*)android_view_DisplayListCanvas_resetDisplayListCanvas},
+ {"nGetMaximumTextureWidth", "()I", (void*)android_view_DisplayListCanvas_getMaxTextureSize},
+ {"nGetMaximumTextureHeight", "()I",
+ (void*)android_view_DisplayListCanvas_getMaxTextureSize},
+ {"nEnableZ", "(JZ)V", (void*)android_view_DisplayListCanvas_enableZ},
+ {"nFinishRecording", "(JJ)V", (void*)android_view_DisplayListCanvas_finishRecording},
+ {"nDrawRenderNode", "(JJ)V", (void*)android_view_DisplayListCanvas_drawRenderNode},
+ {"nDrawTextureLayer", "(JJ)V", (void*)android_view_DisplayListCanvas_drawTextureLayer},
+ {"nDrawCircle", "(JJJJJ)V", (void*)android_view_DisplayListCanvas_drawCircleProps},
+ {"nDrawRoundRect", "(JJJJJJJJ)V", (void*)android_view_DisplayListCanvas_drawRoundRectProps},
+ {"nDrawWebViewFunctor", "(JI)V", (void*)android_view_DisplayListCanvas_drawWebViewFunctor},
+ {"nDrawRipple", "(JJJJJJJJ)V", (void*)android_view_DisplayListCanvas_drawRippleProps},
};
int register_android_view_DisplayListCanvas(JNIEnv* env) {
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index d859541..dd78d58 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -64,6 +64,10 @@
} gHardwareRenderer;
struct {
+ jmethodID onMergeTransaction;
+} gASurfaceTransactionCallback;
+
+struct {
jmethodID onFrameDraw;
} gFrameDrawingCallback;
@@ -509,6 +513,27 @@
}
}
+static void android_view_ThreadedRenderer_setASurfaceTransactionCallback(
+ JNIEnv* env, jobject clazz, jlong proxyPtr, jobject aSurfaceTransactionCallback) {
+ RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+ if (!aSurfaceTransactionCallback) {
+ proxy->setASurfaceTransactionCallback(nullptr);
+ } else {
+ JavaVM* vm = nullptr;
+ LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
+ auto globalCallbackRef = std::make_shared<JGlobalRefHolder>(
+ vm, env->NewGlobalRef(aSurfaceTransactionCallback));
+ proxy->setASurfaceTransactionCallback(
+ [globalCallbackRef](int64_t transObj, int64_t scObj, int64_t frameNr) {
+ JNIEnv* env = getenv(globalCallbackRef->vm());
+ env->CallVoidMethod(globalCallbackRef->object(),
+ gASurfaceTransactionCallback.onMergeTransaction,
+ static_cast<jlong>(transObj), static_cast<jlong>(scObj),
+ static_cast<jlong>(frameNr));
+ });
+ }
+}
+
static void android_view_ThreadedRenderer_setFrameCallback(JNIEnv* env,
jobject clazz, jlong proxyPtr, jobject frameCallback) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
@@ -762,8 +787,7 @@
{"nSetName", "(JLjava/lang/String;)V", (void*)android_view_ThreadedRenderer_setName},
{"nSetSurface", "(JLandroid/view/Surface;Z)V",
(void*)android_view_ThreadedRenderer_setSurface},
- {"nSetSurfaceControl", "(JJ)V",
- (void*)android_view_ThreadedRenderer_setSurfaceControl},
+ {"nSetSurfaceControl", "(JJ)V", (void*)android_view_ThreadedRenderer_setSurfaceControl},
{"nPause", "(J)Z", (void*)android_view_ThreadedRenderer_pause},
{"nSetStopped", "(JZ)V", (void*)android_view_ThreadedRenderer_setStopped},
{"nSetLightAlpha", "(JFF)V", (void*)android_view_ThreadedRenderer_setLightAlpha},
@@ -804,6 +828,9 @@
{"nSetPictureCaptureCallback",
"(JLandroid/graphics/HardwareRenderer$PictureCapturedCallback;)V",
(void*)android_view_ThreadedRenderer_setPictureCapturedCallbackJNI},
+ {"nSetASurfaceTransactionCallback",
+ "(JLandroid/graphics/HardwareRenderer$ASurfaceTransactionCallback;)V",
+ (void*)android_view_ThreadedRenderer_setASurfaceTransactionCallback},
{"nSetFrameCallback", "(JLandroid/graphics/HardwareRenderer$FrameDrawingCallback;)V",
(void*)android_view_ThreadedRenderer_setFrameCallback},
{"nSetFrameCompleteCallback",
@@ -866,6 +893,11 @@
GetStaticMethodIDOrDie(env, hardwareRenderer, "closeHintSession",
"(Landroid/os/PerformanceHintManager$Session;)V");
+ jclass aSurfaceTransactionCallbackClass =
+ FindClassOrDie(env, "android/graphics/HardwareRenderer$ASurfaceTransactionCallback");
+ gASurfaceTransactionCallback.onMergeTransaction =
+ GetMethodIDOrDie(env, aSurfaceTransactionCallbackClass, "onMergeTransaction", "(JJJ)V");
+
jclass frameCallbackClass = FindClassOrDie(env,
"android/graphics/HardwareRenderer$FrameDrawingCallback");
gFrameDrawingCallback.onFrameDraw = GetMethodIDOrDie(env, frameCallbackClass,
diff --git a/libs/hwui/pipeline/skia/AnimatedDrawables.h b/libs/hwui/pipeline/skia/AnimatedDrawables.h
index 7859145..7d65be1 100644
--- a/libs/hwui/pipeline/skia/AnimatedDrawables.h
+++ b/libs/hwui/pipeline/skia/AnimatedDrawables.h
@@ -19,6 +19,7 @@
#include <SkCanvas.h>
#include <SkDrawable.h>
#include <SkRuntimeEffect.h>
+#include <math.h>
#include <utils/RefBase.h>
#include "CanvasProperty.h"
@@ -61,12 +62,14 @@
uirenderer::CanvasPropertyPrimitive* radius,
uirenderer::CanvasPropertyPaint* paint,
uirenderer::CanvasPropertyPrimitive* progress,
+ uirenderer::CanvasPropertyPrimitive* turbulencePhase,
const SkRuntimeShaderBuilder& effectBuilder)
: mX(x)
, mY(y)
, mRadius(radius)
, mPaint(paint)
, mProgress(progress)
+ , mTurbulencePhase(turbulencePhase)
, mRuntimeEffectBuilder(effectBuilder) {}
protected:
@@ -77,22 +80,28 @@
return SkRect::MakeLTRB(x - radius, y - radius, x + radius, y + radius);
}
virtual void onDraw(SkCanvas* canvas) override {
- SkRuntimeShaderBuilder::BuilderUniform center = mRuntimeEffectBuilder.uniform("in_origin");
- if (center.fVar != nullptr) {
- center = SkV2{mX->value, mY->value};
- }
+ setUniform2f("in_origin", mX->value, mY->value);
+ setUniform("in_radius", mRadius);
+ setUniform("in_progress", mProgress);
+ setUniform("in_turbulencePhase", mTurbulencePhase);
- SkRuntimeShaderBuilder::BuilderUniform radiusU =
- mRuntimeEffectBuilder.uniform("in_radius");
- if (radiusU.fVar != nullptr) {
- radiusU = mRadius->value;
- }
-
- SkRuntimeShaderBuilder::BuilderUniform progressU =
- mRuntimeEffectBuilder.uniform("in_progress");
- if (progressU.fVar != nullptr) {
- progressU = mProgress->value;
- }
+ //
+ // Keep in sync with:
+ // frameworks/base/graphics/java/android/graphics/drawable/RippleShader.java
+ //
+ const float turbulencePhase = mTurbulencePhase->value;
+ setUniform2f("in_tCircle1", SCALE * 0.5 + (turbulencePhase * CIRCLE_X_1),
+ SCALE * 0.5 + (turbulencePhase * CIRCLE_Y_1));
+ setUniform2f("in_tCircle2", SCALE * 0.2 + (turbulencePhase * CIRCLE_X_2),
+ SCALE * 0.2 + (turbulencePhase * CIRCLE_Y_2));
+ setUniform2f("in_tCircle3", SCALE + (turbulencePhase * CIRCLE_X_3),
+ SCALE + (turbulencePhase * CIRCLE_Y_3));
+ const float rotation1 = turbulencePhase * PI_ROTATE_RIGHT + 1.7 * PI;
+ setUniform2f("in_tRotation1", cos(rotation1), sin(rotation1));
+ const float rotation2 = turbulencePhase * PI_ROTATE_LEFT + 2 * PI;
+ setUniform2f("in_tRotation2", cos(rotation2), sin(rotation2));
+ const float rotation3 = turbulencePhase * PI_ROTATE_RIGHT + 2.75 * PI;
+ setUniform2f("in_tRotation3", cos(rotation3), sin(rotation3));
SkPaint paint = mPaint->value;
paint.setShader(mRuntimeEffectBuilder.makeShader(nullptr, false));
@@ -105,7 +114,35 @@
sp<uirenderer::CanvasPropertyPrimitive> mRadius;
sp<uirenderer::CanvasPropertyPaint> mPaint;
sp<uirenderer::CanvasPropertyPrimitive> mProgress;
+ sp<uirenderer::CanvasPropertyPrimitive> mTurbulencePhase;
SkRuntimeShaderBuilder mRuntimeEffectBuilder;
+
+ const float PI = 3.1415926535897932384626;
+ const float PI_ROTATE_RIGHT = PI * 0.0078125;
+ const float PI_ROTATE_LEFT = PI * -0.0078125;
+ const float SCALE = 1.5;
+ const float CIRCLE_X_1 = 0.01 * cos(SCALE * 0.55);
+ const float CIRCLE_Y_1 = 0.01 * sin(SCALE * 0.55);
+ const float CIRCLE_X_2 = -0.0066 * cos(SCALE * 0.45);
+ const float CIRCLE_Y_2 = -0.0066 * sin(SCALE * 0.45);
+ const float CIRCLE_X_3 = -0.0066 * cos(SCALE * 0.35);
+ const float CIRCLE_Y_3 = -0.0066 * sin(SCALE * 0.35);
+
+ virtual void setUniform(std::string name, sp<uirenderer::CanvasPropertyPrimitive> property) {
+ SkRuntimeShaderBuilder::BuilderUniform uniform =
+ mRuntimeEffectBuilder.uniform(name.c_str());
+ if (uniform.fVar != nullptr) {
+ uniform = property->value;
+ }
+ }
+
+ virtual void setUniform2f(std::string name, float a, float b) {
+ SkRuntimeShaderBuilder::BuilderUniform uniform =
+ mRuntimeEffectBuilder.uniform(name.c_str());
+ if (uniform.fVar != nullptr) {
+ uniform = SkV2{a, b};
+ }
+ }
};
class AnimatedCircle : public SkDrawable {
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 82814de..9e73f04 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -60,12 +60,11 @@
// Add the marker annotation to allow HWUI to determine where the current
// clip/transformation should be applied
SkVector vector = rect.getSimpleRadii();
- const int dataSize = 2;
- float data[dataSize];
+ float data[2];
data[0] = vector.x();
data[1] = vector.y();
mRecorder.drawAnnotation(rect.rect(), HOLE_PUNCH_ANNOTATION.c_str(),
- SkData::MakeWithCopy(data, dataSize));
+ SkData::MakeWithCopy(data, 2 * sizeof(float)));
// Clear the current rect within the layer itself
SkPaint paint = SkPaint();
@@ -115,9 +114,10 @@
uirenderer::CanvasPropertyPrimitive* radius,
uirenderer::CanvasPropertyPaint* paint,
uirenderer::CanvasPropertyPrimitive* progress,
+ uirenderer::CanvasPropertyPrimitive* turbulencePhase,
const SkRuntimeShaderBuilder& effectBuilder) {
drawDrawable(mDisplayList->allocateDrawable<AnimatedRipple>(x, y, radius, paint, progress,
- effectBuilder));
+ turbulencePhase, effectBuilder));
}
void SkiaRecordingCanvas::enableZ(bool enableZ) {
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
index 06f2a27..4deb3b9 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
@@ -75,6 +75,7 @@
uirenderer::CanvasPropertyPrimitive* radius,
uirenderer::CanvasPropertyPaint* paint,
uirenderer::CanvasPropertyPrimitive* progress,
+ uirenderer::CanvasPropertyPrimitive* turbulencePhase,
const SkRuntimeShaderBuilder& effectBuilder) override;
virtual void drawVectorDrawable(VectorDrawableRoot* vectorDrawable) override;
diff --git a/libs/hwui/pipeline/skia/TransformCanvas.cpp b/libs/hwui/pipeline/skia/TransformCanvas.cpp
index 6bfbb0d..a6e4c4c 100644
--- a/libs/hwui/pipeline/skia/TransformCanvas.cpp
+++ b/libs/hwui/pipeline/skia/TransformCanvas.cpp
@@ -22,7 +22,7 @@
void TransformCanvas::onDrawAnnotation(const SkRect& rect, const char* key, SkData* value) {
if (HOLE_PUNCH_ANNOTATION == key) {
- auto* rectParams = static_cast<const float*>(value->data());
+ auto* rectParams = reinterpret_cast<const float*>(value->data());
float radiusX = rectParams[0];
float radiusY = rectParams[1];
SkRRect roundRect = SkRRect::MakeRectXY(rect, radiusX, radiusY);
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 2482188..bba2207 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -56,6 +56,22 @@
namespace uirenderer {
namespace renderthread {
+namespace {
+class ScopedActiveContext {
+public:
+ ScopedActiveContext(CanvasContext* context) { sActiveContext = context; }
+
+ ~ScopedActiveContext() { sActiveContext = nullptr; }
+
+ static CanvasContext* getActiveContext() { return sActiveContext; }
+
+private:
+ static CanvasContext* sActiveContext;
+};
+
+CanvasContext* ScopedActiveContext::sActiveContext = nullptr;
+} /* namespace */
+
CanvasContext* CanvasContext::create(RenderThread& thread, bool translucent,
RenderNode* rootRenderNode, IContextFactory* contextFactory) {
auto renderType = Properties::getRenderPipelineType();
@@ -473,6 +489,7 @@
return;
}
+ ScopedActiveContext activeContext(this);
mCurrentFrameInfo->set(FrameInfoIndex::FrameInterval) =
mRenderThread.timeLord().frameIntervalNanos();
@@ -880,6 +897,17 @@
return windowDirty;
}
+CanvasContext* CanvasContext::getActiveContext() {
+ return ScopedActiveContext::getActiveContext();
+}
+
+bool CanvasContext::mergeTransaction(ASurfaceTransaction* transaction, ASurfaceControl* control) {
+ if (!mASurfaceTransactionCallback) return false;
+ std::invoke(mASurfaceTransactionCallback, reinterpret_cast<int64_t>(transaction),
+ reinterpret_cast<int64_t>(control), getFrameNumber());
+ return true;
+}
+
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 74f426e..af1ebb2 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -109,6 +109,8 @@
*/
GrDirectContext* getGrContext() const { return mRenderThread.getGrContext(); }
+ ASurfaceControl* getSurfaceControl() const { return mSurfaceControl; }
+
// Won't take effect until next EGLSurface creation
void setSwapBehavior(SwapBehavior swapBehavior);
@@ -201,6 +203,15 @@
static void onSurfaceStatsAvailable(void* context, ASurfaceControl* control,
ASurfaceControlStats* stats);
+ void setASurfaceTransactionCallback(
+ const std::function<void(int64_t, int64_t, int64_t)>& callback) {
+ mASurfaceTransactionCallback = callback;
+ }
+
+ bool mergeTransaction(ASurfaceTransaction* transaction, ASurfaceControl* control);
+
+ static CanvasContext* getActiveContext();
+
private:
CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
IContextFactory* contextFactory, std::unique_ptr<IRenderPipeline> renderPipeline);
@@ -296,6 +307,8 @@
// If set to true, we expect that callbacks into onSurfaceStatsAvailable
bool mExpectSurfaceStats = false;
+
+ std::function<void(int64_t, int64_t, int64_t)> mASurfaceTransactionCallback;
};
} /* namespace renderthread */
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 9361abd..1b4b4b9 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -295,6 +295,12 @@
[this, cb = callback]() { mContext->setPictureCapturedCallback(cb); });
}
+void RenderProxy::setASurfaceTransactionCallback(
+ const std::function<void(int64_t, int64_t, int64_t)>& callback) {
+ mRenderThread.queue().post(
+ [this, cb = callback]() { mContext->setASurfaceTransactionCallback(cb); });
+}
+
void RenderProxy::setFrameCallback(std::function<void(int64_t)>&& callback) {
mDrawFrameTask.setFrameCallback(std::move(callback));
}
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 8d55d3c..288f555 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -120,6 +120,8 @@
void drawRenderNode(RenderNode* node);
void setContentDrawBounds(int left, int top, int right, int bottom);
void setPictureCapturedCallback(const std::function<void(sk_sp<SkPicture>&&)>& callback);
+ void setASurfaceTransactionCallback(
+ const std::function<void(int64_t, int64_t, int64_t)>& callback);
void setFrameCallback(std::function<void(int64_t)>&& callback);
void setFrameCompleteCallback(std::function<void(int64_t)>&& callback);
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 682baa6..04aa1cb 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -54,6 +54,10 @@
ASurfaceControlFunctions::ASurfaceControlFunctions() {
void* handle_ = dlopen("libandroid.so", RTLD_NOW | RTLD_NODELETE);
+ createFunc = (ASC_create)dlsym(handle_, "ASurfaceControl_create");
+ LOG_ALWAYS_FATAL_IF(createFunc == nullptr,
+ "Failed to find required symbol ASurfaceControl_create!");
+
acquireFunc = (ASC_acquire) dlsym(handle_, "ASurfaceControl_acquire");
LOG_ALWAYS_FATAL_IF(acquireFunc == nullptr,
"Failed to find required symbol ASurfaceControl_acquire!");
@@ -81,6 +85,23 @@
"ASurfaceControlStats_getFrameNumber");
LOG_ALWAYS_FATAL_IF(getFrameNumberFunc == nullptr,
"Failed to find required symbol ASurfaceControlStats_getFrameNumber!");
+
+ transactionCreateFunc = (AST_create)dlsym(handle_, "ASurfaceTransaction_create");
+ LOG_ALWAYS_FATAL_IF(transactionCreateFunc == nullptr,
+ "Failed to find required symbol ASurfaceTransaction_create!");
+
+ transactionDeleteFunc = (AST_delete)dlsym(handle_, "ASurfaceTransaction_delete");
+ LOG_ALWAYS_FATAL_IF(transactionDeleteFunc == nullptr,
+ "Failed to find required symbol ASurfaceTransaction_delete!");
+
+ transactionApplyFunc = (AST_apply)dlsym(handle_, "ASurfaceTransaction_apply");
+ LOG_ALWAYS_FATAL_IF(transactionApplyFunc == nullptr,
+ "Failed to find required symbol ASurfaceTransaction_apply!");
+
+ transactionSetVisibilityFunc =
+ (AST_setVisibility)dlsym(handle_, "ASurfaceTransaction_setVisibility");
+ LOG_ALWAYS_FATAL_IF(transactionSetVisibilityFunc == nullptr,
+ "Failed to find required symbol ASurfaceTransaction_setVisibility!");
}
void RenderThread::frameCallback(int64_t frameTimeNanos, void* data) {
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 9e5bce7..cd9b923 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -79,25 +79,39 @@
virtual ~VsyncSource() {}
};
+typedef ASurfaceControl* (*ASC_create)(ASurfaceControl* parent, const char* debug_name);
typedef void (*ASC_acquire)(ASurfaceControl* control);
typedef void (*ASC_release)(ASurfaceControl* control);
typedef void (*ASC_registerSurfaceStatsListener)(ASurfaceControl* control, void* context,
ASurfaceControl_SurfaceStatsListener func);
typedef void (*ASC_unregisterSurfaceStatsListener)(void* context,
- ASurfaceControl_SurfaceStatsListener func);
+ ASurfaceControl_SurfaceStatsListener func);
typedef int64_t (*ASCStats_getAcquireTime)(ASurfaceControlStats* stats);
typedef uint64_t (*ASCStats_getFrameNumber)(ASurfaceControlStats* stats);
+typedef ASurfaceTransaction* (*AST_create)();
+typedef void (*AST_delete)(ASurfaceTransaction* transaction);
+typedef void (*AST_apply)(ASurfaceTransaction* transaction);
+typedef void (*AST_setVisibility)(ASurfaceTransaction* transaction,
+ ASurfaceControl* surface_control, int8_t visibility);
+
struct ASurfaceControlFunctions {
ASurfaceControlFunctions();
+
+ ASC_create createFunc;
ASC_acquire acquireFunc;
ASC_release releaseFunc;
ASC_registerSurfaceStatsListener registerListenerFunc;
ASC_unregisterSurfaceStatsListener unregisterListenerFunc;
ASCStats_getAcquireTime getAcquireTimeFunc;
ASCStats_getFrameNumber getFrameNumberFunc;
+
+ AST_create transactionCreateFunc;
+ AST_delete transactionDeleteFunc;
+ AST_apply transactionApplyFunc;
+ AST_setVisibility transactionSetVisibilityFunc;
};
class ChoreographerSource;
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index 24f553f..3a86786 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -273,8 +273,8 @@
/** Audio data format: compressed audio wrapped in PCM for HDMI
* or S/PDIF passthrough.
- * IEC61937 uses a stereo stream of 16-bit samples as the wrapper.
- * So the channel mask for the track must be {@link #CHANNEL_OUT_STEREO}.
+ * For devices whose SDK version is less than {@link android.os.Build.VERSION_CODES#S}, the
+ * channel mask of IEC61937 track must be {@link #CHANNEL_OUT_STEREO}.
* Data should be written to the stream in a short[] array.
* If the data is written in a byte[] array then there may be endian problems
* on some platforms when converting to short internally.
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 7a2b022..2ea0984 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -1676,13 +1676,11 @@
}
mSampleRate = sampleRateInHz;
- // IEC61937 is based on stereo. We could coerce it to stereo.
- // But the application needs to know the stream is stereo so that
- // it is encoded and played correctly. So better to just reject it.
if (audioFormat == AudioFormat.ENCODING_IEC61937
- && channelConfig != AudioFormat.CHANNEL_OUT_STEREO) {
- throw new IllegalArgumentException(
- "ENCODING_IEC61937 must be configured as CHANNEL_OUT_STEREO");
+ && channelConfig != AudioFormat.CHANNEL_OUT_STEREO
+ && AudioFormat.channelCountFromOutChannelMask(channelConfig) != 8) {
+ Log.w(TAG, "ENCODING_IEC61937 is configured with channel mask as " + channelConfig
+ + ", which is not 2 or 8 channels");
}
//--------------
diff --git a/media/jni/tuner/FilterClient.cpp b/media/jni/tuner/FilterClient.cpp
index 2995572..c080701 100644
--- a/media/jni/tuner/FilterClient.cpp
+++ b/media/jni/tuner/FilterClient.cpp
@@ -921,7 +921,7 @@
Status s = mTunerFilter->getQueueDesc(&aidlMqDesc);
res = ClientHelper::getServiceSpecificErrorCode(s);
if (res == Result::SUCCESS) {
- mFilterMQ = new (nothrow) AidlMQ(aidlMqDesc);
+ mFilterMQ = new (nothrow) AidlMQ(aidlMqDesc, false/*resetPointer*/);
EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterMQEventFlag);
}
return res;
@@ -938,7 +938,7 @@
AidlMQDesc aidlMQDesc;
unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, SynchronizedReadWrite>(
filterMQDesc, &aidlMQDesc);
- mFilterMQ = new (nothrow) AidlMessageQueue(aidlMQDesc);
+ mFilterMQ = new (nothrow) AidlMessageQueue(aidlMQDesc, false/*resetPointer*/);
EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterMQEventFlag);
}
}
diff --git a/native/android/system_fonts.cpp b/native/android/system_fonts.cpp
index 48d7380..60b0f1e 100644
--- a/native/android/system_fonts.cpp
+++ b/native/android/system_fonts.cpp
@@ -54,21 +54,51 @@
XmlCharUniquePtr mLocale;
};
-struct ASystemFontIterator {
- XmlDocUniquePtr mXmlDoc;
- ParserState state;
-
- // The OEM customization XML.
- XmlDocUniquePtr mCustomizationXmlDoc;
-};
-
struct AFont {
std::string mFilePath;
- std::unique_ptr<std::string> mLocale;
+ std::optional<std::string> mLocale;
uint16_t mWeight;
bool mItalic;
uint32_t mCollectionIndex;
std::vector<std::pair<uint32_t, float>> mAxes;
+
+ bool operator==(const AFont& o) const {
+ return mFilePath == o.mFilePath && mLocale == o.mLocale && mWeight == o.mWeight &&
+ mItalic == o.mItalic && mCollectionIndex == o.mCollectionIndex && mAxes == o.mAxes;
+ }
+
+ AFont() = default;
+ AFont(const AFont&) = default;
+};
+
+struct FontHasher {
+ std::size_t operator()(const AFont& font) const {
+ std::size_t r = std::hash<std::string>{}(font.mFilePath);
+ if (font.mLocale) {
+ r = combine(r, std::hash<std::string>{}(*font.mLocale));
+ }
+ r = combine(r, std::hash<uint16_t>{}(font.mWeight));
+ r = combine(r, std::hash<uint32_t>{}(font.mCollectionIndex));
+ for (const auto& [tag, value] : font.mAxes) {
+ r = combine(r, std::hash<uint32_t>{}(tag));
+ r = combine(r, std::hash<float>{}(value));
+ }
+ return r;
+ }
+
+ std::size_t combine(std::size_t l, std::size_t r) const { return l ^ (r << 1); }
+};
+
+struct ASystemFontIterator {
+ std::vector<AFont> fonts;
+ uint32_t index;
+
+ XmlDocUniquePtr mXmlDoc;
+
+ ParserState state;
+
+ // The OEM customization XML.
+ XmlDocUniquePtr mCustomizationXmlDoc;
};
struct AFontMatcher {
@@ -147,10 +177,9 @@
out->mCollectionIndex = indexStr ?
strtol(reinterpret_cast<const char*>(indexStr.get()), nullptr, 10) : 0;
- out->mLocale.reset(
- state.mLocale ?
- new std::string(reinterpret_cast<const char*>(state.mLocale.get()))
- : nullptr);
+ if (state.mLocale) {
+ out->mLocale.emplace(reinterpret_cast<const char*>(state.mLocale.get()));
+ }
const xmlChar* TAG_ATTR_NAME = BAD_CAST("tag");
const xmlChar* STYLEVALUE_ATTR_NAME = BAD_CAST("stylevalue");
@@ -214,8 +243,44 @@
ASystemFontIterator* ASystemFontIterator_open() {
std::unique_ptr<ASystemFontIterator> ite(new ASystemFontIterator());
- ite->mXmlDoc.reset(xmlReadFile("/system/etc/fonts.xml", nullptr, 0));
- ite->mCustomizationXmlDoc.reset(xmlReadFile("/product/etc/fonts_customization.xml", nullptr, 0));
+
+ std::unordered_set<AFont, FontHasher> fonts;
+ minikin::SystemFonts::getFontMap(
+ [&fonts](const std::vector<std::shared_ptr<minikin::FontCollection>>& collections) {
+ for (const auto& fc : collections) {
+ for (const auto& family : fc->getFamilies()) {
+ for (uint32_t i = 0; i < family->getNumFonts(); ++i) {
+ const minikin::Font* font = family->getFont(i);
+
+ std::optional<std::string> locale;
+ uint32_t localeId = font->getLocaleListId();
+ if (localeId != minikin::kEmptyLocaleListId) {
+ locale.emplace(minikin::getLocaleString(localeId));
+ }
+ std::vector<std::pair<uint32_t, float>> axes;
+ for (const auto& [tag, value] : font->typeface()->GetAxes()) {
+ axes.push_back(std::make_pair(tag, value));
+ }
+
+ fonts.insert(
+ {font->typeface()->GetFontPath(), std::move(locale),
+ font->style().weight(),
+ font->style().slant() == minikin::FontStyle::Slant::ITALIC,
+ static_cast<uint32_t>(font->typeface()->GetFontIndex()),
+ axes});
+ }
+ }
+ }
+ });
+
+ if (fonts.empty()) {
+ ite->mXmlDoc.reset(xmlReadFile("/system/etc/fonts.xml", nullptr, 0));
+ ite->mCustomizationXmlDoc.reset(
+ xmlReadFile("/product/etc/fonts_customization.xml", nullptr, 0));
+ } else {
+ ite->index = 0;
+ ite->fonts.assign(fonts.begin(), fonts.end());
+ }
return ite.release();
}
@@ -308,6 +373,13 @@
AFont* ASystemFontIterator_next(ASystemFontIterator* ite) {
LOG_ALWAYS_FATAL_IF(ite == nullptr, "nullptr has passed as iterator argument");
+ if (!ite->fonts.empty()) {
+ if (ite->index >= ite->fonts.size()) {
+ return nullptr;
+ }
+ return new AFont(ite->fonts[ite->index++]);
+ }
+
if (ite->mXmlDoc) {
if (!findNextFontNode(ite->mXmlDoc, &ite->state)) {
// Reached end of the XML file. Continue OEM customization.
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index 83cc263..07d04aa 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -22,6 +22,6 @@
<string name="profile_name_watch" msgid="576290739483672360">"ساعت"</string>
<string name="confirmation_title" msgid="8455544820286920304">"مجاز کردن <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> برای مدیریت کردن <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_summary" msgid="2059360676631420073">"این برنامه برای مدیریت <xliff:g id="PROFILE_NAME">%1$s</xliff:g> شما لازم است. <xliff:g id="PRIVILEGES_DISCPLAIMER">%2$s</xliff:g>"</string>
- <string name="consent_yes" msgid="8344487259618762872">"مجاز"</string>
- <string name="consent_no" msgid="2640796915611404382">"مجاز نیست"</string>
+ <string name="consent_yes" msgid="8344487259618762872">"مجاز بودن"</string>
+ <string name="consent_no" msgid="2640796915611404382">"مجاز نبودن"</string>
</resources>
diff --git a/packages/Connectivity/framework/Android.bp b/packages/Connectivity/framework/Android.bp
index c62402d..bb93af9 100644
--- a/packages/Connectivity/framework/Android.bp
+++ b/packages/Connectivity/framework/Android.bp
@@ -100,6 +100,7 @@
"//frameworks/base",
// Tests using hidden APIs
+ "//cts/tests/netlegacy22.api",
"//external/sl4a:__subpackages__",
"//frameworks/base/tests/net:__subpackages__",
"//frameworks/libs/net/common/testutils",
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt
index 9e2cd3e..c8b04a3 100644
--- a/packages/Connectivity/framework/api/module-lib-current.txt
+++ b/packages/Connectivity/framework/api/module-lib-current.txt
@@ -7,7 +7,7 @@
public class ConnectivityManager {
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void factoryReset();
- method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public java.util.List<android.net.NetworkStateSnapshot> getAllNetworkStateSnapshot();
+ method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public java.util.List<android.net.NetworkStateSnapshot> getAllNetworkStateSnapshots();
method @Nullable public android.net.ProxyInfo getGlobalProxy();
method @NonNull public static android.util.Range<java.lang.Integer> getIpSecNetIdRange();
method @NonNull public static String getPrivateDnsMode(@NonNull android.content.Context);
diff --git a/packages/Connectivity/framework/api/system-current.txt b/packages/Connectivity/framework/api/system-current.txt
index 2194575..3ca7475 100644
--- a/packages/Connectivity/framework/api/system-current.txt
+++ b/packages/Connectivity/framework/api/system-current.txt
@@ -277,7 +277,7 @@
method @NonNull public int[] getAdministratorUids();
method @Nullable public static String getCapabilityCarrierName(int);
method @Nullable public String getSsid();
- method @NonNull public java.util.Set<java.lang.Integer> getSubIds();
+ method @NonNull public java.util.Set<java.lang.Integer> getSubscriptionIds();
method @NonNull public int[] getTransportTypes();
method public boolean isPrivateDnsBroken();
method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
@@ -308,7 +308,7 @@
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorUid(int);
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkCapabilities.Builder setSignalStrength(int);
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setSsid(@Nullable String);
- method @NonNull public android.net.NetworkCapabilities.Builder setSubIds(@NonNull java.util.Set<java.lang.Integer>);
+ method @NonNull public android.net.NetworkCapabilities.Builder setSubscriptionIds(@NonNull java.util.Set<java.lang.Integer>);
method @NonNull public android.net.NetworkCapabilities.Builder setTransportInfo(@Nullable android.net.TransportInfo);
}
@@ -338,7 +338,7 @@
public static class NetworkRequest.Builder {
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkRequest.Builder setSignalStrength(int);
- method @NonNull public android.net.NetworkRequest.Builder setSubIds(@NonNull java.util.Set<java.lang.Integer>);
+ method @NonNull public android.net.NetworkRequest.Builder setSubscriptionIds(@NonNull java.util.Set<java.lang.Integer>);
}
public final class NetworkScore implements android.os.Parcelable {
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java b/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java
index 92a792b..a2e218d 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java
@@ -68,5 +68,11 @@
return cm.startOrGetTestNetworkManager();
}
);
+
+ SystemServiceRegistry.registerContextAwareService(
+ DnsResolverServiceManager.DNS_RESOLVER_SERVICE,
+ DnsResolverServiceManager.class,
+ (context, serviceBinder) -> new DnsResolverServiceManager(serviceBinder)
+ );
}
}
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index 96f2de6..b3c1997 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -1425,9 +1425,9 @@
android.Manifest.permission.NETWORK_STACK,
android.Manifest.permission.NETWORK_SETTINGS})
@NonNull
- public List<NetworkStateSnapshot> getAllNetworkStateSnapshot() {
+ public List<NetworkStateSnapshot> getAllNetworkStateSnapshots() {
try {
- return mService.getAllNetworkStateSnapshot();
+ return mService.getAllNetworkStateSnapshots();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/packages/Connectivity/framework/src/android/net/DnsResolverServiceManager.java b/packages/Connectivity/framework/src/android/net/DnsResolverServiceManager.java
new file mode 100644
index 0000000..79009e8
--- /dev/null
+++ b/packages/Connectivity/framework/src/android/net/DnsResolverServiceManager.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.net;
+
+import android.annotation.NonNull;
+import android.os.IBinder;
+
+/**
+ * Provides a way to obtain the DnsResolver binder objects.
+ *
+ * @hide
+ */
+public class DnsResolverServiceManager {
+ /** Service name for the DNS resolver. Keep in sync with DnsResolverService.h */
+ public static final String DNS_RESOLVER_SERVICE = "dnsresolver";
+
+ private final IBinder mResolver;
+
+ DnsResolverServiceManager(IBinder resolver) {
+ mResolver = resolver;
+ }
+
+ /**
+ * Get an {@link IBinder} representing the DnsResolver stable AIDL interface
+ *
+ * @return {@link android.net.IDnsResolver} IBinder.
+ */
+ @NonNull
+ public IBinder getService() {
+ return mResolver;
+ }
+}
diff --git a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
index 728f375..c434bbc 100644
--- a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
+++ b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
@@ -82,7 +82,7 @@
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
NetworkState[] getAllNetworkState();
- List<NetworkStateSnapshot> getAllNetworkStateSnapshot();
+ List<NetworkStateSnapshot> getAllNetworkStateSnapshots();
boolean isActiveNetworkMetered();
diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
index c4277c3..775c88f 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
@@ -1749,7 +1749,7 @@
combineSSIDs(nc);
combineRequestor(nc);
combineAdministratorUids(nc);
- combineSubIds(nc);
+ combineSubscriptionIds(nc);
}
/**
@@ -1771,7 +1771,7 @@
&& (onlyImmutable || satisfiedByUids(nc))
&& (onlyImmutable || satisfiedBySSID(nc))
&& (onlyImmutable || satisfiedByRequestor(nc))
- && (onlyImmutable || satisfiedBySubIds(nc)));
+ && (onlyImmutable || satisfiedBySubscriptionIds(nc)));
}
/**
@@ -1868,7 +1868,7 @@
&& equalsPrivateDnsBroken(that)
&& equalsRequestor(that)
&& equalsAdministratorUids(that)
- && equalsSubIds(that);
+ && equalsSubscriptionIds(that);
}
@Override
@@ -2346,7 +2346,7 @@
* @hide
*/
@NonNull
- public NetworkCapabilities setSubIds(@NonNull Set<Integer> subIds) {
+ public NetworkCapabilities setSubscriptionIds(@NonNull Set<Integer> subIds) {
mSubIds = new ArraySet(Objects.requireNonNull(subIds));
return this;
}
@@ -2362,14 +2362,14 @@
*/
@NonNull
@SystemApi
- public Set<Integer> getSubIds() {
+ public Set<Integer> getSubscriptionIds() {
return new ArraySet<>(mSubIds);
}
/**
* Tests if the subscription ID set of this network is the same as that of the passed one.
*/
- private boolean equalsSubIds(@NonNull NetworkCapabilities nc) {
+ private boolean equalsSubscriptionIds(@NonNull NetworkCapabilities nc) {
return Objects.equals(mSubIds, nc.mSubIds);
}
@@ -2378,7 +2378,7 @@
* If specified in the request, the passed one need to have at least one subId and at least
* one of them needs to be in the request set.
*/
- private boolean satisfiedBySubIds(@NonNull NetworkCapabilities nc) {
+ private boolean satisfiedBySubscriptionIds(@NonNull NetworkCapabilities nc) {
if (mSubIds.isEmpty()) return true;
if (nc.mSubIds.isEmpty()) return false;
for (final Integer subId : nc.mSubIds) {
@@ -2395,7 +2395,7 @@
* <p>If both subscription IDs are not equal, they belong to different subscription
* (or no subscription). In this case, it would not make sense to add them together.
*/
- private void combineSubIds(@NonNull NetworkCapabilities nc) {
+ private void combineSubscriptionIds(@NonNull NetworkCapabilities nc) {
if (!Objects.equals(mSubIds, nc.mSubIds)) {
throw new IllegalStateException("Can't combine two subscription ID sets");
}
@@ -2737,8 +2737,8 @@
*/
@NonNull
@SystemApi
- public Builder setSubIds(@NonNull final Set<Integer> subIds) {
- mCaps.setSubIds(subIds);
+ public Builder setSubscriptionIds(@NonNull final Set<Integer> subIds) {
+ mCaps.setSubscriptionIds(subIds);
return this;
}
diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
index 78e1011..90aac0e 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
@@ -508,8 +508,8 @@
*/
@NonNull
@SystemApi
- public Builder setSubIds(@NonNull Set<Integer> subIds) {
- mNetworkCapabilities.setSubIds(subIds);
+ public Builder setSubscriptionIds(@NonNull Set<Integer> subIds) {
+ mNetworkCapabilities.setSubscriptionIds(subIds);
return this;
}
}
diff --git a/packages/DynamicSystemInstallationService/res/values-fi/strings.xml b/packages/DynamicSystemInstallationService/res/values-fi/strings.xml
index f32fc37..3e474d8 100644
--- a/packages/DynamicSystemInstallationService/res/values-fi/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-fi/strings.xml
@@ -7,7 +7,7 @@
<string name="notification_install_failed" msgid="4066039210317521404">"Asennus epäonnistui"</string>
<string name="notification_image_validation_failed" msgid="2720357826403917016">"Levykuvan vahvistus epäonnistui. Keskeytä asennus."</string>
<string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Käyttää tällä hetkellä dynaamista järjestelmää. Käynnistä uudelleen käyttääksesi alkuperäistä Android-versiota."</string>
- <string name="notification_action_cancel" msgid="5929299408545961077">"Peruuta"</string>
+ <string name="notification_action_cancel" msgid="5929299408545961077">"Peru"</string>
<string name="notification_action_discard" msgid="1817481003134947493">"Hylkää"</string>
<string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Käynn. uudelleen"</string>
<string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"Käynn. uudelleen"</string>
diff --git a/packages/DynamicSystemInstallationService/res/values-ky/strings.xml b/packages/DynamicSystemInstallationService/res/values-ky/strings.xml
index 320faff..4e1ba66 100644
--- a/packages/DynamicSystemInstallationService/res/values-ky/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ky/strings.xml
@@ -2,11 +2,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="keyguard_description" msgid="8582605799129954556">"Сырсөзүңүздү киргизип, системаны динамикалык жаңыртууга өтүңүз"</string>
- <string name="notification_install_completed" msgid="6252047868415172643">"Динамикалык система даяр. Аны колдонуу үчүн, түзмөктү өчүрүп күйгүзүңүз."</string>
+ <string name="notification_install_completed" msgid="6252047868415172643">"Динамикалык система даяр. Аны колдонуу үчүн түзмөктү өчүрүп күйгүзүңүз."</string>
<string name="notification_install_inprogress" msgid="7383334330065065017">"Орнотулууда"</string>
<string name="notification_install_failed" msgid="4066039210317521404">"Орнотулбай койду"</string>
<string name="notification_image_validation_failed" msgid="2720357826403917016">"Дисктин сүрөтү текшерилбей калды. Орнотууну токтотуңуз."</string>
- <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Учурда динамикалык система колдонулууда. Android\'дин түпнуска версиясын колдонуу үчүн, өчүрүп күйгүзүңүз."</string>
+ <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"Учурда динамикалык система колдонулууда. Android\'дин түпнуска версиясын колдонуу үчүн өчүрүп күйгүзүңүз."</string>
<string name="notification_action_cancel" msgid="5929299408545961077">"Жок"</string>
<string name="notification_action_discard" msgid="1817481003134947493">"Жоюу"</string>
<string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"Өчүрүп күйгүзүү"</string>
diff --git a/packages/DynamicSystemInstallationService/res/values-ne/strings.xml b/packages/DynamicSystemInstallationService/res/values-ne/strings.xml
index 7afbfd9..de92306 100644
--- a/packages/DynamicSystemInstallationService/res/values-ne/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ne/strings.xml
@@ -2,11 +2,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="keyguard_description" msgid="8582605799129954556">"कृपया आफ्नो पासवर्ड प्रविष्टि गर्नुहोस् र Dynamic System Updates को प्रक्रियालाई निरन्तरता दिनुहोस्"</string>
- <string name="notification_install_completed" msgid="6252047868415172643">"Dynamic System तयार छ। यसको प्रयोग सुरु गर्न आफ्नो यन्त्र रिस्टार्ट गर्नुहोस्।"</string>
+ <string name="notification_install_completed" msgid="6252047868415172643">"Dynamic System तयार छ। यसको प्रयोग सुरु गर्न आफ्नो डिभाइस रिस्टार्ट गर्नुहोस्।"</string>
<string name="notification_install_inprogress" msgid="7383334330065065017">"इन्स्टल हुँदै छ"</string>
<string name="notification_install_failed" msgid="4066039210317521404">"स्थापना गर्न सकिएन"</string>
<string name="notification_image_validation_failed" msgid="2720357826403917016">"डिस्कको इमेज पुष्टि गर्न सकिएन। स्थापना गर्ने प्रक्रिया रद्द गर्नुहोस्।"</string>
- <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"हाल Dynamic System चलिरहेको छ। Android को मूल संस्करण प्रयोग गर्न यन्त्र रिस्टार्ट गर्नुहोस्।"</string>
+ <string name="notification_dynsystem_in_use" msgid="1053194595682188396">"हाल Dynamic System चलिरहेको छ। Android को मूल संस्करण प्रयोग गर्न डिभाइस रिस्टार्ट गर्नुहोस्।"</string>
<string name="notification_action_cancel" msgid="5929299408545961077">"रद्द गर्नुहोस्"</string>
<string name="notification_action_discard" msgid="1817481003134947493">"खारेज गर्नुहोस्"</string>
<string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"रिस्टार्ट गर्नु…"</string>
diff --git a/packages/DynamicSystemInstallationService/res/values-pa/strings.xml b/packages/DynamicSystemInstallationService/res/values-pa/strings.xml
index 8f2fd18..ac12bb7 100644
--- a/packages/DynamicSystemInstallationService/res/values-pa/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-pa/strings.xml
@@ -8,7 +8,7 @@
<string name="notification_image_validation_failed" msgid="2720357826403917016">"ਇਮੇਜ ਪ੍ਰਮਾਣਿਕਤਾ ਅਸਫਲ ਰਹੀ। ਸਥਾਪਨਾ ਨੂੰ ਰੱਦ ਕਰੋ।"</string>
<string name="notification_dynsystem_in_use" msgid="1053194595682188396">"ਫ਼ਿਲਹਾਲ ਪਰਿਵਰਤਨਸ਼ੀਲ ਸਿਸਟਮ ਚੱਲ ਰਿਹਾ ਹੈ। ਮੂਲ Android ਵਰਜਨ ਵਰਤਣ ਲਈ ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ।"</string>
<string name="notification_action_cancel" msgid="5929299408545961077">"ਰੱਦ ਕਰੋ"</string>
- <string name="notification_action_discard" msgid="1817481003134947493">"ਖਾਰਜ ਕਰੋ"</string>
+ <string name="notification_action_discard" msgid="1817481003134947493">"ਬਰਖਾਸਤ ਕਰੋ"</string>
<string name="notification_action_reboot_to_dynsystem" msgid="4015817159115912479">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string>
<string name="notification_action_reboot_to_origin" msgid="4013901243271889897">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string>
<string name="toast_dynsystem_discarded" msgid="1733249860276017050">"ਪਰਿਵਰਤਨਸ਼ੀਲ ਸਿਸਟਮ ਰੱਦ ਕੀਤਾ ਗਿਆ"</string>
diff --git a/packages/PackageInstaller/res/values-es/strings.xml b/packages/PackageInstaller/res/values-es/strings.xml
index 3a0757b..7431241 100644
--- a/packages/PackageInstaller/res/values-es/strings.xml
+++ b/packages/PackageInstaller/res/values-es/strings.xml
@@ -19,7 +19,7 @@
<string name="app_name" msgid="7488448184431507488">"Instalador de paquetes"</string>
<string name="install" msgid="711829760615509273">"Instalar"</string>
<string name="update" msgid="3932142540719227615">"Actualizar"</string>
- <string name="done" msgid="6632441120016885253">"Listo"</string>
+ <string name="done" msgid="6632441120016885253">"Hecho"</string>
<string name="cancel" msgid="1018267193425558088">"Cancelar"</string>
<string name="installing" msgid="4921993079741206516">"Instalando…"</string>
<string name="installing_app" msgid="1165095864863849422">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-gl/strings.xml b/packages/PackageInstaller/res/values-gl/strings.xml
index 9d3b775..637e15a 100644
--- a/packages/PackageInstaller/res/values-gl/strings.xml
+++ b/packages/PackageInstaller/res/values-gl/strings.xml
@@ -46,7 +46,7 @@
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Non se puido instalar a aplicación <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera espazo e téntao de novo."</string>
<string name="app_not_found_dlg_title" msgid="5107924008597470285">"Non se atopou a aplicación"</string>
<string name="app_not_found_dlg_text" msgid="5219983779377811611">"Non se atopou a aplicación na lista de aplicacións instaladas."</string>
- <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Acción non-permitida"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Sen permiso"</string>
<string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"O usuario actual non pode realizar esta desinstalación."</string>
<string name="generic_error_dlg_title" msgid="5863195085927067752">"Erro"</string>
<string name="generic_error_dlg_text" msgid="5287861443265795232">"Non se puido desinstalar a aplicación."</string>
@@ -54,10 +54,10 @@
<string name="uninstall_update_title" msgid="824411791011583031">"Desinstalar actualización"</string>
<string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> forma parte da seguinte aplicación:"</string>
<string name="uninstall_application_text" msgid="3816830743706143980">"Queres desinstalar esta aplicación?"</string>
- <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Queres desinstalar esta aplicación para "<b>"todos"</b>" os usuarios? A aplicación e os seus datos eliminaranse de "<b>"todos"</b>" os usuarios do dispositivo."</string>
+ <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Queres desinstalar esta aplicación para "<b>"todos"</b>" os usuarios? A aplicación e os seus datos quitaranse de "<b>"todos"</b>" os usuarios do dispositivo."</string>
<string name="uninstall_application_text_user" msgid="498072714173920526">"Queres desinstalar esta aplicación para o usuario que se chama <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
- <string name="uninstall_update_text" msgid="863648314632448705">"Queres substituír esta aplicación pola versión que viña de fábrica? Eliminaranse todos os datos."</string>
- <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Queres substituír esta aplicación pola versión que viña de fábrica? Eliminaranse todos os datos. Isto afectará a todos os usuarios do dispositivo, incluídos os que teñan perfís de traballo."</string>
+ <string name="uninstall_update_text" msgid="863648314632448705">"Queres substituír esta aplicación pola versión que viña de fábrica? Quitaranse todos os datos."</string>
+ <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Queres substituír esta aplicación pola versión que viña de fábrica? Quitaranse todos os datos. Isto afectará a todos os usuarios do dispositivo, incluídos os que teñan perfís de traballo."</string>
<string name="uninstall_keep_data" msgid="7002379587465487550">"Conservar os datos da aplicación, que ocupan <xliff:g id="SIZE">%1$s</xliff:g>."</string>
<string name="uninstalling_notification_channel" msgid="840153394325714653">"Desinstalacións en curso"</string>
<string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Erros nas desinstalacións"</string>
diff --git a/packages/PackageInstaller/res/values-it/strings.xml b/packages/PackageInstaller/res/values-it/strings.xml
index 42c3cfe..c554aab 100644
--- a/packages/PackageInstaller/res/values-it/strings.xml
+++ b/packages/PackageInstaller/res/values-it/strings.xml
@@ -46,7 +46,7 @@
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Impossibile installare <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera dello spazio e riprova."</string>
<string name="app_not_found_dlg_title" msgid="5107924008597470285">"App non trovata"</string>
<string name="app_not_found_dlg_text" msgid="5219983779377811611">"Impossibile trovare l\'applicazione nell\'elenco di applicazioni installate."</string>
- <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Non consentita"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Autorizzazione non concessa"</string>
<string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"L\'utente corrente non è autorizzato a eseguire questa disinstallazione."</string>
<string name="generic_error_dlg_title" msgid="5863195085927067752">"Errore"</string>
<string name="generic_error_dlg_text" msgid="5287861443265795232">"Impossibile disinstallare l\'app."</string>
diff --git a/packages/PrintSpooler/res/values-az/strings.xml b/packages/PrintSpooler/res/values-az/strings.xml
index 4193afc..887434b 100644
--- a/packages/PrintSpooler/res/values-az/strings.xml
+++ b/packages/PrintSpooler/res/values-az/strings.xml
@@ -83,7 +83,7 @@
<string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ləğv edilir"</string>
<string name="failed_notification_title_template" msgid="2256217208186530973">"Printer xətası <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
<string name="blocked_notification_title_template" msgid="1175435827331588646">"Printer <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> işini blokladı"</string>
- <string name="cancel" msgid="4373674107267141885">"Ləğv et"</string>
+ <string name="cancel" msgid="4373674107267141885">"Ləğv edin"</string>
<string name="restart" msgid="2472034227037808749">"Yenidən başlat"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Printerə heç bir bağlantı yoxdur"</string>
<string name="reason_unknown" msgid="5507940196503246139">"naməlum"</string>
diff --git a/packages/PrintSpooler/res/values-eu/strings.xml b/packages/PrintSpooler/res/values-eu/strings.xml
index 7ccccc9f..49ca881 100644
--- a/packages/PrintSpooler/res/values-eu/strings.xml
+++ b/packages/PrintSpooler/res/values-eu/strings.xml
@@ -49,10 +49,10 @@
<string name="print_options_collapsed" msgid="7455930445670414332">"Inprimatzeko aukerak tolestuta daude"</string>
<string name="search" msgid="5421724265322228497">"Bilatu"</string>
<string name="all_printers_label" msgid="3178848870161526399">"Inprimagailu guztiak"</string>
- <string name="add_print_service_label" msgid="5356702546188981940">"Gehitu zerbitzua"</string>
+ <string name="add_print_service_label" msgid="5356702546188981940">"Gehitu zerbitzu bat"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Bilaketa-koadroa erakutsi da"</string>
<string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Bilaketa-koadroa ezkutatu da"</string>
- <string name="print_add_printer" msgid="1088656468360653455">"Gehitu inprimagailua"</string>
+ <string name="print_add_printer" msgid="1088656468360653455">"Gehitu inprimagailu bat"</string>
<string name="print_select_printer" msgid="7388760939873368698">"Hautatu inprimagailua"</string>
<string name="print_forget_printer" msgid="5035287497291910766">"Ahaztu inprimagailua"</string>
<plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
diff --git a/packages/PrintSpooler/res/values-fi/strings.xml b/packages/PrintSpooler/res/values-fi/strings.xml
index 724d1d7..4289399 100644
--- a/packages/PrintSpooler/res/values-fi/strings.xml
+++ b/packages/PrintSpooler/res/values-fi/strings.xml
@@ -83,7 +83,7 @@
<string name="cancelling_notification_title_template" msgid="1821759594704703197">"Peruutetaan työ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
<string name="failed_notification_title_template" msgid="2256217208186530973">"Tulostinvirhe työlle <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
<string name="blocked_notification_title_template" msgid="1175435827331588646">"Tulostin esti työn <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
- <string name="cancel" msgid="4373674107267141885">"Peruuta"</string>
+ <string name="cancel" msgid="4373674107267141885">"Peru"</string>
<string name="restart" msgid="2472034227037808749">"Käynnistä uudelleen"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Ei yhteyttä tulostimeen"</string>
<string name="reason_unknown" msgid="5507940196503246139">"tuntematon"</string>
diff --git a/packages/PrintSpooler/res/values-gu/strings.xml b/packages/PrintSpooler/res/values-gu/strings.xml
index 4149a86..7419c2a 100644
--- a/packages/PrintSpooler/res/values-gu/strings.xml
+++ b/packages/PrintSpooler/res/values-gu/strings.xml
@@ -65,7 +65,7 @@
<string name="notification_channel_failure" msgid="9042250774797916414">"નિષ્ફળ થયેલ છાપવાના Tasks"</string>
<string name="could_not_create_file" msgid="3425025039427448443">"ફાઇલ બનાવી શક્યાં નથી"</string>
<string name="print_services_disabled_toast" msgid="9089060734685174685">"કેટલીક છાપવાની સેવાઓ અક્ષમ કરેલ છે"</string>
- <string name="print_searching_for_printers" msgid="6550424555079932867">"પ્રિન્ટર્સ માટે શોધી રહ્યું છે"</string>
+ <string name="print_searching_for_printers" msgid="6550424555079932867">"પ્રિન્ટર માટે શોધી રહ્યું છે"</string>
<string name="print_no_print_services" msgid="8561247706423327966">"કોઈ છાપ સેવાઓ સક્ષમ કરેલ નથી"</string>
<string name="print_no_printers" msgid="4869403323900054866">"કોઈ પ્રિન્ટર મળ્યા નથી"</string>
<string name="cannot_add_printer" msgid="7840348733668023106">"પ્રિન્ટર્સ ઉમેરી શકતાં નથી"</string>
diff --git a/packages/PrintSpooler/res/values-kk/strings.xml b/packages/PrintSpooler/res/values-kk/strings.xml
index a822d1c..29126bc 100644
--- a/packages/PrintSpooler/res/values-kk/strings.xml
+++ b/packages/PrintSpooler/res/values-kk/strings.xml
@@ -94,7 +94,7 @@
<item msgid="2762241247228983754">"Түс"</item>
</string-array>
<string-array name="duplex_mode_labels">
- <item msgid="3882302912790928315">"Ешқандай"</item>
+ <item msgid="3882302912790928315">"Жоқ"</item>
<item msgid="7296563835355641719">"Ұзын жиек"</item>
<item msgid="79513688117503758">"Қысқа жиек"</item>
</string-array>
diff --git a/packages/PrintSpooler/res/values-mk/strings.xml b/packages/PrintSpooler/res/values-mk/strings.xml
index 504c956..3fd32b1 100644
--- a/packages/PrintSpooler/res/values-mk/strings.xml
+++ b/packages/PrintSpooler/res/values-mk/strings.xml
@@ -49,7 +49,7 @@
<string name="print_options_collapsed" msgid="7455930445670414332">"Опциите на печатачот се сокриени"</string>
<string name="search" msgid="5421724265322228497">"Пребарај"</string>
<string name="all_printers_label" msgid="3178848870161526399">"Сите печатачи"</string>
- <string name="add_print_service_label" msgid="5356702546188981940">"Додај услуга"</string>
+ <string name="add_print_service_label" msgid="5356702546188981940">"Додајте услуга"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Полето за пребарување е прикажано"</string>
<string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Полето за пребарување е скриено"</string>
<string name="print_add_printer" msgid="1088656468360653455">"Додај печатач"</string>
diff --git a/packages/PrintSpooler/res/values-my/strings.xml b/packages/PrintSpooler/res/values-my/strings.xml
index a6b07e1..cb0b899 100644
--- a/packages/PrintSpooler/res/values-my/strings.xml
+++ b/packages/PrintSpooler/res/values-my/strings.xml
@@ -52,7 +52,7 @@
<string name="add_print_service_label" msgid="5356702546188981940">"ဝန်ဆောင်မှုထည့်ရန်"</string>
<string name="print_search_box_shown_utterance" msgid="7967404953901376090">"ရှာဖွေစရာ နေရာ မြင်တွေ့ရပါသည်"</string>
<string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"ရှာဖွေရန် နေရာ ပျောက်ကွယ်နေပါသည်"</string>
- <string name="print_add_printer" msgid="1088656468360653455">"စာထုတ်စက်ကို ထည့်ပါ"</string>
+ <string name="print_add_printer" msgid="1088656468360653455">"ပရင်တာထည့်ရန်"</string>
<string name="print_select_printer" msgid="7388760939873368698">"စာထုတ်စက်ကို ရွေးရန်"</string>
<string name="print_forget_printer" msgid="5035287497291910766">"စာထုတ်စက်ကို မေ့လိုက်ရန်"</string>
<plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
@@ -65,7 +65,7 @@
<string name="notification_channel_failure" msgid="9042250774797916414">"မအောင်မြင်သည့် ပရင့်ထုတ်မှုများ"</string>
<string name="could_not_create_file" msgid="3425025039427448443">"ဖိုင်အမည်ကို ထည့်၍မရပါ"</string>
<string name="print_services_disabled_toast" msgid="9089060734685174685">"အချို့ပုံနှိပ်ဝန်ဆောင်မှုများကို ပိတ်ထားပါသည်"</string>
- <string name="print_searching_for_printers" msgid="6550424555079932867">"ပုံနှိပ်စက်များကို ရှာနေသည်"</string>
+ <string name="print_searching_for_printers" msgid="6550424555079932867">"ပရင်တာများကို ရှာနေသည်"</string>
<string name="print_no_print_services" msgid="8561247706423327966">"ပုံနှိပ်ထုတ်ယူရေး ဝန်ဆောင်မှုများ ဖွင့်မထားပါ"</string>
<string name="print_no_printers" msgid="4869403323900054866">"စာထုတ်စက် တစ်ခုမှ မတွေ့ရှိပါ"</string>
<string name="cannot_add_printer" msgid="7840348733668023106">"ပုံနှိပ်စက်များကို ထည့်၍မရပါ"</string>
diff --git a/packages/PrintSpooler/res/values-ne/strings.xml b/packages/PrintSpooler/res/values-ne/strings.xml
index d0b7a5e4..be7af70 100644
--- a/packages/PrintSpooler/res/values-ne/strings.xml
+++ b/packages/PrintSpooler/res/values-ne/strings.xml
@@ -35,7 +35,7 @@
<string name="install_for_print_preview" msgid="6366303997385509332">"पूर्वावलोकनको लागि PDF भ्यूअर स्थापना गर्नुहोस्"</string>
<string name="printing_app_crashed" msgid="854477616686566398">"प्रिन्टिङ एप क्र्यास भयो"</string>
<string name="generating_print_job" msgid="3119608742651698916">"प्रिन्ट कार्य निर्माण गरिँदै"</string>
- <string name="save_as_pdf" msgid="5718454119847596853">"PDF को रूपमा सुरक्षित गर्नुहोस्"</string>
+ <string name="save_as_pdf" msgid="5718454119847596853">"PDF को रूपमा सेभ गर्नुहोस्"</string>
<string name="all_printers" msgid="5018829726861876202">"सबै प्रिन्टरहरू..."</string>
<string name="print_dialog" msgid="32628687461331979">"सम्वाद प्रिन्ट गर्नुहोस्"</string>
<string name="current_page_template" msgid="5145005201131935302">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g>/<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string>
@@ -44,7 +44,7 @@
<string name="expand_handle" msgid="7282974448109280522">"ह्यान्डल विस्तार गर्नुहोस्"</string>
<string name="collapse_handle" msgid="6886637989442507451">"ह्यान्डल कोल्याप्स गर्नुहोस्"</string>
<string name="print_button" msgid="645164566271246268">"प्रिन्ट गर्नुहोस्"</string>
- <string name="savetopdf_button" msgid="2976186791686924743">"PDF सुरक्षित गर्नुहोस्"</string>
+ <string name="savetopdf_button" msgid="2976186791686924743">"PDF सेभ गर्नुहोस्"</string>
<string name="print_options_expanded" msgid="6944679157471691859">"विस्तार गरेका विकल्पहरू प्रिन्ट गर्नुहोस्"</string>
<string name="print_options_collapsed" msgid="7455930445670414332">"कोल्याप्स गरेका विकल्पहरू प्रिन्ट गर्नुहोस्"</string>
<string name="search" msgid="5421724265322228497">"खोज्नुहोस्"</string>
@@ -65,7 +65,7 @@
<string name="notification_channel_failure" msgid="9042250774797916414">"कार्यहरूलाई छाप्न सकिएन"</string>
<string name="could_not_create_file" msgid="3425025039427448443">"फाइल सिर्जना गर्न सकिएन"</string>
<string name="print_services_disabled_toast" msgid="9089060734685174685">"केही प्रिन्टिङ सम्बन्धी सेवाहरूलाई असक्षम गरिएको छ"</string>
- <string name="print_searching_for_printers" msgid="6550424555079932867">"प्रिन्टरहरू खोज्दै"</string>
+ <string name="print_searching_for_printers" msgid="6550424555079932867">"प्रिन्टरहरू खोजिँदै छ"</string>
<string name="print_no_print_services" msgid="8561247706423327966">"कुनै पनि प्रिन्टिङ सेवाहरू सक्रिय छैनन्"</string>
<string name="print_no_printers" msgid="4869403323900054866">"कुनै प्रिन्टरहरू भेटाइएन"</string>
<string name="cannot_add_printer" msgid="7840348733668023106">"प्रिन्टरहरू थप्न सक्दैन"</string>
diff --git a/packages/PrintSpooler/res/values-pa/strings.xml b/packages/PrintSpooler/res/values-pa/strings.xml
index 1cacc10..601fa83 100644
--- a/packages/PrintSpooler/res/values-pa/strings.xml
+++ b/packages/PrintSpooler/res/values-pa/strings.xml
@@ -65,7 +65,7 @@
<string name="notification_channel_failure" msgid="9042250774797916414">"ਅਸਫਲ ਰਹੇ ਪ੍ਰਿੰਟ ਜੌਬ"</string>
<string name="could_not_create_file" msgid="3425025039427448443">"ਫ਼ਾਈਲ ਨੂੰ ਬਣਾਇਆ ਨਹੀਂ ਜਾ ਸਕਿਆ"</string>
<string name="print_services_disabled_toast" msgid="9089060734685174685">"ਕੁਝ ਪ੍ਰਿੰਟ ਸੇਵਾਵਾਂ ਬੰਦ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ"</string>
- <string name="print_searching_for_printers" msgid="6550424555079932867">"ਪ੍ਰਿੰਟਰ ਖੋਜ ਰਿਹਾ ਹੈ"</string>
+ <string name="print_searching_for_printers" msgid="6550424555079932867">"ਪ੍ਰਿੰਟਰ ਖੋਜਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="print_no_print_services" msgid="8561247706423327966">"ਪ੍ਰਿੰਟ ਸੇਵਾਵਾਂ ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਕੀਤਾ ਗਿਆ"</string>
<string name="print_no_printers" msgid="4869403323900054866">"ਕੋਈ ਪ੍ਰਿੰਟਰ ਨਹੀਂ ਮਿਲੇ"</string>
<string name="cannot_add_printer" msgid="7840348733668023106">"ਪ੍ਰਿੰਟਰ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ"</string>
diff --git a/packages/PrintSpooler/res/values-te/strings.xml b/packages/PrintSpooler/res/values-te/strings.xml
index 79944bb..cf0e0f6 100644
--- a/packages/PrintSpooler/res/values-te/strings.xml
+++ b/packages/PrintSpooler/res/values-te/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4469836075319831821">"ముద్రణ స్పూలర్"</string>
- <string name="more_options_button" msgid="2243228396432556771">"మరిన్ని ఎంపికలు"</string>
+ <string name="more_options_button" msgid="2243228396432556771">"మరిన్ని ఆప్షన్లు"</string>
<string name="label_destination" msgid="9132510997381599275">"గమ్యం"</string>
<string name="label_copies" msgid="3634531042822968308">"కాపీలు"</string>
<string name="label_copies_summary" msgid="3861966063536529540">"కాపీలు:"</string>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-gu/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-gu/strings.xml
index a24456e..f57061a 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values-gu/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-gu/strings.xml
@@ -18,5 +18,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="enabled_by_admin" msgid="6630472777476410137">"વ્યવસ્થાપકે ચાલુ કરેલ"</string>
- <string name="disabled_by_admin" msgid="4023569940620832713">"વ્યવસ્થાપકે બંધ કરેલ"</string>
+ <string name="disabled_by_admin" msgid="4023569940620832713">"વ્યવસ્થાપકે બંધ કરેલું"</string>
</resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-it/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-it/strings.xml
index 199a2d6..bddf43c 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values-it/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-it/strings.xml
@@ -18,5 +18,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="enabled_by_admin" msgid="6630472777476410137">"Attivata dall\'amministratore"</string>
- <string name="disabled_by_admin" msgid="4023569940620832713">"Disattivata dall\'amministratore"</string>
+ <string name="disabled_by_admin" msgid="4023569940620832713">"Opzione disattivata dall\'amministratore"</string>
</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-or/strings.xml b/packages/SettingsLib/SearchWidget/res/values-or/strings.xml
index c2379ac..cf824de 100644
--- a/packages/SettingsLib/SearchWidget/res/values-or/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-or/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="search_menu" msgid="1914043873178389845">"ସନ୍ଧାନ ସେଟିଂସ୍"</string>
+ <string name="search_menu" msgid="1914043873178389845">"ସେଟିଂସ୍ ସନ୍ଧାନ କରନ୍ତୁ"</string>
</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml b/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml
index 5fe116e..02229b8 100644
--- a/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-pt-rPT/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="search_menu" msgid="1914043873178389845">"Pesquisar nas definições"</string>
+ <string name="search_menu" msgid="1914043873178389845">"Pesquise nas definições"</string>
</resources>
diff --git a/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml b/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml
index 31b3fe5..d2c6fa2 100644
--- a/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml
+++ b/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml
@@ -24,29 +24,27 @@
android:orientation="vertical"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
- android:paddingTop="32dp"
- android:paddingBottom="32dp">
+ android:paddingTop="16dp"
+ android:paddingBottom="16dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/usage_summary"
- android:layout_width="0dp"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- app:layout_constraintWidth_percent="0.45"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBaseline_toBaselineOf="@id/total_summary"
android:ellipsize="marquee"
- android:fontFamily="@*android:string/config_headlineFontFamily"
- android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Display1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textSize="14sp"
android:textAlignment="viewStart"/>
<TextView
android:id="@+id/total_summary"
android:layout_width="0dp"
android:layout_height="wrap_content"
- app:layout_constraintWidth_percent="0.45"
+ app:layout_constraintStart_toEndOf="@id/usage_summary"
app:layout_constraintEnd_toStartOf="@id/custom_content"
android:ellipsize="marquee"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
@@ -54,12 +52,11 @@
android:textAlignment="viewEnd"/>
<FrameLayout
android:id="@+id/custom_content"
- android:layout_width="0dp"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/total_summary"
- app:layout_constraintWidth_percent="0.1"/>
+ app:layout_constraintBottom_toBottomOf="@id/total_summary"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<ProgressBar
@@ -67,8 +64,7 @@
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:scaleY="2"
- android:layout_marginTop="4dp"
+ android:scaleY="4"
android:max="100"/>
<TextView
diff --git a/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java b/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java
index a2b1de2..fbf325c 100644
--- a/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java
+++ b/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java
@@ -20,7 +20,7 @@
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
-import android.text.style.RelativeSizeSpan;
+import android.text.style.AbsoluteSizeSpan;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
@@ -192,7 +192,7 @@
final Matcher matcher = mNumberPattern.matcher(summary);
if (matcher.find()) {
final SpannableString spannableSummary = new SpannableString(summary);
- spannableSummary.setSpan(new RelativeSizeSpan(2.4f), matcher.start(),
+ spannableSummary.setSpan(new AbsoluteSizeSpan(64, true /* dip */), matcher.start(),
matcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannableSummary;
}
diff --git a/packages/SettingsProvider/res/values-es/strings.xml b/packages/SettingsProvider/res/values-es/strings.xml
index a3d3469..c799689 100644
--- a/packages/SettingsProvider/res/values-es/strings.xml
+++ b/packages/SettingsProvider/res/values-es/strings.xml
@@ -20,6 +20,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="4567566098528588863">"Almacenamiento de configuración"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Se han cambiado los ajustes del punto de acceso"</string>
+ <string name="wifi_softap_config_change" msgid="5688373762357941645">"Se han cambiado los ajustes de Compartir Internet"</string>
<string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Toca para ver información detallada"</string>
</resources>
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index f685d88..a8d1534 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -162,6 +162,7 @@
<uses-permission android:name="android.permission.READ_INPUT_STATE" />
<uses-permission android:name="android.permission.SET_ORIENTATION" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
+ <uses-permission android:name="com.android.permission.USE_INSTALLER_V2" />
<uses-permission android:name="com.android.permission.USE_SYSTEM_DATA_LOADERS" />
<uses-permission android:name="android.permission.MOVE_PACKAGE" />
<uses-permission android:name="android.permission.KEEP_UNINSTALLED_PACKAGES" />
diff --git a/packages/Shell/res/values-ne/strings.xml b/packages/Shell/res/values-ne/strings.xml
index 3c58796..69da552 100644
--- a/packages/Shell/res/values-ne/strings.xml
+++ b/packages/Shell/res/values-ne/strings.xml
@@ -42,6 +42,6 @@
<string name="bugreport_info_name" msgid="4414036021935139527">"फाइलको नाम"</string>
<string name="bugreport_info_title" msgid="2306030793918239804">"बगको शीर्षक"</string>
<string name="bugreport_info_description" msgid="5072835127481627722">"बगको सारांश"</string>
- <string name="save" msgid="4781509040564835759">"सुरक्षित गर्नुहोस्"</string>
+ <string name="save" msgid="4781509040564835759">"सेभ गर्नुहोस्"</string>
<string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"बग रिपोर्ट सेयर गर्नुहोस्"</string>
</resources>
diff --git a/packages/Shell/res/values-vi/strings.xml b/packages/Shell/res/values-vi/strings.xml
index 1f91a5a..2aaa094 100644
--- a/packages/Shell/res/values-vi/strings.xml
+++ b/packages/Shell/res/values-vi/strings.xml
@@ -29,7 +29,7 @@
<string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Bấm để chia sẻ báo cáo lỗi mà không cần ảnh chụp màn hình hoặc đợi hoàn tất ảnh chụp màn hình"</string>
<string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Bấm để chia sẻ báo cáo lỗi mà không cần ảnh chụp màn hình hoặc đợi hoàn tất ảnh chụp màn hình"</string>
<string name="bugreport_confirm" msgid="5917407234515812495">"Các báo cáo lỗi chứa dữ liệu từ nhiều tệp nhật ký khác nhau của hệ thống, có thể bao gồm dữ liệu mà bạn coi là nhạy cảm (chẳng hạn như dữ liệu vị trí và dữ liệu sử dụng ứng dụng). Chỉ chia sẻ báo cáo lỗi với những người và ứng dụng mà bạn tin tưởng."</string>
- <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Không hiển thị lại"</string>
+ <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Không hiện lại"</string>
<string name="bugreport_storage_title" msgid="5332488144740527109">"Báo cáo lỗi"</string>
<string name="bugreport_unreadable_text" msgid="586517851044535486">"Không thể đọc tệp báo cáo lỗi"</string>
<string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Không thể thêm chi tiết báo cáo lỗi vào tệp zip"</string>
diff --git a/packages/SoundPicker/res/values-gu/strings.xml b/packages/SoundPicker/res/values-gu/strings.xml
index f50dc9a..209769f 100644
--- a/packages/SoundPicker/res/values-gu/strings.xml
+++ b/packages/SoundPicker/res/values-gu/strings.xml
@@ -18,7 +18,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="ringtone_default" msgid="798836092118824500">"ડિફોલ્ટ રિંગટોન"</string>
<string name="notification_sound_default" msgid="8133121186242636840">"ડિફૉલ્ટ નોટિફિકેશન સાઉન્ડ"</string>
- <string name="alarm_sound_default" msgid="4787646764557462649">"ડિફૉલ્ટ એલાર્મ સાઉન્ડ"</string>
+ <string name="alarm_sound_default" msgid="4787646764557462649">"ડિફૉલ્ટ અલાર્મ સાઉન્ડ"</string>
<string name="add_ringtone_text" msgid="6642389991738337529">"રિંગટોન ઉમેરો"</string>
<string name="add_alarm_text" msgid="3545497316166999225">"અલાર્મ ઉમેરો"</string>
<string name="add_notification_text" msgid="4431129543300614788">"નોટિફિકેશન ઉમેરો"</string>
diff --git a/packages/SoundPicker/res/values-it/strings.xml b/packages/SoundPicker/res/values-it/strings.xml
index 20965d0..632cb41 100644
--- a/packages/SoundPicker/res/values-it/strings.xml
+++ b/packages/SoundPicker/res/values-it/strings.xml
@@ -18,7 +18,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="ringtone_default" msgid="798836092118824500">"Suoneria predefinita"</string>
<string name="notification_sound_default" msgid="8133121186242636840">"Suono di notifica predefinito"</string>
- <string name="alarm_sound_default" msgid="4787646764557462649">"Suono sveglia predefinito"</string>
+ <string name="alarm_sound_default" msgid="4787646764557462649">"Suoneria sveglia predefinita"</string>
<string name="add_ringtone_text" msgid="6642389991738337529">"Aggiungi suoneria"</string>
<string name="add_alarm_text" msgid="3545497316166999225">"Aggiungi sveglia"</string>
<string name="add_notification_text" msgid="4431129543300614788">"Aggiungi notifica"</string>
diff --git a/packages/SoundPicker/res/values-kk/strings.xml b/packages/SoundPicker/res/values-kk/strings.xml
index ad6d0e0..8c4c169 100644
--- a/packages/SoundPicker/res/values-kk/strings.xml
+++ b/packages/SoundPicker/res/values-kk/strings.xml
@@ -18,7 +18,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="ringtone_default" msgid="798836092118824500">"Әдепкі рингтон"</string>
<string name="notification_sound_default" msgid="8133121186242636840">"Әдепкі хабарландыру дыбысы"</string>
- <string name="alarm_sound_default" msgid="4787646764557462649">"Әдепкі дабыл дыбысы"</string>
+ <string name="alarm_sound_default" msgid="4787646764557462649">"Әдепкі оятқыш дыбысы"</string>
<string name="add_ringtone_text" msgid="6642389991738337529">"Рингтон қосу"</string>
<string name="add_alarm_text" msgid="3545497316166999225">"Оятқыш енгізу"</string>
<string name="add_notification_text" msgid="4431129543300614788">"Хабарландыру енгізу"</string>
diff --git a/packages/SoundPicker/res/values-mr/strings.xml b/packages/SoundPicker/res/values-mr/strings.xml
index eb55fc7..3ddb991 100644
--- a/packages/SoundPicker/res/values-mr/strings.xml
+++ b/packages/SoundPicker/res/values-mr/strings.xml
@@ -18,7 +18,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="ringtone_default" msgid="798836092118824500">"डीफॉल्ट रिंगटोन"</string>
<string name="notification_sound_default" msgid="8133121186242636840">"डीफॉल्ट सूचना आवाज"</string>
- <string name="alarm_sound_default" msgid="4787646764557462649">"डीफॉल्ट अलार्म ध्वनी"</string>
+ <string name="alarm_sound_default" msgid="4787646764557462649">"डीफॉल्ट अलार्म आवाज"</string>
<string name="add_ringtone_text" msgid="6642389991738337529">"रिंगटोन जोडा"</string>
<string name="add_alarm_text" msgid="3545497316166999225">"अलार्म जोडा"</string>
<string name="add_notification_text" msgid="4431129543300614788">"सूचना जोडा"</string>
diff --git a/packages/SoundPicker/res/values-ne/strings.xml b/packages/SoundPicker/res/values-ne/strings.xml
index 7dc7893..0a2bceb 100644
--- a/packages/SoundPicker/res/values-ne/strings.xml
+++ b/packages/SoundPicker/res/values-ne/strings.xml
@@ -16,9 +16,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="ringtone_default" msgid="798836092118824500">"पूर्वनिर्धारित रिङटोन"</string>
- <string name="notification_sound_default" msgid="8133121186242636840">"सूचनाको पूर्वनिर्धारित ध्वनि"</string>
- <string name="alarm_sound_default" msgid="4787646764557462649">"अलार्मका लागि पूर्वनिर्धारित ध्वनि"</string>
+ <string name="ringtone_default" msgid="798836092118824500">"डिफल्ट रिङटोन"</string>
+ <string name="notification_sound_default" msgid="8133121186242636840">"सूचनाको डिफल्ट साउन्ड"</string>
+ <string name="alarm_sound_default" msgid="4787646764557462649">"अलार्मको डिफल्ट साउन्ड"</string>
<string name="add_ringtone_text" msgid="6642389991738337529">"रिङटोन थप्नुहोस्"</string>
<string name="add_alarm_text" msgid="3545497316166999225">"अलार्म थप्नुहोस्"</string>
<string name="add_notification_text" msgid="4431129543300614788">"सूचना थप्नुहोस्"</string>
diff --git a/packages/SoundPicker/res/values-pa/strings.xml b/packages/SoundPicker/res/values-pa/strings.xml
index eb630c9..1e62f64 100644
--- a/packages/SoundPicker/res/values-pa/strings.xml
+++ b/packages/SoundPicker/res/values-pa/strings.xml
@@ -18,7 +18,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="ringtone_default" msgid="798836092118824500">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਰਿੰਗਟੋਨ"</string>
<string name="notification_sound_default" msgid="8133121186242636840">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਸੂਚਨਾ ਧੁਨੀ"</string>
- <string name="alarm_sound_default" msgid="4787646764557462649">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਅਲਾਰਮ ਧੁਨੀ"</string>
+ <string name="alarm_sound_default" msgid="4787646764557462649">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਅਲਾਰਮ ਧੁਨੀ"</string>
<string name="add_ringtone_text" msgid="6642389991738337529">"ਰਿੰਗਟੋਨ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="add_alarm_text" msgid="3545497316166999225">"ਅਲਾਰਮ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="add_notification_text" msgid="4431129543300614788">"ਸੂਚਨਾ ਸ਼ਾਮਲ ਕਰੋ"</string>
diff --git a/packages/SoundPicker/res/values-vi/strings.xml b/packages/SoundPicker/res/values-vi/strings.xml
index bf5c33a..bed0e96 100644
--- a/packages/SoundPicker/res/values-vi/strings.xml
+++ b/packages/SoundPicker/res/values-vi/strings.xml
@@ -18,7 +18,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="ringtone_default" msgid="798836092118824500">"Nhạc chuông mặc định"</string>
<string name="notification_sound_default" msgid="8133121186242636840">"Âm thanh thông báo mặc định"</string>
- <string name="alarm_sound_default" msgid="4787646764557462649">"Âm thanh báo thức mặc định"</string>
+ <string name="alarm_sound_default" msgid="4787646764557462649">"Âm thanh chuông báo mặc định"</string>
<string name="add_ringtone_text" msgid="6642389991738337529">"Thêm nhạc chuông"</string>
<string name="add_alarm_text" msgid="3545497316166999225">"Thêm báo thức"</string>
<string name="add_notification_text" msgid="4431129543300614788">"Thêm thông báo"</string>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index a834784..173e959 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -762,7 +762,7 @@
android:showForAllUsers="true"
android:finishOnTaskLaunch="true"
android:launchMode="singleInstance"
- android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
+ android:configChanges="screenSize|smallestScreenSize|screenLayout|keyboard|keyboardHidden"
android:visibleToInstantApps="true">
</activity>
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 3363f8e..03d844a 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -31,14 +31,16 @@
companion object {
const val ANIMATION_DURATION = 500L
const val ANIMATION_DURATION_FADE_OUT_CONTENT = 183L
- const val ANIMATION_DURATION_FADE_IN_WINDOW = 216L
- const val ANIMATION_DELAY_FADE_IN_WINDOW = 166L
+ const val ANIMATION_DURATION_FADE_IN_WINDOW = 217L
+ const val ANIMATION_DELAY_FADE_IN_WINDOW = 167L
private const val ANIMATION_DURATION_NAV_FADE_IN = 266L
private const val ANIMATION_DURATION_NAV_FADE_OUT = 133L
private const val ANIMATION_DELAY_NAV_FADE_IN =
ANIMATION_DURATION - ANIMATION_DURATION_NAV_FADE_IN
private const val LAUNCH_TIMEOUT = 1000L
+ private val CONTENT_FADE_OUT_INTERPOLATOR = PathInterpolator(0f, 0f, 0.2f, 1f)
+ private val WINDOW_FADE_IN_INTERPOLATOR = PathInterpolator(0f, 0f, 0.6f, 1f)
private val NAV_FADE_IN_INTERPOLATOR = PathInterpolator(0f, 0f, 0f, 1f)
private val NAV_FADE_OUT_INTERPOLATOR = PathInterpolator(0.2f, 0f, 1f, 1f)
@@ -418,12 +420,12 @@
val contentAlphaProgress = getProgress(linearProgress, 0,
ANIMATION_DURATION_FADE_OUT_CONTENT)
state.contentAlpha =
- 1 - Interpolators.ALPHA_OUT.getInterpolation(contentAlphaProgress)
+ 1 - CONTENT_FADE_OUT_INTERPOLATOR.getInterpolation(contentAlphaProgress)
val backgroundAlphaProgress = getProgress(linearProgress,
ANIMATION_DELAY_FADE_IN_WINDOW, ANIMATION_DURATION_FADE_IN_WINDOW)
state.backgroundAlpha =
- 1 - Interpolators.ALPHA_IN.getInterpolation(backgroundAlphaProgress)
+ 1 - WINDOW_FADE_IN_INTERPOLATOR.getInterpolation(backgroundAlphaProgress)
applyStateToWindow(window, state)
navigationBar?.let { applyStateToNavigationBar(it, state, linearProgress) }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
index 01ec447..3da4521 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
@@ -9,6 +9,7 @@
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
+import android.graphics.drawable.InsetDrawable
import android.graphics.drawable.LayerDrawable
import android.view.GhostView
import android.view.View
@@ -186,6 +187,10 @@
return drawable
}
+ if (drawable is InsetDrawable) {
+ return drawable.drawable?.let { findGradientDrawable(it) }
+ }
+
if (drawable is LayerDrawable) {
for (i in 0 until drawable.numberOfLayers) {
val maybeGradient = drawable.getDrawable(i)
@@ -255,6 +260,11 @@
}
private fun setXfermode(background: Drawable, mode: PorterDuffXfermode?) {
+ if (background is InsetDrawable) {
+ background.drawable?.let { setXfermode(it, mode) }
+ return
+ }
+
if (background !is LayerDrawable) {
background.setXfermode(mode)
return
@@ -323,6 +333,11 @@
return
}
+ if (drawable is InsetDrawable) {
+ drawable.drawable?.let { applyBackgroundRadii(it, radii) }
+ return
+ }
+
if (drawable !is LayerDrawable) {
return
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
index 00bea8d..47a373e 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
@@ -60,6 +60,8 @@
*/
void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade, int flags);
void startActivity(Intent intent, boolean dismissShade);
+ void startActivity(Intent intent, boolean dismissShade,
+ @Nullable ActivityLaunchAnimator.Controller animationController);
void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade);
void startActivity(Intent intent, boolean dismissShade, Callback callback);
void postStartActivityDismissingKeyguard(Intent intent, int delay);
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index 93fe516..9f00e66 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -106,7 +106,7 @@
<string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"PIN kodea idatzi beharko duzu gailua berrabiarazten denean"</string>
<string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Pasahitza idatzi beharko duzu gailua berrabiarazten denean"</string>
<string name="kg_prompt_reason_timeout_pattern" msgid="9170360502528959889">"Eredua behar da gailua babestuago izateko"</string>
- <string name="kg_prompt_reason_timeout_pin" msgid="5945186097160029201">"PIN kodea behar da gailua babestuago izateko"</string>
+ <string name="kg_prompt_reason_timeout_pin" msgid="5945186097160029201">"PINa behar da gailua babestuago izateko"</string>
<string name="kg_prompt_reason_timeout_password" msgid="2258263949430384278">"Pasahitza behar da gailua babestuago izateko"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="1922016914701991230">"Eredua marraztu beharko duzu profilez aldatzen baduzu"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="6490434826361055400">"PIN kodea idatzi beharko duzu profilez aldatzen baduzu"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index 6f8a108..707488d 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -51,7 +51,7 @@
<string name="keyguard_sim_puk_locked_message" msgid="6253830777745450550">"SIM कार्ड PUK-लक भएको छ।"</string>
<string name="keyguard_sim_unlock_progress_dialog_message" msgid="2394023844117630429">"SIM कार्ड अनलक गरिँदै..."</string>
<string name="keyguard_accessibility_pin_area" msgid="7403009340414014734">"PIN क्षेत्र"</string>
- <string name="keyguard_accessibility_password" msgid="3524161948484801450">"यन्त्रको पासवर्ड"</string>
+ <string name="keyguard_accessibility_password" msgid="3524161948484801450">"डिभाइसको पासवर्ड"</string>
<string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"SIM को PIN क्षेत्र"</string>
<string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"SIM को PUK क्षेत्र"</string>
<string name="keyguard_accessibility_next_alarm" msgid="4492876946798984630">"अर्को अलार्म <xliff:g id="ALARM">%1$s</xliff:g> का लागि सेट गरियो"</string>
@@ -71,7 +71,7 @@
<string name="kg_pattern_instructions" msgid="5376036737065051736">"आफ्नो ढाँचा कोर्नुहोस्"</string>
<string name="kg_sim_pin_instructions" msgid="1942424305184242951">"SIM को PIN प्रविष्टि गर्नुहोस्।"</string>
<string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" को SIM को PIN प्रविष्टि गर्नुहोस्।"</string>
- <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> मोबाइल सेवा बिना यन्त्रको प्रयोग गर्न eSIM लाई असक्षम पार्नुहोस्।"</string>
+ <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> मोबाइल सेवा बिना डिभाइसको प्रयोग गर्न eSIM लाई असक्षम पार्नुहोस्।"</string>
<string name="kg_pin_instructions" msgid="822353548385014361">"PIN प्रविष्टि गर्नुहोस्"</string>
<string name="kg_password_instructions" msgid="324455062831719903">"पासवर्ड प्रविष्टि गर्नुहोस्"</string>
<string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM कार्ड अहिले असक्षम छ। सुचारु गर्नको लागि PUK कोड प्रविष्टि गर्नुहोस्। विवरणको लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।"</string>
@@ -85,7 +85,7 @@
<string name="kg_login_too_many_attempts" msgid="4519957179182578690">"अत्यन्त धेरै ढाँचा कोर्ने प्रयासहरू"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले आफ्नो PIN प्रविष्ट गर्नुभएको छ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक आफ्नो गलत पासवर्ड प्रविष्ट गर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
- <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले आफ्नो अनलक ढाँचा कोर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले आफ्नो अनलक प्याटर्न कोर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM को PIN कोड गलत छ। तपाईंले अब आफ्नो यन्त्र खोल्न आफ्नो सेवा प्रदायकलाई सम्पर्क गर्नै पर्ने हुन्छ।"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
<item quantity="other">SIM को PIN कोड गलत छ, तपाईं अझै <xliff:g id="NUMBER_1">%d</xliff:g> पटक प्रयास गर्न सक्नुहुन्छ।</item>
@@ -135,7 +135,7 @@
<item quantity="other">SIM लाई असक्षम पारिएको छ। जारी राख्न PUK कोड प्रविष्टि गर्नुहोस्। तपाईंसँग <xliff:g id="_NUMBER_1">%d</xliff:g> प्रयासहरू बाँकी छन्, त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुन्छ। विवरणहरूका लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।</item>
<item quantity="one">SIM लाई असक्षम पारिएको छ। जारी राख्न PUK कोड प्रविष्टि गर्नुहोस्। तपाईंसँग <xliff:g id="_NUMBER_0">%d</xliff:g> प्रयास बाँकी छ, त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुन्छ। विवरणहरूका लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।</item>
</plurals>
- <string name="clock_title_default" msgid="6342735240617459864">"पूर्वनिर्धारित"</string>
+ <string name="clock_title_default" msgid="6342735240617459864">"डिफल्ट"</string>
<string name="clock_title_bubble" msgid="2204559396790593213">"बबल"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"एनालग"</string>
</resources>
diff --git a/packages/SystemUI/res-product/values-ne/strings.xml b/packages/SystemUI/res-product/values-ne/strings.xml
index 148cb51..1d368f4 100644
--- a/packages/SystemUI/res-product/values-ne/strings.xml
+++ b/packages/SystemUI/res-product/values-ne/strings.xml
@@ -22,7 +22,7 @@
<string name="dock_alignment_slow_charging" product="default" msgid="6997633396534416792">"अझ छिटो चार्ज गर्न फोनलाई फेरि मिलाउनुहोस्"</string>
<string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"तारविनै चार्ज गर्न फोनलाई फेरि मिलाउनुहोस्"</string>
<string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"Android टिभी यन्त्र चाँडै निष्क्रिय हुने छ; सक्रिय राख्न कुनै बटन थिच्नुहोस्।"</string>
- <string name="inattentive_sleep_warning_message" product="default" msgid="5693904520452332224">"यो यन्त्र चाँडै निष्क्रिय हुने छ; सक्रिय राख्न थिच्नुहोस्।"</string>
+ <string name="inattentive_sleep_warning_message" product="default" msgid="5693904520452332224">"यो डिभाइस चाँडै निष्क्रिय हुने छ; सक्रिय राख्न थिच्नुहोस्।"</string>
<string name="keyguard_missing_sim_message" product="tablet" msgid="5018086454277963787">"ट्याब्लेटमा SIM कार्ड छैन।"</string>
<string name="keyguard_missing_sim_message" product="default" msgid="7053347843877341391">"फोनमा SIM कार्ड छैन।"</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="6278551068943958651">"PIN कोडहरू मिलेनन्"</string>
diff --git a/packages/SystemUI/res/drawable/ic_brightness.xml b/packages/SystemUI/res/drawable/ic_brightness.xml
index f443332..842af26 100644
--- a/packages/SystemUI/res/drawable/ic_brightness.xml
+++ b/packages/SystemUI/res/drawable/ic_brightness.xml
@@ -1,29 +1,23 @@
<!--
-Copyright (C) 2020 The Android Open Source Project
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
- 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="M18,14.48V18h-3.52L12,20.48L9.52,18H6v-3.52L3.52,12L6,9.52V6h3.52L12,3.52L14.48,6H18v3.52L20.48,12L18,14.48z"
- />
-
- <path
- android:pathData=" M20,8.69 V4h-4.69L12,0.69L8.69,4H4v4.69L0.69,12L4,15.31V20h4.69L12,23.31L15.31,20H20v-4.69L23.31,12L20,8.69z M18,14.48V18h-3.52L12,20.48L9.52,18H6v-3.52L3.52,12L6,9.52V6h3.52L12,3.52L14.48,6H18v3.52L20.48,12L18,14.48z M12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5s5,-2.24 5,-5S14.76,7 12,7z"
- android:fillColor="#FFFFFF" />
-</vector>
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Levels in drawables go from 0 to 10000 -->
+ <!-- "One third" of the range per icon -->
+ <item android:maxLevel="3333" android:drawable="@drawable/ic_brightness_low" />
+ <item android:maxLevel="6666" android:drawable="@drawable/ic_brightness_medium" />
+ <item android:maxLevel="10000" android:drawable="@drawable/ic_brightness_full" />
+</level-list>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml b/packages/SystemUI/res/drawable/ic_brightness_full.xml
similarity index 86%
rename from packages/SystemUI/res/drawable/ic_brightness_thumb.xml
rename to packages/SystemUI/res/drawable/ic_brightness_full.xml
index d721988..f443332 100644
--- a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
+++ b/packages/SystemUI/res/drawable/ic_brightness_full.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2017 The Android Open Source Project
+Copyright (C) 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -21,9 +21,9 @@
<path
android:pathData="M18,14.48V18h-3.52L12,20.48L9.52,18H6v-3.52L3.52,12L6,9.52V6h3.52L12,3.52L14.48,6H18v3.52L20.48,12L18,14.48z"
- android:fillColor="?android:attr/colorBackgroundFloating" />
+ />
<path
android:pathData=" M20,8.69 V4h-4.69L12,0.69L8.69,4H4v4.69L0.69,12L4,15.31V20h4.69L12,23.31L15.31,20H20v-4.69L23.31,12L20,8.69z M18,14.48V18h-3.52L12,20.48L9.52,18H6v-3.52L3.52,12L6,9.52V6h3.52L12,3.52L14.48,6H18v3.52L20.48,12L18,14.48z M12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5s5,-2.24 5,-5S14.76,7 12,7z"
- android:fillColor="?android:attr/colorControlActivated" />
+ android:fillColor="#FFFFFF" />
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_brightness_low.xml b/packages/SystemUI/res/drawable/ic_brightness_low.xml
new file mode 100644
index 0000000..b463556
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_brightness_low.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M20,8.69L20,4h-4.69L12,0.69 8.69,4L4,4v4.69L0.69,12 4,15.31L4,20h4.69L12,23.31 15.31,20L20,20v-4.69L23.31,12 20,8.69zM18,14.48L18,18h-3.52L12,20.48 9.52,18L6,18v-3.52L3.52,12 6,9.52L6,6h3.52L12,3.52 14.48,6L18,6v3.52L20.48,12 18,14.48zM12,9c1.65,0 3,1.35 3,3s-1.35,3 -3,3 -3,-1.35 -3,-3 1.35,-3 3,-3m0,-2c-2.76,0 -5,2.24 -5,5s2.24,5 5,5 5,-2.24 5,-5 -2.24,-5 -5,-5z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_brightness_medium.xml b/packages/SystemUI/res/drawable/ic_brightness_medium.xml
new file mode 100644
index 0000000..80acc4d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_brightness_medium.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M20,8.69L20,4h-4.69L12,0.69 8.69,4L4,4v4.69L0.69,12 4,15.31L4,20h4.69L12,23.31 15.31,20L20,20v-4.69L23.31,12 20,8.69zM18,14.48L18,18h-3.52L12,20.48 9.52,18L6,18v-3.52L3.52,12 6,9.52L6,6h3.52L12,3.52 14.48,6L18,6v3.52L20.48,12 18,14.48zM12,17c2.76,0 5,-2.24 5,-5s-2.24,-5 -5,-5v10z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/qs_footer_action_chip_background.xml b/packages/SystemUI/res/drawable/qs_footer_action_chip_background.xml
index 6022206..77b9871 100644
--- a/packages/SystemUI/res/drawable/qs_footer_action_chip_background.xml
+++ b/packages/SystemUI/res/drawable/qs_footer_action_chip_background.xml
@@ -23,13 +23,18 @@
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
<solid android:color="@android:color/white"/>
+ <corners android:radius="@dimen/screenshot_button_corner_radius"/>
+ </shape>
+ </item>
+ <item>
+ <shape android:shape="rectangle">
+ <solid android:color="?attr/underSurfaceColor"/>
<corners android:radius="@dimen/qs_footer_action_corner_radius"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
- <stroke android:width="1dp" android:color="@color/qs_footer_action_border"/>
- <solid android:color="@android:color/transparent"/>
+ <stroke android:width="1dp" android:color="@color/qs_footer_action_border"/>
<corners android:radius="@dimen/qs_footer_action_corner_radius"/>
</shape>
</item>
diff --git a/packages/SystemUI/res/drawable/system_animation_ongoing_dot.xml b/packages/SystemUI/res/drawable/system_animation_ongoing_dot.xml
new file mode 100644
index 0000000..4e9d380
--- /dev/null
+++ b/packages/SystemUI/res/drawable/system_animation_ongoing_dot.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- dot drawable for ongoing system privacy events -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <solid
+ android:color="@color/privacy_circle"/>
+ <size
+ android:width="6dp"
+ android:height="6dp"
+ />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/long_screenshot.xml b/packages/SystemUI/res/layout/long_screenshot.xml
index fb783a7..ceba4e3 100644
--- a/packages/SystemUI/res/layout/long_screenshot.xml
+++ b/packages/SystemUI/res/layout/long_screenshot.xml
@@ -19,6 +19,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="?android:colorBackgroundFloating"
+ android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -119,4 +120,14 @@
app:layout_constraintRight_toRightOf="parent"
/>
+ <ImageView
+ android:id="@+id/transition"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintTop_toBottomOf="@id/save"
+ app:layout_constraintStart_toStartOf="parent"
+ android:scaleType="matrix"
+ android:visibility="gone"
+ />
+
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/res/layout/media_output_list_item.xml b/packages/SystemUI/res/layout/media_output_list_item.xml
index c98c3a0..b563633 100644
--- a/packages/SystemUI/res/layout/media_output_list_item.xml
+++ b/packages/SystemUI/res/layout/media_output_list_item.xml
@@ -28,7 +28,7 @@
<FrameLayout
android:layout_width="36dp"
android:layout_height="36dp"
- android:layout_gravity="center_vertical"
+ android:layout_gravity="center_vertical|start"
android:layout_marginStart="16dp">
<ImageView
android:id="@+id/title_icon"
@@ -41,7 +41,7 @@
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
+ android:layout_gravity="center_vertical|start"
android:layout_marginStart="68dp"
android:ellipsize="end"
android:maxLines="1"
diff --git a/packages/SystemUI/res/layout/people_tile_medium_empty.xml b/packages/SystemUI/res/layout/people_tile_medium_empty.xml
index 7d9cbb9..4236493 100644
--- a/packages/SystemUI/res/layout/people_tile_medium_empty.xml
+++ b/packages/SystemUI/res/layout/people_tile_medium_empty.xml
@@ -14,7 +14,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -22,57 +22,49 @@
<LinearLayout
android:background="@drawable/people_space_tile_view_card"
android:id="@+id/item"
- android:orientation="vertical"
+ android:gravity="center"
+ android:paddingHorizontal="16dp"
+ android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
-
+ <ImageView
+ android:id="@+id/person_icon"
+ android:layout_marginTop="-2dp"
+ android:layout_marginStart="-2dp"
+ android:layout_width="64dp"
+ android:layout_height="64dp" />
+ <ImageView
+ android:id="@+id/availability"
+ android:layout_marginStart="-2dp"
+ android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:background="@drawable/circle_green_10dp" />
<LinearLayout
- android:orientation="horizontal"
- android:gravity="center"
- android:layout_gravity="center"
- android:paddingVertical="2dp"
- android:paddingHorizontal="8dp"
+ android:orientation="vertical"
+ android:paddingStart="6dp"
+ android:gravity="top"
android:layout_width="match_parent"
- android:layout_height="match_parent">
- <ImageView
- android:id="@+id/person_icon"
- android:layout_width="64dp"
- android:layout_height="64dp"/>
- <ImageView
- android:id="@+id/availability"
- android:layout_marginStart="-2dp"
- android:layout_width="10dp"
- android:layout_height="10dp"
- android:background="@drawable/circle_green_10dp"/>
- <LinearLayout
- android:orientation="vertical"
- android:paddingStart="6dp"
- android:gravity="top"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <TextView
- android:id="@+id/name"
- android:text="@string/empty_user_name"
- android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
- android:textColor="?android:attr/textColorPrimary"
- android:textSize="14sp"
- android:maxLines="1"
- android:ellipsize="end"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
-
- <TextView
- android:id="@+id/last_interaction"
- android:text="@string/empty_status"
- android:textColor="?android:attr/textColorSecondary"
- android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
- android:textSize="12sp"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:maxLines="3"
- android:ellipsize="end"/>
- </LinearLayout>
+ android:layout_height="wrap_content">
+ <TextView
+ android:id="@+id/name"
+ android:text="@string/empty_user_name"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="14sp"
+ android:maxLines="1"
+ android:ellipsize="end"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <TextView
+ android:id="@+id/last_interaction"
+ android:text="@string/empty_status"
+ android:textColor="?android:attr/textColorSecondary"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+ android:textSize="12sp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLines="3"
+ android:ellipsize="end" />
</LinearLayout>
</LinearLayout>
-</LinearLayout>
\ No newline at end of file
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/people_tile_medium_with_content.xml b/packages/SystemUI/res/layout/people_tile_medium_with_content.xml
index c9e4945..7070660 100644
--- a/packages/SystemUI/res/layout/people_tile_medium_with_content.xml
+++ b/packages/SystemUI/res/layout/people_tile_medium_with_content.xml
@@ -97,7 +97,7 @@
android:gravity="bottom"
android:layout_gravity="center_vertical"
android:orientation="horizontal"
- android:paddingTop="4dp"
+ android:paddingTop="2dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToOutline="true">
diff --git a/packages/SystemUI/res/layout/people_tile_small.xml b/packages/SystemUI/res/layout/people_tile_small.xml
index 34aa8e4..7c28fc1 100644
--- a/packages/SystemUI/res/layout/people_tile_small.xml
+++ b/packages/SystemUI/res/layout/people_tile_small.xml
@@ -21,7 +21,7 @@
<LinearLayout
android:id="@+id/item"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
android:layout_gravity="center"
android:background="@drawable/people_space_tile_view_card"
android:orientation="vertical"
@@ -42,12 +42,12 @@
android:tint="?android:attr/colorAccent"
android:layout_gravity="center"
android:layout_width="18dp"
- android:layout_height="22dp"
- android:layout_weight="1" />
+ android:layout_height="22dp" />
<TextView
android:id="@+id/messages_count"
android:layout_gravity="center"
+ android:gravity="center"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
@@ -59,7 +59,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
- android:layout_weight="1"
/>
<TextView
@@ -67,7 +66,6 @@
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:paddingHorizontal="4dp"
diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml
index ae3adb8..4fcce24 100644
--- a/packages/SystemUI/res/layout/remote_input.xml
+++ b/packages/SystemUI/res/layout/remote_input.xml
@@ -31,8 +31,7 @@
android:paddingTop="2dp"
android:paddingStart="16dp"
android:paddingEnd="12dp"
- android:layout_marginRight="20dp"
- android:layout_marginLeft="20dp"
+ android:layout_marginLeft="16dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="16dp"
android:layout_gravity="start|center_vertical"
@@ -52,12 +51,10 @@
android:layout_gravity="center_vertical">
<ImageButton
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:paddingLeft="10dp"
- android:layout_marginBottom="12dp"
- android:layout_marginEnd="12dp"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_gravity="center_horizontal|bottom"
+ android:layout_marginBottom="22dp"
android:id="@+id/remote_input_send"
android:src="@drawable/ic_send"
android:contentDescription="@*android:string/ime_action_send"
@@ -69,8 +66,8 @@
android:id="@+id/remote_input_progress"
android:layout_width="24dp"
android:layout_height="24dp"
- android:layout_marginBottom="12dp"
- android:layout_gravity="center_vertical"
+ android:layout_marginBottom="34dp"
+ android:layout_gravity="center_horizontal|bottom"
android:visibility="invisible"
android:indeterminate="true"
style="?android:attr/progressBarStyleSmall" />
diff --git a/packages/SystemUI/res/layout/rounded_corners.xml b/packages/SystemUI/res/layout/rounded_corners.xml
index db892d7..04fe918 100644
--- a/packages/SystemUI/res/layout/rounded_corners.xml
+++ b/packages/SystemUI/res/layout/rounded_corners.xml
@@ -14,6 +14,8 @@
** See the License for the specific language governing permissions and
** limitations under the License.
-->
+
+<!-- TODO: remove this in favor of requiring top and bottom layouts -->
<com.android.systemui.RegionInterceptingFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rounded_corners_default"
@@ -26,6 +28,25 @@
android:layout_gravity="left|top"
android:tint="#ff000000"
android:src="@drawable/rounded"/>
+
+ <FrameLayout
+ android:id="@+id/privacy_dot_left_container"
+ android:layout_height="@dimen/status_bar_height"
+ android:layout_width="wrap_content"
+ android:layout_marginTop="@dimen/status_bar_padding_top"
+ android:layout_marginLeft="8dp"
+ android:layout_gravity="left|top"
+ android:visibility="invisible" >
+ <ImageView
+ android:id="@+id/privacy_dot_left"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center"
+ android:src="@drawable/system_animation_ongoing_dot"
+ android:visibility="visible" />
+ </FrameLayout>
+
+
<ImageView
android:id="@+id/right"
android:layout_width="12dp"
@@ -33,4 +54,22 @@
android:tint="#ff000000"
android:layout_gravity="right|bottom"
android:src="@drawable/rounded"/>
+ <FrameLayout
+ android:id="@+id/privacy_dot_right_container"
+ android:layout_height="@dimen/status_bar_height"
+ android:layout_width="wrap_content"
+ android:layout_marginTop="@dimen/status_bar_padding_top"
+ android:layout_marginRight="8dp"
+ android:layout_gravity="right|top"
+ android:visibility="invisible" >
+ <ImageView
+ android:id="@+id/privacy_dot_right"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center"
+ android:src="@drawable/system_animation_ongoing_dot"
+ android:visibility="visible" />
+
+ </FrameLayout>
+
</com.android.systemui.RegionInterceptingFrameLayout>
diff --git a/packages/SystemUI/res/layout/rounded_corners_bottom.xml b/packages/SystemUI/res/layout/rounded_corners_bottom.xml
index dde1248..720e47b 100644
--- a/packages/SystemUI/res/layout/rounded_corners_bottom.xml
+++ b/packages/SystemUI/res/layout/rounded_corners_bottom.xml
@@ -26,6 +26,24 @@
android:layout_gravity="left|bottom"
android:tint="#ff000000"
android:src="@drawable/rounded_corner_bottom"/>
+
+ <FrameLayout
+ android:id="@+id/privacy_dot_left_container"
+ android:layout_height="@dimen/status_bar_height"
+ android:layout_width="wrap_content"
+ android:layout_marginTop="@dimen/status_bar_padding_top"
+ android:layout_marginLeft="0dp"
+ android:layout_gravity="left|bottom"
+ android:visibility="invisible" >
+ <ImageView
+ android:id="@+id/privacy_dot"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_vertical|right"
+ android:src="@drawable/system_animation_ongoing_dot"
+ android:visibility="visible" />
+ </FrameLayout>
+
<ImageView
android:id="@+id/right"
android:layout_width="12dp"
@@ -33,4 +51,21 @@
android:tint="#ff000000"
android:layout_gravity="right|bottom"
android:src="@drawable/rounded_corner_bottom"/>
+ <FrameLayout
+ android:id="@+id/privacy_dot_right_container"
+ android:layout_height="@dimen/status_bar_height"
+ android:layout_width="wrap_content"
+ android:layout_marginTop="@dimen/status_bar_padding_top"
+ android:layout_marginRight="0dp"
+ android:layout_gravity="right|bottom"
+ android:visibility="invisible" >
+ <ImageView
+ android:id="@+id/privacy_dot"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_vertical|left"
+ android:src="@drawable/system_animation_ongoing_dot"
+ android:visibility="visible" />
+ </FrameLayout>
+
</com.android.systemui.RegionInterceptingFrameLayout>
diff --git a/packages/SystemUI/res/layout/rounded_corners_top.xml b/packages/SystemUI/res/layout/rounded_corners_top.xml
index 813c97d..6abe406 100644
--- a/packages/SystemUI/res/layout/rounded_corners_top.xml
+++ b/packages/SystemUI/res/layout/rounded_corners_top.xml
@@ -26,6 +26,24 @@
android:layout_gravity="left|top"
android:tint="#ff000000"
android:src="@drawable/rounded_corner_top"/>
+
+ <FrameLayout
+ android:id="@+id/privacy_dot_left_container"
+ android:layout_height="@*android:dimen/status_bar_height_portrait"
+ android:layout_width="wrap_content"
+ android:layout_marginTop="@dimen/status_bar_padding_top"
+ android:layout_marginLeft="0dp"
+ android:layout_gravity="left|top"
+ android:visibility="invisible" >
+ <ImageView
+ android:id="@+id/privacy_dot"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_vertical|right"
+ android:src="@drawable/system_animation_ongoing_dot"
+ android:visibility="visible" />
+ </FrameLayout>
+
<ImageView
android:id="@+id/right"
android:layout_width="12dp"
@@ -33,4 +51,24 @@
android:tint="#ff000000"
android:layout_gravity="right|top"
android:src="@drawable/rounded_corner_top"/>
+
+ <FrameLayout
+ android:id="@+id/privacy_dot_right_container"
+ android:layout_height="@*android:dimen/status_bar_height_portrait"
+ android:layout_width="wrap_content"
+ android:layout_marginTop="@dimen/status_bar_padding_top"
+ android:layout_marginRight="0dp"
+ android:layout_gravity="right|top"
+ android:visibility="invisible" >
+ <ImageView
+ android:id="@+id/privacy_dot"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_vertical|left"
+ android:src="@drawable/system_animation_ongoing_dot"
+ android:visibility="visible" />
+
+ </FrameLayout>
+
+
</com.android.systemui.RegionInterceptingFrameLayout>
diff --git a/packages/SystemUI/res/layout/system_event_animation_window.xml b/packages/SystemUI/res/layout/system_event_animation_window.xml
new file mode 100644
index 0000000..c92dec9
--- /dev/null
+++ b/packages/SystemUI/res/layout/system_event_animation_window.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_vertical|end"
+ android:paddingTop="@dimen/status_bar_padding_top"
+ android:paddingEnd="8dp"
+ >
+
+ <ImageView
+ android:id="@+id/dot_view"
+ android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:layout_gravity="center_vertical|end"
+ android:src="@drawable/system_animation_ongoing_dot"
+ android:visibility="invisible"
+ />
+
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-night/styles.xml b/packages/SystemUI/res/values-night/styles.xml
index cd2395e..fe52dee 100644
--- a/packages/SystemUI/res/values-night/styles.xml
+++ b/packages/SystemUI/res/values-night/styles.xml
@@ -31,6 +31,7 @@
<!-- Screenshots -->
<style name="LongScreenshotActivity" parent="@android:style/Theme.DeviceDefault.DayNight">
+ <item name="android:windowNoTitle">true</item>
<item name="android:windowLightStatusBar">false</item>
<item name="android:windowLightNavigationBar">false</item>
</style>
diff --git a/packages/SystemUI/res/values-pt-ldrtl/strings.xml b/packages/SystemUI/res/values-pt-ldrtl/strings.xml
index 6fd2bc1..53b2473 100644
--- a/packages/SystemUI/res/values-pt-ldrtl/strings.xml
+++ b/packages/SystemUI/res/values-pt-ldrtl/strings.xml
@@ -19,5 +19,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"Arraste para a esquerda para alternar rapidamente entre os apps"</string>
+ <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"Arraste para a esquerda para mudar rapidamente de app"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR-ldrtl/strings.xml b/packages/SystemUI/res/values-pt-rBR-ldrtl/strings.xml
index 6fd2bc1..53b2473 100644
--- a/packages/SystemUI/res/values-pt-rBR-ldrtl/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR-ldrtl/strings.xml
@@ -19,5 +19,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"Arraste para a esquerda para alternar rapidamente entre os apps"</string>
+ <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"Arraste para a esquerda para mudar rapidamente de app"</string>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 62ac75e..210efd8 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -871,7 +871,9 @@
<dimen name="keyguard_affordance_width">48dp</dimen>
<dimen name="keyguard_affordance_horizontal_offset">32dp</dimen>
<dimen name="keyguard_affordance_vertical_offset">32dp</dimen>
-
+ <!-- Value should be at least sum of 'keyguard_affordance_width' +
+ 'keyguard_affordance_horizontal_offset' -->
+ <dimen name="keyguard_indication_area_padding">82dp</dimen>
<!-- The width/height of the unlock icon view on keyguard. -->
<dimen name="keyguard_lock_height">42dp</dimen>
@@ -1397,6 +1399,7 @@
<dimen name="max_people_avatar_size_for_large_content">64dp</dimen>
<dimen name="max_people_avatar_size">108dp</dimen>
<dimen name="name_text_size_for_small">14sp</dimen>
+ <dimen name="name_text_size_for_medium">14sp</dimen>
<dimen name="name_text_size_for_large">24sp</dimen>
<dimen name="content_text_size_for_medium">12sp</dimen>
<dimen name="content_text_size_for_large">14sp</dimen>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index f89e365..e7418e6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -23,8 +23,6 @@
import android.app.smartspace.SmartspaceConfig;
import android.app.smartspace.SmartspaceManager;
import android.app.smartspace.SmartspaceSession;
-import android.content.ContentResolver;
-import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.text.TextUtils;
@@ -39,14 +37,13 @@
import com.android.keyguard.clock.ClockManager;
import com.android.settingslib.Utils;
import com.android.systemui.R;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.BcSmartspaceDataPlugin;
import com.android.systemui.plugins.ClockPlugin;
-import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
@@ -69,14 +66,16 @@
public class KeyguardClockSwitchController extends ViewController<KeyguardClockSwitch> {
private static final boolean CUSTOM_CLOCKS_ENABLED = true;
- private final Resources mResources;
private final StatusBarStateController mStatusBarStateController;
private final SysuiColorExtractor mColorExtractor;
private final ClockManager mClockManager;
private final KeyguardSliceViewController mKeyguardSliceViewController;
private final NotificationIconAreaController mNotificationIconAreaController;
private final BroadcastDispatcher mBroadcastDispatcher;
+ private final Executor mUiExecutor;
private final BatteryController mBatteryController;
+ private final FeatureFlags mFeatureFlags;
+ private final SystemUIFactory mSystemUIFactory;
/**
* Clock for both small and large sizes
@@ -86,10 +85,6 @@
private AnimatableClockController mLargeClockViewController;
private FrameLayout mLargeClockFrame;
- private PluginManager mPluginManager;
- private boolean mIsSmartspaceEnabled;
- PluginListener mPluginListener;
- private Executor mUiExecutor;
private SmartspaceSession mSmartspaceSession;
private SmartspaceSession.Callback mSmartspaceCallback;
private float mDozeAmount;
@@ -137,31 +132,28 @@
@Inject
public KeyguardClockSwitchController(
KeyguardClockSwitch keyguardClockSwitch,
- @Main Resources resources,
StatusBarStateController statusBarStateController,
SysuiColorExtractor colorExtractor, ClockManager clockManager,
KeyguardSliceViewController keyguardSliceViewController,
NotificationIconAreaController notificationIconAreaController,
- ContentResolver contentResolver,
BroadcastDispatcher broadcastDispatcher,
- PluginManager pluginManager,
FeatureFlags featureFlags,
@Main Executor uiExecutor,
BatteryController batteryController,
- ConfigurationController configurationController) {
+ ConfigurationController configurationController,
+ SystemUIFactory systemUIFactory) {
super(keyguardClockSwitch);
- mResources = resources;
mStatusBarStateController = statusBarStateController;
mColorExtractor = colorExtractor;
mClockManager = clockManager;
mKeyguardSliceViewController = keyguardSliceViewController;
mNotificationIconAreaController = notificationIconAreaController;
mBroadcastDispatcher = broadcastDispatcher;
- mPluginManager = pluginManager;
- mIsSmartspaceEnabled = featureFlags.isSmartspaceEnabled();
+ mFeatureFlags = featureFlags;
mUiExecutor = uiExecutor;
mBatteryController = batteryController;
mConfigurationController = configurationController;
+ mSystemUIFactory = systemUIFactory;
}
/**
@@ -206,75 +198,45 @@
mStatusBarStateController.addCallback(mStatusBarStateListener);
mConfigurationController.addCallback(mConfigurationListener);
- // If a smartspace plugin is detected, replace the existing smartspace
- // (keyguard_status_area), and initialize a new session
- mPluginListener = new PluginListener<BcSmartspaceDataPlugin>() {
+ BcSmartspaceDataPlugin smartspaceDataPlugin = mSystemUIFactory.getSmartspaceDataProvider();
+ if (mFeatureFlags.isSmartspaceEnabled() && smartspaceDataPlugin != null) {
+ View ksa = mView.findViewById(R.id.keyguard_status_area);
+ int ksaIndex = mView.indexOfChild(ksa);
+ ksa.setVisibility(View.GONE);
- @Override
- public void onPluginConnected(BcSmartspaceDataPlugin plugin, Context pluginContext) {
- if (!mIsSmartspaceEnabled) return;
+ mSmartspaceView = smartspaceDataPlugin.getView(mView);
+ mSmartspaceView.registerDataProvider(smartspaceDataPlugin);
+ updateSmartspaceColor();
+ View asView = (View) mSmartspaceView;
- View ksa = mView.findViewById(R.id.keyguard_status_area);
- int ksaIndex = mView.indexOfChild(ksa);
- ksa.setVisibility(View.GONE);
+ // Place smartspace view below normal clock...
+ RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
+ MATCH_PARENT, WRAP_CONTENT);
+ lp.addRule(RelativeLayout.BELOW, R.id.lockscreen_clock_view);
- mSmartspaceView = plugin.getView(mView);
- mSmartspaceView.registerDataProvider(plugin);
- updateSmartspaceColor();
- View asView = (View) mSmartspaceView;
+ mView.addView(asView, ksaIndex, lp);
+ int padding = getContext().getResources()
+ .getDimensionPixelSize(R.dimen.below_clock_padding_start);
+ asView.setPadding(padding, 0, padding, 0);
- // Place plugin view below normal clock...
- RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
- MATCH_PARENT, WRAP_CONTENT);
- lp.addRule(RelativeLayout.BELOW, R.id.lockscreen_clock_view);
+ // ... but above the large clock
+ lp = new RelativeLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
+ lp.addRule(RelativeLayout.BELOW, asView.getId());
+ mLargeClockFrame.setLayoutParams(lp);
- mView.addView(asView, ksaIndex, lp);
- int padding = getContext().getResources()
- .getDimensionPixelSize(R.dimen.below_clock_padding_start);
- asView.setPadding(padding, 0, padding, 0);
+ View nic = mView.findViewById(
+ R.id.left_aligned_notification_icon_container);
+ lp = (RelativeLayout.LayoutParams) nic.getLayoutParams();
+ lp.addRule(RelativeLayout.BELOW, asView.getId());
+ nic.setLayoutParams(lp);
- // ... but above the large clock
- lp = new RelativeLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT);
- lp.addRule(RelativeLayout.BELOW, asView.getId());
- mLargeClockFrame.setLayoutParams(lp);
-
- View nic = mView.findViewById(
- com.android.systemui.R.id.left_aligned_notification_icon_container);
- lp = (RelativeLayout.LayoutParams) nic.getLayoutParams();
- lp.addRule(RelativeLayout.BELOW, asView.getId());
- nic.setLayoutParams(lp);
-
- createSmartspaceSession(plugin);
- }
-
- @Override
- public void onPluginDisconnected(BcSmartspaceDataPlugin plugin) {
- if (!mIsSmartspaceEnabled) return;
-
- mView.removeView((View) mSmartspaceView);
- mView.findViewById(R.id.keyguard_status_area).setVisibility(View.VISIBLE);
-
- View nic = mView.findViewById(
- com.android.systemui.R.id.left_aligned_notification_icon_container);
- RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)
- nic.getLayoutParams();
- lp.addRule(RelativeLayout.BELOW, R.id.keyguard_status_area);
- nic.setLayoutParams(lp);
- mLargeClockFrame.setLayoutParams(lp);
-
- mSmartspaceView = null;
- }
-
- private void createSmartspaceSession(BcSmartspaceDataPlugin plugin) {
- mSmartspaceSession = getContext().getSystemService(SmartspaceManager.class)
- .createSmartspaceSession(
- new SmartspaceConfig.Builder(getContext(), "lockscreen").build());
- mSmartspaceCallback = targets -> plugin.onTargetsAvailable(targets);
- mSmartspaceSession.registerSmartspaceUpdates(mUiExecutor, mSmartspaceCallback);
- mSmartspaceSession.requestSmartspaceUpdate();
- }
- };
- mPluginManager.addPluginListener(mPluginListener, BcSmartspaceDataPlugin.class, false);
+ mSmartspaceSession = getContext().getSystemService(SmartspaceManager.class)
+ .createSmartspaceSession(
+ new SmartspaceConfig.Builder(getContext(), "lockscreen").build());
+ mSmartspaceCallback = targets -> smartspaceDataPlugin.onTargetsAvailable(targets);
+ mSmartspaceSession.registerSmartspaceUpdates(mUiExecutor, mSmartspaceCallback);
+ mSmartspaceSession.requestSmartspaceUpdate();
+ }
}
private void updateWallpaperColor() {
@@ -303,7 +265,6 @@
mSmartspaceSession.destroy();
mSmartspaceSession = null;
}
- mPluginManager.removePluginListener(mPluginListener);
mStatusBarStateController.removeCallback(mStatusBarStateListener);
mConfigurationController.removeCallback(mConfigurationListener);
}
diff --git a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
index 983b1bb..62d5a45 100644
--- a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
@@ -91,6 +91,13 @@
}
@Override
+ public void startActivity(Intent intent, boolean dismissShade,
+ @Nullable ActivityLaunchAnimator.Controller animationController) {
+ mActualStarter.ifPresent(
+ starter -> starter.get().startActivity(intent, dismissShade, animationController));
+ }
+
+ @Override
public void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade) {
mActualStarter.ifPresent(
starter -> starter.get().startActivity(intent, onlyProvisioned, dismissShade));
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index a686fc0..cbfdce5 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -79,6 +79,8 @@
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.VibratorHelper;
+import com.android.systemui.statusbar.events.PrivacyDotViewController;
+import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager.KeyguardEnvironment;
import com.android.systemui.statusbar.notification.NotificationFilter;
@@ -352,6 +354,8 @@
@Inject Lazy<DeviceConfigProxy> mDeviceConfigProxy;
@Inject Lazy<NavigationBarOverlayController> mNavbarButtonsControllerLazy;
@Inject Lazy<TelephonyListenerManager> mTelephonyListenerManager;
+ @Inject Lazy<SystemStatusAnimationScheduler> mSystemStatusAnimationSchedulerLazy;
+ @Inject Lazy<PrivacyDotViewController> mPrivacyDotViewControllerLazy;
@Inject
public Dependency() {
@@ -561,6 +565,10 @@
mProviders.put(NavigationBarOverlayController.class, mNavbarButtonsControllerLazy::get);
+ mProviders.put(SystemStatusAnimationScheduler.class,
+ mSystemStatusAnimationSchedulerLazy::get);
+ mProviders.put(PrivacyDotViewController.class, mPrivacyDotViewControllerLazy::get);
+
Dependency.setInstance(this);
}
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 5fa98bc..d07723e 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -88,6 +88,7 @@
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.qs.SecureSetting;
import com.android.systemui.settings.UserTracker;
+import com.android.systemui.statusbar.events.PrivacyDotViewController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import com.android.systemui.util.settings.SecureSettings;
@@ -126,6 +127,7 @@
private DisplayManager.DisplayListener mDisplayListener;
private CameraAvailabilityListener mCameraListener;
private final UserTracker mUserTracker;
+ private final PrivacyDotViewController mDotViewController;
//TODO: These are piecemeal being updated to Points for now to support non-square rounded
// corners. for now it is only supposed when reading the intrinsic size from the drawables with
@@ -140,6 +142,11 @@
protected View[] mOverlays;
@Nullable
private DisplayCutoutView[] mCutoutViews;
+ //TODO:
+ View mTopLeftDot;
+ View mTopRightDot;
+ View mBottomLeftDot;
+ View mBottomRightDot;
private float mDensity;
private WindowManager mWindowManager;
private int mRotation;
@@ -147,6 +154,8 @@
private Handler mHandler;
private boolean mPendingRotationChange;
private boolean mIsRoundedCornerMultipleRadius;
+ private int mStatusBarHeightPortrait;
+ private int mStatusBarHeightLandscape;
private CameraAvailabilityListener.CameraTransitionCallback mCameraTransitionCallback =
new CameraAvailabilityListener.CameraTransitionCallback() {
@@ -205,13 +214,15 @@
SecureSettings secureSettings,
BroadcastDispatcher broadcastDispatcher,
TunerService tunerService,
- UserTracker userTracker) {
+ UserTracker userTracker,
+ PrivacyDotViewController dotViewController) {
super(context);
mMainHandler = handler;
mSecureSettings = secureSettings;
mBroadcastDispatcher = broadcastDispatcher;
mTunerService = tunerService;
mUserTracker = userTracker;
+ mDotViewController = dotViewController;
}
@Override
@@ -222,6 +233,7 @@
}
mHandler = startHandlerThread();
mHandler.post(this::startOnScreenDecorationsThread);
+ mDotViewController.setUiExecutor(mHandler::post);
}
@VisibleForTesting
@@ -286,6 +298,7 @@
private void setupDecorations() {
if (hasRoundedCorners() || shouldDrawCutout()) {
+ updateStatusBarHeight();
final DisplayCutout cutout = getCutout();
final Rect[] bounds = cutout == null ? null : cutout.getBoundingRectsAll();
int rotatedPos;
@@ -298,6 +311,10 @@
removeOverlay(i);
}
}
+ // Overlays have been created, send the dots to the controller
+ //TODO: need a better way to do this
+ mDotViewController.initialize(
+ mTopLeftDot, mTopRightDot, mBottomLeftDot, mBottomRightDot);
} else {
removeAllOverlays();
}
@@ -431,14 +448,21 @@
private View overlayForPosition(@BoundsPosition int pos) {
switch (pos) {
case BOUNDS_POSITION_TOP:
- return LayoutInflater.from(mContext)
+ case BOUNDS_POSITION_LEFT:
+ View top = LayoutInflater.from(mContext)
.inflate(R.layout.rounded_corners_top, null);
+ mTopLeftDot = top.findViewById(R.id.privacy_dot_left_container);
+ mTopRightDot = top.findViewById(R.id.privacy_dot_right_container);
+ return top;
case BOUNDS_POSITION_BOTTOM:
- return LayoutInflater.from(mContext)
+ case BOUNDS_POSITION_RIGHT:
+ View bottom = LayoutInflater.from(mContext)
.inflate(R.layout.rounded_corners_bottom, null);
+ mBottomLeftDot = bottom.findViewById(R.id.privacy_dot_left_container);
+ mBottomRightDot = bottom.findViewById(R.id.privacy_dot_right_container);
+ return bottom;
default:
- return LayoutInflater.from(mContext)
- .inflate(R.layout.rounded_corners, null);
+ throw new IllegalArgumentException("Unknown bounds position");
}
}
@@ -575,6 +599,11 @@
View child;
for (int j = 0; j < size; j++) {
child = ((ViewGroup) mOverlays[i]).getChildAt(j);
+ if (child.getId() == R.id.privacy_dot_left_container
+ || child.getId() == R.id.privacy_dot_right_container) {
+ // Exclude privacy dot from color inversion (for now?)
+ continue;
+ }
if (child instanceof ImageView) {
((ImageView) child).setImageTintList(tintList);
} else if (child instanceof DisplayCutoutView) {
@@ -611,10 +640,15 @@
Preconditions.checkState(mHandler.getLooper().getThread() == Thread.currentThread(),
"must call on " + mHandler.getLooper().getThread()
+ ", but was " + Thread.currentThread());
+
+ int newRotation = mContext.getDisplay().getRotation();
+ if (mRotation != newRotation) {
+ mDotViewController.updateRotation(newRotation);
+ }
+
if (mPendingRotationChange) {
return;
}
- int newRotation = mContext.getDisplay().getRotation();
if (newRotation != mRotation) {
mRotation = newRotation;
@@ -630,6 +664,14 @@
}
}
+ private void updateStatusBarHeight() {
+ mStatusBarHeightLandscape = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height_landscape);
+ mStatusBarHeightPortrait = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height_portrait);
+ mDotViewController.setStatusBarHeights(mStatusBarHeightPortrait, mStatusBarHeightLandscape);
+ }
+
private void updateRoundedCornerRadii() {
// We should eventually move to just using the intrinsic size of the drawables since
// they should be sized to the exact pixels they want to cover. Therefore I'm purposely not
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index cc167b9..af064e1 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -29,6 +29,7 @@
import com.android.systemui.dagger.SysUIComponent;
import com.android.systemui.dagger.WMComponent;
import com.android.systemui.navigationbar.gestural.BackGestureTfClassifierProvider;
+import com.android.systemui.plugins.BcSmartspaceDataPlugin;
import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider;
import com.android.wm.shell.transition.Transitions;
@@ -209,4 +210,8 @@
AssetManager am, String modelName) {
return new BackGestureTfClassifierProvider();
}
+
+ public BcSmartspaceDataPlugin getSmartspaceDataProvider() {
+ return null;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsController.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsController.java
index 2661d89..b544599 100644
--- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsController.java
@@ -60,17 +60,31 @@
/**
* Returns a copy of the list containing all the active AppOps that the controller tracks.
*
- * @return List of active AppOps information
+ * @return List of active AppOps information, without paused elements.
*/
List<AppOpItem> getActiveAppOps();
/**
+ * Returns a copy of the list containing all the active AppOps that the controller tracks.
+ *
+ * @param showPaused {@code true} to also obtain paused items. {@code false} otherwise.
+ * @return List of active AppOps information
+ */
+ List<AppOpItem> getActiveAppOps(boolean showPaused);
+
+ /**
* Returns a copy of the list containing all the active AppOps that the controller tracks, for
* a given user id.
*
* @param userId User id to track
+ * @param showPaused {@code true} to also obtain paused items. {@code false} otherwise.
*
* @return List of active AppOps information for that user id
*/
- List<AppOpItem> getActiveAppOpsForUser(int userId);
+ List<AppOpItem> getActiveAppOpsForUser(int userId, boolean showPaused);
+
+ /**
+ * @return whether this controller is considering the microphone as muted.
+ */
+ boolean isMicMuted();
}
diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
index 994401d..534f93e 100644
--- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
@@ -241,9 +241,9 @@
AppOpItem item = getAppOpItemLocked(mActiveItems, code, uid, packageName);
if (item == null && active) {
item = new AppOpItem(code, uid, packageName, mClock.elapsedRealtime());
- if (code == AppOpsManager.OP_RECORD_AUDIO) {
+ if (isOpMicrophone(code)) {
item.setDisabled(isAnyRecordingPausedLocked(uid));
- } else if (code == AppOpsManager.OP_CAMERA) {
+ } else if (isOpCamera(code)) {
item.setDisabled(mCameraDisabled);
}
mActiveItems.add(item);
@@ -298,6 +298,11 @@
return PermissionManager.shouldShowPackageForIndicatorCached(mContext, packageName);
}
+ @WorkerThread
+ public List<AppOpItem> getActiveAppOps() {
+ return getActiveAppOps(false);
+ }
+
/**
* Returns a copy of the list containing all the active AppOps that the controller tracks.
*
@@ -306,8 +311,8 @@
* @return List of active AppOps information
*/
@WorkerThread
- public List<AppOpItem> getActiveAppOps() {
- return getActiveAppOpsForUser(UserHandle.USER_ALL);
+ public List<AppOpItem> getActiveAppOps(boolean showPaused) {
+ return getActiveAppOpsForUser(UserHandle.USER_ALL, showPaused);
}
/**
@@ -321,7 +326,7 @@
* @return List of active AppOps information for that user id
*/
@WorkerThread
- public List<AppOpItem> getActiveAppOpsForUser(int userId) {
+ public List<AppOpItem> getActiveAppOpsForUser(int userId, boolean showPaused) {
Assert.isNotMainThread();
List<AppOpItem> list = new ArrayList<>();
synchronized (mActiveItems) {
@@ -330,7 +335,8 @@
AppOpItem item = mActiveItems.get(i);
if ((userId == UserHandle.USER_ALL
|| UserHandle.getUserId(item.getUid()) == userId)
- && isUserVisible(item.getPackageName()) && !item.isDisabled()) {
+ && isUserVisible(item.getPackageName())
+ && (showPaused || !item.isDisabled())) {
list.add(item);
}
}
@@ -441,9 +447,9 @@
AppOpItem item = mActiveItems.get(i);
boolean paused = false;
- if (item.getCode() == AppOpsManager.OP_RECORD_AUDIO) {
+ if (isOpMicrophone(item.getCode())) {
paused = isAnyRecordingPausedLocked(item.getUid());
- } else if (item.getCode() == AppOpsManager.OP_CAMERA) {
+ } else if (isOpCamera(item.getCode())) {
paused = mCameraDisabled;
}
@@ -502,6 +508,19 @@
});
}
+ @Override
+ public boolean isMicMuted() {
+ return mMicMuted;
+ }
+
+ private boolean isOpCamera(int op) {
+ return op == AppOpsManager.OP_CAMERA || op == AppOpsManager.OP_PHONE_CALL_CAMERA;
+ }
+
+ private boolean isOpMicrophone(int op) {
+ return op == AppOpsManager.OP_RECORD_AUDIO || op == AppOpsManager.OP_PHONE_CALL_MICROPHONE;
+ }
+
protected class H extends Handler {
H(Looper looper) {
super(looper);
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java b/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java
index 6a012eb..6f70672 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java
@@ -42,6 +42,7 @@
public static final int QS_COLLAPSE = 12;
public static final int UDFPS_AUTHENTICATION = 13;
public static final int DISABLED_UDFPS_AFFORDANCE = 14;
+ public static final int QS_SWIPE = 15;
@IntDef({
QUICK_SETTINGS,
@@ -59,7 +60,8 @@
QS_COLLAPSE,
BRIGHTNESS_SLIDER,
UDFPS_AUTHENTICATION,
- DISABLED_UDFPS_AFFORDANCE
+ DISABLED_UDFPS_AFFORDANCE,
+ QS_SWIPE
})
@Retention(RetentionPolicy.SOURCE)
public @interface InteractionType {}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java
index a4e1637..2298010 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/DistanceClassifier.java
@@ -155,7 +155,8 @@
|| interactionType == SHADE_DRAG
|| interactionType == QS_COLLAPSE
|| interactionType == Classifier.UDFPS_AUTHENTICATION
- || interactionType == Classifier.DISABLED_UDFPS_AFFORDANCE) {
+ || interactionType == Classifier.DISABLED_UDFPS_AFFORDANCE
+ || interactionType == Classifier.QS_SWIPE) {
return Result.passed(0);
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java
index 3bc24c7..72d4303 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java
@@ -19,6 +19,7 @@
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD;
import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
import static com.android.systemui.classifier.Classifier.QS_COLLAPSE;
+import static com.android.systemui.classifier.Classifier.QS_SWIPE;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import android.provider.DeviceConfig;
@@ -118,7 +119,7 @@
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
if (interactionType == QUICK_SETTINGS || interactionType == BRIGHTNESS_SLIDER
- || interactionType == QS_COLLAPSE) {
+ || interactionType == QS_COLLAPSE || interactionType == QS_SWIPE) {
return Result.passed(0);
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java
index 1042516..c2ad7e6 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/TypeClassifier.java
@@ -24,6 +24,7 @@
import static com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN;
import static com.android.systemui.classifier.Classifier.PULSE_EXPAND;
import static com.android.systemui.classifier.Classifier.QS_COLLAPSE;
+import static com.android.systemui.classifier.Classifier.QS_SWIPE;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE;
import static com.android.systemui.classifier.Classifier.SHADE_DRAG;
@@ -85,6 +86,9 @@
case QS_COLLAPSE:
wrongDirection = !vertical || !up;
break;
+ case QS_SWIPE:
+ wrongDirection = vertical;
+ break;
default:
wrongDirection = true;
break;
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 365a102..126724c 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -26,6 +26,7 @@
import com.android.keyguard.dagger.KeyguardBouncerComponent;
import com.android.systemui.BootCompleteCache;
import com.android.systemui.BootCompleteCacheImpl;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.appops.dagger.AppOpsModule;
import com.android.systemui.assist.AssistModule;
import com.android.systemui.classifier.FalsingModule;
@@ -159,6 +160,11 @@
@Binds
abstract SystemClock bindSystemClock(SystemClockImpl systemClock);
+ @Provides
+ static SystemUIFactory getSystemUIFactory() {
+ return SystemUIFactory.getInstance();
+ }
+
// TODO: This should provided by the WM component
/** Provides Optional of BubbleManager */
@SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
index de00d50..2e03d9a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
@@ -17,10 +17,20 @@
package com.android.systemui.keyguard;
import android.annotation.IntDef;
+import android.app.IWallpaperManager;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Point;
+import android.os.Bundle;
import android.os.PowerManager;
+import android.os.RemoteException;
import android.os.Trace;
+import android.util.DisplayMetrics;
+
+import androidx.annotation.Nullable;
import com.android.systemui.Dumpable;
+import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import java.io.FileDescriptor;
@@ -31,7 +41,7 @@
import javax.inject.Inject;
/**
- * Tracks the wakefulness lifecycle.
+ * Tracks the wakefulness lifecycle, including why we're waking or sleeping.
*/
@SysUISingleton
public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observer> implements
@@ -51,13 +61,32 @@
public static final int WAKEFULNESS_AWAKE = 2;
public static final int WAKEFULNESS_GOING_TO_SLEEP = 3;
+ private final Context mContext;
+ private final DisplayMetrics mDisplayMetrics;
+
+ @Nullable
+ private final IWallpaperManager mWallpaperManagerService;
+
private int mWakefulness = WAKEFULNESS_ASLEEP;
+
private @PowerManager.WakeReason int mLastWakeReason = PowerManager.WAKE_REASON_UNKNOWN;
+
+ @Nullable
+ private Point mLastWakeOriginLocation = null;
+
private @PowerManager.GoToSleepReason int mLastSleepReason =
PowerManager.GO_TO_SLEEP_REASON_MIN;
+ @Nullable
+ private Point mLastSleepOriginLocation = null;
+
@Inject
- public WakefulnessLifecycle() {
+ public WakefulnessLifecycle(
+ Context context,
+ @Nullable IWallpaperManager wallpaperManagerService) {
+ mContext = context;
+ mDisplayMetrics = context.getResources().getDisplayMetrics();
+ mWallpaperManagerService = wallpaperManagerService;
}
public @Wakefulness int getWakefulness() {
@@ -85,6 +114,17 @@
}
setWakefulness(WAKEFULNESS_WAKING);
mLastWakeReason = pmWakeReason;
+ updateLastWakeOriginLocation();
+
+ if (mWallpaperManagerService != null) {
+ try {
+ mWallpaperManagerService.notifyWakingUp(
+ mLastWakeOriginLocation.x, mLastWakeOriginLocation.y, new Bundle());
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
dispatch(Observer::onStartedWakingUp);
}
@@ -102,6 +142,17 @@
}
setWakefulness(WAKEFULNESS_GOING_TO_SLEEP);
mLastSleepReason = pmSleepReason;
+ updateLastSleepOriginLocation();
+
+ if (mWallpaperManagerService != null) {
+ try {
+ mWallpaperManagerService.notifyGoingToSleep(
+ mLastSleepOriginLocation.x, mLastSleepOriginLocation.y, new Bundle());
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
dispatch(Observer::onStartedGoingToSleep);
}
@@ -124,6 +175,60 @@
Trace.traceCounter(Trace.TRACE_TAG_APP, "wakefulness", wakefulness);
}
+ private void updateLastWakeOriginLocation() {
+ mLastWakeOriginLocation = null;
+
+ switch (mLastWakeReason) {
+ case PowerManager.WAKE_REASON_POWER_BUTTON:
+ mLastWakeOriginLocation = getPowerButtonOrigin();
+ break;
+ default:
+ mLastWakeOriginLocation = getDefaultWakeSleepOrigin();
+ break;
+ }
+ }
+
+ private void updateLastSleepOriginLocation() {
+ mLastSleepOriginLocation = null;
+
+ switch (mLastSleepReason) {
+ case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON:
+ mLastSleepOriginLocation = getPowerButtonOrigin();
+ break;
+ default:
+ mLastSleepOriginLocation = getDefaultWakeSleepOrigin();
+ break;
+ }
+ }
+
+ /**
+ * Returns the point on the screen closest to the physical power button.
+ */
+ private Point getPowerButtonOrigin() {
+ final boolean isPortrait = mContext.getResources().getConfiguration().orientation
+ == Configuration.ORIENTATION_PORTRAIT;
+
+ if (isPortrait) {
+ return new Point(
+ mDisplayMetrics.widthPixels,
+ mContext.getResources().getDimensionPixelSize(
+ R.dimen.physical_power_button_center_screen_location_y));
+ } else {
+ return new Point(
+ mContext.getResources().getDimensionPixelSize(
+ R.dimen.physical_power_button_center_screen_location_y),
+ mDisplayMetrics.heightPixels);
+ }
+ }
+
+ /**
+ * Returns the point on the screen used as the default origin for wake/sleep events. This is the
+ * middle-bottom of the screen.
+ */
+ private Point getDefaultWakeSleepOrigin() {
+ return new Point(mDisplayMetrics.widthPixels / 2, mDisplayMetrics.heightPixels);
+ }
+
public interface Observer {
default void onStartedWakingUp() {}
default void onFinishedWakingUp() {}
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java b/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java
index 59329d1..41957bc 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java
@@ -93,7 +93,7 @@
: Dependency.get(NotificationEntryManager.class);
RemoteViews view = PeopleSpaceUtils.getPreview(getContext(), mPeopleManager, mLauncherApps,
- mNotificationEntryManager, shortcutId, userHandle, packageName);
+ mNotificationEntryManager, shortcutId, userHandle, packageName, extras);
if (view == null) {
if (DEBUG) Log.d(TAG, "No preview available for shortcutId: " + shortcutId);
return null;
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
index a0b5521..38a6186 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
@@ -23,18 +23,14 @@
import static com.android.systemui.people.PeopleTileViewHelper.getSizeInDp;
import android.app.Activity;
-import android.app.INotificationManager;
-import android.app.people.IPeopleManager;
import android.app.people.PeopleSpaceTile;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.LauncherApps;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
-import android.os.ServiceManager;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@@ -43,7 +39,6 @@
import com.android.systemui.R;
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
import java.util.ArrayList;
import java.util.List;
@@ -56,19 +51,13 @@
private static final String TAG = "PeopleSpaceActivity";
private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
- private IPeopleManager mPeopleManager;
private PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
- private INotificationManager mNotificationManager;
- private LauncherApps mLauncherApps;
private Context mContext;
- private NotificationEntryManager mNotificationEntryManager;
private int mAppWidgetId;
@Inject
- public PeopleSpaceActivity(NotificationEntryManager notificationEntryManager,
- PeopleSpaceWidgetManager peopleSpaceWidgetManager) {
+ public PeopleSpaceActivity(PeopleSpaceWidgetManager peopleSpaceWidgetManager) {
super();
- mNotificationEntryManager = notificationEntryManager;
mPeopleSpaceWidgetManager = peopleSpaceWidgetManager;
}
@@ -77,11 +66,6 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getApplicationContext();
- mNotificationManager = INotificationManager.Stub.asInterface(
- ServiceManager.getService(Context.NOTIFICATION_SERVICE));
- mPeopleManager = IPeopleManager.Stub.asInterface(
- ServiceManager.getService(Context.PEOPLE_SERVICE));
- mLauncherApps = mContext.getSystemService(LauncherApps.class);
mAppWidgetId = getIntent().getIntExtra(EXTRA_APPWIDGET_ID,
INVALID_APPWIDGET_ID);
setResult(RESULT_CANCELED);
@@ -92,10 +76,8 @@
List<PeopleSpaceTile> priorityTiles = new ArrayList<>();
List<PeopleSpaceTile> recentTiles = new ArrayList<>();
try {
- priorityTiles = PeopleSpaceUtils.getPriorityTiles(mContext, mNotificationManager,
- mPeopleManager, mLauncherApps, mNotificationEntryManager);
- recentTiles = PeopleSpaceUtils.getRecentTiles(mContext, mNotificationManager,
- mPeopleManager, mLauncherApps, mNotificationEntryManager);
+ priorityTiles = mPeopleSpaceWidgetManager.getPriorityTiles();
+ recentTiles = mPeopleSpaceWidgetManager.getRecentTiles();
} catch (Exception e) {
Log.e(TAG, "Couldn't retrieve conversations", e);
}
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
index 0fbe1f7..c0a16e1 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
@@ -19,8 +19,6 @@
import static android.app.Notification.CATEGORY_MISSED_CALL;
import static android.app.Notification.EXTRA_MESSAGES;
-import android.annotation.NonNull;
-import android.app.INotificationManager;
import android.app.Notification;
import android.app.people.ConversationChannel;
import android.app.people.IPeopleManager;
@@ -36,16 +34,13 @@
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.icu.text.MeasureFormat;
-import android.icu.util.Measure;
-import android.icu.util.MeasureUnit;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.ContactsContract;
-import android.service.notification.ConversationChannelWrapper;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.Log;
@@ -65,7 +60,6 @@
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import java.text.SimpleDateFormat;
-import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -73,7 +67,6 @@
import java.util.Date;
import java.util.HashSet;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -85,9 +78,6 @@
/** Turns on debugging information about People Space. */
public static final boolean DEBUG = true;
private static final String TAG = "PeopleSpaceUtils";
- private static final int DAYS_IN_A_WEEK = 7;
- private static final int MIN_HOUR = 1;
- private static final int ONE_DAY = 1;
public static final String PACKAGE_NAME = "package_name";
public static final String USER_ID = "user_id";
public static final String SHORTCUT_ID = "shortcut_id";
@@ -127,58 +117,6 @@
}
}
- /** Returns a list of map entries corresponding to user's priority conversations. */
- @NonNull
- public static List<PeopleSpaceTile> getPriorityTiles(
- Context context, INotificationManager notificationManager, IPeopleManager peopleManager,
- LauncherApps launcherApps, NotificationEntryManager notificationEntryManager)
- throws Exception {
- List<ConversationChannelWrapper> conversations =
- notificationManager.getConversations(
- false).getList();
- // Add priority conversations to tiles list.
- Stream<ShortcutInfo> priorityConversations = conversations.stream()
- .filter(c -> c.getNotificationChannel() != null
- && c.getNotificationChannel().isImportantConversation())
- .map(c -> c.getShortcutInfo());
- List<PeopleSpaceTile> priorityTiles = getSortedTiles(peopleManager, launcherApps,
- priorityConversations);
- priorityTiles = augmentTilesFromVisibleNotifications(
- context, priorityTiles, notificationEntryManager);
- return priorityTiles;
- }
-
- /** Returns a list of map entries corresponding to user's recent conversations. */
- @NonNull
- public static List<PeopleSpaceTile> getRecentTiles(
- Context context, INotificationManager notificationManager, IPeopleManager peopleManager,
- LauncherApps launcherApps, NotificationEntryManager notificationEntryManager)
- throws Exception {
- if (DEBUG) Log.d(TAG, "Add recent conversations");
- List<ConversationChannelWrapper> conversations =
- notificationManager.getConversations(
- false).getList();
- Stream<ShortcutInfo> nonPriorityConversations = conversations.stream()
- .filter(c -> c.getNotificationChannel() == null
- || !c.getNotificationChannel().isImportantConversation())
- .map(c -> c.getShortcutInfo());
-
- List<ConversationChannel> recentConversationsList =
- peopleManager.getRecentConversations().getList();
- Stream<ShortcutInfo> recentConversations = recentConversationsList
- .stream()
- .map(c -> c.getShortcutInfo());
-
- Stream<ShortcutInfo> mergedStream = Stream.concat(nonPriorityConversations,
- recentConversations);
- List<PeopleSpaceTile> recentTiles =
- getSortedTiles(peopleManager, launcherApps, mergedStream);
-
- recentTiles = augmentTilesFromVisibleNotifications(
- context, recentTiles, notificationEntryManager);
- return recentTiles;
- }
-
/** Returns stored widgets for the conversation specified. */
public static Set<String> getStoredWidgetIds(SharedPreferences sp, PeopleTileKey key) {
if (!key.isValid()) {
@@ -255,7 +193,8 @@
return augmentedTile.get(0);
}
- static List<PeopleSpaceTile> augmentTilesFromVisibleNotifications(Context context,
+ /** Adds to {@code tiles} any visible notifications. */
+ public static List<PeopleSpaceTile> augmentTilesFromVisibleNotifications(Context context,
List<PeopleSpaceTile> tiles, NotificationEntryManager notificationEntryManager) {
if (notificationEntryManager == null) {
Log.w(TAG, "NotificationEntryManager is null");
@@ -356,11 +295,12 @@
}
/** Returns a list sorted by ascending last interaction time from {@code stream}. */
- private static List<PeopleSpaceTile> getSortedTiles(IPeopleManager peopleManager,
- LauncherApps launcherApps,
+ public static List<PeopleSpaceTile> getSortedTiles(IPeopleManager peopleManager,
+ LauncherApps launcherApps, UserManager userManager,
Stream<ShortcutInfo> stream) {
return stream
.filter(Objects::nonNull)
+ .filter(c -> !userManager.isQuietModeEnabled(c.getUserHandle()))
.map(c -> new PeopleSpaceTile.Builder(c, launcherApps).build())
.filter(c -> shouldKeepConversation(c))
.map(c -> c.toBuilder().setLastInteractionTimestamp(
@@ -426,36 +366,6 @@
return bitmap;
}
- /** Returns a readable status describing the {@code lastInteraction}. */
- public static String getLastInteractionString(Context context, long lastInteraction) {
- if (lastInteraction == 0L) {
- Log.e(TAG, "Could not get valid last interaction");
- return context.getString(R.string.basic_status);
- }
- long now = System.currentTimeMillis();
- Duration durationSinceLastInteraction = Duration.ofMillis(now - lastInteraction);
- MeasureFormat formatter = MeasureFormat.getInstance(Locale.getDefault(),
- MeasureFormat.FormatWidth.WIDE);
- if (durationSinceLastInteraction.toHours() < MIN_HOUR) {
- return context.getString(R.string.timestamp, formatter.formatMeasures(
- new Measure(durationSinceLastInteraction.toMinutes(), MeasureUnit.MINUTE)));
- } else if (durationSinceLastInteraction.toDays() < ONE_DAY) {
- return context.getString(R.string.timestamp, formatter.formatMeasures(
- new Measure(durationSinceLastInteraction.toHours(),
- MeasureUnit.HOUR)));
- } else if (durationSinceLastInteraction.toDays() < DAYS_IN_A_WEEK) {
- return context.getString(R.string.timestamp, formatter.formatMeasures(
- new Measure(durationSinceLastInteraction.toHours(),
- MeasureUnit.DAY)));
- } else {
- return context.getString(durationSinceLastInteraction.toDays() == DAYS_IN_A_WEEK
- ? R.string.timestamp : R.string.over_timestamp,
- formatter.formatMeasures(
- new Measure(durationSinceLastInteraction.toDays() / DAYS_IN_A_WEEK,
- MeasureUnit.WEEK)));
- }
- }
-
/**
* Returns whether the {@code conversation} should be kept for display in the People Space.
*
@@ -619,7 +529,7 @@
*/
public static RemoteViews getPreview(Context context, IPeopleManager peopleManager,
LauncherApps launcherApps, NotificationEntryManager notificationEntryManager,
- String shortcutId, UserHandle userHandle, String packageName) {
+ String shortcutId, UserHandle userHandle, String packageName, Bundle options) {
peopleManager = (peopleManager != null) ? peopleManager : IPeopleManager.Stub.asInterface(
ServiceManager.getService(Context.PEOPLE_SERVICE));
launcherApps = (launcherApps != null) ? launcherApps
@@ -646,8 +556,7 @@
context, tile, notificationEntryManager);
if (DEBUG) Log.i(TAG, "Returning tile preview for shortcutId: " + shortcutId);
- Bundle bundle = new Bundle();
- return new PeopleTileViewHelper(context, augmentedTile, 0, bundle).getViews();
+ return new PeopleTileViewHelper(context, augmentedTile, 0, options).getViews();
}
/** Returns the userId associated with a {@link PeopleSpaceTile} */
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
index 51af47d..6b917c5 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
@@ -33,7 +33,6 @@
import static com.android.systemui.people.PeopleSpaceUtils.convertDrawableToBitmap;
import static com.android.systemui.people.PeopleSpaceUtils.getUserId;
-import android.annotation.ColorInt;
import android.annotation.Nullable;
import android.app.PendingIntent;
import android.app.people.ConversationStatus;
@@ -41,27 +40,28 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
-import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
+import android.icu.text.MeasureFormat;
+import android.icu.util.Measure;
+import android.icu.util.MeasureUnit;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.IconDrawableFactory;
import android.util.Log;
-import android.view.ContextThemeWrapper;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.people.widget.LaunchConversationActivity;
import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
import java.text.NumberFormat;
+import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
@@ -76,6 +76,10 @@
public static final boolean DEBUG = true;
private static final String TAG = "PeopleTileView";
+ private static final int DAYS_IN_A_WEEK = 7;
+ private static final int ONE_DAY = 1;
+ private static final int MAX_WEEKS = 2;
+
public static final int LAYOUT_SMALL = 0;
public static final int LAYOUT_MEDIUM = 1;
public static final int LAYOUT_LARGE = 2;
@@ -83,7 +87,9 @@
private static final int MIN_CONTENT_MAX_LINES = 2;
private static final int FIXED_HEIGHT_DIMENS_FOR_LARGE_CONTENT = 14 + 12 + 4 + 16;
- private static final int FIXED_HEIGHT_DIMENS_FOR_MEDIUM_CONTENT = 8 + 4 + 4 + 8;
+ private static final int MIN_MEDIUM_VERTICAL_PADDING = 4;
+ private static final int MAX_MEDIUM_PADDING = 16;
+ private static final int FIXED_HEIGHT_DIMENS_FOR_MEDIUM_CONTENT_BEFORE_PADDING = 4 + 4;
private static final int FIXED_HEIGHT_DIMENS_FOR_SMALL = 6 + 4 + 8;
private static final int FIXED_WIDTH_DIMENS_FOR_SMALL = 4 + 4;
@@ -96,6 +102,8 @@
public static final String EMPTY_STRING = "";
+ private int mMediumVerticalPadding;
+
private Context mContext;
private PeopleSpaceTile mTile;
private float mDensity;
@@ -205,7 +213,8 @@
private int getContentHeightForLayout(int lineHeight) {
switch (mLayoutSize) {
case LAYOUT_MEDIUM:
- return mHeight - (lineHeight + FIXED_HEIGHT_DIMENS_FOR_MEDIUM_CONTENT);
+ return mHeight - (lineHeight + FIXED_HEIGHT_DIMENS_FOR_MEDIUM_CONTENT_BEFORE_PADDING
+ + mMediumVerticalPadding * 2);
case LAYOUT_LARGE:
return mHeight - (getSizeInDp(
R.dimen.max_people_avatar_size_for_large_content) + lineHeight
@@ -224,7 +233,16 @@
}
// Small layout used below a certain minimum mWidth with any mHeight.
if (mWidth >= getSizeInDp(R.dimen.required_width_for_medium)) {
- if (DEBUG) Log.d(TAG, "Medium view for mWidth: " + mWidth + " mHeight: " + mHeight);
+ int spaceAvailableForPadding =
+ mHeight - (getSizeInDp(R.dimen.avatar_size_for_medium) + 4 + getLineHeight(
+ getSizeInDp(R.dimen.name_text_size_for_medium)));
+ if (DEBUG) {
+ Log.d(TAG, "Medium view for mWidth: " + mWidth + " mHeight: " + mHeight
+ + " with padding space: " + spaceAvailableForPadding);
+ }
+ int maxVerticalPadding = Math.min(Math.floorDiv(spaceAvailableForPadding, 2),
+ MAX_MEDIUM_PADDING);
+ mMediumVerticalPadding = Math.max(MIN_MEDIUM_VERTICAL_PADDING, maxVerticalPadding);
return LAYOUT_MEDIUM;
}
// Small layout can always handle our minimum mWidth and mHeight for our widget.
@@ -347,11 +365,7 @@
setMaxLines(views);
CharSequence content = mTile.getNotificationContent();
views = setPunctuationRemoteViewsFields(views, content);
- // TODO(b/184931139): Update to RemoteViews wrapper to set via attribute once available
- @ColorInt int color = Utils.getColorAttr(mContext,
- android.R.attr.textColorPrimary).getDefaultColor();
- views.setInt(R.id.text_content, "setTextColor", color);
-
+ views.setColorAttr(R.id.text_content, "setTextColor", android.R.attr.textColorPrimary);
views.setTextViewText(R.id.text_content, mTile.getNotificationContent());
views.setViewVisibility(R.id.image, View.GONE);
views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_message);
@@ -398,9 +412,7 @@
views.setViewVisibility(R.id.messages_count, View.GONE);
setMaxLines(views);
// Secondary text color for statuses.
- @ColorInt int secondaryColor = Utils.getColorAttr(mContext,
- android.R.attr.textColorSecondary).getDefaultColor();
- views.setInt(R.id.text_content, "setTextColor", secondaryColor);
+ views.setColorAttr(R.id.text_content, "setTextColor", android.R.attr.textColorSecondary);
views.setTextViewText(R.id.text_content, statusText);
Icon statusIcon = status.getIcon();
@@ -541,6 +553,14 @@
views.setViewVisibility(R.id.text_content, View.VISIBLE);
views.setViewVisibility(R.id.subtext, View.GONE);
}
+
+ if (mLayoutSize == LAYOUT_MEDIUM) {
+ if (DEBUG) Log.d(TAG, "Set vertical padding: " + mMediumVerticalPadding);
+ int horizontalPadding = (int) Math.floor(MAX_MEDIUM_PADDING * mDensity);
+ int verticalPadding = (int) Math.floor(mMediumVerticalPadding * mDensity);
+ views.setViewPadding(R.id.item, horizontalPadding, verticalPadding, horizontalPadding,
+ verticalPadding);
+ }
return views;
}
@@ -551,9 +571,16 @@
views.setViewVisibility(R.id.predefined_icon, View.GONE);
views.setViewVisibility(R.id.messages_count, View.GONE);
}
- String status = PeopleSpaceUtils.getLastInteractionString(mContext,
+ String status = getLastInteractionString(mContext,
mTile.getLastInteractionTimestamp());
- views.setTextViewText(R.id.last_interaction, status);
+ if (status != null) {
+ if (DEBUG) Log.d(TAG, "Show last interaction");
+ views.setViewVisibility(R.id.last_interaction, View.VISIBLE);
+ views.setTextViewText(R.id.last_interaction, status);
+ } else {
+ if (DEBUG) Log.d(TAG, "Hide last interaction");
+ views.setViewVisibility(R.id.last_interaction, View.GONE);
+ }
return views;
}
@@ -599,4 +626,34 @@
hasNewStory);
return convertDrawableToBitmap(personDrawable);
}
+
+ /** Returns a readable status describing the {@code lastInteraction}. */
+ @Nullable
+ public static String getLastInteractionString(Context context, long lastInteraction) {
+ if (lastInteraction == 0L) {
+ Log.e(TAG, "Could not get valid last interaction");
+ return null;
+ }
+ long now = System.currentTimeMillis();
+ Duration durationSinceLastInteraction = Duration.ofMillis(now - lastInteraction);
+ MeasureFormat formatter = MeasureFormat.getInstance(Locale.getDefault(),
+ MeasureFormat.FormatWidth.WIDE);
+ if (durationSinceLastInteraction.toDays() <= ONE_DAY) {
+ return null;
+ } else if (durationSinceLastInteraction.toDays() < DAYS_IN_A_WEEK) {
+ return context.getString(R.string.timestamp, formatter.formatMeasures(
+ new Measure(durationSinceLastInteraction.toHours(),
+ MeasureUnit.DAY)));
+ } else if (durationSinceLastInteraction.toDays() <= DAYS_IN_A_WEEK * 2) {
+ return context.getString(durationSinceLastInteraction.toDays() == DAYS_IN_A_WEEK
+ ? R.string.timestamp : R.string.over_timestamp,
+ formatter.formatMeasures(
+ new Measure(durationSinceLastInteraction.toDays() / DAYS_IN_A_WEEK,
+ MeasureUnit.WEEK)));
+ } else {
+ // Over 2 weeks ago
+ return context.getString(R.string.over_timestamp,
+ formatter.formatMeasures(new Measure(MAX_WEEKS, MeasureUnit.WEEK)));
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java b/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java
index c01a52d..c416b5e 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java
@@ -23,11 +23,13 @@
import android.os.Bundle;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.os.UserManager;
import android.service.notification.NotificationStats;
import android.text.TextUtils;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.UnlaunchableAppActivity;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
import com.android.internal.statusbar.IStatusBarService;
@@ -48,15 +50,17 @@
private UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
private NotificationEntryManager mNotificationEntryManager;
private final Optional<BubblesManager> mBubblesManagerOptional;
+ private final UserManager mUserManager;
private boolean mIsForTesting;
private IStatusBarService mIStatusBarService;
@Inject
public LaunchConversationActivity(NotificationEntryManager notificationEntryManager,
- Optional<BubblesManager> bubblesManagerOptional) {
+ Optional<BubblesManager> bubblesManagerOptional, UserManager userManager) {
super();
mNotificationEntryManager = notificationEntryManager;
mBubblesManagerOptional = bubblesManagerOptional;
+ mUserManager = userManager;
}
@Override
@@ -80,12 +84,24 @@
}
mUiEventLogger.log(PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_CLICKED);
try {
+
+ if (mUserManager.isQuietModeEnabled(userHandle)) {
+ if (DEBUG) Log.d(TAG, "Cannot launch app when quieted");
+ final Intent dialogIntent =
+ UnlaunchableAppActivity.createInQuietModeDialogIntent(
+ userHandle.getIdentifier());
+ this.getApplicationContext().startActivity(dialogIntent);
+ finish();
+ return;
+ }
+
NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(
notificationKey);
if (entry != null && entry.canBubble() && mBubblesManagerOptional.isPresent()) {
if (DEBUG) Log.d(TAG, "Open bubble for conversation");
mBubblesManagerOptional.get().expandStackAndSelectBubble(entry);
// Just opt-out and don't cancel the notification for bubbles.
+ finish();
return;
}
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 d63dc4a..fb0dcc2 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -31,7 +31,9 @@
import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetOptionsAndView;
import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetViews;
+import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.PendingIntent;
@@ -51,7 +53,9 @@
import android.os.Bundle;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.os.UserManager;
import android.preference.PreferenceManager;
+import android.service.notification.ConversationChannelWrapper;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;
@@ -76,6 +80,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.stream.Stream;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -96,6 +101,8 @@
private NotificationEntryManager mNotificationEntryManager;
private PackageManager mPackageManager;
private PeopleSpaceWidgetProvider mPeopleSpaceWidgetProvider;
+ private INotificationManager mINotificationManager;
+ private UserManager mUserManager;
public UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
@GuardedBy("mLock")
public static Map<PeopleTileKey, PeopleSpaceWidgetProvider.TileConversationListener>
@@ -121,17 +128,21 @@
mNotificationEntryManager = Dependency.get(NotificationEntryManager.class);
mPackageManager = mContext.getPackageManager();
mPeopleSpaceWidgetProvider = new PeopleSpaceWidgetProvider();
+ mINotificationManager = INotificationManager.Stub.asInterface(
+ ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+ mUserManager = context.getSystemService(UserManager.class);
}
/**
* AppWidgetManager setter used for testing.
*/
@VisibleForTesting
- protected void setAppWidgetManager(
+ public void setAppWidgetManager(
AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager,
PeopleManager peopleManager, LauncherApps launcherApps,
NotificationEntryManager notificationEntryManager, PackageManager packageManager,
- boolean isForTesting, PeopleSpaceWidgetProvider peopleSpaceWidgetProvider) {
+ boolean isForTesting, PeopleSpaceWidgetProvider peopleSpaceWidgetProvider,
+ UserManager userManager, INotificationManager notificationManager) {
mAppWidgetManager = appWidgetManager;
mIPeopleManager = iPeopleManager;
mPeopleManager = peopleManager;
@@ -140,6 +151,8 @@
mPackageManager = packageManager;
mIsForTesting = isForTesting;
mPeopleSpaceWidgetProvider = peopleSpaceWidgetProvider;
+ mUserManager = userManager;
+ mINotificationManager = notificationManager;
}
/**
@@ -764,12 +777,12 @@
* Builds a request to pin a People Tile app widget, with a preview and storing necessary
* information as the callback.
*/
- public boolean requestPinAppWidget(ShortcutInfo shortcutInfo) {
+ public boolean requestPinAppWidget(ShortcutInfo shortcutInfo, Bundle options) {
if (DEBUG) Log.d(TAG, "Requesting pin widget, shortcutId: " + shortcutInfo.getId());
RemoteViews widgetPreview = PeopleSpaceUtils.getPreview(mContext, mIPeopleManager,
mLauncherApps, mNotificationEntryManager, shortcutInfo.getId(),
- shortcutInfo.getUserHandle(), shortcutInfo.getPackage());
+ shortcutInfo.getUserHandle(), shortcutInfo.getPackage(), options);
if (widgetPreview == null) {
Log.w(TAG, "Skipping pinning widget: no tile for shortcutId: " + shortcutInfo.getId());
return false;
@@ -783,4 +796,52 @@
ComponentName componentName = new ComponentName(mContext, PeopleSpaceWidgetProvider.class);
return mAppWidgetManager.requestPinAppWidget(componentName, extras, successCallback);
}
+
+ /** Returns a list of map entries corresponding to user's priority conversations. */
+ @NonNull
+ public List<PeopleSpaceTile> getPriorityTiles()
+ throws Exception {
+ List<ConversationChannelWrapper> conversations =
+ mINotificationManager.getConversations(true).getList();
+ // Add priority conversations to tiles list.
+ Stream<ShortcutInfo> priorityConversations = conversations.stream()
+ .filter(c -> c.getNotificationChannel() != null
+ && c.getNotificationChannel().isImportantConversation())
+ .map(c -> c.getShortcutInfo());
+ List<PeopleSpaceTile> priorityTiles = PeopleSpaceUtils.getSortedTiles(mIPeopleManager,
+ mLauncherApps, mUserManager,
+ priorityConversations);
+ priorityTiles = PeopleSpaceUtils.augmentTilesFromVisibleNotifications(
+ mContext, priorityTiles, mNotificationEntryManager);
+ return priorityTiles;
+ }
+
+ /** Returns a list of map entries corresponding to user's recent conversations. */
+ @NonNull
+ public List<PeopleSpaceTile> getRecentTiles()
+ throws Exception {
+ if (DEBUG) Log.d(TAG, "Add recent conversations");
+ List<ConversationChannelWrapper> conversations =
+ mINotificationManager.getConversations(false).getList();
+ Stream<ShortcutInfo> nonPriorityConversations = conversations.stream()
+ .filter(c -> c.getNotificationChannel() == null
+ || !c.getNotificationChannel().isImportantConversation())
+ .map(c -> c.getShortcutInfo());
+
+ List<ConversationChannel> recentConversationsList =
+ mIPeopleManager.getRecentConversations().getList();
+ Stream<ShortcutInfo> recentConversations = recentConversationsList
+ .stream()
+ .map(c -> c.getShortcutInfo());
+
+ Stream<ShortcutInfo> mergedStream = Stream.concat(nonPriorityConversations,
+ recentConversations);
+ List<PeopleSpaceTile> recentTiles =
+ PeopleSpaceUtils.getSortedTiles(mIPeopleManager, mLauncherApps, mUserManager,
+ mergedStream);
+
+ recentTiles = PeopleSpaceUtils.augmentTilesFromVisibleNotifications(
+ mContext, recentTiles, mNotificationEntryManager);
+ return recentTiles;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt
index f87ea7c..feb27d80 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt
@@ -29,6 +29,7 @@
import androidx.annotation.MainThread
import androidx.annotation.VisibleForTesting
import androidx.annotation.WorkerThread
+import com.android.systemui.appops.AppOpsController
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -48,7 +49,6 @@
return PrivacyDialog(context, list, starter)
}
}
-
/**
* Controller for [PrivacyDialog].
*
@@ -66,6 +66,7 @@
private val uiExecutor: Executor,
private val privacyLogger: PrivacyLogger,
private val keyguardStateController: KeyguardStateController,
+ private val appOpsController: AppOpsController,
@VisibleForTesting private val dialogProvider: DialogProvider
) {
@@ -79,7 +80,8 @@
@Background backgroundExecutor: Executor,
@Main uiExecutor: Executor,
privacyLogger: PrivacyLogger,
- keyguardStateController: KeyguardStateController
+ keyguardStateController: KeyguardStateController,
+ appOpsController: AppOpsController
) : this(
permissionManager,
packageManager,
@@ -90,6 +92,7 @@
uiExecutor,
privacyLogger,
keyguardStateController,
+ appOpsController,
defaultDialogProvider
)
@@ -127,7 +130,9 @@
}
@WorkerThread
- private fun permGroupUsage(): List<PermGroupUsage> = permissionManager.indicatorAppOpUsageData
+ private fun permGroupUsage(): List<PermGroupUsage> {
+ return permissionManager.getIndicatorAppOpUsageData(appOpsController.isMicMuted)
+ }
/**
* Show the [PrivacyDialog]
@@ -261,4 +266,4 @@
starter: (String, Int) -> Unit
): PrivacyDialog
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
index 4c617ed..63ec6e5 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
@@ -54,7 +54,8 @@
data class PrivacyItem(
val privacyType: PrivacyType,
val application: PrivacyApplication,
- val timeStampElapsed: Long = UNKNOWN_TIMESTAMP
+ val timeStampElapsed: Long = UNKNOWN_TIMESTAMP,
+ val paused: Boolean = false
) {
val log = "(${privacyType.logName}, ${application.packageName}(${application.uid}), " +
"$timeStampElapsed)"
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
index f7e2a31..8b27b6e 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
@@ -257,7 +257,7 @@
privacyList = emptyList()
return
}
- val list = appOpsController.getActiveAppOpsForUser(UserHandle.USER_ALL).filter {
+ val list = appOpsController.getActiveAppOps(true).filter {
UserHandle.getUserId(it.uid) in currentUserIds ||
it.code == AppOpsManager.OP_PHONE_CALL_MICROPHONE ||
it.code == AppOpsManager.OP_PHONE_CALL_CAMERA
@@ -279,7 +279,9 @@
// Anything earlier than this timestamp can be removed
val removeBeforeTime = systemClock.elapsedRealtime() - TIME_TO_HOLD_INDICATORS
- val mustKeep = privacyList.filter { it.timeStampElapsed > removeBeforeTime && it !in list }
+ val mustKeep = privacyList.filter {
+ it.timeStampElapsed > removeBeforeTime && !(it isIn list)
+ }
// There are items we must keep because they haven't been around for enough time.
if (mustKeep.isNotEmpty()) {
@@ -291,7 +293,18 @@
logger.logPrivacyItemsUpdateScheduled(delay)
holdingRunnableCanceler = bgExecutor.executeDelayed(updateListAndNotifyChanges, delay)
}
- return list + mustKeep
+ return list.filter { !it.paused } + mustKeep
+ }
+
+ /**
+ * Ignores the paused status to determine if the element is in the list
+ */
+ private infix fun PrivacyItem.isIn(list: List<PrivacyItem>): Boolean {
+ return list.any {
+ it.privacyType == privacyType &&
+ it.application == application &&
+ it.timeStampElapsed == timeStampElapsed
+ }
}
private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? {
@@ -308,7 +321,7 @@
return null
}
val app = PrivacyApplication(appOpItem.packageName, appOpItem.uid)
- return PrivacyItem(type, app, appOpItem.timeStartedElapsed)
+ return PrivacyItem(type, app, appOpItem.timeStartedElapsed, appOpItem.isDisabled)
}
interface Callback {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
index 3718713..c4986cc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
@@ -280,7 +280,7 @@
mMultiUserSwitch.setVisibility(showUserSwitcher() ? View.VISIBLE : View.GONE);
mSettingsButton.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
- mBuildText.setVisibility(mExpanded && mShouldShowBuildText ? View.VISIBLE : View.GONE);
+ mBuildText.setVisibility(mExpanded && mShouldShowBuildText ? View.VISIBLE : View.INVISIBLE);
}
private boolean showUserSwitcher() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
index 3467838..74ae3a6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
@@ -32,6 +32,7 @@
import com.android.internal.logging.nano.MetricsProto;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
+import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.globalactions.GlobalActionsDialogLite;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
@@ -65,6 +66,7 @@
private final MetricsLogger mMetricsLogger;
private final FalsingManager mFalsingManager;
private final SettingsButton mSettingsButton;
+ private final View mSettingsButtonContainer;
private final TextView mBuildText;
private final View mEdit;
private final MultiUserSwitch mMultiUserSwitch;
@@ -152,6 +154,7 @@
mFalsingManager = falsingManager;
mSettingsButton = mView.findViewById(R.id.settings_button);
+ mSettingsButtonContainer = mView.findViewById(R.id.settings_button_container);
mBuildText = mView.findViewById(R.id.build);
mEdit = mView.findViewById(android.R.id.edit);
mMultiUserSwitch = mView.findViewById(R.id.multi_user_switch);
@@ -258,10 +261,12 @@
mView.disable(state2, isTunerEnabled());
}
-
private void startSettingsActivity() {
+ ActivityLaunchAnimator.Controller animationController =
+ mSettingsButtonContainer != null ? ActivityLaunchAnimator.Controller.fromView(
+ mSettingsButtonContainer) : null;
mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS),
- true /* dismissShade */);
+ true /* dismissShade */, animationController);
}
private boolean isTunerEnabled() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index 5b6b5df..93ccfc72 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -16,12 +16,14 @@
package com.android.systemui.qs;
+import static com.android.systemui.classifier.Classifier.QS_SWIPE;
import static com.android.systemui.media.dagger.MediaModule.QS_PANEL;
import static com.android.systemui.qs.QSPanel.QS_SHOW_BRIGHTNESS;
import static com.android.systemui.qs.dagger.QSFragmentModule.QS_USING_MEDIA_PLAYER;
import android.annotation.NonNull;
import android.content.res.Configuration;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -31,6 +33,7 @@
import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.MediaHierarchyManager;
import com.android.systemui.media.MediaHost;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.customize.QSCustomizerController;
@@ -58,6 +61,7 @@
private final TunerService mTunerService;
private final QSCustomizerController mQsCustomizerController;
private final QSTileRevealController.Factory mQsTileRevealControllerFactory;
+ private final FalsingManager mFalsingManager;
private final BrightnessController mBrightnessController;
private final BrightnessSlider.Factory mBrightnessSliderFactory;
private final BrightnessSlider mBrightnessSlider;
@@ -81,6 +85,16 @@
private final BrightnessMirrorController.BrightnessMirrorListener mBrightnessMirrorListener =
mirror -> updateBrightnessMirror();
+ private View.OnTouchListener mTileLayoutTouchListener = new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ if (event.getActionMasked() == MotionEvent.ACTION_UP) {
+ mFalsingManager.isFalseTouch(QS_SWIPE);
+ }
+ return false;
+ }
+ };
+
@Inject
QSPanelController(QSPanel view, QSSecurityFooter qsSecurityFooter, TunerService tunerService,
QSTileHost qstileHost, QSCustomizerController qsCustomizerController,
@@ -89,7 +103,7 @@
QSTileRevealController.Factory qsTileRevealControllerFactory,
DumpManager dumpManager, MetricsLogger metricsLogger, UiEventLogger uiEventLogger,
QSLogger qsLogger, BrightnessController.Factory brightnessControllerFactory,
- BrightnessSlider.Factory brightnessSliderFactory,
+ BrightnessSlider.Factory brightnessSliderFactory, FalsingManager falsingManager,
FeatureFlags featureFlags) {
super(view, qstileHost, qsCustomizerController, usingMediaPlayer, mediaHost,
metricsLogger, uiEventLogger, qsLogger, dumpManager, featureFlags);
@@ -97,6 +111,7 @@
mTunerService = tunerService;
mQsCustomizerController = qsCustomizerController;
mQsTileRevealControllerFactory = qsTileRevealControllerFactory;
+ mFalsingManager = falsingManager;
mQsSecurityFooter.setHostEnvironment(qstileHost);
mBrightnessSliderFactory = brightnessSliderFactory;
@@ -133,6 +148,9 @@
if (mBrightnessMirrorController != null) {
mBrightnessMirrorController.addCallback(mBrightnessMirrorListener);
}
+
+ ((PagedTileLayout) mView.createRegularTileLayout())
+ .setOnTouchListener(mTileLayoutTouchListener);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 3f06312..7123e49 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -235,6 +235,12 @@
public void onAnimationStarted() {
mIconContainer.removeIgnoredSlot(mMobileSlotName);
}
+
+ @Override
+ public void onAnimationAtStart() {
+ super.onAnimationAtStart();
+ mIconContainer.removeIgnoredSlot(mMobileSlotName);
+ }
});
}
mAlphaAnimator = builder.build();
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 b728b43..6f19276 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
@@ -184,8 +184,7 @@
@Override
public CharSequence getTileLabel() {
- CharSequence qawLabel = mQuickAccessWalletClient.getServiceLabel();
- return qawLabel == null ? mLabel : qawLabel;
+ return mLabel;
}
private void queryWalletCards() {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index 33041d2..fa28754 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -17,11 +17,12 @@
package com.android.systemui.screenshot;
import android.app.Activity;
+import android.app.ActivityOptions;
import android.content.ComponentName;
-import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.HardwareRenderer;
+import android.graphics.Matrix;
import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.RenderNode;
@@ -32,11 +33,14 @@
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
-import android.view.IWindowManager;
import android.view.ScrollCaptureResponse;
import android.view.View;
+import android.view.Window;
import android.widget.ImageView;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.android.internal.app.ChooserActivity;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Background;
@@ -64,17 +68,16 @@
public static final String EXTRA_CAPTURE_RESPONSE = "capture-response";
private static final String KEY_SAVED_IMAGE_PATH = "saved-image-path";
+ private static final boolean USE_SHARED_ELEMENT = false;
+
private final UiEventLogger mUiEventLogger;
- private final ScrollCaptureController mScrollCaptureController;
private final Executor mUiExecutor;
private final Executor mBackgroundExecutor;
private final ImageExporter mImageExporter;
-
- // If true, the activity is re-loading an image from storage, which should either succeed and
- // populate the UI or fail and finish the activity.
- private boolean mRestoringInstance;
+ private final LongScreenshotHolder mLongScreenshotHolder;
private ImageView mPreview;
+ private ImageView mTransitionView;
private View mSave;
private View mEdit;
private View mShare;
@@ -86,8 +89,8 @@
private ListenableFuture<File> mCacheSaveFuture;
private ListenableFuture<ImageLoader.Result> mCacheLoadFuture;
- private ListenableFuture<LongScreenshot> mLongScreenshotFuture;
private LongScreenshot mLongScreenshot;
+ private boolean mTransitionStarted;
private enum PendingAction {
SHARE,
@@ -97,21 +100,21 @@
@Inject
public LongScreenshotActivity(UiEventLogger uiEventLogger, ImageExporter imageExporter,
- @Main Executor mainExecutor, @Background Executor bgExecutor, IWindowManager wms,
- Context context, ScrollCaptureController scrollCaptureController) {
+ @Main Executor mainExecutor, @Background Executor bgExecutor,
+ LongScreenshotHolder longScreenshotHolder) {
mUiEventLogger = uiEventLogger;
mUiExecutor = mainExecutor;
mBackgroundExecutor = bgExecutor;
mImageExporter = imageExporter;
- mScrollCaptureController = scrollCaptureController;
+ mLongScreenshotHolder = longScreenshotHolder;
}
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate(savedInstanceState = " + savedInstanceState + ")");
-
super.onCreate(savedInstanceState);
+ getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
setContentView(R.layout.long_screenshot);
mPreview = requireViewById(R.id.preview);
@@ -121,6 +124,7 @@
mCropView = requireViewById(R.id.crop_view);
mMagnifierView = requireViewById(R.id.magnifier);
mCropView.setCropInteractionListener(mMagnifierView);
+ mTransitionView = requireViewById(R.id.transition);
mSave.setOnClickListener(this::onClicked);
mEdit.setOnClickListener(this::onClicked);
@@ -152,7 +156,7 @@
super.onStart();
if (mCacheLoadFuture != null) {
- Log.d(TAG, "mRestoringInstance = true");
+ Log.d(TAG, "mCacheLoadFuture != null");
final ListenableFuture<ImageLoader.Result> future = mCacheLoadFuture;
mCacheLoadFuture.addListener(() -> {
Log.d(TAG, "cached bitmap load complete");
@@ -170,42 +174,22 @@
}, mUiExecutor);
mCacheLoadFuture = null;
return;
- }
-
- if (mLongScreenshotFuture == null) {
- Log.d(TAG, "mLongScreenshotFuture == null");
- // First run through, ensure we have a connection to use (see #onCreate)
- if (mScrollCaptureResponse == null || !mScrollCaptureResponse.isConnected()) {
- Log.e(TAG, "Did not receive a live scroll capture connection, bailing out!");
- finishAndRemoveTask();
- return;
- }
- mLongScreenshotFuture = mScrollCaptureController.run(mScrollCaptureResponse);
- mLongScreenshotFuture.addListener(() -> {
- LongScreenshot longScreenshot;
- try {
- longScreenshot = mLongScreenshotFuture.get();
- } catch (CancellationException | InterruptedException | ExecutionException e) {
- Log.e(TAG, "Error capturing long screenshot!", e);
- finishAndRemoveTask();
- return;
- }
- if (longScreenshot.getHeight() == 0) {
- Log.e(TAG, "Got a zero height result");
- finishAndRemoveTask();
- return;
- }
- onCaptureCompleted(longScreenshot);
- }, mUiExecutor);
} else {
- Log.d(TAG, "mLongScreenshotFuture != null");
+ LongScreenshot longScreenshot = mLongScreenshotHolder.takeLongScreenshot();
+ if (longScreenshot != null) {
+ onLongScreenshotReceived(longScreenshot);
+ } else {
+ Log.e(TAG, "No long screenshot available!");
+ finishAndRemoveTask();
+ }
}
}
- private void onCaptureCompleted(LongScreenshot longScreenshot) {
- Log.d(TAG, "onCaptureCompleted(longScreenshot=" + longScreenshot + ")");
+ private void onLongScreenshotReceived(LongScreenshot longScreenshot) {
+ Log.d(TAG, "onLongScreenshotReceived(longScreenshot=" + longScreenshot + ")");
mLongScreenshot = longScreenshot;
mPreview.setImageDrawable(mLongScreenshot.getDrawable());
+ mTransitionView.setImageDrawable(mLongScreenshot.getDrawable());
updateImageDimensions();
mCropView.setVisibility(View.VISIBLE);
mMagnifierView.setDrawable(mLongScreenshot.getDrawable(),
@@ -277,15 +261,15 @@
protected void onStop() {
Log.d(TAG, "onStop finishing=" + isFinishing());
super.onStop();
+ if (mTransitionStarted) {
+ finish();
+ }
if (isFinishing()) {
if (mScrollCaptureResponse != null) {
mScrollCaptureResponse.close();
}
cleanupCache();
- if (mLongScreenshotFuture != null) {
- mLongScreenshotFuture.cancel(true);
- }
if (mLongScreenshot != null) {
mLongScreenshot.release();
}
@@ -323,11 +307,22 @@
intent.setComponent(ComponentName.unflattenFromString(editorPackage));
}
intent.setDataAndType(uri, "image/png");
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK
- | Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- startActivityAsUser(intent, UserHandle.CURRENT);
- finishAndRemoveTask();
+ if (USE_SHARED_ELEMENT) {
+ updateImageDimensions();
+ mTransitionView.setVisibility(View.VISIBLE);
+ // TODO: listen for transition completing instead of finishing onStop
+ mTransitionStarted = true;
+ startActivity(intent,
+ ActivityOptions.makeSceneTransitionAnimation(this, mTransitionView,
+ ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME).toBundle());
+ } else {
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ startActivityAsUser(intent, UserHandle.CURRENT);
+ finishAndRemoveTask();
+ }
}
private void doShare(Uri uri) {
@@ -417,19 +412,47 @@
- mPreview.getPaddingBottom();
float viewRatio = previewWidth / (float) previewHeight;
+ // Top and left offsets of the image relative to mPreview.
+ int imageLeft = mPreview.getPaddingLeft();
+ int imageTop = mPreview.getPaddingTop();
+
+ // The image width and height on screen
+ int imageHeight = previewHeight;
+ int imageWidth = previewWidth;
+ float scale;
if (imageRatio > viewRatio) {
// Image is full width and height is constrained, compute extra padding to inform
// CropView
- float imageHeight = previewHeight * viewRatio / imageRatio;
- int extraPadding = (int) (previewHeight - imageHeight) / 2;
+ imageHeight = (int) (previewHeight * viewRatio / imageRatio);
+ int extraPadding = (previewHeight - imageHeight) / 2;
mCropView.setExtraPadding(extraPadding + mPreview.getPaddingTop(),
extraPadding + mPreview.getPaddingBottom());
+ imageTop += (previewHeight - imageHeight) / 2;
+ scale = imageHeight / bounds.height();
+ mCropView.setExtraPadding(extraPadding, extraPadding);
mCropView.setImageWidth(previewWidth);
} else {
+ imageWidth = (int) (previewWidth * imageRatio / viewRatio);
+ imageLeft += (previewWidth - imageWidth) / 2;
+ scale = imageWidth / (float) bounds.width();
// Image is full height
mCropView.setExtraPadding(mPreview.getPaddingTop(), mPreview.getPaddingBottom());
mCropView.setImageWidth((int) (previewHeight * imageRatio));
}
+ // Update transition view's position and scale.
+ Rect boundaries = mCropView.getCropBoundaries(imageWidth, imageHeight);
+ mTransitionView.setTranslationX(imageLeft + boundaries.left);
+ mTransitionView.setTranslationY(imageTop + boundaries.top);
+ ConstraintLayout.LayoutParams params =
+ (ConstraintLayout.LayoutParams) mTransitionView.getLayoutParams();
+ params.width = boundaries.width();
+ params.height = boundaries.height();
+ mTransitionView.setLayoutParams(params);
+
+ Matrix matrix = new Matrix();
+ matrix.postScale(scale, scale, 0, 0);
+ matrix.postTranslate(-boundaries.left, -boundaries.top);
+ mTransitionView.setImageMatrix(matrix);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotHolder.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotHolder.java
new file mode 100644
index 0000000..39c6f07
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotHolder.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.screenshot;
+
+import com.android.systemui.dagger.SysUISingleton;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.inject.Inject;
+
+/**
+ * LongScreenshotHolder holds on to 1 LongScreenshot reference to facilitate indirect in-process
+ * passing.
+ */
+@SysUISingleton
+public class LongScreenshotHolder {
+ private final AtomicReference<ScrollCaptureController.LongScreenshot> mLongScreenshot;
+
+ @Inject
+ public LongScreenshotHolder() {
+ mLongScreenshot = new AtomicReference<>();
+ }
+
+ /**
+ * Set the holder's stored LongScreenshot.
+ */
+ public void setLongScreenshot(ScrollCaptureController.LongScreenshot longScreenshot) {
+ mLongScreenshot.set(longScreenshot);
+ }
+
+ /**
+ * @return true if the holder has a non-null LongScreenshot.
+ */
+ public boolean hasLongScreenshot() {
+ return mLongScreenshot.get() != null;
+ }
+
+ /**
+ * Return the current stored LongScreenshot, clear the holder's storage.
+ */
+ public ScrollCaptureController.LongScreenshot takeLongScreenshot() {
+ return mLongScreenshot.getAndSet(null);
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index badffce..9d01986 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -191,6 +191,8 @@
private final ScrollCaptureClient mScrollCaptureClient;
private final PhoneWindow mWindow;
private final DisplayManager mDisplayManager;
+ private final ScrollCaptureController mScrollCaptureController;
+ private final LongScreenshotHolder mLongScreenshotHolder;
private ScreenshotView mScreenshotView;
private Bitmap mScreenBitmap;
@@ -233,13 +235,17 @@
ScrollCaptureClient scrollCaptureClient,
UiEventLogger uiEventLogger,
ImageExporter imageExporter,
- @Main Executor mainExecutor) {
+ @Main Executor mainExecutor,
+ ScrollCaptureController scrollCaptureController,
+ LongScreenshotHolder longScreenshotHolder) {
mScreenshotSmartActions = screenshotSmartActions;
mNotificationsController = screenshotNotificationsController;
mScrollCaptureClient = scrollCaptureClient;
mUiEventLogger = uiEventLogger;
mImageExporter = imageExporter;
mMainExecutor = mainExecutor;
+ mScrollCaptureController = scrollCaptureController;
+ mLongScreenshotHolder = longScreenshotHolder;
mBgExecutor = Executors.newSingleThreadExecutor();
mDisplayManager = requireNonNull(context.getSystemService(DisplayManager.class));
@@ -569,15 +575,30 @@
}
Log.d(TAG, "ScrollCapture: connected to window ["
+ mLastScrollCaptureResponse.getWindowTitle() + "]");
- final Intent intent = new Intent(mContext, LongScreenshotActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- intent.putExtra(LongScreenshotActivity.EXTRA_CAPTURE_RESPONSE,
- mLastScrollCaptureResponse);
+
+ final ScrollCaptureResponse response = mLastScrollCaptureResponse;
mScreenshotView.showScrollChip(/* onClick */ () -> {
// Clear the reference to prevent close() in dismissScreenshot
mLastScrollCaptureResponse = null;
- mContext.startActivity(intent);
- dismissScreenshot(false);
+ final ListenableFuture<ScrollCaptureController.LongScreenshot> future =
+ mScrollCaptureController.run(response);
+ future.addListener(() -> {
+ ScrollCaptureController.LongScreenshot longScreenshot;
+ try {
+ longScreenshot = future.get();
+ } catch (CancellationException | InterruptedException | ExecutionException e) {
+ Log.e(TAG, "Exception", e);
+ return;
+ }
+
+ mLongScreenshotHolder.setLongScreenshot(longScreenshot);
+
+ final Intent intent = new Intent(mContext, LongScreenshotActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ mContext.startActivity(intent);
+
+ dismissScreenshot(false);
+ }, mMainExecutor);
});
} catch (CancellationException e) {
// Ignore
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java
index 29f67f3..6ebab8a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java
@@ -57,6 +57,13 @@
ERROR,
TIMEOUT
}
+
+ /* Enum to define screenshot smart action types. */
+ public enum ScreenshotSmartActionType {
+ REGULAR_SMART_ACTIONS,
+ QUICK_SHARE_ACTION
+ }
+
/**
* Default implementation that returns an empty list.
* This method is overridden in vendor-specific Sys UI implementation.
@@ -68,7 +75,8 @@
* @param userHandle user handle of the foreground task owner
*/
public CompletableFuture<List<Notification.Action>> getActions(String screenshotId,
- Uri screenshotUri, Bitmap bitmap, ComponentName componentName, UserHandle userHandle) {
+ Uri screenshotUri, Bitmap bitmap, ComponentName componentName,
+ ScreenshotSmartActionType actionType, UserHandle userHandle) {
if (DEBUG_ACTIONS) {
Log.d(TAG, "Returning empty smart action list.");
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java
index 1184dc7..9bd7923 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotSmartActions.java
@@ -20,6 +20,7 @@
import static com.android.systemui.screenshot.LogConfig.DEBUG_ACTIONS;
import static com.android.systemui.screenshot.LogConfig.logTag;
+import static com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider.ScreenshotSmartActionType;
import android.app.ActivityManager;
import android.app.Notification;
@@ -87,8 +88,8 @@
(runningTask != null && runningTask.topActivity != null)
? runningTask.topActivity
: new ComponentName("", "");
- smartActionsFuture = smartActionsProvider.getActions(
- screenshotId, screenshotUri, image, componentName, userHandle);
+ smartActionsFuture = smartActionsProvider.getActions(screenshotId, screenshotUri, image,
+ componentName, ScreenshotSmartActionType.REGULAR_SMART_ACTIONS, userHandle);
} catch (Throwable e) {
long waitTimeMs = SystemClock.uptimeMillis() - startTimeMs;
smartActionsFuture = CompletableFuture.completedFuture(Collections.emptyList());
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
index dbd6758..b60fd13 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java
@@ -48,7 +48,7 @@
super(context, attrs);
}
- // Inflated from quick_settings_brightness_dialog or quick_settings_brightness_dialog_thick
+ // Inflated from quick_settings_brightness_dialog
@Override
protected void onFinishInflate() {
super.onFinishInflate();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 23e6a9f..0e56ab7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -169,8 +169,6 @@
return mCallback.handleRemoteViewClick(view, pendingIntent,
action == null ? false : action.isAuthenticationRequired(), () -> {
Pair<Intent, ActivityOptions> options = response.getLaunchOptions(view);
- options.second.setLaunchWindowingMode(
- WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
mLogger.logStartingIntentWithDefaultHandler(entry, pendingIntent);
return RemoteViews.startPendingIntent(view, pendingIntent, options);
});
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
index 20383fe..fad7480 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
@@ -24,6 +24,7 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.media.MediaDataManager;
+import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.ActionClickLogger;
import com.android.systemui.statusbar.CommandQueue;
@@ -237,9 +238,11 @@
static OngoingCallController provideOngoingCallController(
CommonNotifCollection notifCollection,
FeatureFlags featureFlags,
- SystemClock systemClock) {
+ SystemClock systemClock,
+ ActivityStarter activityStarter) {
OngoingCallController ongoingCallController =
- new OngoingCallController(notifCollection, featureFlags, systemClock);
+ new OngoingCallController(
+ notifCollection, featureFlags, systemClock, activityStarter);
ongoingCallController.init();
return ongoingCallController;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
new file mode 100644
index 0000000..5ab71bc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.events
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.ObjectAnimator
+import android.annotation.UiThread
+import android.util.Log
+import android.view.Gravity
+import android.view.View
+import android.widget.FrameLayout
+
+import com.android.systemui.animation.Interpolators
+import com.android.systemui.R
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+
+import java.lang.IllegalStateException
+import java.util.concurrent.Executor
+import javax.inject.Inject
+
+/**
+ * Understands how to keep the persistent privacy dot in the corner of the screen in
+ * ScreenDecorations, which does not rotate with the device.
+ *
+ * The basic principle here is that each dot will sit in a box that is equal to the margins of the
+ * status bar (specifically the status_bar_contents view in PhoneStatusBarView). Each dot container
+ * will have its gravity set towards the corner (i.e., top-right corner gets top|right gravity), and
+ * the contained ImageView will be set to center_vertical and away from the corner horizontally. The
+ * Views will match the status bar top padding and status bar height so that the dot can appear to
+ * reside directly after the status bar system contents (basically to the right of the battery).
+ *
+ * NOTE: any operation that modifies views directly must run on the provided executor, because
+ * these views are owned by ScreenDecorations and it runs in its own thread
+ */
+
+@SysUISingleton
+class PrivacyDotViewController @Inject constructor(
+ @Main val mainExecutor: Executor,
+ val animationScheduler: SystemStatusAnimationScheduler
+) {
+ private var rotation = 0
+ private var leftSize = 0
+ private var rightSize = 0
+
+ private var sbHeightPortrait = 0
+ private var sbHeightLandscape = 0
+
+ private var hasMultipleHeights = false
+ private var needsHeightUpdate = false
+ private var needsRotationUpdate = false
+ private var needsMarginUpdate = false
+
+ private lateinit var tl: View
+ private lateinit var tr: View
+ private lateinit var bl: View
+ private lateinit var br: View
+
+ // Track which corner is active (based on orientation + RTL)
+ private var designatedCorner: View? = null
+
+ // Privacy dots are created in ScreenDecoration's UiThread, which is not the main thread
+ private var uiExecutor: Executor? = null
+
+ private val views: Sequence<View>
+ get() = if (!this::tl.isInitialized) sequenceOf() else sequenceOf(tl, tr, br, bl)
+
+ fun setUiExecutor(e: Executor) {
+ uiExecutor = e
+ }
+
+ @UiThread
+ fun updateRotation(rot: Int) {
+ if (rot == rotation) {
+ return
+ }
+
+ // A rotation has started, hide the views to avoid flicker
+ setCornerVisibilities(View.INVISIBLE)
+
+ if (hasMultipleHeights && (rotation % 2) != (rot % 2)) {
+ // we've changed from vertical to horizontal; update status bar height
+ needsHeightUpdate = true
+ }
+
+ rotation = rot
+ needsRotationUpdate = true
+ }
+
+ @UiThread
+ private fun updateHeights(rot: Int) {
+ val height = when (rot) {
+ 0, 2 -> sbHeightPortrait
+ 1, 3 -> sbHeightLandscape
+ else -> 0
+ }
+
+ views.forEach { it.layoutParams.height = height }
+ }
+
+ // Update the gravity and margins of the privacy views
+ @UiThread
+ private fun updateRotations() {
+ // To keep a view in the corner, its gravity is always the description of its current corner
+ // Therefore, just figure out which view is in which corner. This turns out to be something
+ // like (myCorner - rot) mod 4, where topLeft = 0, topRight = 1, etc. and portrait = 0, and
+ // rotating the device counter-clockwise increments rotation by 1
+
+ views.forEach { corner ->
+ val rotatedCorner = rotatedCorner(cornerForView(corner))
+ (corner.layoutParams as FrameLayout.LayoutParams).apply {
+ gravity = rotatedCorner.toGravity()
+ }
+
+ // Set the dot's view gravity to hug the status bar
+ (corner.findViewById<View>(R.id.privacy_dot)
+ .layoutParams as FrameLayout.LayoutParams)
+ .gravity = rotatedCorner.innerGravity()
+ }
+ }
+
+ @UiThread
+ private fun updateCornerSizes() {
+ views.forEach { corner ->
+ val rotatedCorner = rotatedCorner(cornerForView(corner))
+ val w = widthForCorner(rotatedCorner)
+ Log.d(TAG, "updateCornerSizes: setting (${cornerForView(corner)}) to $w")
+ (corner.layoutParams as FrameLayout.LayoutParams).width = w
+ corner.requestLayout()
+ }
+ }
+
+ // Designated view will be the one at statusbar's view.END
+ @UiThread
+ private fun selectDesignatedCorner(): View? {
+ if (!this::tl.isInitialized) {
+ return null
+ }
+
+ val isRtl = tl.isLayoutRtl
+
+ return when (rotation) {
+ 0 -> if (isRtl) tl else tr
+ 1 -> if (isRtl) tr else br
+ 2 -> if (isRtl) br else bl
+ 3 -> if (isRtl) bl else tl
+ else -> throw IllegalStateException("unknown rotation")
+ }
+ }
+
+ // Track the current designated corner and maybe animate to a new rotation
+ @UiThread
+ private fun updateDesignatedCorner(newCorner: View) {
+ designatedCorner = newCorner
+
+ if (animationScheduler.hasPersistentDot) {
+ designatedCorner!!.visibility = View.VISIBLE
+ designatedCorner!!.alpha = 0f
+ designatedCorner!!.animate()
+ .alpha(1.0f)
+ .setDuration(300)
+ .start()
+ }
+ }
+
+ @UiThread
+ private fun setCornerVisibilities(vis: Int) {
+ views.forEach { corner ->
+ corner.visibility = vis
+ }
+ }
+
+ private fun cornerForView(v: View): Int {
+ return when (v) {
+ tl -> TOP_LEFT
+ tr -> TOP_RIGHT
+ bl -> BOTTOM_LEFT
+ br -> BOTTOM_RIGHT
+ else -> throw IllegalArgumentException("not a corner view")
+ }
+ }
+
+ private fun rotatedCorner(corner: Int): Int {
+ var modded = corner - rotation
+ if (modded < 0) {
+ modded += 4
+ }
+
+ return modded
+ }
+
+ private fun widthForCorner(corner: Int): Int {
+ return when (corner) {
+ TOP_LEFT, BOTTOM_LEFT -> leftSize
+ TOP_RIGHT, BOTTOM_RIGHT -> rightSize
+ else -> throw IllegalArgumentException("Unknown corner")
+ }
+ }
+
+ fun initialize(topLeft: View, topRight: View, bottomLeft: View, bottomRight: View) {
+ if (this::tl.isInitialized && this::tr.isInitialized &&
+ this::bl.isInitialized && this::br.isInitialized) {
+ if (tl == topLeft && tr == topRight && bl == bottomLeft && br == bottomRight) {
+ return
+ }
+ }
+
+ tl = topLeft
+ tr = topRight
+ bl = bottomLeft
+ br = bottomRight
+
+ designatedCorner = selectDesignatedCorner()
+ mainExecutor.execute {
+ animationScheduler.addCallback(systemStatusAnimationCallback)
+ }
+ }
+
+ /**
+ * Set the status bar height in portrait and landscape, in pixels. If they are the same you can
+ * pass the same value twice
+ */
+ fun setStatusBarHeights(portrait: Int, landscape: Int) {
+ sbHeightPortrait = portrait
+ sbHeightLandscape = landscape
+
+ hasMultipleHeights = portrait != landscape
+ }
+
+ /**
+ * The dot view containers will fill the margin in order to position the dots correctly
+ *
+ * @param left the space between the status bar contents and the left side of the screen
+ * @param right space between the status bar contents and the right side of the screen
+ */
+ fun setStatusBarMargins(left: Int, right: Int) {
+ leftSize = left
+ rightSize = right
+
+ needsMarginUpdate = true
+
+ // Margins come after PhoneStatusBarView does a layout pass, and so will always happen
+ // after rotation changes. It is safe to execute the updates from here
+ uiExecutor?.execute {
+ doUpdates(needsRotationUpdate, needsHeightUpdate, needsMarginUpdate)
+ }
+ }
+
+ private fun doUpdates(rot: Boolean, height: Boolean, width: Boolean) {
+ var newDesignatedCorner: View? = null
+
+ if (rot) {
+ needsRotationUpdate = false
+ updateRotations()
+ newDesignatedCorner = selectDesignatedCorner()
+ }
+
+ if (height) {
+ needsHeightUpdate = false
+ updateHeights(rotation)
+ }
+
+ if (width) {
+ needsMarginUpdate = false
+ updateCornerSizes()
+ }
+
+ if (newDesignatedCorner != null && newDesignatedCorner != designatedCorner) {
+ updateDesignatedCorner(newDesignatedCorner)
+ }
+ }
+
+ private val systemStatusAnimationCallback: SystemStatusAnimationCallback =
+ object : SystemStatusAnimationCallback {
+ override fun onSystemStatusAnimationTransitionToPersistentDot(): Animator? {
+ if (designatedCorner == null) {
+ return null
+ }
+
+ val alpha = ObjectAnimator.ofFloat(
+ designatedCorner, "alpha", 0f, 1f)
+ alpha.duration = DURATION
+ alpha.interpolator = Interpolators.ALPHA_OUT
+ alpha.addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationStart(animator: Animator) {
+ uiExecutor?.execute { designatedCorner?.visibility = View.VISIBLE }
+ }
+ })
+ return alpha
+ }
+
+ override fun onHidePersistentDot(): Animator? {
+ if (designatedCorner == null) {
+ return null
+ }
+
+ val alpha = ObjectAnimator.ofFloat(
+ designatedCorner, "alpha", 1f, 0f)
+ alpha.duration = DURATION
+ alpha.interpolator = Interpolators.ALPHA_OUT
+ alpha.addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animator: Animator) {
+ uiExecutor?.execute { designatedCorner?.visibility = View.INVISIBLE }
+ }
+ })
+ alpha.start()
+ return null
+ }
+ }
+}
+
+const val TOP_LEFT = 0
+const val TOP_RIGHT = 1
+const val BOTTOM_RIGHT = 2
+const val BOTTOM_LEFT = 3
+private const val DURATION = 160L
+private const val TAG = "PrivacyDotViewController"
+
+private fun Int.toGravity(): Int {
+ return when (this) {
+ TOP_LEFT -> Gravity.TOP or Gravity.LEFT
+ TOP_RIGHT -> Gravity.TOP or Gravity.RIGHT
+ BOTTOM_LEFT -> Gravity.BOTTOM or Gravity.LEFT
+ BOTTOM_RIGHT -> Gravity.BOTTOM or Gravity.RIGHT
+ else -> throw IllegalArgumentException("Not a corner")
+ }
+}
+
+private fun Int.innerGravity(): Int {
+ return when (this) {
+ TOP_LEFT -> Gravity.CENTER_VERTICAL or Gravity.RIGHT
+ TOP_RIGHT -> Gravity.CENTER_VERTICAL or Gravity.LEFT
+ BOTTOM_LEFT -> Gravity.CENTER_VERTICAL or Gravity.RIGHT
+ BOTTOM_RIGHT -> Gravity.CENTER_VERTICAL or Gravity.LEFT
+ else -> throw IllegalArgumentException("Not a corner")
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
new file mode 100644
index 0000000..6380dc0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.events
+
+import android.content.Context
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.ImageView
+import com.android.settingslib.graph.ThemedBatteryDrawable
+import com.android.systemui.R
+import com.android.systemui.privacy.OngoingPrivacyChip
+import com.android.systemui.privacy.PrivacyItem
+
+interface StatusEvent {
+ val priority: Int
+ // Whether or not to force the status bar open and show a dot
+ val forceVisible: Boolean
+ val viewCreator: (context: Context) -> View
+}
+
+class BatteryEvent : StatusEvent {
+ override val priority = 50
+ override val forceVisible = false
+
+ override val viewCreator: (context: Context) -> View = { context ->
+ val iv = ImageView(context)
+ iv.setImageDrawable(ThemedBatteryDrawable(context, Color.WHITE))
+ iv.setBackgroundDrawable(ColorDrawable(Color.GREEN))
+ iv
+ }
+
+ override fun toString(): String {
+ return javaClass.simpleName
+ }
+}
+class PrivacyEvent : StatusEvent {
+ override val priority = 100
+ override val forceVisible = true
+ var privacyItems: List<PrivacyItem> = listOf()
+
+ override val viewCreator: (context: Context) -> View = { context ->
+ val v = LayoutInflater.from(context)
+ .inflate(R.layout.ongoing_privacy_chip, null) as OngoingPrivacyChip
+ v.privacyList = privacyItems
+ v
+ }
+
+ override fun toString(): String {
+ return javaClass.simpleName
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
new file mode 100644
index 0000000..6209630
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.events
+
+import android.animation.ValueAnimator
+import android.content.Context
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup.LayoutParams.MATCH_PARENT
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import android.widget.FrameLayout
+
+import com.android.systemui.R
+import com.android.systemui.statusbar.SuperStatusBarViewFactory
+import com.android.systemui.statusbar.phone.StatusBarWindowController
+import com.android.systemui.statusbar.phone.StatusBarWindowView
+
+import javax.inject.Inject
+
+/**
+ * //TODO: this _probably_ doesn't control a window anymore
+ * Controls the window for system event animations.
+ */
+class SystemEventChipAnimationController @Inject constructor(
+ private val context: Context,
+ private val statusBarViewFactory: SuperStatusBarViewFactory,
+ private val statusBarWindowController: StatusBarWindowController
+) : SystemStatusChipAnimationCallback {
+ var showPersistentDot = false
+ set(value) {
+ field = value
+ statusBarWindowController.setForceStatusBarVisible(value)
+ maybeUpdateShowDot()
+ }
+
+ private lateinit var animationWindowView: FrameLayout
+ private lateinit var animationDotView: View
+ private lateinit var statusBarWindowView: StatusBarWindowView
+ private var currentAnimatedView: View? = null
+
+ // TODO: move to dagger
+ private var initialized = false
+
+ override fun onChipAnimationStart(
+ viewCreator: (context: Context) -> View,
+ @SystemAnimationState state: Int
+ ) {
+ if (!initialized) init()
+
+ if (state == ANIMATING_IN) {
+ currentAnimatedView = viewCreator(context)
+ animationWindowView.addView(currentAnimatedView, layoutParamsDefault)
+
+ // We are animating IN; chip comes in from View.END
+ currentAnimatedView?.apply {
+ translationX = width.toFloat()
+ alpha = 0f
+ visibility = View.VISIBLE
+ }
+ } else {
+ // We are animating away
+ currentAnimatedView?.apply {
+ translationX = 0f
+ alpha = 1f
+ }
+ }
+ }
+
+ override fun onChipAnimationEnd(@SystemAnimationState state: Int) {
+ if (state == ANIMATING_IN) {
+ // Finished animating in
+ currentAnimatedView?.apply {
+ translationX = 0f
+ alpha = 1f
+ }
+ } else {
+ // Finished animating away
+ currentAnimatedView?.apply {
+ visibility = View.INVISIBLE
+ }
+ animationWindowView.removeView(currentAnimatedView)
+ }
+ }
+
+ override fun onChipAnimationUpdate(
+ animator: ValueAnimator,
+ @SystemAnimationState state: Int
+ ) {
+ // Alpha is parameterized 0,1, and translation from (width, 0)
+ currentAnimatedView?.apply {
+ val amt = animator.animatedValue as Float
+
+ alpha = amt
+
+ val w = width
+ val translation = (1 - amt) * w
+ translationX = translation
+ }
+ }
+
+ private fun maybeUpdateShowDot() {
+ if (!initialized) return
+ if (!showPersistentDot && currentAnimatedView == null) {
+ animationDotView.visibility = View.INVISIBLE
+ }
+ }
+
+ private fun init() {
+ initialized = true
+ statusBarWindowView = statusBarViewFactory.statusBarWindowView
+ animationWindowView = LayoutInflater.from(context)
+ .inflate(R.layout.system_event_animation_window, null) as FrameLayout
+ animationDotView = animationWindowView.findViewById(R.id.dot_view)
+ val lp = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
+ lp.gravity = Gravity.END or Gravity.CENTER_VERTICAL
+ statusBarWindowView.addView(animationWindowView, lp)
+ }
+
+ private val layoutParamsDefault = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).also {
+ it.gravity = Gravity.END or Gravity.CENTER_VERTICAL
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
new file mode 100644
index 0000000..b481823
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.events
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.privacy.PrivacyItem
+import com.android.systemui.privacy.PrivacyItemController
+import com.android.systemui.statusbar.policy.BatteryController
+import javax.inject.Inject
+
+/**
+ * Listens for system events (battery, privacy, connectivity) and allows listeners
+ * to show status bar animations when they happen
+ */
+@SysUISingleton
+class SystemEventCoordinator @Inject constructor(
+ private val batteryController: BatteryController,
+ private val privacyController: PrivacyItemController
+) {
+ private lateinit var scheduler: SystemStatusAnimationScheduler
+
+ fun startObserving() {
+ /* currently unused
+ batteryController.addCallback(batteryStateListener)
+ */
+ privacyController.addCallback(privacyStateListener)
+ }
+
+ fun stopObserving() {
+ /* currently unused
+ batteryController.removeCallback(batteryStateListener)
+ */
+ privacyController.removeCallback(privacyStateListener)
+ }
+
+ fun attachScheduler(s: SystemStatusAnimationScheduler) {
+ this.scheduler = s
+ }
+
+ fun notifyPluggedIn() {
+ scheduler.onStatusEvent(BatteryEvent())
+ }
+
+ fun notifyPrivacyItemsEmpty() {
+ scheduler.setShouldShowPersistentPrivacyIndicator(false)
+ }
+
+ fun notifyPrivacyItemsChanged() {
+ val event = PrivacyEvent()
+ event.privacyItems = privacyStateListener.currentPrivacyItems
+ scheduler.onStatusEvent(event)
+ }
+
+ private val batteryStateListener = object : BatteryController.BatteryStateChangeCallback {
+ var plugged = false
+ var stateKnown = false
+ override fun onBatteryLevelChanged(level: Int, pluggedIn: Boolean, charging: Boolean) {
+ if (!stateKnown) {
+ stateKnown = true
+ plugged = pluggedIn
+ notifyListeners()
+ return
+ }
+
+ if (plugged != pluggedIn) {
+ plugged = pluggedIn
+ notifyListeners()
+ }
+ }
+
+ private fun notifyListeners() {
+ // We only care about the plugged in status
+ if (plugged) notifyPluggedIn()
+ }
+ }
+
+ private val privacyStateListener = object : PrivacyItemController.Callback {
+ var currentPrivacyItems = listOf<PrivacyItem>()
+
+ override fun onPrivacyItemsChanged(privacyItems: List<PrivacyItem>) {
+ if (privacyItems.isNotEmpty() && currentPrivacyItems.containsAll(privacyItems)) {
+ return
+ }
+ currentPrivacyItems = privacyItems
+ notifyListeners()
+ }
+
+ private fun notifyListeners() {
+ if (currentPrivacyItems.isEmpty()) {
+ notifyPrivacyItemsEmpty()
+ } else {
+ notifyPrivacyItemsChanged()
+ }
+ }
+ }
+}
+
+private const val TAG = "SystemEventCoordinator"
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
new file mode 100644
index 0000000..b85d031
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.events
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.AnimatorSet
+import android.animation.ValueAnimator
+import android.annotation.IntDef
+import android.content.Context
+import android.os.Process
+import android.util.Log
+import android.view.View
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.statusbar.phone.StatusBarWindowController
+import com.android.systemui.statusbar.policy.CallbackController
+import com.android.systemui.util.Assert
+import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.time.SystemClock
+
+import javax.inject.Inject
+
+/**
+ * Dead-simple scheduler for system status events. Obeys the following principles (all values TBD):
+ * - Avoiding log spam by only allowing 12 events per minute (1event/5s)
+ * - Waits 100ms to schedule any event for debouncing/prioritization
+ * - Simple prioritization: Privacy > Battery > connectivity (encoded in StatusEvent)
+ * - Only schedules a single event, and throws away lowest priority events
+ *
+ * There are 4 basic stages of animation at play here:
+ * 1. System chrome animation OUT
+ * 2. Chip animation IN
+ * 3. Chip animation OUT; potentially into a dot
+ * 4. System chrome animation IN
+ *
+ * Thus we can keep all animations synchronized with two separate ValueAnimators, one for system
+ * chrome and the other for the chip. These can animate from 0,1 and listeners can parameterize
+ * their respective views based on the progress of the animator. Interpolation differences TBD
+ */
+@SysUISingleton
+class SystemStatusAnimationScheduler @Inject constructor(
+ private val coordinator: SystemEventCoordinator,
+ private val chipAnimationController: SystemEventChipAnimationController,
+ private val statusBarWindowController: StatusBarWindowController,
+ private val systemClock: SystemClock,
+ @Main private val executor: DelayableExecutor
+) : CallbackController<SystemStatusAnimationCallback> {
+
+ /** True from the time a scheduled event starts until it's animation finishes */
+ var isActive = false
+ private set
+
+ @SystemAnimationState var animationState: Int = IDLE
+ private set
+
+ /** True if the persistent privacy dot should be active */
+ var hasPersistentDot = false
+ private set
+
+ private var scheduledEvent: StatusEvent? = null
+ private var cancelExecutionRunnable: Runnable? = null
+ private val listeners = mutableSetOf<SystemStatusAnimationCallback>()
+
+ init {
+ coordinator.attachScheduler(this)
+ }
+
+ fun onStatusEvent(event: StatusEvent) {
+ // Ignore any updates until the system is up and running
+ if (isTooEarly()) {
+ return
+ }
+
+ // Don't deal with threading for now (no need let's be honest)
+ Assert.isMainThread()
+ if (event.priority > scheduledEvent?.priority ?: -1) {
+ if (DEBUG) {
+ Log.d(TAG, "scheduling event $event")
+ }
+ scheduleEvent(event)
+ } else {
+ if (DEBUG) {
+ Log.d(TAG, "ignoring event $event")
+ }
+ }
+ }
+
+ private fun clearDotIfVisible() {
+ notifyHidePersistentDot()
+ }
+
+ fun setShouldShowPersistentPrivacyIndicator(should: Boolean) {
+ if (hasPersistentDot == should) {
+ return
+ }
+
+ hasPersistentDot = should
+
+ if (!hasPersistentDot) {
+ clearDotIfVisible()
+ }
+ }
+
+ private fun isTooEarly(): Boolean {
+ Log.d(TAG, "time=> ${systemClock.uptimeMillis() - Process.getStartUptimeMillis()}")
+ return systemClock.uptimeMillis() - Process.getStartUptimeMillis() < MIN_UPTIME
+ }
+
+ /**
+ * Clear the scheduled event (if any) and schedule a new one
+ */
+ private fun scheduleEvent(event: StatusEvent) {
+ scheduledEvent = event
+ if (scheduledEvent!!.forceVisible) {
+ hasPersistentDot = true
+ }
+
+ // Schedule the animation to start after a debounce period
+ cancelExecutionRunnable = executor.executeDelayed({
+ cancelExecutionRunnable = null
+ animationState = ANIMATING_IN
+ statusBarWindowController.setForceStatusBarVisible(true)
+
+ val entranceAnimator = ValueAnimator.ofFloat(1f, 0f)
+ entranceAnimator.duration = ENTRANCE_ANIM_LENGTH
+ entranceAnimator.addListener(systemAnimatorAdapter)
+ entranceAnimator.addUpdateListener(systemUpdateListener)
+
+ val chipAnimator = ValueAnimator.ofFloat(0f, 1f)
+ chipAnimator.duration = CHIP_ANIM_LENGTH
+ chipAnimator.addListener(
+ ChipAnimatorAdapter(RUNNING_CHIP_ANIM, scheduledEvent!!.viewCreator))
+ chipAnimator.addUpdateListener(chipUpdateListener)
+
+ val aSet2 = AnimatorSet()
+ aSet2.playSequentially(entranceAnimator, chipAnimator)
+ aSet2.start()
+
+ executor.executeDelayed({
+ animationState = ANIMATING_OUT
+
+ val systemAnimator = ValueAnimator.ofFloat(0f, 1f)
+ systemAnimator.duration = ENTRANCE_ANIM_LENGTH
+ systemAnimator.addListener(systemAnimatorAdapter)
+ systemAnimator.addUpdateListener(systemUpdateListener)
+
+ val chipAnimator = ValueAnimator.ofFloat(1f, 0f)
+ chipAnimator.duration = CHIP_ANIM_LENGTH
+ chipAnimator.addListener(ChipAnimatorAdapter(IDLE, scheduledEvent!!.viewCreator))
+ chipAnimator.addUpdateListener(chipUpdateListener)
+
+ val aSet2 = AnimatorSet()
+
+ aSet2.play(chipAnimator).before(systemAnimator)
+ if (hasPersistentDot) {
+ val dotAnim = notifyTransitionToPersistentDot()
+ if (dotAnim != null) aSet2.playTogether(systemAnimator, dotAnim)
+ }
+
+ aSet2.start()
+
+ statusBarWindowController.setForceStatusBarVisible(false)
+ scheduledEvent = null
+ }, DISPLAY_LENGTH)
+ }, DELAY)
+ }
+
+ private fun notifyTransitionToPersistentDot(): Animator? {
+ val anims: List<Animator> = listeners.mapNotNull {
+ it.onSystemStatusAnimationTransitionToPersistentDot()
+ }
+ if (anims.isNotEmpty()) {
+ val aSet = AnimatorSet()
+ aSet.playTogether(anims)
+ return aSet
+ }
+
+ return null
+ }
+
+ private fun notifyHidePersistentDot(): Animator? {
+ val anims: List<Animator> = listeners.mapNotNull {
+ it.onHidePersistentDot()
+ }
+
+ if (anims.isNotEmpty()) {
+ val aSet = AnimatorSet()
+ aSet.playTogether(anims)
+ return aSet
+ }
+
+ return null
+ }
+
+ private fun notifySystemStart() {
+ listeners.forEach { it.onSystemChromeAnimationStart() }
+ }
+
+ private fun notifySystemFinish() {
+ listeners.forEach { it.onSystemChromeAnimationEnd() }
+ }
+
+ private fun notifySystemAnimationUpdate(anim: ValueAnimator) {
+ listeners.forEach { it.onSystemChromeAnimationUpdate(anim) }
+ }
+
+ override fun addCallback(listener: SystemStatusAnimationCallback) {
+ Assert.isMainThread()
+
+ if (listeners.isEmpty()) {
+ coordinator.startObserving()
+ }
+ listeners.add(listener)
+ }
+
+ override fun removeCallback(listener: SystemStatusAnimationCallback) {
+ Assert.isMainThread()
+
+ listeners.remove(listener)
+ if (listeners.isEmpty()) {
+ coordinator.stopObserving()
+ }
+ }
+
+ private val systemUpdateListener = ValueAnimator.AnimatorUpdateListener {
+ anim -> notifySystemAnimationUpdate(anim)
+ }
+
+ private val systemAnimatorAdapter = object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(p0: Animator?) {
+ notifySystemFinish()
+ }
+
+ override fun onAnimationStart(p0: Animator?) {
+ notifySystemStart()
+ }
+ }
+
+ private val chipUpdateListener = ValueAnimator.AnimatorUpdateListener {
+ anim -> chipAnimationController.onChipAnimationUpdate(anim, animationState)
+ }
+
+ inner class ChipAnimatorAdapter(
+ @SystemAnimationState val endState: Int,
+ val viewCreator: (context: Context) -> View
+ ) : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(p0: Animator?) {
+ chipAnimationController.onChipAnimationEnd(animationState)
+ animationState = endState
+ }
+
+ override fun onAnimationStart(p0: Animator?) {
+ chipAnimationController.onChipAnimationStart(viewCreator, animationState)
+ }
+ }
+}
+
+/**
+ * The general idea here is that this scheduler will run two value animators, and provide
+ * animator-like callbacks for each kind of animation. The SystemChrome animation is expected to
+ * create space for the chip animation to display. This means hiding the system elements in the
+ * status bar and keyguard.
+ *
+ * TODO: the chip animation really only has one client, we can probably remove it from this
+ * interface
+ *
+ * The value animators themselves are simple animators from 0.0 to 1.0. Listeners can apply any
+ * interpolation they choose but realistically these are most likely to be simple alpha transitions
+ */
+interface SystemStatusAnimationCallback {
+ @JvmDefault fun onSystemChromeAnimationUpdate(animator: ValueAnimator) {}
+ @JvmDefault fun onSystemChromeAnimationStart() {}
+ @JvmDefault fun onSystemChromeAnimationEnd() {}
+
+ // Best method name, change my mind
+ @JvmDefault fun onSystemStatusAnimationTransitionToPersistentDot(): Animator? { return null }
+ @JvmDefault fun onHidePersistentDot(): Animator? { return null }
+}
+
+interface SystemStatusChipAnimationCallback {
+ fun onChipAnimationUpdate(animator: ValueAnimator, @SystemAnimationState state: Int) {}
+
+ fun onChipAnimationStart(
+ viewCreator: (context: Context) -> View,
+ @SystemAnimationState state: Int
+ ) {}
+
+ fun onChipAnimationEnd(@SystemAnimationState state: Int) {}
+}
+
+/**
+ */
+@Retention(AnnotationRetention.SOURCE)
+@IntDef(
+ value = [
+ IDLE, ANIMATING_IN, RUNNING_CHIP_ANIM, ANIMATING_OUT
+ ]
+)
+annotation class SystemAnimationState
+
+/** No animation is in progress */
+const val IDLE = 0
+/** System is animating out, and chip is animating in */
+const val ANIMATING_IN = 1
+/** Chip has animated in and is awaiting exit animation, and optionally playing its own animation */
+const val RUNNING_CHIP_ANIM = 2
+/** Chip is animating away and system is animating back */
+const val ANIMATING_OUT = 3
+
+private const val TAG = "SystemStatusAnimationScheduler"
+private const val DELAY: Long = 100
+private const val DISPLAY_LENGTH = 5000L
+private const val ENTRANCE_ANIM_LENGTH = 500L
+private const val CHIP_ANIM_LENGTH = 500L
+private const val MIN_UPTIME: Long = 5 * 1000
+
+private const val DEBUG = false
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationActivityStarter.java
index 5748c4a..2537b19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationActivityStarter.java
@@ -18,6 +18,7 @@
import android.content.Intent;
import android.service.notification.StatusBarNotification;
+import android.view.View;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -33,7 +34,8 @@
void startNotificationGutsIntent(Intent intent, int appUid,
ExpandableNotificationRow row);
- void startHistoryIntent(boolean showHistory);
+ /** Called when the user clicks "Manage" or "History" in the Shade. */
+ void startHistoryIntent(View view, boolean showHistory);
default boolean isCollapsingToShowActivityOverLockscreen() {
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 78fcf18c..f8543f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -170,8 +170,8 @@
}
private void updateColors() {
- mNormalColor = Utils.getColorAttr(mContext, android.R.attr.colorBackground)
- .getDefaultColor();
+ mNormalColor = Utils.getColorAttrDefaultColor(mContext,
+ com.android.internal.R.attr.colorSurface);
mTintedRippleColor = mContext.getColor(
R.color.notification_ripple_tinted_color);
mNormalRippleColor = mContext.getColor(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
index 4ed5056..3bf0ddb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
@@ -106,10 +106,6 @@
showHistory(mShowHistory);
}
- public boolean isButtonVisible() {
- return mManageButton.getAlpha() != 0.0f;
- }
-
@Override
public ExpandableViewState createExpandableViewState() {
return new FooterViewState();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index fa6f23d..3434f67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -44,6 +44,7 @@
import android.content.pm.ShortcutManager;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -181,7 +182,7 @@
showPriorityOnboarding();
} else if (mSelectedAction == ACTION_FAVORITE && getPriority() != mSelectedAction) {
mShadeController.animateCollapsePanels();
- mPeopleSpaceWidgetManager.requestPinAppWidget(mShortcutInfo);
+ mPeopleSpaceWidgetManager.requestPinAppWidget(mShortcutInfo, new Bundle());
}
mGutsContainer.closeControls(v, true);
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PriorityOnboardingDialogController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PriorityOnboardingDialogController.kt
index 9bbe616..270721f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PriorityOnboardingDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PriorityOnboardingDialogController.kt
@@ -28,6 +28,7 @@
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
+import android.os.Bundle
import android.text.SpannableStringBuilder
import android.text.style.BulletSpan
import android.view.Gravity
@@ -86,7 +87,7 @@
Prefs.putBoolean(context, Prefs.Key.HAS_SEEN_PRIORITY_ONBOARDING_IN_S, true)
dialog.dismiss()
shadeController.animateCollapsePanels()
- peopleSpaceWidgetManager.requestPinAppWidget(shortcutInfo)
+ peopleSpaceWidgetManager.requestPinAppWidget(shortcutInfo, Bundle())
}
private fun settings() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 733a9f6..751573a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -4877,7 +4877,7 @@
clearNotifications(ROWS_ALL, true /* closeShade */);
});
footerView.setManageButtonClickListener(v -> {
- mNotificationActivityStarter.startHistoryIntent(mFooterView.isHistoryShown());
+ mNotificationActivityStarter.startHistoryIntent(v, mFooterView.isHistoryShown());
});
setFooterView(footerView);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index 40e6b40..1eccfd8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -19,10 +19,16 @@
import static android.app.StatusBarManager.DISABLE_NOTIFICATION_ICONS;
import static android.app.StatusBarManager.DISABLE_SYSTEM_INFO;
+import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.ANIMATING_IN;
+import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.ANIMATING_OUT;
+import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.IDLE;
+
+import android.animation.ValueAnimator;
import android.annotation.Nullable;
import android.app.Fragment;
import android.os.Bundle;
import android.os.Parcelable;
+import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
@@ -36,6 +42,9 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.events.PrivacyDotViewController;
+import com.android.systemui.statusbar.events.SystemStatusAnimationCallback;
+import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallListener;
@@ -44,6 +53,8 @@
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
+import org.jetbrains.annotations.NotNull;
+
import java.util.ArrayList;
import java.util.List;
@@ -55,7 +66,8 @@
* updated by the StatusBarIconController and DarkIconManager while it is attached.
*/
public class CollapsedStatusBarFragment extends Fragment implements CommandQueue.Callbacks,
- StatusBarStateController.StateListener {
+ StatusBarStateController.StateListener,
+ SystemStatusAnimationCallback {
public static final String TAG = "CollapsedStatusBarFragment";
private static final String EXTRA_PANEL_STATE = "panel_state";
@@ -78,6 +90,8 @@
private View mOperatorNameFrame;
private CommandQueue mCommandQueue;
private OngoingCallController mOngoingCallController;
+ private final SystemStatusAnimationScheduler mAnimationScheduler;
+ private final PrivacyDotViewController mDotViewController;
private List<String> mBlockedIcons = new ArrayList<>();
@@ -103,8 +117,14 @@
};
@Inject
- public CollapsedStatusBarFragment(OngoingCallController ongoingCallController) {
+ public CollapsedStatusBarFragment(
+ OngoingCallController ongoingCallController,
+ SystemStatusAnimationScheduler animationScheduler,
+ PrivacyDotViewController dotViewController
+ ) {
mOngoingCallController = ongoingCallController;
+ mAnimationScheduler = animationScheduler;
+ mDotViewController = dotViewController;
}
@Override
@@ -127,6 +147,9 @@
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mStatusBar = (PhoneStatusBarView) view;
+ View contents = mStatusBar.findViewById(R.id.status_bar_contents);
+ contents.addOnLayoutChangeListener(mStatusBarLayoutListener);
+ updateStatusBarLocation(contents.getLeft(), contents.getRight());
if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_PANEL_STATE)) {
mStatusBar.restoreHierarchyState(
savedInstanceState.getSparseParcelableArray(EXTRA_PANEL_STATE));
@@ -139,10 +162,12 @@
Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager);
mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area);
mClockView = mStatusBar.findViewById(R.id.clock);
+ mOngoingCallChip = mStatusBar.findViewById(R.id.ongoing_call_chip);
showSystemIconArea(false);
showClock(false);
initEmergencyCryptkeeperText();
initOperatorName();
+ mAnimationScheduler.addCallback(this);
}
@Override
@@ -158,7 +183,7 @@
super.onResume();
mCommandQueue.addCallback(this);
mStatusBarStateController.addCallback(this);
- mOngoingCallController.addCallback(mOngoingCallListener);
+ initOngoingCallChip();
}
@Override
@@ -197,8 +222,6 @@
}
statusBarCenteredIconArea.addView(mCenteredIconArea);
- initOngoingCallChip();
-
// Default to showing until we know otherwise.
showNotificationIconArea(false);
}
@@ -208,6 +231,7 @@
if (displayId != getContext().getDisplayId()) {
return;
}
+ Log.d(TAG, "disable: ");
state1 = adjustDisableFlags(state1);
final int old1 = mDisabled1;
final int diff1 = state1 ^ old1;
@@ -248,7 +272,7 @@
state |= DISABLE_CLOCK;
}
- if (mOngoingCallController.getHasOngoingCall()) {
+ if (mOngoingCallController.hasOngoingCall()) {
state |= DISABLE_NOTIFICATION_ICONS;
}
@@ -292,19 +316,22 @@
return false;
}
- public void hideSystemIconArea(boolean animate) {
+ private void hideSystemIconArea(boolean animate) {
animateHide(mSystemIconArea, animate);
}
- public void showSystemIconArea(boolean animate) {
- animateShow(mSystemIconArea, animate);
+ private void showSystemIconArea(boolean animate) {
+ // Only show the system icon area if we are not currently animating
+ if (mAnimationScheduler.getAnimationState() == IDLE) {
+ animateShow(mSystemIconArea, animate);
+ }
}
- public void hideClock(boolean animate) {
+ private void hideClock(boolean animate) {
animateHiddenState(mClockView, clockHiddenMode(), animate);
}
- public void showClock(boolean animate) {
+ private void showClock(boolean animate) {
animateShow(mClockView, animate);
}
@@ -420,17 +447,65 @@
}
private void initOngoingCallChip() {
- mOngoingCallChip = mStatusBar.findViewById(R.id.ongoing_call_chip);
+ mOngoingCallController.addCallback(mOngoingCallListener);
mOngoingCallController.setChipView(mOngoingCallChip);
}
@Override
- public void onStateChanged(int newState) {
-
- }
+ public void onStateChanged(int newState) { }
@Override
public void onDozingChanged(boolean isDozing) {
disable(getContext().getDisplayId(), mDisabled1, mDisabled1, false /* animate */);
}
+
+ @Override
+ public void onSystemChromeAnimationStart() {
+ if (mAnimationScheduler.getAnimationState() == ANIMATING_OUT
+ && !isSystemIconAreaDisabled()) {
+ mSystemIconArea.setVisibility(View.VISIBLE);
+ mSystemIconArea.setAlpha(0f);
+ }
+ }
+
+ @Override
+ public void onSystemChromeAnimationEnd() {
+ // Make sure the system icons are out of the way
+ if (mAnimationScheduler.getAnimationState() == ANIMATING_IN) {
+ mSystemIconArea.setVisibility(View.INVISIBLE);
+ mSystemIconArea.setAlpha(0f);
+ } else {
+ if (isSystemIconAreaDisabled()) {
+ // don't unhide
+ return;
+ }
+
+ mSystemIconArea.setAlpha(1f);
+ mSystemIconArea.setVisibility(View.VISIBLE);
+ }
+ }
+
+ @Override
+ public void onSystemChromeAnimationUpdate(@NotNull ValueAnimator animator) {
+ mSystemIconArea.setAlpha((float) animator.getAnimatedValue());
+ }
+
+ private boolean isSystemIconAreaDisabled() {
+ return (mDisabled1 & DISABLE_SYSTEM_INFO) != 0 || (mDisabled2 & DISABLE2_SYSTEM_ICONS) != 0;
+ }
+
+ private void updateStatusBarLocation(int left, int right) {
+ int leftMargin = left - mStatusBar.getLeft();
+ int rightMargin = mStatusBar.getRight() - right;
+
+ mDotViewController.setStatusBarMargins(leftMargin, rightMargin);
+ }
+
+ // Listen for view end changes of PhoneStatusBarView and publish that to the privacy dot
+ private View.OnLayoutChangeListener mStatusBarLayoutListener =
+ (view, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
+ if (left != oldLeft || right != oldRight) {
+ updateStatusBarLocation(left, right);
+ }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index c3325b1..8cef23f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -68,6 +68,7 @@
import android.widget.TextView;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.LockPatternUtils;
@@ -154,6 +155,7 @@
private StatusBar mStatusBar;
private KeyguardAffordanceHelper mAffordanceHelper;
private FalsingManager mFalsingManager;
+ @Nullable private Executor mUiExecutor;
private boolean mUserSetupComplete;
private boolean mPrewarmBound;
private Messenger mPrewarmMessenger;
@@ -181,6 +183,7 @@
private String mLeftButtonStr;
private boolean mDozing;
private int mIndicationBottomMargin;
+ private int mIndicationPadding;
private float mDarkAmount;
private int mBurnInXOffset;
private int mBurnInYOffset;
@@ -274,6 +277,10 @@
mAccessibilityController = Dependency.get(AccessibilityController.class);
mActivityIntentHelper = new ActivityIntentHelper(getContext());
updateLeftAffordance();
+
+ mIndicationPadding = getResources().getDimensionPixelSize(
+ R.dimen.keyguard_indication_area_padding);
+ updateWalletVisibility();
}
@Override
@@ -356,6 +363,10 @@
lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
mWalletButton.setLayoutParams(lp);
+
+ mIndicationPadding = getResources().getDimensionPixelSize(
+ R.dimen.keyguard_indication_area_padding);
+ updateWalletVisibility();
}
private void updateRightAffordanceIcon() {
@@ -429,11 +440,13 @@
}
private void updateWalletVisibility() {
- if (mDozing || !mWalletEnabled) {
+ if (mDozing || !mWalletEnabled || !mHasCard) {
mWalletButton.setVisibility(GONE);
+ mIndicationArea.setPadding(0, 0, 0, 0);
} else {
mWalletButton.setVisibility(VISIBLE);
mWalletButton.setOnClickListener(this::onWalletClick);
+ mIndicationArea.setPadding(mIndicationPadding, 0, mIndicationPadding, 0);
}
}
@@ -659,6 +672,13 @@
updateCameraVisibility();
}
+ @Override
+ public void onKeyguardShowingChanged() {
+ if (mKeyguardStateController.isShowing()) {
+ queryWalletCards();
+ }
+ }
+
private void inflateCameraPreview() {
View previewBefore = mCameraPreview;
boolean visibleBefore = false;
@@ -897,18 +917,20 @@
public void initWallet(QuickAccessWalletClient client, Executor uiExecutor, boolean enabled) {
mQuickAccessWalletClient = client;
mWalletEnabled = enabled && client.isWalletFeatureAvailable();
+ mUiExecutor = uiExecutor;
+ queryWalletCards();
- if (mWalletEnabled) {
- queryWalletCards(uiExecutor);
- }
updateWalletVisibility();
}
- private void queryWalletCards(Executor uiExecutor) {
+ private void queryWalletCards() {
+ if (!mWalletEnabled || mUiExecutor == null) {
+ return;
+ }
GetWalletCardsRequest request =
new GetWalletCardsRequest(1 /* cardWidth */, 1 /* cardHeight */,
1 /* iconSizePx */, 2 /* maxCards */);
- mQuickAccessWalletClient.getWalletCards(uiExecutor, request, mCardRetriever);
+ mQuickAccessWalletClient.getWalletCards(mUiExecutor, request, mCardRetriever);
}
private void onWalletClick(View v) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 0694737..c22fec9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -18,7 +18,10 @@
import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection;
+import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.ANIMATING_IN;
+import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.ANIMATING_OUT;
+import android.animation.ValueAnimator;
import android.annotation.ColorInt;
import android.content.Context;
import android.content.res.Configuration;
@@ -47,6 +50,8 @@
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
+import com.android.systemui.statusbar.events.SystemStatusAnimationCallback;
+import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
@@ -64,8 +69,11 @@
/**
* The header group on Keyguard.
*/
-public class KeyguardStatusBarView extends RelativeLayout
- implements BatteryStateChangeCallback, OnUserInfoChangedListener, ConfigurationListener {
+public class KeyguardStatusBarView extends RelativeLayout implements
+ BatteryStateChangeCallback,
+ OnUserInfoChangedListener,
+ ConfigurationListener,
+ SystemStatusAnimationCallback {
private static final int LAYOUT_NONE = 0;
private static final int LAYOUT_CUTOUT = 1;
@@ -96,6 +104,8 @@
private ViewGroup mStatusIconArea;
private int mLayoutState = LAYOUT_NONE;
+ private SystemStatusAnimationScheduler mAnimationScheduler;
+
/**
* Draw this many pixels into the left/right side of the cutout to optimally use the space
*/
@@ -125,6 +135,7 @@
loadDimens();
loadBlockList();
mBatteryController = Dependency.get(BatteryController.class);
+ mAnimationScheduler = Dependency.get(SystemStatusAnimationScheduler.class);
}
@Override
@@ -349,6 +360,7 @@
mIconManager = new TintedIconManager(findViewById(R.id.statusIcons));
mIconManager.setBlockList(mBlockedIcons);
Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager);
+ mAnimationScheduler.addCallback(this);
onThemeChanged();
}
@@ -358,6 +370,7 @@
Dependency.get(UserInfoController.class).removeCallback(this);
Dependency.get(StatusBarIconController.class).removeIconGroup(mIconManager);
Dependency.get(ConfigurationController.class).removeCallback(this);
+ mAnimationScheduler.removeCallback(this);
}
@Override
@@ -509,4 +522,30 @@
mBatteryView.dump(fd, pw, args);
}
}
+
+ /** SystemStatusAnimationCallback */
+ @Override
+ public void onSystemChromeAnimationStart() {
+ if (mAnimationScheduler.getAnimationState() == ANIMATING_OUT) {
+ mSystemIconsContainer.setVisibility(View.VISIBLE);
+ mSystemIconsContainer.setAlpha(0f);
+ }
+ }
+
+ @Override
+ public void onSystemChromeAnimationEnd() {
+ // Make sure the system icons are out of the way
+ if (mAnimationScheduler.getAnimationState() == ANIMATING_IN) {
+ mSystemIconsContainer.setVisibility(View.INVISIBLE);
+ mSystemIconsContainer.setAlpha(0f);
+ } else {
+ mSystemIconsContainer.setAlpha(1f);
+ mSystemIconsContainer.setVisibility(View.VISIBLE);
+ }
+ }
+
+ @Override
+ public void onSystemChromeAnimationUpdate(ValueAnimator anim) {
+ mSystemIconsContainer.setAlpha((float) anim.getAnimatedValue());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index 5aecb72..0c8122c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -666,7 +666,9 @@
pw.println(TAG + ":");
pw.println(" mKeyguardDisplayMode=" + mKeyguardDisplayMode);
pw.println(mCurrentState);
- mNotificationShadeView.getViewRootImpl().dump(" ", pw);
+ if (mNotificationShadeView != null && mNotificationShadeView.getViewRootImpl() != null) {
+ mNotificationShadeView.getViewRootImpl().dump(" ", pw);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index d386ebd..0e99d3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -208,6 +208,8 @@
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.charging.WiredChargingRippleController;
+import com.android.systemui.statusbar.events.PrivacyDotViewController;
+import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
@@ -426,6 +428,8 @@
private final DemoModeController mDemoModeController;
private NotificationsController mNotificationsController;
private final OngoingCallController mOngoingCallController;
+ private final SystemStatusAnimationScheduler mAnimationScheduler;
+ private final PrivacyDotViewController mDotViewController;
// expanded notifications
// the sliding/resizing panel within the notification window
@@ -794,6 +798,8 @@
BrightnessSlider.Factory brightnessSliderFactory,
WiredChargingRippleController chargingRippleAnimationController,
OngoingCallController ongoingCallController,
+ SystemStatusAnimationScheduler animationScheduler,
+ PrivacyDotViewController dotViewController,
TunerService tunerService,
FeatureFlags featureFlags) {
super(context);
@@ -875,6 +881,8 @@
mBrightnessSliderFactory = brightnessSliderFactory;
mChargingRippleAnimationController = chargingRippleAnimationController;
mOngoingCallController = ongoingCallController;
+ mAnimationScheduler = animationScheduler;
+ mDotViewController = dotViewController;
mFeatureFlags = featureFlags;
tunerService.addTunable(
@@ -1171,7 +1179,10 @@
}).getFragmentManager()
.beginTransaction()
.replace(R.id.status_bar_container,
- new CollapsedStatusBarFragment(mOngoingCallController),
+ new CollapsedStatusBarFragment(
+ mOngoingCallController,
+ mAnimationScheduler,
+ mDotViewController),
CollapsedStatusBarFragment.TAG)
.commit();
@@ -1788,7 +1799,15 @@
@Override
public void startActivity(Intent intent, boolean dismissShade) {
- startActivityDismissingKeyguard(intent, false, dismissShade);
+ startActivityDismissingKeyguard(intent, false /* onlyProvisioned */, dismissShade);
+ }
+
+ @Override
+ public void startActivity(Intent intent, boolean dismissShade,
+ ActivityLaunchAnimator.Controller animationController) {
+ startActivityDismissingKeyguard(intent, false, dismissShade,
+ false /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */,
+ 0 /* flags */, animationController);
}
@Override
@@ -4603,9 +4622,6 @@
} else {
options = ActivityOptions.makeBasic();
}
- // Anything launched from the notification shade should always go into the secondary
- // split-screen windowing mode.
- options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
return options;
}
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 3404528..4356b52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -39,6 +39,7 @@
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.EventLog;
+import android.view.View;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.NotificationVisibility;
@@ -462,7 +463,7 @@
mActivityStarter.dismissKeyguardThenExecute(() -> {
AsyncTask.execute(() -> {
ActivityLaunchAnimator.Controller animationController = null;
- if (!mStatusBar.isOccluded() && mStatusBar.areLaunchAnimationsEnabled()) {
+ if (mStatusBar.areLaunchAnimationsEnabled()) {
animationController = new StatusBarLaunchAnimatorController(
mNotificationAnimationProvider.getAnimatorController(row), mStatusBar,
true /* isActivityIntent */);
@@ -495,7 +496,7 @@
}
@Override
- public void startHistoryIntent(boolean showHistory) {
+ public void startHistoryIntent(View view, boolean showHistory) {
mActivityStarter.dismissKeyguardThenExecute(() -> {
AsyncTask.execute(() -> {
Intent intent = showHistory ? new Intent(
@@ -506,11 +507,27 @@
if (showHistory) {
tsb.addNextIntent(intent);
}
- tsb.startActivities(null, UserHandle.CURRENT);
- // Putting it back on the main thread, since we're touching views
- mMainThreadHandler.post(() -> mCommandQueue.animateCollapsePanels(
- CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */));
+ ActivityLaunchAnimator.Controller animationController = null;
+ if (mStatusBar.areLaunchAnimationsEnabled()) {
+ animationController = new StatusBarLaunchAnimatorController(
+ ActivityLaunchAnimator.Controller.fromView(view), mStatusBar,
+ true /* isActivityIntent */);
+ }
+
+ mActivityLaunchAnimator.startIntentWithAnimation(animationController,
+ (adapter) -> tsb.startActivities(
+ getActivityOptions(mStatusBar.getDisplayId(), adapter),
+ UserHandle.CURRENT));
+
+ // Note that other cases when we should still collapse (like activity already on
+ // top) is handled by the StatusBarLaunchAnimatorController.
+ boolean shouldCollapse = animationController == null;
+ if (shouldCollapse) {
+ // Putting it back on the main thread, since we're touching views
+ mMainThreadHandler.post(() -> mCommandQueue.animateCollapsePanels(
+ CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */));
+ }
});
return true;
}, null, false /* afterKeyguardGone */);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 2c2779e..24e6db8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -61,6 +61,8 @@
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.charging.WiredChargingRippleController;
+import com.android.systemui.statusbar.events.PrivacyDotViewController;
+import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
@@ -209,6 +211,8 @@
BrightnessSlider.Factory brightnessSliderFactory,
WiredChargingRippleController chargingRippleAnimationController,
OngoingCallController ongoingCallController,
+ SystemStatusAnimationScheduler animationScheduler,
+ PrivacyDotViewController dotViewController,
TunerService tunerService,
FeatureFlags featureFlags) {
return new StatusBar(
@@ -293,6 +297,8 @@
brightnessSliderFactory,
chargingRippleAnimationController,
ongoingCallController,
+ animationScheduler,
+ dotViewController,
tunerService,
featureFlags);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index b55db6f..96473c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -18,11 +18,14 @@
import android.app.Notification
import android.app.Notification.CallStyle.CALL_TYPE_ONGOING
+import android.content.Intent
import android.util.Log
import android.view.ViewGroup
import android.widget.Chronometer
import com.android.systemui.R
+import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.statusbar.FeatureFlags
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
@@ -38,11 +41,12 @@
class OngoingCallController @Inject constructor(
private val notifCollection: CommonNotifCollection,
private val featureFlags: FeatureFlags,
- private val systemClock: SystemClock
+ private val systemClock: SystemClock,
+ private val activityStarter: ActivityStarter
) : CallbackController<OngoingCallListener> {
- var hasOngoingCall = false
- private set
+ /** Null if there's no ongoing call. */
+ private var ongoingCallInfo: OngoingCallInfo? = null
private var chipView: ViewGroup? = null
private val mListeners: MutableList<OngoingCallListener> = mutableListOf()
@@ -50,25 +54,16 @@
private val notifListener = object : NotifCollectionListener {
override fun onEntryUpdated(entry: NotificationEntry) {
if (isOngoingCallNotification(entry)) {
- val timeView = chipView?.findViewById<Chronometer>(R.id.ongoing_call_chip_time)
- if (timeView != null) {
- hasOngoingCall = true
- val callStartTime = entry.sbn.notification.`when`
- timeView.base = callStartTime -
- System.currentTimeMillis() +
- systemClock.elapsedRealtime()
- timeView.start()
- mListeners.forEach { l -> l.onOngoingCallStarted(animate = true) }
- } else if (DEBUG) {
- Log.w(TAG, "Ongoing call chip view could not be found; " +
- "Not displaying chip in status bar")
- }
+ ongoingCallInfo = OngoingCallInfo(
+ entry.sbn.notification.`when`,
+ entry.sbn.notification.contentIntent.intent)
+ updateChip()
}
}
override fun onEntryRemoved(entry: NotificationEntry, reason: Int) {
if (isOngoingCallNotification(entry)) {
- hasOngoingCall = false
+ ongoingCallInfo = null
mListeners.forEach { l -> l.onOngoingCallEnded(animate = true) }
}
}
@@ -80,10 +75,23 @@
}
}
- fun setChipView(chipView: ViewGroup?) {
+ /**
+ * Sets the chip view that will contain ongoing call information.
+ *
+ * Should only be called from [CollapedStatusBarFragment].
+ */
+ fun setChipView(chipView: ViewGroup) {
this.chipView = chipView
+ if (hasOngoingCall()) {
+ updateChip()
+ }
}
+ /**
+ * Returns true if there's an active ongoing call that can be displayed in a status bar chip.
+ */
+ fun hasOngoingCall(): Boolean = ongoingCallInfo != null
+
override fun addCallback(listener: OngoingCallListener) {
synchronized(mListeners) {
if (!mListeners.contains(listener)) {
@@ -97,6 +105,43 @@
mListeners.remove(listener)
}
}
+
+ private fun updateChip() {
+ val currentOngoingCallInfo = ongoingCallInfo ?: return
+
+ val currentChipView = chipView
+ val timeView =
+ currentChipView?.findViewById<Chronometer>(R.id.ongoing_call_chip_time)
+
+ if (currentChipView != null && timeView != null) {
+ timeView.base = currentOngoingCallInfo.callStartTime -
+ System.currentTimeMillis() +
+ systemClock.elapsedRealtime()
+ timeView.start()
+
+ currentChipView.setOnClickListener {
+ activityStarter.postStartActivityDismissingKeyguard(
+ currentOngoingCallInfo.intent, 0,
+ ActivityLaunchAnimator.Controller.fromView(it))
+ }
+
+ mListeners.forEach { l -> l.onOngoingCallStarted(animate = true) }
+ } else {
+ // If we failed to update the chip, don't store the ongoing call info. Then
+ // [hasOngoingCall] will return false and we fall back to typical notification handling.
+ ongoingCallInfo = null
+
+ if (DEBUG) {
+ Log.w(TAG, "Ongoing call chip view could not be found; " +
+ "Not displaying chip in status bar")
+ }
+ }
+ }
+
+ private class OngoingCallInfo(
+ val callStartTime: Long,
+ val intent: Intent
+ )
}
private fun isOngoingCallNotification(entry: NotificationEntry): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java
index d195062..d1a2c8a 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java
@@ -222,6 +222,11 @@
if (mIsDismissed) {
return;
}
+ int cardWidthPx = mCardCarousel.getCardWidthPx();
+ int cardHeightPx = mCardCarousel.getCardHeightPx();
+ if (cardWidthPx == 0 || cardHeightPx == 0) {
+ return;
+ }
if (!mHasRegisteredListener) {
// Listener is registered even when device is locked. Should only be registered once.
mWalletClient.addWalletServiceEventListener(this);
@@ -231,8 +236,6 @@
mWalletView.show();
mWalletView.hideErrorMessage();
int iconSizePx = mContext.getResources().getDimensionPixelSize(R.dimen.wallet_icon_size);
- int cardWidthPx = mCardCarousel.getCardWidthPx();
- int cardHeightPx = mCardCarousel.getCardHeightPx();
GetWalletCardsRequest request =
new GetWalletCardsRequest(cardWidthPx, cardHeightPx, iconSizePx, MAX_CARDS);
mWalletClient.getWalletCards(mExecutor, request, this);
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index 74b79d5..81bb819 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -268,6 +268,7 @@
public void onStop() {
mSysUiMainExecutor.execute(() -> {
if (oneHanded.isOneHandedEnabled()) {
+ // Log metrics for 3-button navigation mode.
oneHanded.stopOneHanded(
OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_GESTURE_OUT);
} else if (oneHanded.isSwipeToNotificationEnabled()) {
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
index 3fc3d89..f96d344 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
@@ -381,8 +381,8 @@
@WMSingleton
@Provides
static StartingWindowController provideStartingWindowController(Context context,
- @ShellSplashscreenThread ShellExecutor executor, TransactionPool pool) {
- return new StartingWindowController(context, executor, pool);
+ @ShellSplashscreenThread ShellExecutor splashScreenExecutor, TransactionPool pool) {
+ return new StartingWindowController(context, splashScreenExecutor, pool);
}
//
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index a870915..4d4acd9 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -16,16 +16,15 @@
package com.android.keyguard;
+import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.test.suitebuilder.annotation.SmallTest;
@@ -38,13 +37,13 @@
import com.android.internal.colorextraction.ColorExtractor;
import com.android.keyguard.clock.ClockManager;
import com.android.systemui.R;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.plugins.BcSmartspaceDataPlugin;
import com.android.systemui.plugins.ClockPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
@@ -87,12 +86,8 @@
@Mock
NotificationIconAreaController mNotificationIconAreaController;
@Mock
- ContentResolver mContentResolver;
- @Mock
BroadcastDispatcher mBroadcastDispatcher;
@Mock
- private PluginManager mPluginManager;
- @Mock
private FeatureFlags mFeatureFlags;
@Mock
private Executor mExecutor;
@@ -106,6 +101,12 @@
BatteryController mBatteryController;
@Mock
ConfigurationController mConfigurationController;
+ @Mock
+ BcSmartspaceDataPlugin mSmartspaceDataProvider;
+ @Mock
+ SmartspaceView mSmartspaceView;
+ @Mock
+ SystemUIFactory mSystemUIFactory;
private KeyguardClockSwitchController mController;
private View mStatusArea;
@@ -129,27 +130,28 @@
when(mFeatureFlags.isSmartspaceEnabled()).thenReturn(true);
when(mView.isAttachedToWindow()).thenReturn(true);
when(mResources.getString(anyInt())).thenReturn("h:mm");
+ when(mSystemUIFactory.getSmartspaceDataProvider()).thenReturn(mSmartspaceDataProvider);
mController = new KeyguardClockSwitchController(
mView,
- mResources,
mStatusBarStateController,
mColorExtractor,
mClockManager,
mKeyguardSliceViewController,
mNotificationIconAreaController,
- mContentResolver,
mBroadcastDispatcher,
- mPluginManager,
mFeatureFlags,
mExecutor,
mBatteryController,
- mConfigurationController);
+ mConfigurationController,
+ mSystemUIFactory
+ );
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
when(mColorExtractor.getColors(anyInt())).thenReturn(mGradientColors);
- mStatusArea = mock(View.class);
+ mStatusArea = new View(getContext());
when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(mStatusArea);
+ when(mSmartspaceDataProvider.getView(any())).thenReturn(mSmartspaceView);
}
@@ -210,43 +212,37 @@
}
@Test
- public void testSmartspacePluginConnectedRemovesKeyguardStatusArea() {
+ public void testSmartspaceEnabledRemovesKeyguardStatusArea() {
+ when(mFeatureFlags.isSmartspaceEnabled()).thenReturn(true);
mController.init();
- BcSmartspaceDataPlugin plugin = mock(BcSmartspaceDataPlugin.class);
- TestView view = mock(TestView.class);
- when(plugin.getView(any())).thenReturn(view);
-
- mController.mPluginListener.onPluginConnected(plugin, mContext);
- verify(mStatusArea).setVisibility(View.GONE);
+ assertEquals(View.GONE, mStatusArea.getVisibility());
}
@Test
- public void testSmartspacePluginDisconnectedShowsKeyguardStatusArea() {
+ public void testSmartspaceEnabledNoDataProviderShowsKeyguardStatusArea() {
+ when(mFeatureFlags.isSmartspaceEnabled()).thenReturn(true);
+ when(mSystemUIFactory.getSmartspaceDataProvider()).thenReturn(null);
mController.init();
- BcSmartspaceDataPlugin plugin = mock(BcSmartspaceDataPlugin.class);
- TestView view = mock(TestView.class);
- when(plugin.getView(any())).thenReturn(view);
+ assertEquals(View.VISIBLE, mStatusArea.getVisibility());
+ }
- mController.mPluginListener.onPluginConnected(plugin, mContext);
- mController.mPluginListener.onPluginDisconnected(plugin);
- verify(mStatusArea).setVisibility(View.VISIBLE);
+ @Test
+ public void testSmartspaceDisabledShowsKeyguardStatusArea() {
+ when(mFeatureFlags.isSmartspaceEnabled()).thenReturn(false);
+ mController.init();
+
+ assertEquals(View.VISIBLE, mStatusArea.getVisibility());
}
@Test
public void testThemeChangeNotifiesSmartspace() {
mController.init();
+ verify(mSmartspaceView).setPrimaryTextColor(anyInt());
- BcSmartspaceDataPlugin plugin = mock(BcSmartspaceDataPlugin.class);
- TestView view = mock(TestView.class);
- when(plugin.getView(any())).thenReturn(view);
-
- mController.mPluginListener.onPluginConnected(plugin, mContext);
-
- reset(view);
mController.getConfigurationListener().onThemeChanged();
- verify(view).setPrimaryTextColor(anyInt());
+ verify(mSmartspaceView, times(2)).setPrimaryTextColor(anyInt());
}
private void verifyAttachment(VerificationMode times) {
@@ -257,8 +253,9 @@
verify(mView, times).updateColors(mGradientColors);
}
- private static class TestView extends View implements BcSmartspaceDataPlugin.SmartspaceView {
- TestView(Context context, AttributeSet attrs) {
+ private static class SmartspaceView extends View
+ implements BcSmartspaceDataPlugin.SmartspaceView {
+ SmartspaceView(Context context, AttributeSet attrs) {
super(context, attrs);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index 59262cf..3252750 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -63,6 +63,7 @@
import com.android.systemui.R.dimen;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.settings.UserTracker;
+import com.android.systemui.statusbar.events.PrivacyDotViewController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.settings.FakeSettings;
import com.android.systemui.util.settings.SecureSettings;
@@ -94,6 +95,8 @@
private BroadcastDispatcher mBroadcastDispatcher;
@Mock
private UserTracker mUserTracker;
+ @Mock
+ private PrivacyDotViewController mDotViewController;
@Before
public void setup() {
@@ -116,7 +119,7 @@
mContext.addMockSystemService(DisplayManager.class, mDisplayManager);
mScreenDecorations = spy(new ScreenDecorations(mContext, mMainHandler, mSecureSettings,
- mBroadcastDispatcher, mTunerService, mUserTracker) {
+ mBroadcastDispatcher, mTunerService, mUserTracker, mDotViewController) {
@Override
public void start() {
super.start();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
index 3f0831c..78c6717 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
@@ -233,9 +233,9 @@
TEST_UID, TEST_PACKAGE_NAME, TEST_ATTRIBUTION_NAME,
AppOpsManager.OP_FLAG_SELF, AppOpsManager.MODE_ALLOWED);
assertEquals(2,
- mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID)).size());
- assertEquals(1,
- mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID_OTHER)).size());
+ mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID), false).size());
+ assertEquals(1, mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID_OTHER),
+ false).size());
}
@Test
@@ -245,11 +245,11 @@
mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO,
TEST_UID_NON_USER_SENSITIVE, mExemptedRolePkgName, true);
assertEquals(0, mController.getActiveAppOpsForUser(
- UserHandle.getUserId(TEST_UID_NON_USER_SENSITIVE)).size());
+ UserHandle.getUserId(TEST_UID_NON_USER_SENSITIVE), false).size());
mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO,
TEST_UID_NON_USER_SENSITIVE, SYSTEM_PKG, true);
assertEquals(0, mController.getActiveAppOpsForUser(
- UserHandle.getUserId(TEST_UID_NON_USER_SENSITIVE)).size());
+ UserHandle.getUserId(TEST_UID_NON_USER_SENSITIVE), false).size());
}
@Test
@@ -441,7 +441,19 @@
}
@Test
- public void testOnlyRecordAudioPaused() {
+ public void testPausedPhoneCallMicrophoneFilteredOut() {
+ mController.addCallback(new int[]{AppOpsManager.OP_PHONE_CALL_MICROPHONE}, mCallback);
+ mTestableLooper.processAllMessages();
+
+ mController.onOpActiveChanged(
+ AppOpsManager.OP_PHONE_CALL_MICROPHONE, TEST_UID, TEST_PACKAGE_NAME, true);
+ mTestableLooper.processAllMessages();
+
+ assertTrue(mController.getActiveAppOps().isEmpty());
+ }
+
+ @Test
+ public void testOnlyRecordAudioPhoneCallMicrophonePaused() {
mController.addCallback(new int[]{
AppOpsManager.OP_RECORD_AUDIO,
AppOpsManager.OP_CAMERA
@@ -532,6 +544,40 @@
}
@Test
+ public void testPhoneCallMicrophoneFilteredWhenMicDisabled() {
+ mController.addCallback(
+ new int[]{AppOpsManager.OP_PHONE_CALL_MICROPHONE, AppOpsManager.OP_CAMERA},
+ mCallback);
+ mTestableLooper.processAllMessages();
+ mController.onOpActiveChanged(
+ AppOpsManager.OP_PHONE_CALL_MICROPHONE, TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
+ mTestableLooper.processAllMessages();
+ List<AppOpItem> list = mController.getActiveAppOps();
+ assertEquals(1, list.size());
+ assertEquals(AppOpsManager.OP_PHONE_CALL_MICROPHONE, list.get(0).getCode());
+ assertFalse(list.get(0).isDisabled());
+
+ // Add a camera op, and disable the microphone. The camera op should be the only op returned
+ mController.onSensorBlockedChanged(MICROPHONE, true);
+ mController.onOpActiveChanged(
+ AppOpsManager.OP_CAMERA, TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
+ mTestableLooper.processAllMessages();
+ list = mController.getActiveAppOps();
+ assertEquals(1, list.size());
+ assertEquals(AppOpsManager.OP_CAMERA, list.get(0).getCode());
+
+
+ // Re enable the microphone, and verify the op returns
+ mController.onSensorBlockedChanged(MICROPHONE, false);
+ mTestableLooper.processAllMessages();
+
+ list = mController.getActiveAppOps();
+ assertEquals(2, list.size());
+ int micIdx = list.get(0).getCode() == AppOpsManager.OP_CAMERA ? 1 : 0;
+ assertEquals(AppOpsManager.OP_PHONE_CALL_MICROPHONE, list.get(micIdx).getCode());
+ }
+
+ @Test
public void testCameraFilteredWhenCameraDisabled() {
mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_CAMERA},
mCallback);
@@ -563,6 +609,39 @@
assertEquals(AppOpsManager.OP_CAMERA, list.get(cameraIdx).getCode());
}
+ @Test
+ public void testPhoneCallCameraFilteredWhenCameraDisabled() {
+ mController.addCallback(
+ new int[]{AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_PHONE_CALL_CAMERA},
+ mCallback);
+ mTestableLooper.processAllMessages();
+ mController.onOpActiveChanged(
+ AppOpsManager.OP_PHONE_CALL_CAMERA, TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
+ mTestableLooper.processAllMessages();
+ List<AppOpItem> list = mController.getActiveAppOps();
+ assertEquals(1, list.size());
+ assertEquals(AppOpsManager.OP_PHONE_CALL_CAMERA, list.get(0).getCode());
+ assertFalse(list.get(0).isDisabled());
+
+ // Add an audio op, and disable the camera. The audio op should be the only op returned
+ mController.onSensorBlockedChanged(CAMERA, true);
+ mController.onOpActiveChanged(
+ AppOpsManager.OP_RECORD_AUDIO, TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
+ mTestableLooper.processAllMessages();
+ list = mController.getActiveAppOps();
+ assertEquals(1, list.size());
+ assertEquals(AppOpsManager.OP_RECORD_AUDIO, list.get(0).getCode());
+
+ // Re enable the camera, and verify the op returns
+ mController.onSensorBlockedChanged(CAMERA, false);
+ mTestableLooper.processAllMessages();
+
+ list = mController.getActiveAppOps();
+ assertEquals(2, list.size());
+ int cameraIdx = list.get(0).getCode() == AppOpsManager.OP_PHONE_CALL_CAMERA ? 0 : 1;
+ assertEquals(AppOpsManager.OP_PHONE_CALL_CAMERA, list.get(cameraIdx).getCode());
+ }
+
private class TestHandler extends AppOpsControllerImpl.H {
TestHandler(Looper looper) {
mController.super(looper);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
index c912419..8e00d10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
@@ -17,6 +17,7 @@
package com.android.systemui.classifier;
import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
+import static com.android.systemui.classifier.Classifier.QS_SWIPE;
import static com.google.common.truth.Truth.assertThat;
@@ -103,4 +104,11 @@
assertThat(mClassifier.classifyGesture(BRIGHTNESS_SLIDER, 0.5, 1).isFalse())
.isFalse();
}
+
+ @Test
+ public void testPass_QsSwipeAlwaysPasses() {
+ mClassifier.onTouchEvent(appendDownEvent(1, 1));
+ assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 1).isFalse())
+ .isFalse();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/TypeClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/TypeClassifierTest.java
index 32537b4..1d61e29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/TypeClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/TypeClassifierTest.java
@@ -22,6 +22,7 @@
import static com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS;
import static com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN;
import static com.android.systemui.classifier.Classifier.PULSE_EXPAND;
+import static com.android.systemui.classifier.Classifier.QS_SWIPE;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE;
import static com.android.systemui.classifier.Classifier.UNLOCK;
@@ -320,4 +321,46 @@
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture(BRIGHTNESS_SLIDER, 0.5, 0).isFalse()).isTrue();
}
+
+ @Test
+ public void testPass_QsSwipe() {
+ when(mDataProvider.isVertical()).thenReturn(false);
+
+ when(mDataProvider.isUp()).thenReturn(false); // up and right should cause no effect.
+ when(mDataProvider.isRight()).thenReturn(false);
+ assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isFalse();
+
+ when(mDataProvider.isUp()).thenReturn(true);
+ when(mDataProvider.isRight()).thenReturn(false);
+ assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isFalse();
+
+ when(mDataProvider.isUp()).thenReturn(false);
+ when(mDataProvider.isRight()).thenReturn(true);
+ assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isFalse();
+
+ when(mDataProvider.isUp()).thenReturn(true);
+ when(mDataProvider.isRight()).thenReturn(true);
+ assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isFalse();
+ }
+
+ @Test
+ public void testFalse_QsSwipe() {
+ when(mDataProvider.isVertical()).thenReturn(true);
+
+ when(mDataProvider.isUp()).thenReturn(false); // up and right should cause no effect.
+ when(mDataProvider.isRight()).thenReturn(false);
+ assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isTrue();
+
+ when(mDataProvider.isUp()).thenReturn(true);
+ when(mDataProvider.isRight()).thenReturn(false);
+ assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isTrue();
+
+ when(mDataProvider.isUp()).thenReturn(false);
+ when(mDataProvider.isRight()).thenReturn(true);
+ assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isTrue();
+
+ when(mDataProvider.isUp()).thenReturn(true);
+ when(mDataProvider.isRight()).thenReturn(true);
+ assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isTrue();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java
index 42e88b0..63ce98a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/WakefulnessLifecycleTest.java
@@ -22,6 +22,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+import android.app.IWallpaperManager;
import android.os.PowerManager;
import android.testing.AndroidTestingRunner;
@@ -43,9 +44,12 @@
private WakefulnessLifecycle mWakefulness;
private WakefulnessLifecycle.Observer mWakefulnessObserver;
+ private IWallpaperManager mWallpaperManager;
+
@Before
public void setUp() throws Exception {
- mWakefulness = new WakefulnessLifecycle();
+ mWallpaperManager = mock(IWallpaperManager.class);
+ mWakefulness = new WakefulnessLifecycle(mContext, mWallpaperManager);
mWakefulnessObserver = mock(WakefulnessLifecycle.Observer.class);
mWakefulness.addObserver(mWakefulnessObserver);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
index 0ce03ad..81ca4c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
@@ -22,8 +22,6 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
@@ -35,10 +33,7 @@
import android.app.INotificationManager;
import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
import android.app.Person;
-import android.app.people.ConversationChannel;
import android.app.people.IPeopleManager;
import android.app.people.PeopleSpaceTile;
import android.appwidget.AppWidgetManager;
@@ -47,7 +42,6 @@
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
-import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -57,7 +51,6 @@
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.ContactsContract;
-import android.service.notification.ConversationChannelWrapper;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import android.util.DisplayMetrics;
@@ -81,10 +74,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.util.Arrays;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
@RunWith(AndroidTestingRunner.class)
@SmallTest
@@ -185,8 +176,6 @@
@Mock
private IPeopleManager mPeopleManager;
@Mock
- private LauncherApps mLauncherApps;
- @Mock
private IAppWidgetService mIAppWidgetService;
@Mock
private AppWidgetManager mAppWidgetManager;
@@ -239,84 +228,6 @@
}
@Test
- public void testGetRecentTilesReturnsSortedListWithOnlyRecentConversations() throws Exception {
- // Ensure the less-recent Important conversation is before more recent conversations.
- ConversationChannelWrapper newerNonImportantConversation = getConversationChannelWrapper(
- SHORTCUT_ID_1, false, 3);
- ConversationChannelWrapper newerImportantConversation = getConversationChannelWrapper(
- SHORTCUT_ID_1 + 1, true, 3);
- ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper(
- SHORTCUT_ID_1 + 2,
- true, 1);
- when(mNotificationManager.getConversations(anyBoolean())).thenReturn(
- new ParceledListSlice(Arrays.asList(
- newerNonImportantConversation, newerImportantConversation,
- olderImportantConversation)));
-
- // Ensure the non-Important conversation is sorted between these recent conversations.
- ConversationChannel recentConversationBeforeNonImportantConversation =
- getConversationChannel(
- SHORTCUT_ID_1 + 3, 4);
- ConversationChannel recentConversationAfterNonImportantConversation =
- getConversationChannel(SHORTCUT_ID_1 + 4,
- 2);
- when(mPeopleManager.getRecentConversations()).thenReturn(
- new ParceledListSlice(Arrays.asList(recentConversationAfterNonImportantConversation,
- recentConversationBeforeNonImportantConversation)));
-
- List<String> orderedShortcutIds = PeopleSpaceUtils.getRecentTiles(
- mContext, mNotificationManager, mPeopleManager,
- mLauncherApps, mNotificationEntryManager)
- .stream().map(tile -> tile.getId()).collect(Collectors.toList());
-
- // Check for sorted recent conversations.
- assertThat(orderedShortcutIds).containsExactly(
- recentConversationBeforeNonImportantConversation.getShortcutInfo().getId(),
- newerNonImportantConversation.getShortcutInfo().getId(),
- recentConversationAfterNonImportantConversation.getShortcutInfo().getId())
- .inOrder();
- }
-
- @Test
- public void testGetPriorityTilesReturnsSortedListWithOnlyImportantConversations()
- throws Exception {
- // Ensure the less-recent Important conversation is before more recent conversations.
- ConversationChannelWrapper newerNonImportantConversation = getConversationChannelWrapper(
- SHORTCUT_ID_1, false, 3);
- ConversationChannelWrapper newerImportantConversation = getConversationChannelWrapper(
- SHORTCUT_ID_1 + 1, true, 3);
- ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper(
- SHORTCUT_ID_1 + 2,
- true, 1);
- when(mNotificationManager.getConversations(anyBoolean())).thenReturn(
- new ParceledListSlice(Arrays.asList(
- newerNonImportantConversation, newerImportantConversation,
- olderImportantConversation)));
-
- // Ensure the non-Important conversation is sorted between these recent conversations.
- ConversationChannel recentConversationBeforeNonImportantConversation =
- getConversationChannel(
- SHORTCUT_ID_1 + 3, 4);
- ConversationChannel recentConversationAfterNonImportantConversation =
- getConversationChannel(SHORTCUT_ID_1 + 4,
- 2);
- when(mPeopleManager.getRecentConversations()).thenReturn(
- new ParceledListSlice(Arrays.asList(recentConversationAfterNonImportantConversation,
- recentConversationBeforeNonImportantConversation)));
-
- List<String> orderedShortcutIds = PeopleSpaceUtils.getPriorityTiles(
- mContext, mNotificationManager, mPeopleManager,
- mLauncherApps, mNotificationEntryManager)
- .stream().map(tile -> tile.getId()).collect(Collectors.toList());
-
- // Check for sorted priority conversations.
- assertThat(orderedShortcutIds).containsExactly(
- newerImportantConversation.getShortcutInfo().getId(),
- olderImportantConversation.getShortcutInfo().getId())
- .inOrder();
- }
-
- @Test
public void testGetMessagingStyleMessagesNoMessage() {
Notification notification = new Notification.Builder(mContext, "test")
.setContentTitle("TEST_TITLE")
@@ -570,30 +481,4 @@
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
any());
}
-
- private ConversationChannelWrapper getConversationChannelWrapper(String shortcutId,
- boolean importantConversation, long lastInteractionTimestamp) throws Exception {
- ConversationChannelWrapper convo = new ConversationChannelWrapper();
- NotificationChannel notificationChannel = new NotificationChannel(shortcutId,
- "channel" + shortcutId,
- NotificationManager.IMPORTANCE_DEFAULT);
- notificationChannel.setImportantConversation(importantConversation);
- convo.setNotificationChannel(notificationChannel);
- convo.setShortcutInfo(new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
- "name").build());
- when(mPeopleManager.getLastInteraction(anyString(), anyInt(),
- eq(shortcutId))).thenReturn(lastInteractionTimestamp);
- return convo;
- }
-
- private ConversationChannel getConversationChannel(String shortcutId,
- long lastInteractionTimestamp) throws Exception {
- ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
- "name").build();
- ConversationChannel convo = new ConversationChannel(shortcutInfo, 0, null, null,
- lastInteractionTimestamp, false);
- when(mPeopleManager.getLastInteraction(anyString(), anyInt(),
- eq(shortcutId))).thenReturn(lastInteractionTimestamp);
- return convo;
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
index 107ac83..3cc55f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
@@ -114,8 +114,6 @@
when(mMockContext.getString(R.string.birthday_status)).thenReturn(
mContext.getString(R.string.birthday_status));
- when(mMockContext.getString(R.string.basic_status)).thenReturn(
- mContext.getString(R.string.basic_status));
when(mMockContext.getPackageManager()).thenReturn(mPackageManager);
when(mMockContext.getString(R.string.over_timestamp)).thenReturn(
mContext.getString(R.string.over_timestamp));
@@ -126,7 +124,6 @@
when(resources.getConfiguration()).thenReturn(configuration);
when(resources.getDisplayMetrics()).thenReturn(displayMetrics);
TextView textView = mock(TextView.class);
- // when(new TextView(mMockContext)).thenReturn(textView);
when(textView.getLineHeight()).thenReturn(16);
when(mPackageManager.getApplicationIcon(anyString())).thenReturn(null);
mPeopleTileViewHelper = new PeopleTileViewHelper(mContext,
@@ -134,16 +131,41 @@
}
@Test
- public void testCreateRemoteViewsWithLastInteractionTime() {
+ public void testCreateRemoteViewsWithLastInteractionTimeUnderOneDayHidden() {
RemoteViews views = new PeopleTileViewHelper(mContext,
PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions).getViews();
View result = views.apply(mContext, null);
+ // Not showing last interaction.
+ assertEquals(View.GONE, result.findViewById(R.id.last_interaction).getVisibility());
+
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_width_for_large));
+ mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
+ getSizeInDp(R.dimen.required_height_for_large));
+ RemoteViews largeView = new PeopleTileViewHelper(mContext,
+ PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions).getViews();
+ View largeResult = largeView.apply(mContext, null);
+
+ // Not showing last interaction.
+ assertEquals(View.GONE, largeResult.findViewById(R.id.last_interaction).getVisibility());
+ }
+
+ @Test
+ public void testCreateRemoteViewsWithLastInteractionTime() {
+ PeopleSpaceTile tileWithLastInteraction =
+ PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setLastInteractionTimestamp(
+ 123445L).build();
+ RemoteViews views = new PeopleTileViewHelper(mContext,
+ tileWithLastInteraction, 0, mOptions).getViews();
+ View result = views.apply(mContext, null);
+
TextView name = (TextView) result.findViewById(R.id.name);
assertEquals(name.getText(), NAME);
// Has last interaction.
+ assertEquals(View.VISIBLE, result.findViewById(R.id.last_interaction).getVisibility());
TextView lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
- assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
+ assertEquals(lastInteraction.getText(), "Over 2 weeks ago");
// No availability.
assertEquals(View.GONE, result.findViewById(R.id.availability).getVisibility());
// Shows person icon.
@@ -154,7 +176,7 @@
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_width_for_medium) - 1);
RemoteViews smallView = new PeopleTileViewHelper(mContext,
- PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions).getViews();
+ tileWithLastInteraction, 0, mOptions).getViews();
View smallResult = smallView.apply(mContext, null);
// Show name over predefined icon.
@@ -171,14 +193,15 @@
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_height_for_large));
RemoteViews largeView = new PeopleTileViewHelper(mContext,
- PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions).getViews();
+ tileWithLastInteraction, 0, mOptions).getViews();
View largeResult = largeView.apply(mContext, null);
name = (TextView) largeResult.findViewById(R.id.name);
assertEquals(name.getText(), NAME);
// Has last interaction.
+ assertEquals(View.VISIBLE, largeResult.findViewById(R.id.last_interaction).getVisibility());
lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
- assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
+ assertEquals(lastInteraction.getText(), "Over 2 weeks ago");
// No availability.
assertEquals(View.GONE, result.findViewById(R.id.availability).getVisibility());
// Shows person icon.
@@ -202,8 +225,7 @@
TextView name = (TextView) result.findViewById(R.id.name);
assertEquals(name.getText(), NAME);
// Has last interaction over status.
- TextView lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
- assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
+ assertEquals(View.GONE, result.findViewById(R.id.last_interaction).getVisibility());
// Has availability.
assertEquals(View.VISIBLE, result.findViewById(R.id.availability).getVisibility());
// Has person icon.
@@ -237,14 +259,13 @@
name = (TextView) largeResult.findViewById(R.id.name);
assertEquals(name.getText(), NAME);
// Has last interaction.
- lastInteraction = (TextView) result.findViewById(R.id.last_interaction);
- assertEquals(lastInteraction.getText(), mContext.getString(R.string.basic_status));
+ assertEquals(View.GONE, largeResult.findViewById(R.id.last_interaction).getVisibility());
// Has availability.
- assertEquals(View.VISIBLE, result.findViewById(R.id.availability).getVisibility());
+ assertEquals(View.VISIBLE, largeResult.findViewById(R.id.availability).getVisibility());
// Shows person icon.
- assertEquals(View.VISIBLE, result.findViewById(R.id.person_icon).getVisibility());
+ assertEquals(View.VISIBLE, largeResult.findViewById(R.id.person_icon).getVisibility());
// No status.
- assertThat((View) result.findViewById(R.id.text_content)).isNull();
+ assertThat((View) largeResult.findViewById(R.id.text_content)).isNull();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java
index 0ef3ca2..ccb40e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/LaunchConversationActivityTest.java
@@ -29,6 +29,7 @@
import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
+import android.os.UserManager;
import android.service.notification.NotificationListenerService;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
@@ -83,6 +84,8 @@
private BubblesManager mBubblesManager;
@Mock
private NotificationListenerService.Ranking mRanking;
+ @Mock
+ private UserManager mUserManager;
@Captor
private ArgumentCaptor<NotificationVisibility> mNotificationVisibilityCaptor;
@@ -93,7 +96,7 @@
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mActivity = new LaunchConversationActivity(mNotificationEntryManager,
- Optional.of(mBubblesManager));
+ Optional.of(mBubblesManager), mUserManager);
mActivity.setIsForTesting(true, mIStatusBarService);
mIntent = new Intent();
mIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_TILE_ID, "tile ID");
@@ -113,6 +116,7 @@
when(mNotifEntryCanBubble.canBubble()).thenReturn(true);
when(mNotifEntryNoRanking.getRanking()).thenReturn(null);
when(mRanking.getRank()).thenReturn(NOTIF_RANK);
+ when(mUserManager.isQuietModeEnabled(any(UserHandle.class))).thenReturn(false);
}
@Test
@@ -176,4 +180,18 @@
anyInt(), any(), anyInt(), anyInt(), any());
verify(mBubblesManager, times(1)).expandStackAndSelectBubble(eq(mNotifEntryCanBubble));
}
+
+ @Test
+ public void testQuietModeOpensQuietModeDialog() throws Exception {
+ mIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_NOTIFICATION_KEY,
+ NOTIF_KEY);
+ when(mUserManager.isQuietModeEnabled(eq(USER_HANDLE))).thenReturn(true);
+ mActivity.setIntent(mIntent);
+ mActivity.onCreate(new Bundle());
+
+ assertThat(mActivity.isFinishing()).isTrue();
+ verify(mIStatusBarService, never()).onNotificationClear(any(),
+ anyInt(), any(), anyInt(), anyInt(), any());
+ verify(mBubblesManager, never()).expandStackAndSelectBubble(any());
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
index 7125500..1ab5d34 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
@@ -35,7 +35,9 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -45,8 +47,10 @@
import static java.util.Objects.requireNonNull;
+import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationChannel;
+import android.app.NotificationManager;
import android.app.Person;
import android.app.people.ConversationChannel;
import android.app.people.ConversationStatus;
@@ -59,11 +63,14 @@
import android.content.SharedPreferences;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Bundle;
import android.os.UserHandle;
+import android.os.UserManager;
+import android.service.notification.ConversationChannelWrapper;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
@@ -95,6 +102,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.stream.Collectors;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -169,6 +177,10 @@
private NotificationEntryManager mNotificationEntryManager;
@Mock
private PackageManager mPackageManager;
+ @Mock
+ private INotificationManager mNotificationManager;
+ @Mock
+ private UserManager mUserManager;
@Captor
private ArgumentCaptor<NotificationHandler> mListenerCaptor;
@@ -189,7 +201,8 @@
mProvider = new PeopleSpaceWidgetProvider();
mProvider.setPeopleSpaceWidgetManager(mManager);
mManager.setAppWidgetManager(mAppWidgetManager, mIPeopleManager, mPeopleManager,
- mLauncherApps, mNotificationEntryManager, mPackageManager, true, mProvider);
+ mLauncherApps, mNotificationEntryManager, mPackageManager, true, mProvider,
+ mUserManager, mNotificationManager);
mManager.attach(mListenerService);
verify(mListenerService).addNotificationHandler(mListenerCaptor.capture());
@@ -201,6 +214,98 @@
addTileForWidget(PERSON_TILE_WITH_SAME_URI, WIDGET_ID_WITH_SAME_URI);
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITHOUT_SHORTCUT)))
.thenReturn(new Bundle());
+ when(mUserManager.isQuietModeEnabled(any())).thenReturn(false);
+ }
+
+ @Test
+ public void testGetRecentTilesReturnsSortedListWithOnlyRecentConversations() throws Exception {
+ // Ensure the less-recent Important conversation is before more recent conversations.
+ ConversationChannelWrapper newerNonImportantConversation = getConversationChannelWrapper(
+ SHORTCUT_ID, false, 3);
+ ConversationChannelWrapper newerImportantConversation = getConversationChannelWrapper(
+ SHORTCUT_ID + 1, true, 3);
+ ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper(
+ SHORTCUT_ID + 2,
+ true, 1);
+ when(mNotificationManager.getConversations(anyBoolean())).thenReturn(
+ new ParceledListSlice(Arrays.asList(
+ newerNonImportantConversation, newerImportantConversation,
+ olderImportantConversation)));
+
+ // Ensure the non-Important conversation is sorted between these recent conversations.
+ ConversationChannel recentConversationBeforeNonImportantConversation =
+ getConversationChannel(
+ SHORTCUT_ID + 3, 4);
+ ConversationChannel recentConversationAfterNonImportantConversation =
+ getConversationChannel(SHORTCUT_ID + 4,
+ 2);
+ when(mIPeopleManager.getRecentConversations()).thenReturn(
+ new ParceledListSlice(Arrays.asList(recentConversationAfterNonImportantConversation,
+ recentConversationBeforeNonImportantConversation)));
+
+ List<String> orderedShortcutIds = mManager.getRecentTiles()
+ .stream().map(tile -> tile.getId()).collect(Collectors.toList());
+
+ // Check for sorted recent conversations.
+ assertThat(orderedShortcutIds).containsExactly(
+ recentConversationBeforeNonImportantConversation.getShortcutInfo().getId(),
+ newerNonImportantConversation.getShortcutInfo().getId(),
+ recentConversationAfterNonImportantConversation.getShortcutInfo().getId())
+ .inOrder();
+ }
+
+ @Test
+ public void testGetPriorityTilesReturnsSortedListWithOnlyImportantConversations()
+ throws Exception {
+ // Ensure the less-recent Important conversation is before more recent conversations.
+ ConversationChannelWrapper newerNonImportantConversation = getConversationChannelWrapper(
+ SHORTCUT_ID, false, 3);
+ ConversationChannelWrapper newerImportantConversation = getConversationChannelWrapper(
+ SHORTCUT_ID + 1, true, 3);
+ ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper(
+ SHORTCUT_ID + 2,
+ true, 1);
+ when(mNotificationManager.getConversations(anyBoolean())).thenReturn(
+ new ParceledListSlice(Arrays.asList(
+ newerNonImportantConversation, newerImportantConversation,
+ olderImportantConversation)));
+
+ List<String> orderedShortcutIds = mManager.getPriorityTiles()
+ .stream().map(tile -> tile.getId()).collect(Collectors.toList());
+
+ // Check for sorted priority conversations.
+ assertThat(orderedShortcutIds).containsExactly(
+ newerImportantConversation.getShortcutInfo().getId(),
+ olderImportantConversation.getShortcutInfo().getId())
+ .inOrder();
+ }
+
+ @Test
+ public void testGetTilesReturnsNothingInQuietMode()
+ throws Exception {
+ // Ensure the less-recent Important conversation is before more recent conversations.
+ ConversationChannelWrapper newerNonImportantConversation = getConversationChannelWrapper(
+ SHORTCUT_ID, false, 3);
+ ConversationChannelWrapper newerImportantConversation = getConversationChannelWrapper(
+ SHORTCUT_ID + 1, true, 3);
+ ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper(
+ SHORTCUT_ID + 2,
+ true, 1);
+ when(mNotificationManager.getConversations(anyBoolean())).thenReturn(
+ new ParceledListSlice(Arrays.asList(
+ newerNonImportantConversation, newerImportantConversation,
+ olderImportantConversation)));
+ ConversationChannel recentConversation =
+ getConversationChannel(
+ SHORTCUT_ID + 3, 4);
+ when(mIPeopleManager.getRecentConversations()).thenReturn(
+ new ParceledListSlice(Arrays.asList(recentConversation)));
+
+ when(mUserManager.isQuietModeEnabled(any())).thenReturn(true);
+
+ // Check nothing returned.
+ assertThat(mManager.getPriorityTiles()).isEmpty();
+ assertThat(mManager.getRecentTiles()).isEmpty();
}
@Test
@@ -1038,7 +1143,7 @@
when(mAppWidgetManager.requestPinAppWidget(any(), any(), any())).thenReturn(true);
ShortcutInfo info = new ShortcutInfo.Builder(mMockContext, SHORTCUT_ID).build();
- boolean valid = mManager.requestPinAppWidget(info);
+ boolean valid = mManager.requestPinAppWidget(info, new Bundle());
assertThat(valid).isTrue();
verify(mAppWidgetManager, times(1)).requestPinAppWidget(
@@ -1052,7 +1157,7 @@
when(mIPeopleManager.getConversation(PACKAGE_NAME, 0, SHORTCUT_ID)).thenReturn(null);
ShortcutInfo info = new ShortcutInfo.Builder(mMockContext, SHORTCUT_ID).build();
- boolean valid = mManager.requestPinAppWidget(info);
+ boolean valid = mManager.requestPinAppWidget(info, new Bundle());
assertThat(valid).isFalse();
verify(mAppWidgetManager, never()).requestPinAppWidget(any(), any(), any());
@@ -1208,4 +1313,30 @@
editor.putStringSet(contactUri.toString(), storedWidgetIdsByUri);
editor.apply();
}
+
+ private ConversationChannelWrapper getConversationChannelWrapper(String shortcutId,
+ boolean importantConversation, long lastInteractionTimestamp) throws Exception {
+ ConversationChannelWrapper convo = new ConversationChannelWrapper();
+ NotificationChannel notificationChannel = new NotificationChannel(shortcutId,
+ "channel" + shortcutId,
+ NotificationManager.IMPORTANCE_DEFAULT);
+ notificationChannel.setImportantConversation(importantConversation);
+ convo.setNotificationChannel(notificationChannel);
+ convo.setShortcutInfo(new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
+ "name").build());
+ when(mIPeopleManager.getLastInteraction(anyString(), anyInt(),
+ eq(shortcutId))).thenReturn(lastInteractionTimestamp);
+ return convo;
+ }
+
+ private ConversationChannel getConversationChannel(String shortcutId,
+ long lastInteractionTimestamp) throws Exception {
+ ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
+ "name").build();
+ ConversationChannel convo = new ConversationChannel(shortcutInfo, 0, null, null,
+ lastInteractionTimestamp, false);
+ when(mIPeopleManager.getLastInteraction(anyString(), anyInt(),
+ eq(shortcutId))).thenReturn(lastInteractionTimestamp);
+ return convo;
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt
index 791dd12..05a1e4f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt
@@ -28,6 +28,7 @@
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.appops.AppOpsController
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.privacy.logging.PrivacyLogger
import com.android.systemui.settings.UserTracker
@@ -43,6 +44,7 @@
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Captor
@@ -86,6 +88,8 @@
private lateinit var privacyLogger: PrivacyLogger
@Mock
private lateinit var keyguardStateController: KeyguardStateController
+ @Mock
+ private lateinit var appOpsController: AppOpsController
@Captor
private lateinit var dialogDismissedCaptor: ArgumentCaptor<PrivacyDialog.OnDialogDismissed>
@Captor
@@ -131,6 +135,7 @@
uiExecutor,
privacyLogger,
keyguardStateController,
+ appOpsController,
dialogProvider
)
}
@@ -143,18 +148,27 @@
}
@Test
+ fun testMicMutedParameter() {
+ `when`(appOpsController.isMicMuted).thenReturn(true)
+ controller.showDialog(context)
+ backgroundExecutor.runAllReady()
+
+ verify(permissionManager).getIndicatorAppOpUsageData(true)
+ }
+
+ @Test
fun testPermissionManagerOnlyCalledInBackgroundThread() {
controller.showDialog(context)
- verify(permissionManager, never()).indicatorAppOpUsageData
+ verify(permissionManager, never()).getIndicatorAppOpUsageData(anyBoolean())
backgroundExecutor.runAllReady()
- verify(permissionManager).indicatorAppOpUsageData
+ verify(permissionManager).getIndicatorAppOpUsageData(anyBoolean())
}
@Test
fun testPackageManagerOnlyCalledInBackgroundThread() {
val usage = createMockPermGroupUsage()
`when`(usage.isPhoneCall).thenReturn(false)
- `when`(permissionManager.indicatorAppOpUsageData).thenReturn(listOf(usage))
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(listOf(usage))
controller.showDialog(context)
verify(packageManager, never()).getApplicationInfoAsUser(anyString(), anyInt(), anyInt())
@@ -217,7 +231,7 @@
isPhoneCall = false,
attribution = TEST_ATTRIBUTION
)
- `when`(permissionManager.indicatorAppOpUsageData).thenReturn(listOf(usage))
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(listOf(usage))
controller.showDialog(context)
exhaustExecutors()
@@ -246,7 +260,7 @@
packageName = "${TEST_PACKAGE_NAME}_microphone",
permGroupName = PERM_MICROPHONE
)
- `when`(permissionManager.indicatorAppOpUsageData).thenReturn(
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(
listOf(usage_microphone, usage_camera)
)
@@ -269,7 +283,7 @@
packageName = "${TEST_PACKAGE_NAME}_recent",
isActive = false
)
- `when`(permissionManager.indicatorAppOpUsageData).thenReturn(
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(
listOf(usage_recent, usage_active)
)
@@ -292,7 +306,7 @@
isActive = true,
lastAccess = 1L
)
- `when`(permissionManager.indicatorAppOpUsageData).thenReturn(
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(
listOf(usage_active, usage_active_moreRecent)
)
controller.showDialog(context)
@@ -319,7 +333,7 @@
isActive = false,
lastAccess = 2L
)
- `when`(permissionManager.indicatorAppOpUsageData).thenReturn(
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(
listOf(usage_recent, usage_mostRecent, usage_moreRecent)
)
@@ -342,7 +356,7 @@
permGroupName = PERM_LOCATION
)
- `when`(permissionManager.indicatorAppOpUsageData).thenReturn(
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(
listOf(usage_camera, usage_location, usage_microphone)
)
`when`(privacyItemController.micCameraAvailable).thenReturn(false)
@@ -366,7 +380,7 @@
permGroupName = PERM_LOCATION
)
- `when`(permissionManager.indicatorAppOpUsageData).thenReturn(
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(
listOf(usage_camera, usage_location, usage_microphone)
)
`when`(privacyItemController.locationAvailable).thenReturn(false)
@@ -392,7 +406,7 @@
permGroupName = PERM_LOCATION
)
- `when`(permissionManager.indicatorAppOpUsageData).thenReturn(
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(
listOf(usage_camera, usage_location, usage_microphone)
)
`when`(privacyItemController.micCameraAvailable).thenReturn(true)
@@ -416,7 +430,7 @@
permGroupName = PERM_LOCATION
)
- `when`(permissionManager.indicatorAppOpUsageData).thenReturn(
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(
listOf(usage_camera, usage_location, usage_microphone)
)
`when`(privacyItemController.micCameraAvailable).thenReturn(false)
@@ -433,7 +447,8 @@
val usage_enterprise = createMockPermGroupUsage(
uid = generateUidForUser(ENT_USER_ID)
)
- `when`(permissionManager.indicatorAppOpUsageData).thenReturn(listOf(usage_enterprise))
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean()))
+ .thenReturn(listOf(usage_enterprise))
controller.showDialog(context)
exhaustExecutors()
@@ -446,7 +461,8 @@
val usage_other = createMockPermGroupUsage(
uid = generateUidForUser(ENT_USER_ID + 1)
)
- `when`(permissionManager.indicatorAppOpUsageData).thenReturn(listOf(usage_other))
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean()))
+ .thenReturn(listOf(usage_other))
controller.showDialog(context)
exhaustExecutors()
@@ -514,7 +530,8 @@
}
private fun setUpDefaultMockResponses() {
- `when`(permissionManager.indicatorAppOpUsageData).thenReturn(emptyList())
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(emptyList())
+ `when`(appOpsController.isMicMuted).thenReturn(false)
`when`(packageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
.thenAnswer {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
index bba1c6a..e4d7b1b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
@@ -46,7 +46,7 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyList
import org.mockito.Captor
import org.mockito.Mock
@@ -156,7 +156,7 @@
fun testDistinctItems() {
doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 0),
AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 0)))
- .`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ .`when`(appOpsController).getActiveAppOps(anyBoolean())
privacyItemController.addCallback(callback)
executor.runAllReady()
@@ -168,7 +168,7 @@
fun testSimilarItemsDifferentTimeStamp() {
doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 0),
AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 1)))
- .`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ .`when`(appOpsController).getActiveAppOps(anyBoolean())
privacyItemController.addCallback(callback)
executor.runAllReady()
@@ -215,7 +215,7 @@
@Test
fun testMultipleCallbacksAreUpdated() {
- doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOps(anyBoolean())
val otherCallback = mock(PrivacyItemController.Callback::class.java)
privacyItemController.addCallback(callback)
@@ -233,7 +233,7 @@
@Test
fun testRemoveCallback() {
- doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOps(anyBoolean())
val otherCallback = mock(PrivacyItemController.Callback::class.java)
privacyItemController.addCallback(callback)
privacyItemController.addCallback(otherCallback)
@@ -254,7 +254,7 @@
fun testListShouldNotHaveNull() {
doReturn(listOf(AppOpItem(AppOpsManager.OP_ACTIVATE_VPN, TEST_UID, "", 0),
AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, "", 0)))
- .`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ .`when`(appOpsController).getActiveAppOps(anyBoolean())
privacyItemController.addCallback(callback)
executor.runAllReady()
executor.runAllReady()
@@ -292,7 +292,7 @@
doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 0),
AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, "", 0)))
- .`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ .`when`(appOpsController).getActiveAppOps(anyBoolean())
privacyItemController.addCallback(callback)
executor.runAllReady()
@@ -306,7 +306,7 @@
@Test
fun testNotUpdated_LocationChangeWhenOnlyMicCamera() {
doReturn(listOf(AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, "", 0)))
- .`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ .`when`(appOpsController).getActiveAppOps(anyBoolean())
privacyItemController.addCallback(callback)
changeLocation(false)
@@ -338,7 +338,7 @@
fun testLogListUpdated() {
doReturn(listOf(
AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, 0))
- ).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ ).`when`(appOpsController).getActiveAppOps(anyBoolean())
privacyItemController.addCallback(callback)
executor.runAllReady()
@@ -362,10 +362,10 @@
}
@Test
- fun testListRequestedForAllUsers() {
+ fun testListRequestedShowPaused() {
privacyItemController.addCallback(callback)
executor.runAllReady()
- verify(appOpsController).getActiveAppOpsForUser(UserHandle.USER_ALL)
+ verify(appOpsController).getActiveAppOps(true)
}
@Test
@@ -377,7 +377,7 @@
doReturn(listOf(
AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, 0),
AppOpItem(AppOpsManager.OP_CAMERA, otherUserUid, TEST_PACKAGE_NAME, 0))
- ).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ ).`when`(appOpsController).getActiveAppOps(anyBoolean())
privacyItemController.userTrackerCallback.onUserChanged(otherUser, mContext)
executor.runAllReady()
@@ -401,7 +401,7 @@
AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, 0),
AppOpItem(AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, 0),
AppOpItem(AppOpsManager.OP_PHONE_CALL_CAMERA, TEST_UID, TEST_PACKAGE_NAME, 0))
- ).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ ).`when`(appOpsController).getActiveAppOps(anyBoolean())
privacyItemController.userTrackerCallback.onUserChanged(otherUser, mContext)
executor.runAllReady()
@@ -424,7 +424,7 @@
AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, 0),
AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, TEST_PACKAGE_NAME, 0),
AppOpItem(AppOpsManager.OP_PHONE_CALL_MICROPHONE, TEST_UID, TEST_PACKAGE_NAME, 0))
- ).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ ).`when`(appOpsController).getActiveAppOps(anyBoolean())
privacyItemController.userTrackerCallback.onUserChanged(otherUser, mContext)
executor.runAllReady()
@@ -442,7 +442,7 @@
fun testPassageOfTimeDoesNotRemoveIndicators() {
doReturn(listOf(
AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, TEST_PACKAGE_NAME, elapsedTime)
- )).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ )).`when`(appOpsController).getActiveAppOps(anyBoolean())
privacyItemController.addCallback(callback)
@@ -458,12 +458,12 @@
// Start with some element at time 0
doReturn(listOf(
AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, TEST_PACKAGE_NAME, elapsedTime)
- )).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ )).`when`(appOpsController).getActiveAppOps(anyBoolean())
privacyItemController.addCallback(callback)
executor.runAllReady()
// Then remove it at time HOLD + 1
- doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOps(anyBoolean())
fakeClock.advanceTime(PrivacyItemController.TIME_TO_HOLD_INDICATORS + 1)
verify(appOpsController).addCallback(any(), capture(argCaptorCallback))
@@ -481,12 +481,12 @@
// Start with some element at time 0
doReturn(listOf(
AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, TEST_PACKAGE_NAME, elapsedTime)
- )).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ )).`when`(appOpsController).getActiveAppOps(anyBoolean())
privacyItemController.addCallback(callback)
executor.runAllReady()
// Then remove it at time HOLD - 1
- doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOps(anyBoolean())
fakeClock.advanceTime(PrivacyItemController.TIME_TO_HOLD_INDICATORS - 1)
verify(appOpsController).addCallback(any(), capture(argCaptorCallback))
@@ -504,12 +504,12 @@
// Start with some element at time 0
doReturn(listOf(
AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, TEST_PACKAGE_NAME, elapsedTime)
- )).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ )).`when`(appOpsController).getActiveAppOps(anyBoolean())
privacyItemController.addCallback(callback)
executor.runAllReady()
// Then remove it at time HOLD - 1
- doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+ doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOps(anyBoolean())
fakeClock.advanceTime(PrivacyItemController.TIME_TO_HOLD_INDICATORS - 1)
verify(appOpsController).addCallback(any(), capture(argCaptorCallback))
@@ -525,6 +525,30 @@
assertTrue(privacyItemController.privacyList.isEmpty())
}
+ @Test
+ fun testPausedElementsAreRemoved() {
+ val item = AppOpItem(
+ AppOpsManager.OP_RECORD_AUDIO,
+ TEST_UID,
+ TEST_PACKAGE_NAME,
+ elapsedTime
+ )
+ `when`(appOpsController.getActiveAppOps(anyBoolean())).thenReturn(listOf(item))
+ privacyItemController.addCallback(callback)
+ executor.runAllReady()
+
+ item.isDisabled = true
+ fakeClock.advanceTime(1)
+ verify(appOpsController).addCallback(any(), capture(argCaptorCallback))
+ argCaptorCallback.value.onActiveStateChanged(
+ AppOpsManager.OP_CAMERA, TEST_UID, TEST_PACKAGE_NAME, false)
+
+ executor.runAllReady()
+
+ verify(callback).onPrivacyItemsChanged(emptyList())
+ assertTrue(privacyItemController.privacyList.isEmpty())
+ }
+
private fun changeMicCamera(value: Boolean?) = changeProperty(MIC_CAMERA, value)
private fun changeLocation(value: Boolean?) = changeProperty(LOCATION_INDICATOR, value)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
index bacc493..53eae8c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
@@ -32,6 +32,7 @@
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.MediaHost;
import com.android.systemui.plugins.qs.QSTileView;
@@ -94,6 +95,7 @@
QSTileView mQSTileView;
@Mock
PagedTileLayout mPagedTileLayout;
+ FalsingManagerFake mFalsingManager = new FalsingManagerFake();
@Mock
FeatureFlags mFeatureFlags;
@@ -121,7 +123,7 @@
mQSTileHost, mQSCustomizerController, true, mMediaHost,
mQSTileRevealControllerFactory, mDumpManager, mMetricsLogger, mUiEventLogger,
mQSLogger, mBrightnessControllerFactory, mToggleSliderViewControllerFactory,
- mFeatureFlags
+ mFalsingManager, mFeatureFlags
);
mController.init();
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 d236023..4bba0d0 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
@@ -233,6 +233,11 @@
}
@Test
+ public void testGetTileLabel() {
+ assertEquals(mContext.getString(R.string.wallet_title), mTile.getTileLabel().toString());
+ }
+
+ @Test
public void testHandleUpdateState_hasCard_deviceLocked_tileInactive() {
when(mKeyguardStateController.isUnlocked()).thenReturn(false);
QSTile.State state = new QSTile.State();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
index 03f93fa..8c7d762 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
@@ -82,7 +82,7 @@
when(bitmap.getConfig()).thenReturn(Bitmap.Config.HARDWARE);
ScreenshotNotificationSmartActionsProvider smartActionsProvider = mock(
ScreenshotNotificationSmartActionsProvider.class);
- when(smartActionsProvider.getActions(any(), any(), any(), any(), any()))
+ when(smartActionsProvider.getActions(any(), any(), any(), any(), any(), any()))
.thenThrow(RuntimeException.class);
CompletableFuture<List<Notification.Action>> smartActionsFuture =
mScreenshotSmartActions.getSmartActionsFuture(
@@ -128,7 +128,7 @@
mScreenshotSmartActions.getSmartActionsFuture(
"", Uri.parse("content://autority/data"), bitmap, mSmartActionsProvider,
true, UserHandle.of(UserHandle.myUserId()));
- verify(mSmartActionsProvider, never()).getActions(any(), any(), any(), any(), any());
+ verify(mSmartActionsProvider, never()).getActions(any(), any(), any(), any(), any(), any());
assertNotNull(smartActionsFuture);
List<Notification.Action> smartActions = smartActionsFuture.get(5, TimeUnit.MILLISECONDS);
assertEquals(Collections.emptyList(), smartActions);
@@ -142,7 +142,8 @@
mScreenshotSmartActions.getSmartActionsFuture(
"", Uri.parse("content://autority/data"), bitmap, mSmartActionsProvider, true,
UserHandle.of(UserHandle.myUserId()));
- verify(mSmartActionsProvider, times(1)).getActions(any(), any(), any(), any(), any());
+ verify(mSmartActionsProvider, times(1)).getActions(
+ any(), any(), any(), any(), any(), any());
}
// Tests for a hardware bitmap, a completed future is returned.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index 12e341a5..5d29f52 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -31,7 +31,6 @@
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
@@ -239,7 +238,7 @@
when(mBuilder.build()).thenReturn(mock(PriorityOnboardingDialogController.class));
- when(mPeopleSpaceWidgetManager.requestPinAppWidget(any())).thenReturn(true);
+ when(mPeopleSpaceWidgetManager.requestPinAppWidget(any(), any())).thenReturn(true);
}
@Test
@@ -1289,7 +1288,7 @@
mNotificationInfo.findViewById(R.id.done).performClick();
// THEN the user is presented with the People Tile pinning request
- verify(mPeopleSpaceWidgetManager, times(1)).requestPinAppWidget(any());
+ verify(mPeopleSpaceWidgetManager, times(1)).requestPinAppWidget(any(), any());
}
@Test
@@ -1325,7 +1324,7 @@
mNotificationInfo.findViewById(R.id.done).performClick();
// THEN the user is not presented with the People Tile pinning request
- verify(mPeopleSpaceWidgetManager, never()).requestPinAppWidget(mShortcutInfo);
+ verify(mPeopleSpaceWidgetManager, never()).requestPinAppWidget(eq(mShortcutInfo), any());
}
@Test
@@ -1364,6 +1363,6 @@
mNotificationInfo.findViewById(R.id.done).performClick();
// THEN the user is not presented with the People Tile pinning request
- verify(mPeopleSpaceWidgetManager, never()).requestPinAppWidget(mShortcutInfo);
+ verify(mPeopleSpaceWidgetManager, never()).requestPinAppWidget(eq(mShortcutInfo), any());
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
index 67fd5eb..0e3e0cc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
@@ -37,6 +37,8 @@
import com.android.systemui.R;
import com.android.systemui.SysuiBaseFragmentTest;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.events.PrivacyDotViewController;
+import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallListener;
@@ -58,6 +60,8 @@
private View mCenteredNotificationAreaView;
private StatusBarStateController mStatusBarStateController;
private OngoingCallController mOngoingCallController;
+ private SystemStatusAnimationScheduler mAnimationScheduler;
+ private PrivacyDotViewController mDotViewController;
public CollapsedStatusBarFragmentTest() {
super(CollapsedStatusBarFragment.class);
@@ -180,7 +184,7 @@
Mockito.verify(mOngoingCallController).addCallback(ongoingCallListenerCaptor.capture());
OngoingCallListener listener = Objects.requireNonNull(ongoingCallListenerCaptor.getValue());
- when(mOngoingCallController.getHasOngoingCall()).thenReturn(true);
+ when(mOngoingCallController.hasOngoingCall()).thenReturn(true);
listener.onOngoingCallStarted(/* animate= */ false);
assertEquals(View.VISIBLE,
@@ -201,7 +205,7 @@
Mockito.verify(mOngoingCallController).addCallback(ongoingCallListenerCaptor.capture());
OngoingCallListener listener = Objects.requireNonNull(ongoingCallListenerCaptor.getValue());
- when(mOngoingCallController.getHasOngoingCall()).thenReturn(false);
+ when(mOngoingCallController.hasOngoingCall()).thenReturn(false);
listener.onOngoingCallEnded(/* animate= */ false);
assertEquals(View.GONE,
@@ -212,6 +216,11 @@
@Override
protected Fragment instantiate(Context context, String className, Bundle arguments) {
mOngoingCallController = mock(OngoingCallController.class);
- return new CollapsedStatusBarFragment(mOngoingCallController);
+ mAnimationScheduler = mock(SystemStatusAnimationScheduler.class);
+ mDotViewController = mock(PrivacyDotViewController.class);
+ return new CollapsedStatusBarFragment(
+ mOngoingCallController,
+ mAnimationScheduler,
+ mDotViewController);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 08d6d2d..11f96c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -38,6 +38,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.IWallpaperManager;
import android.app.Notification;
import android.app.StatusBarManager;
import android.app.trust.TrustManager;
@@ -113,6 +114,8 @@
import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.charging.WiredChargingRippleController;
+import com.android.systemui.statusbar.events.PrivacyDotViewController;
+import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -263,8 +266,11 @@
@Mock private BrightnessSlider.Factory mBrightnessSliderFactory;
@Mock private WiredChargingRippleController mWiredChargingRippleController;
@Mock private OngoingCallController mOngoingCallController;
+ @Mock private SystemStatusAnimationScheduler mAnimationScheduler;
+ @Mock private PrivacyDotViewController mDotViewController;
@Mock private TunerService mTunerService;
@Mock private FeatureFlags mFeatureFlags;
+ @Mock private IWallpaperManager mWallpaperManager;
private ShadeController mShadeController;
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
private InitController mInitController = new InitController();
@@ -323,7 +329,8 @@
when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
- WakefulnessLifecycle wakefulnessLifecycle = new WakefulnessLifecycle();
+ WakefulnessLifecycle wakefulnessLifecycle =
+ new WakefulnessLifecycle(mContext, mWallpaperManager);
wakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
wakefulnessLifecycle.dispatchFinishedWakingUp();
@@ -429,6 +436,8 @@
mBrightnessSliderFactory,
mWiredChargingRippleController,
mOngoingCallController,
+ mAnimationScheduler,
+ mDotViewController,
mTunerService,
mFeatureFlags);
when(mKeyguardViewMediator.registerStatusBar(any(StatusBar.class), any(ViewGroup.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
index d87d1d1..c244290 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
@@ -19,14 +19,16 @@
import android.app.Notification
import android.app.PendingIntent
import android.app.Person
+import android.content.Intent
import android.service.notification.NotificationListenerService.REASON_USER_STOPPED
-import androidx.test.filters.SmallTest
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.LayoutInflater
import android.widget.LinearLayout
+import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.statusbar.FeatureFlags
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
@@ -43,6 +45,7 @@
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.never
+import org.mockito.Mockito.times
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@@ -55,6 +58,7 @@
private lateinit var notifCollectionListener: NotifCollectionListener
@Mock private lateinit var mockOngoingCallListener: OngoingCallListener
+ @Mock private lateinit var mockActivityStarter: ActivityStarter
private lateinit var chipView: LinearLayout
@@ -71,7 +75,8 @@
`when`(featureFlags.isOngoingCallStatusBarChipEnabled).thenReturn(true)
val notificationCollection = mock(CommonNotifCollection::class.java)
- controller = OngoingCallController(notificationCollection, featureFlags, FakeSystemClock())
+ controller = OngoingCallController(
+ notificationCollection, featureFlags, FakeSystemClock(), mockActivityStarter)
controller.init()
controller.addCallback(mockOngoingCallListener)
controller.setChipView(chipView)
@@ -111,22 +116,24 @@
@Test
fun hasOngoingCall_noOngoingCallNotifSent_returnsFalse() {
- assertThat(controller.hasOngoingCall).isFalse()
+ assertThat(controller.hasOngoingCall()).isFalse()
}
@Test
fun hasOngoingCall_ongoingCallNotifSentAndChipViewSet_returnsTrue() {
notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
- assertThat(controller.hasOngoingCall).isTrue()
+ assertThat(controller.hasOngoingCall()).isTrue()
}
@Test
- fun hasOngoingCall_ongoingCallNotifSentButNoChipView_returnsFalse() {
- controller.setChipView(null)
+ fun hasOngoingCall_ongoingCallNotifSentButInvalidChipView_returnsFalse() {
+ val invalidChipView = LinearLayout(context)
+ controller.setChipView(invalidChipView)
+
notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
- assertThat(controller.hasOngoingCall).isFalse()
+ assertThat(controller.hasOngoingCall()).isFalse()
}
@Test
@@ -136,12 +143,42 @@
notifCollectionListener.onEntryUpdated(ongoingCallNotifEntry)
notifCollectionListener.onEntryRemoved(ongoingCallNotifEntry, REASON_USER_STOPPED)
- assertThat(controller.hasOngoingCall).isFalse()
+ assertThat(controller.hasOngoingCall()).isFalse()
+ }
+
+ /**
+ * This test fakes a theme change during an ongoing call.
+ *
+ * When a theme change happens, [CollapsedStatusBarFragment] and its views get re-created, so
+ * [OngoingCallController.setChipView] gets called with a new view. If there's an active ongoing
+ * call when the theme changes, the new view needs to be updated with the call information.
+ */
+ @Test
+ fun setChipView_whenHasOngoingCallIsTrue_listenerNotifiedWithNewView() {
+ // Start an ongoing call.
+ notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
+
+ lateinit var newChipView: LinearLayout
+ TestableLooper.get(this).runWithLooper {
+ newChipView = LayoutInflater.from(mContext)
+ .inflate(R.layout.ongoing_call_chip, null) as LinearLayout
+ }
+
+ // Change the chip view associated with the controller.
+ controller.setChipView(newChipView)
+
+ // Verify the listener was notified once for the initial call and again when the new view
+ // was set.
+ verify(mockOngoingCallListener, times(2)).onOngoingCallStarted(anyBoolean())
}
private fun createOngoingCallNotifEntry(): NotificationEntry {
val notificationEntryBuilder = NotificationEntryBuilder()
notificationEntryBuilder.modifyNotification(context).style = ongoingCallStyle
+
+ val contentIntent = mock(PendingIntent::class.java)
+ `when`(contentIntent.intent).thenReturn(mock(Intent::class.java))
+ notificationEntryBuilder.modifyNotification(context).setContentIntent(contentIntent)
return notificationEntryBuilder.build()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 4471778..40439a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -36,7 +36,6 @@
import android.app.Instrumentation;
import android.net.ConnectivityManager;
-import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
@@ -323,34 +322,37 @@
public void setConnectivityViaCallbackInNetworkControllerForVcn(
int networkType, boolean validated, boolean isConnected, VcnTransportInfo info) {
- mNetCapabilities.setTransportInfo(info);
- setConnectivityCommon(networkType, validated, isConnected);
- mDefaultCallbackInNetworkController.onCapabilitiesChanged(
- mNetwork, new NetworkCapabilities(mNetCapabilities));
+ final NetworkCapabilities.Builder builder =
+ new NetworkCapabilities.Builder(mNetCapabilities);
+ builder.setTransportInfo(info);
+ setConnectivityCommon(builder, networkType, validated, isConnected);
+ mDefaultCallbackInNetworkController.onCapabilitiesChanged(mNetwork, builder.build());
}
public void setConnectivityViaCallbackInNetworkController(
int networkType, boolean validated, boolean isConnected, WifiInfo wifiInfo) {
+ final NetworkCapabilities.Builder builder =
+ new NetworkCapabilities.Builder(mNetCapabilities);
if (networkType == NetworkCapabilities.TRANSPORT_WIFI) {
- mNetCapabilities.setTransportInfo(wifiInfo);
+ builder.setTransportInfo(wifiInfo);
}
- setConnectivityCommon(networkType, validated, isConnected);
- mDefaultCallbackInNetworkController.onCapabilitiesChanged(
- mNetwork, new NetworkCapabilities(mNetCapabilities));
+ setConnectivityCommon(builder, networkType, validated, isConnected);
+ mDefaultCallbackInNetworkController.onCapabilitiesChanged(mNetwork, builder.build());
}
public void setConnectivityViaCallbackInWifiTracker(
int networkType, boolean validated, boolean isConnected, WifiInfo wifiInfo) {
+ final NetworkCapabilities.Builder builder =
+ new NetworkCapabilities.Builder(mNetCapabilities);
if (networkType == NetworkCapabilities.TRANSPORT_WIFI) {
- mNetCapabilities.setTransportInfo(wifiInfo);
+ builder.setTransportInfo(wifiInfo);
}
- setConnectivityCommon(networkType, validated, isConnected);
+ setConnectivityCommon(builder, networkType, validated, isConnected);
if (networkType == NetworkCapabilities.TRANSPORT_WIFI) {
if (isConnected) {
- mNetworkCallback.onAvailable(mNetwork,
- new NetworkCapabilities(mNetCapabilities), new LinkProperties(), false);
- mNetworkCallback.onCapabilitiesChanged(
- mNetwork, new NetworkCapabilities(mNetCapabilities));
+ final NetworkCapabilities newCap = builder.build();
+ mNetworkCallback.onAvailable(mNetwork);
+ mNetworkCallback.onCapabilitiesChanged(mNetwork, newCap);
} else {
mNetworkCallback.onLost(mNetwork);
}
@@ -359,16 +361,16 @@
public void setConnectivityViaCallbackInWifiTrackerForVcn(
int networkType, boolean validated, boolean isConnected, VcnTransportInfo info) {
- mNetCapabilities.setTransportInfo(info);
- setConnectivityCommon(networkType, validated, isConnected);
+ final NetworkCapabilities.Builder builder =
+ new NetworkCapabilities.Builder(mNetCapabilities);
+ builder.setTransportInfo(info);
+ setConnectivityCommon(builder, networkType, validated, isConnected);
if (networkType == NetworkCapabilities.TRANSPORT_CELLULAR) {
if (isConnected) {
- mNetworkCallback.onAvailable(mNetwork,
- new NetworkCapabilities(mNetCapabilities), new LinkProperties(), false);
- mNetworkCallback.onCapabilitiesChanged(
- mNetwork, new NetworkCapabilities(mNetCapabilities));
- mDefaultCallbackInWifiTracker.onCapabilitiesChanged(
- mNetwork, new NetworkCapabilities(mNetCapabilities));
+ final NetworkCapabilities newCap = builder.build();
+ mNetworkCallback.onAvailable(mNetwork);
+ mNetworkCallback.onCapabilitiesChanged(mNetwork, newCap);
+ mDefaultCallbackInWifiTracker.onCapabilitiesChanged(mNetwork, newCap);
} else {
mNetworkCallback.onLost(mNetwork);
}
@@ -377,26 +379,28 @@
public void setConnectivityViaDefaultCallbackInWifiTracker(
int networkType, boolean validated, boolean isConnected, WifiInfo wifiInfo) {
+ final NetworkCapabilities.Builder builder =
+ new NetworkCapabilities.Builder(mNetCapabilities);
if (networkType == NetworkCapabilities.TRANSPORT_WIFI) {
- mNetCapabilities.setTransportInfo(wifiInfo);
+ builder.setTransportInfo(wifiInfo);
}
- setConnectivityCommon(networkType, validated, isConnected);
+ setConnectivityCommon(builder, networkType, validated, isConnected);
mDefaultCallbackInWifiTracker.onCapabilitiesChanged(
- mNetwork, new NetworkCapabilities(mNetCapabilities));
+ mNetwork, builder.build());
}
- private void setConnectivityCommon(
+ private static void setConnectivityCommon(NetworkCapabilities.Builder builder,
int networkType, boolean validated, boolean isConnected){
// TODO: Separate out into several NetworkCapabilities.
if (isConnected) {
- mNetCapabilities.addTransportType(networkType);
+ builder.addTransportType(networkType);
} else {
- mNetCapabilities.removeTransportType(networkType);
+ builder.removeTransportType(networkType);
}
if (validated) {
- mNetCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+ builder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
} else {
- mNetCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+ builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
index ed87a40..c38a547 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
@@ -202,8 +202,8 @@
@Test
public void testNetworkRequest() {
verify(mConnectivityManager, times(1)).registerNetworkCallback(argThat(
- (NetworkRequest request) -> request.networkCapabilities.getUids() == null
- && request.networkCapabilities.getCapabilities().length == 0
+ (NetworkRequest request) ->
+ request.equals(new NetworkRequest.Builder().clearCapabilities().build())
), any(NetworkCallback.class));
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java
index 653946e..6f6ef72 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java
@@ -71,15 +71,17 @@
public class WalletScreenControllerTest extends SysuiTestCase {
private static final int MAX_CARDS = 10;
+ private static final int CARD_CAROUSEL_WIDTH = 10;
private static final String CARD_ID = "card_id";
private static final CharSequence SHORTCUT_SHORT_LABEL = "View all";
private static final CharSequence SHORTCUT_LONG_LABEL = "Add a payment method";
private static final CharSequence SERVICE_LABEL = "Wallet app";
- private final WalletView mWalletView = new WalletView(mContext);
private final Drawable mWalletLogo = mContext.getDrawable(android.R.drawable.ic_lock_lock);
private final Intent mWalletIntent = new Intent(QuickAccessWalletService.ACTION_VIEW_WALLET)
.setComponent(new ComponentName(mContext.getPackageName(), "WalletActivity"));
+ private WalletView mWalletView;
+
@Mock
QuickAccessWalletClient mWalletClient;
@Mock
@@ -104,6 +106,8 @@
MockitoAnnotations.initMocks(this);
mTestableLooper = TestableLooper.get(this);
when(mUserTracker.getUserContext()).thenReturn(mContext);
+ mWalletView = new WalletView(mContext);
+ mWalletView.getCardCarousel().setExpectedViewWidth(CARD_CAROUSEL_WIDTH);
when(mWalletClient.getLogo()).thenReturn(mWalletLogo);
when(mWalletClient.getShortcutLongLabel()).thenReturn(SHORTCUT_LONG_LABEL);
when(mWalletClient.getShortcutShortLabel()).thenReturn(SHORTCUT_SHORT_LABEL);
@@ -132,7 +136,12 @@
verify(mWalletClient).getWalletCards(any(), any(), mCallbackCaptor.capture());
- mCallbackCaptor.getValue().onWalletCardsRetrieved(response);
+ QuickAccessWalletClient.OnWalletCardsRetrievedCallback callback =
+ mCallbackCaptor.getValue();
+
+ assertEquals(mController, callback);
+
+ callback.onWalletCardsRetrieved(response);
mTestableLooper.processAllMessages();
assertEquals(VISIBLE, mWalletView.getCardCarouselContainer().getVisibility());
diff --git a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-ne/strings.xml b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-ne/strings.xml
index 8765aeb..0b019ae8 100644
--- a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-ne/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-ne/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="display_cutout_emulation_overlay" msgid="1677693377327336341">"कुनाको कटआउट"</string>
+ <string name="display_cutout_emulation_overlay" msgid="1677693377327336341">"कर्नर कटआउट"</string>
</resources>
diff --git a/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values-ne/strings.xml b/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values-ne/strings.xml
index 61653c3..ac29086 100644
--- a/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values-ne/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationWaterfallOverlay/res/values-ne/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="display_cutout_emulation_overlay" msgid="3523556473422419323">"झरनाको कटआउट"</string>
+ <string name="display_cutout_emulation_overlay" msgid="3523556473422419323">"वाटरफल कटआउट"</string>
</resources>
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 05d4ba5..9abe00f 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -149,7 +149,6 @@
*/
public class AccessibilityManagerService extends IAccessibilityManager.Stub
implements AbstractAccessibilityServiceConnection.SystemSupport,
- AccessibilityTrace,
AccessibilityUserState.ServiceInfoChangeListener,
AccessibilityWindowManager.AccessibilityEventSender,
AccessibilitySecurityPolicy.AccessibilityUserManager,
@@ -244,7 +243,7 @@
final SparseArray<AccessibilityUserState> mUserStates = new SparseArray<>();
private final UiAutomationManager mUiAutomationManager = new UiAutomationManager(mLock);
- private final WindowManagerInternal.AccessibilityControllerInternal mA11yController;
+ private final AccessibilityTraceManager mTraceManager;
private int mCurrentUserId = UserHandle.USER_SYSTEM;
@@ -290,7 +289,8 @@
mContext = context;
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mWindowManagerService = LocalServices.getService(WindowManagerInternal.class);
- mA11yController = mWindowManagerService.getAccessibilityController();
+ mTraceManager = new AccessibilityTraceManager(
+ mWindowManagerService.getAccessibilityController(), this);
mMainHandler = new MainHandler(mContext.getMainLooper());
mActivityTaskManagerService = LocalServices.getService(ActivityTaskManagerInternal.class);
mPackageManager = packageManager;
@@ -311,7 +311,8 @@
mContext = context;
mPowerManager = context.getSystemService(PowerManager.class);
mWindowManagerService = LocalServices.getService(WindowManagerInternal.class);
- mA11yController = mWindowManagerService.getAccessibilityController();
+ mTraceManager = new AccessibilityTraceManager(
+ mWindowManagerService.getAccessibilityController(), this);
mMainHandler = new MainHandler(mContext.getMainLooper());
mActivityTaskManagerService = LocalServices.getService(ActivityTaskManagerInternal.class);
mPackageManager = mContext.getPackageManager();
@@ -338,24 +339,25 @@
@Override
public int getCurrentUserIdLocked() {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".getCurrentUserIdLocked");
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".getCurrentUserIdLocked");
}
return mCurrentUserId;
}
@Override
public boolean isAccessibilityButtonShown() {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".isAccessibilityButtonShown");
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".isAccessibilityButtonShown");
}
return mIsAccessibilityButtonShown;
}
@Override
public void onServiceInfoChangedLocked(AccessibilityUserState userState) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".onServiceInfoChangedLocked", "userState=" + userState);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(
+ LOG_TAG + ".onServiceInfoChangedLocked", "userState=" + userState);
}
mSecurityPolicy.onBoundServicesChangedLocked(userState.mUserId,
userState.mBoundServices);
@@ -376,6 +378,12 @@
}
}
+ AccessibilityUserState getCurrentUserState() {
+ synchronized (mLock) {
+ return getCurrentUserStateLocked();
+ }
+ }
+
private AccessibilityUserState getUserState(int userId) {
synchronized (mLock) {
return getUserStateLocked(userId);
@@ -416,8 +424,8 @@
PackageMonitor monitor = new PackageMonitor() {
@Override
public void onSomePackagesChanged() {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".PM.onSomePackagesChanged");
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".PM.onSomePackagesChanged");
}
synchronized (mLock) {
@@ -444,8 +452,8 @@
// mBindingServices in binderDied() during updating. Remove services from this
// package from mBindingServices, and then update the user state to re-bind new
// versions of them.
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".PM.onPackageUpdateFinished",
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".PM.onPackageUpdateFinished",
"packageName=" + packageName + ";uid=" + uid);
}
synchronized (mLock) {
@@ -477,8 +485,8 @@
@Override
public void onPackageRemoved(String packageName, int uid) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".PM.onPackageRemoved",
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".PM.onPackageRemoved",
"packageName=" + packageName + ";uid=" + uid);
}
@@ -521,9 +529,10 @@
@Override
public boolean onHandleForceStop(Intent intent, String[] packages,
int uid, boolean doit) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".PM.onHandleForceStop", "intent=" + intent + ";packages="
- + packages + ";uid=" + uid + ";doit=" + doit);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".PM.onHandleForceStop",
+ "intent=" + intent + ";packages=" + packages + ";uid=" + uid
+ + ";doit=" + doit);
}
synchronized (mLock) {
final int userId = getChangingUserId();
@@ -571,8 +580,9 @@
mContext.registerReceiverAsUser(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".BR.onReceive", "context=" + context + ";intent=" + intent);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".BR.onReceive",
+ "context=" + context + ";intent=" + intent);
}
String action = intent.getAction();
@@ -658,8 +668,9 @@
@Override
public long addClient(IAccessibilityManagerClient callback, int userId) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".addClient", "callback=" + callback + ";userId=" + userId);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".addClient",
+ "callback=" + callback + ";userId=" + userId);
}
synchronized (mLock) {
@@ -700,8 +711,9 @@
@Override
public void sendAccessibilityEvent(AccessibilityEvent event, int userId) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".sendAccessibilityEvent", "event=" + event + ";userId=" + userId);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".sendAccessibilityEvent",
+ "event=" + event + ";userId=" + userId);
}
boolean dispatchEvent = false;
@@ -795,9 +807,9 @@
*/
@Override
public void registerSystemAction(RemoteAction action, int actionId) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".registerSystemAction", "action=" + action + ";actionId="
- + actionId);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".registerSystemAction",
+ "action=" + action + ";actionId=" + actionId);
}
mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY);
getSystemActionPerformer().registerSystemAction(actionId, action);
@@ -810,8 +822,8 @@
*/
@Override
public void unregisterSystemAction(int actionId) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".unregisterSystemAction", "actionId=" + actionId);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".unregisterSystemAction", "actionId=" + actionId);
}
mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY);
getSystemActionPerformer().unregisterSystemAction(actionId);
@@ -827,8 +839,9 @@
@Override
public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(int userId) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".getInstalledAccessibilityServiceList", "userId=" + userId);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".getInstalledAccessibilityServiceList",
+ "userId=" + userId);
}
synchronized (mLock) {
@@ -848,8 +861,8 @@
@Override
public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType,
int userId) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".getEnabledAccessibilityServiceList",
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".getEnabledAccessibilityServiceList",
"feedbackType=" + feedbackType + ";userId=" + userId);
}
@@ -881,8 +894,8 @@
@Override
public void interrupt(int userId) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".interrupt", "userId=" + userId);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".interrupt", "userId=" + userId);
}
List<IAccessibilityServiceClient> interfacesToInterrupt;
@@ -911,8 +924,8 @@
}
for (int i = 0, count = interfacesToInterrupt.size(); i < count; i++) {
try {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".IAccessibilityServiceClient.onInterrupt");
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".IAccessibilityServiceClient.onInterrupt");
}
interfacesToInterrupt.get(i).onInterrupt();
} catch (RemoteException re) {
@@ -926,8 +939,8 @@
public int addAccessibilityInteractionConnection(IWindow windowToken, IBinder leashToken,
IAccessibilityInteractionConnection connection, String packageName,
int userId) throws RemoteException {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".addAccessibilityInteractionConnection",
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".addAccessibilityInteractionConnection",
"windowToken=" + windowToken + "leashToken=" + leashToken + ";connection="
+ connection + "; packageName=" + packageName + ";userId=" + userId);
}
@@ -938,8 +951,9 @@
@Override
public void removeAccessibilityInteractionConnection(IWindow window) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".removeAccessibilityInteractionConnection", "window=" + window);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".removeAccessibilityInteractionConnection",
+ "window=" + window);
}
mA11yWindowManager.removeAccessibilityInteractionConnection(window);
}
@@ -947,8 +961,8 @@
@Override
public void setPictureInPictureActionReplacingConnection(
IAccessibilityInteractionConnection connection) throws RemoteException {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".setPictureInPictureActionReplacingConnection",
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".setPictureInPictureActionReplacingConnection",
"connection=" + connection);
}
mSecurityPolicy.enforceCallingPermission(Manifest.permission.MODIFY_ACCESSIBILITY_DATA,
@@ -961,8 +975,8 @@
IAccessibilityServiceClient serviceClient,
AccessibilityServiceInfo accessibilityServiceInfo,
int flags) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".registerUiTestAutomationService", "owner=" + owner
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".registerUiTestAutomationService", "owner=" + owner
+ ";serviceClient=" + serviceClient + ";accessibilityServiceInfo="
+ accessibilityServiceInfo + ";flags=" + flags);
}
@@ -973,16 +987,16 @@
synchronized (mLock) {
mUiAutomationManager.registerUiTestAutomationServiceLocked(owner, serviceClient,
mContext, accessibilityServiceInfo, sIdCounter++, mMainHandler,
- mSecurityPolicy, this, this, mWindowManagerService, getSystemActionPerformer(),
- mA11yWindowManager, flags);
+ mSecurityPolicy, this, getTraceManager(), mWindowManagerService,
+ getSystemActionPerformer(), mA11yWindowManager, flags);
onUserStateChangedLocked(getCurrentUserStateLocked());
}
}
@Override
public void unregisterUiTestAutomationService(IAccessibilityServiceClient serviceClient) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".unregisterUiTestAutomationService",
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".unregisterUiTestAutomationService",
"serviceClient=" + serviceClient);
}
synchronized (mLock) {
@@ -993,8 +1007,9 @@
@Override
public void temporaryEnableAccessibilityStateUntilKeyguardRemoved(
ComponentName service, boolean touchExplorationEnabled) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".temporaryEnableAccessibilityStateUntilKeyguardRemoved",
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(
+ LOG_TAG + ".temporaryEnableAccessibilityStateUntilKeyguardRemoved",
"service=" + service + ";touchExplorationEnabled=" + touchExplorationEnabled);
}
@@ -1026,8 +1041,9 @@
@Override
public IBinder getWindowToken(int windowId, int userId) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".getWindowToken", "windowId=" + windowId + ";userId=" + userId);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".getWindowToken",
+ "windowId=" + windowId + ";userId=" + userId);
}
mSecurityPolicy.enforceCallingPermission(
@@ -1069,8 +1085,8 @@
*/
@Override
public void notifyAccessibilityButtonClicked(int displayId, String targetName) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".notifyAccessibilityButtonClicked",
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".notifyAccessibilityButtonClicked",
"displayId=" + displayId + ";targetName=" + targetName);
}
@@ -1099,8 +1115,9 @@
*/
@Override
public void notifyAccessibilityButtonVisibilityChanged(boolean shown) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".notifyAccessibilityButtonVisibilityChanged", "shown=" + shown);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".notifyAccessibilityButtonVisibilityChanged",
+ "shown=" + shown);
}
mSecurityPolicy.enforceCallingOrSelfPermission(
@@ -1131,8 +1148,8 @@
*/
@Override
public void onSystemActionsChanged() {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".onSystemActionsChanged");
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".onSystemActionsChanged");
}
synchronized (mLock) {
@@ -1197,8 +1214,9 @@
@Override
public @Nullable MotionEventInjector getMotionEventInjectorForDisplayLocked(int displayId) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".getMotionEventInjectorForDisplayLocked", "displayId=" + displayId);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".getMotionEventInjectorForDisplayLocked",
+ "displayId=" + displayId);
}
final long endMillis = SystemClock.uptimeMillis() + WAIT_MOTION_INJECTOR_TIMEOUT_MILLIS;
@@ -1411,7 +1429,7 @@
private int getClientStateLocked(AccessibilityUserState userState) {
return userState.getClientStateLocked(
mUiAutomationManager.isUiAutomationRunningLocked(),
- mA11yController.isAccessibilityTracingEnabled());
+ mTraceManager.isA11yTracingEnabled());
}
private InteractionBridge getInteractionBridge() {
@@ -1770,9 +1788,10 @@
@Override
public void persistComponentNamesToSettingLocked(String settingName,
Set<ComponentName> componentNames, int userId) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".persistComponentNamesToSettingLocked", "settingName=" + settingName
- + ";componentNames=" + componentNames + ";userId=" + userId);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".persistComponentNamesToSettingLocked",
+ "settingName=" + settingName + ";componentNames=" + componentNames + ";userId="
+ + userId);
}
persistColonDelimitedSetToSettingLocked(settingName, userId, componentNames,
@@ -1859,8 +1878,9 @@
if (service == null) {
service = new AccessibilityServiceConnection(userState, mContext, componentName,
installedService, sIdCounter++, mMainHandler, mLock, mSecurityPolicy,
- this, this, mWindowManagerService, getSystemActionPerformer(),
- mA11yWindowManager, mActivityTaskManagerService);
+ this, getTraceManager(), mWindowManagerService,
+ getSystemActionPerformer(), mA11yWindowManager,
+ mActivityTaskManagerService);
} else if (userState.mBoundServices.contains(service)) {
continue;
}
@@ -1892,6 +1912,12 @@
updateAccessibilityEnabledSettingLocked(userState);
}
+ void scheduleUpdateClientsIfNeeded(AccessibilityUserState userState) {
+ synchronized (mLock) {
+ scheduleUpdateClientsIfNeededLocked(userState);
+ }
+ }
+
private void scheduleUpdateClientsIfNeededLocked(AccessibilityUserState userState) {
final int clientState = getClientStateLocked(userState);
if (userState.getLastSentClientStateLocked() != clientState
@@ -2737,8 +2763,9 @@
@GuardedBy("mLock")
@Override
public MagnificationSpec getCompatibleMagnificationSpecLocked(int windowId) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".getCompatibleMagnificationSpecLocked", "windowId=" + windowId);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".getCompatibleMagnificationSpecLocked",
+ "windowId=" + windowId);
}
IBinder windowToken = mA11yWindowManager.getWindowTokenForUserAndWindowIdLocked(
@@ -2752,8 +2779,8 @@
@Override
public KeyEventDispatcher getKeyEventDispatcher() {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".getKeyEventDispatcher");
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".getKeyEventDispatcher");
}
if (mKeyEventDispatcher == null) {
@@ -2768,9 +2795,10 @@
@SuppressWarnings("AndroidFrameworkPendingIntentMutability")
public PendingIntent getPendingIntentActivity(Context context, int requestCode, Intent intent,
int flags) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".getPendingIntentActivity", "context=" + context + ";requestCode="
- + requestCode + ";intent=" + intent + ";flags=" + flags);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".getPendingIntentActivity",
+ "context=" + context + ";requestCode=" + requestCode + ";intent=" + intent
+ + ";flags=" + flags);
}
@@ -2788,8 +2816,9 @@
*/
@Override
public void performAccessibilityShortcut(String targetName) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".performAccessibilityShortcut", "targetName=" + targetName);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".performAccessibilityShortcut",
+ "targetName=" + targetName);
}
if ((UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID)
@@ -2976,8 +3005,9 @@
@Override
public List<String> getAccessibilityShortcutTargets(@ShortcutType int shortcutType) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".getAccessibilityShortcutTargets", "shortcutType=" + shortcutType);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".getAccessibilityShortcutTargets",
+ "shortcutType=" + shortcutType);
}
if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
@@ -3049,8 +3079,9 @@
@Override
public void sendAccessibilityEventForCurrentUserLocked(AccessibilityEvent event) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".sendAccessibilityEventForCurrentUserLocked", "event=" + event);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".sendAccessibilityEventForCurrentUserLocked",
+ "event=" + event);
}
sendAccessibilityEventLocked(event, mCurrentUserId);
@@ -3074,8 +3105,9 @@
*/
@Override
public boolean sendFingerprintGesture(int gestureKeyCode) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".sendFingerprintGesture", "gestureKeyCode=" + gestureKeyCode);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".sendFingerprintGesture",
+ "gestureKeyCode=" + gestureKeyCode);
}
synchronized(mLock) {
@@ -3099,8 +3131,9 @@
*/
@Override
public int getAccessibilityWindowId(@Nullable IBinder windowToken) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".getAccessibilityWindowId", "windowToken=" + windowToken);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".getAccessibilityWindowId",
+ "windowToken=" + windowToken);
}
synchronized (mLock) {
@@ -3120,8 +3153,8 @@
*/
@Override
public long getRecommendedTimeoutMillis() {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".getRecommendedTimeoutMillis");
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".getRecommendedTimeoutMillis");
}
synchronized(mLock) {
@@ -3138,8 +3171,9 @@
@Override
public void setWindowMagnificationConnection(
IWindowMagnificationConnection connection) throws RemoteException {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".setWindowMagnificationConnection", "connection=" + connection);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".setWindowMagnificationConnection",
+ "connection=" + connection);
}
mSecurityPolicy.enforceCallingOrSelfPermission(
@@ -3172,8 +3206,8 @@
@Override
public void associateEmbeddedHierarchy(@NonNull IBinder host, @NonNull IBinder embedded) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".associateEmbeddedHierarchy",
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".associateEmbeddedHierarchy",
"host=" + host + ";embedded=" + embedded);
}
@@ -3184,8 +3218,8 @@
@Override
public void disassociateEmbeddedHierarchy(@NonNull IBinder token) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".disassociateEmbeddedHierarchy", "token=" + token);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".disassociateEmbeddedHierarchy", "token=" + token);
}
synchronized (mLock) {
@@ -3265,8 +3299,8 @@
@Override
public FullScreenMagnificationController getFullScreenMagnificationController() {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".getFullScreenMagnificationController");
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".getFullScreenMagnificationController");
}
synchronized (mLock) {
return mMagnificationController.getFullScreenMagnificationController();
@@ -3275,8 +3309,9 @@
@Override
public void onClientChangeLocked(boolean serviceInfoChanged) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".onClientChangeLocked", "serviceInfoChanged=" + serviceInfoChanged);
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".onClientChangeLocked",
+ "serviceInfoChanged=" + serviceInfoChanged);
}
AccessibilityUserState userState = getUserStateLocked(mCurrentUserId);
@@ -3314,9 +3349,9 @@
AccessibilityServiceConnection service = new AccessibilityServiceConnection(
userState, mContext,
COMPONENT_NAME, info, sIdCounter++, mMainHandler, mLock, mSecurityPolicy,
- AccessibilityManagerService.this, AccessibilityManagerService.this,
- mWindowManagerService, getSystemActionPerformer(), mA11yWindowManager,
- mActivityTaskManagerService) {
+ AccessibilityManagerService.this,
+ AccessibilityManagerService.this.getTraceManager(), mWindowManagerService,
+ getSystemActionPerformer(), mA11yWindowManager, mActivityTaskManagerService) {
@Override
public boolean supportsFlagForNotImportantViews(AccessibilityServiceInfo info) {
return true;
@@ -3805,8 +3840,8 @@
@Override
public void setGestureDetectionPassthroughRegion(int displayId, Region region) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".setGestureDetectionPassthroughRegion",
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".setGestureDetectionPassthroughRegion",
"displayId=" + displayId + ";region=" + region);
}
@@ -3820,8 +3855,8 @@
@Override
public void setTouchExplorationPassthroughRegion(int displayId, Region region) {
- if (isA11yTracingEnabled()) {
- logTrace(LOG_TAG + ".setTouchExplorationPassthroughRegion",
+ if (mTraceManager.isA11yTracingEnabled()) {
+ mTraceManager.logTrace(LOG_TAG + ".setTouchExplorationPassthroughRegion",
"displayId=" + displayId + ";region=" + region);
}
@@ -3863,46 +3898,7 @@
}
- @Override
- public boolean isA11yTracingEnabled() {
- return mA11yController.isAccessibilityTracingEnabled();
- }
-
- @Override
- public void startTrace() {
- if (!mA11yController.isAccessibilityTracingEnabled()) {
- mA11yController.startTrace();
- final AccessibilityUserState userState = getUserStateLocked(UserHandle.USER_SYSTEM);
- scheduleUpdateClientsIfNeededLocked(userState);
- }
- }
-
- @Override
- public void stopTrace() {
- if (mA11yController.isAccessibilityTracingEnabled()) {
- mA11yController.stopTrace();
- final AccessibilityUserState userState = getUserStateLocked(UserHandle.USER_SYSTEM);
- scheduleUpdateClientsIfNeededLocked(userState);
- }
- }
-
- @Override
- public void logTrace(String where) {
- logTrace(where, "");
- }
-
- @Override
- public void logTrace(String where, String callingParams) {
- mA11yController.logTrace(where, callingParams, "".getBytes(),
- Binder.getCallingUid(), Thread.currentThread().getStackTrace());
- }
-
- @Override
- public void logTrace(long timestamp, String where, String callingParams, int processId,
- long threadId, int callingUid, StackTraceElement[] callStack) {
- if (mA11yController.isAccessibilityTracingEnabled()) {
- mA11yController.logTrace(where, callingParams, "".getBytes(), callingUid, callStack,
- timestamp, processId, threadId);
- }
+ AccessibilityTraceManager getTraceManager() {
+ return mTraceManager;
}
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java
index 16ce177..6396960 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java
@@ -59,9 +59,8 @@
return runCallSystemAction();
}
case "start-trace":
- return startTrace();
case "stop-trace":
- return stopTrace();
+ return mService.getTraceManager().onShellCommand(cmd);
}
return -1;
}
@@ -107,16 +106,6 @@
return -1;
}
- private int startTrace() {
- mService.startTrace();
- return 0;
- }
-
- private int stopTrace() {
- mService.stopTrace();
- return 0;
- }
-
private Integer parseUserId() {
final String option = getNextOption();
if (option != null) {
@@ -142,9 +131,6 @@
pw.println(" Get whether binding to services provided by instant apps is allowed.");
pw.println(" call-system-action <ACTION_ID>");
pw.println(" Calls the system action with the given action id.");
- pw.println(" start-trace");
- pw.println(" Start the debug tracing.");
- pw.println(" stop-trace");
- pw.println(" Stop the debug tracing.");
+ mService.getTraceManager().onHelp(pw);
}
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityTraceManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityTraceManager.java
new file mode 100644
index 0000000..6105e8a
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityTraceManager.java
@@ -0,0 +1,100 @@
+/**
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.accessibility;
+
+import android.annotation.NonNull;
+import android.os.Binder;
+
+import com.android.server.wm.WindowManagerInternal;
+
+import java.io.PrintWriter;
+
+/**
+ * Manager of accessibility trace.
+ */
+class AccessibilityTraceManager implements AccessibilityTrace {
+ private final WindowManagerInternal.AccessibilityControllerInternal mA11yController;
+ private final AccessibilityManagerService mService;
+
+ AccessibilityTraceManager(
+ @NonNull WindowManagerInternal.AccessibilityControllerInternal a11yController,
+ @NonNull AccessibilityManagerService service) {
+ mA11yController = a11yController;
+ mService = service;
+ }
+
+ @Override
+ public boolean isA11yTracingEnabled() {
+ return mA11yController.isAccessibilityTracingEnabled();
+ }
+
+ @Override
+ public void startTrace() {
+ if (!mA11yController.isAccessibilityTracingEnabled()) {
+ mA11yController.startTrace();
+ mService.scheduleUpdateClientsIfNeeded(mService.getCurrentUserState());
+ }
+ }
+
+ @Override
+ public void stopTrace() {
+ if (mA11yController.isAccessibilityTracingEnabled()) {
+ mA11yController.stopTrace();
+ mService.scheduleUpdateClientsIfNeeded(mService.getCurrentUserState());
+ }
+ }
+
+ @Override
+ public void logTrace(String where) {
+ logTrace(where, "");
+ }
+
+ @Override
+ public void logTrace(String where, String callingParams) {
+ mA11yController.logTrace(where, callingParams, "".getBytes(),
+ Binder.getCallingUid(), Thread.currentThread().getStackTrace());
+ }
+
+ @Override
+ public void logTrace(long timestamp, String where, String callingParams, int processId,
+ long threadId, int callingUid, StackTraceElement[] callStack) {
+ if (mA11yController.isAccessibilityTracingEnabled()) {
+ mA11yController.logTrace(where, callingParams, "".getBytes(), callingUid, callStack,
+ timestamp, processId, threadId);
+ }
+ }
+
+ int onShellCommand(String cmd) {
+ switch (cmd) {
+ case "start-trace": {
+ startTrace();
+ return 0;
+ }
+ case "stop-trace": {
+ stopTrace();
+ return 0;
+ }
+ }
+ return -1;
+ }
+
+ void onHelp(PrintWriter pw) {
+ pw.println(" start-trace");
+ pw.println(" Start the debug tracing.");
+ pw.println(" stop-trace");
+ pw.println(" Stop the debug tracing.");
+ }
+}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index f8b770b..6bf4967 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -1311,7 +1311,9 @@
@Override
public void onServiceDied(@NonNull RemoteFillService service) {
Slog.w(TAG, "removing session because service died");
- forceRemoveFromServiceLocked();
+ synchronized (mLock) {
+ forceRemoveFromServiceLocked();
+ }
}
// AutoFillUiCallback
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 5cbcacf..5dc11c5 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -132,7 +132,6 @@
],
static_libs: [
- "protolog-lib",
"time_zone_distro",
"time_zone_distro_installer",
"android.hardware.authsecret-V1.0-java",
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index a9eb2c1..5dd9b0e 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -825,6 +825,12 @@
String packageName, int userId);
/**
+ * Return the enabled setting for a package component (activity, receiver, service, provider).
+ */
+ public abstract @PackageManager.EnabledState int getComponentEnabledSetting(
+ @NonNull ComponentName componentName, int callingUid, int userId);
+
+ /**
* Extra field name for the token of a request to enable rollback for a
* package.
*/
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index feed220..c3a5d1f 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -714,9 +714,6 @@
Slog.w(TAG, "Callback is null in unregisterAdapter");
return;
}
- if (!checkConnectPermissionForPreflight(mContext)) {
- return;
- }
synchronized (mCallbacks) {
mCallbacks.unregister(callback);
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 4d96162..809ef41 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -630,7 +630,9 @@
}
private static IDnsResolver getDnsResolver(Context context) {
- return IDnsResolver.Stub.asInterface(DnsResolverServiceManager.getService(context));
+ final DnsResolverServiceManager dsm = context.getSystemService(
+ DnsResolverServiceManager.class);
+ return IDnsResolver.Stub.asInterface(dsm.getService());
}
/** Handler thread used for all of the handlers below. */
@@ -1924,7 +1926,7 @@
newNc.setAdministratorUids(new int[0]);
if (!checkAnyPermissionOf(
callerPid, callerUid, android.Manifest.permission.NETWORK_FACTORY)) {
- newNc.setSubIds(Collections.emptySet());
+ newNc.setSubscriptionIds(Collections.emptySet());
}
return newNc;
@@ -2147,7 +2149,7 @@
PermissionUtils.enforceNetworkStackPermission(mContext);
final ArrayList<NetworkState> result = new ArrayList<>();
- for (NetworkStateSnapshot snapshot : getAllNetworkStateSnapshot()) {
+ for (NetworkStateSnapshot snapshot : getAllNetworkStateSnapshots()) {
// NetworkStateSnapshot doesn't contain NetworkInfo, so need to fetch it from the
// NetworkAgentInfo.
final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(snapshot.network);
@@ -2162,7 +2164,7 @@
@Override
@NonNull
- public List<NetworkStateSnapshot> getAllNetworkStateSnapshot() {
+ public List<NetworkStateSnapshot> getAllNetworkStateSnapshots() {
// This contains IMSI details, so make sure the caller is privileged.
PermissionUtils.enforceNetworkStackPermission(mContext);
@@ -2808,6 +2810,8 @@
@Override
protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
@Nullable String[] args) {
+ if (!checkDumpPermission(mContext, TAG, writer)) return;
+
mPriorityDumper.dump(fd, writer, args);
}
@@ -2825,7 +2829,6 @@
private void doDump(FileDescriptor fd, PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
- if (!checkDumpPermission(mContext, TAG, pw)) return;
if (CollectionUtils.contains(args, DIAG_ARG)) {
dumpNetworkDiagnostics(pw);
@@ -3969,17 +3972,16 @@
// multilayer requests, returning as soon as a NetworkAgentInfo satisfies a request
// is important so as to not evaluate lower priority requests further in
// nri.mRequests.
- final boolean isNetworkNeeded = candidate.isSatisfyingRequest(req.requestId)
- // Note that this catches two important cases:
- // 1. Unvalidated cellular will not be reaped when unvalidated WiFi
- // is currently satisfying the request. This is desirable when
- // cellular ends up validating but WiFi does not.
- // 2. Unvalidated WiFi will not be reaped when validated cellular
- // is currently satisfying the request. This is desirable when
- // WiFi ends up validating and out scoring cellular.
- || nri.getSatisfier().getCurrentScore()
- < candidate.getCurrentScoreAsValidated();
- return isNetworkNeeded;
+ final NetworkAgentInfo champion = req.equals(nri.getActiveRequest())
+ ? nri.getSatisfier() : null;
+ // Note that this catches two important cases:
+ // 1. Unvalidated cellular will not be reaped when unvalidated WiFi
+ // is currently satisfying the request. This is desirable when
+ // cellular ends up validating but WiFi does not.
+ // 2. Unvalidated WiFi will not be reaped when validated cellular
+ // is currently satisfying the request. This is desirable when
+ // WiFi ends up validating and out scoring cellular.
+ return mNetworkRanker.mightBeat(req, champion, candidate.getValidatedScoreable());
}
}
@@ -5726,7 +5728,7 @@
}
mAppOpsManager.checkPackage(callerUid, callerPackageName);
- if (!nc.getSubIds().isEmpty()) {
+ if (!nc.getSubscriptionIds().isEmpty()) {
enforceNetworkFactoryPermission();
}
}
@@ -6148,6 +6150,7 @@
@Override
public int registerNetworkProvider(Messenger messenger, String name) {
enforceNetworkFactoryOrSettingsPermission();
+ Objects.requireNonNull(messenger, "messenger must be non-null");
NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger,
nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger));
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi));
@@ -7811,7 +7814,7 @@
@NonNull final Collection<NetworkRequestInfo> networkRequests) {
final NetworkReassignment changes = new NetworkReassignment();
- // Gather the list of all relevant agents and sort them by score.
+ // Gather the list of all relevant agents.
final ArrayList<NetworkAgentInfo> nais = new ArrayList<>();
for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
if (!nai.everConnected) {
@@ -9186,6 +9189,7 @@
@Override
public void unregisterConnectivityDiagnosticsCallback(
@NonNull IConnectivityDiagnosticsCallback callback) {
+ Objects.requireNonNull(callback, "callback must be non-null");
mConnectivityDiagnosticsHandler.sendMessage(
mConnectivityDiagnosticsHandler.obtainMessage(
ConnectivityDiagnosticsHandler
@@ -9556,6 +9560,7 @@
*/
@Override
public void unregisterQosCallback(@NonNull final IQosCallback callback) {
+ Objects.requireNonNull(callback, "callback must be non-null");
mQosCallbackTracker.unregisterCallback(callback);
}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 98bfa28..ee3530a 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -2551,11 +2551,12 @@
* Send a notification to registrants that the configs of physical channel has changed for
* a particular subscription.
*
+ * @param phoneId the phone id.
* @param subId the subId
* @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel.
*/
- public void notifyPhysicalChannelConfigForSubscriber(
- int subId, List<PhysicalChannelConfig> configs) {
+ public void notifyPhysicalChannelConfigForSubscriber(int phoneId, int subId,
+ List<PhysicalChannelConfig> configs) {
if (!checkNotifyPermission("notifyPhysicalChannelConfig()")) {
return;
}
@@ -2567,7 +2568,6 @@
}
synchronized (mRecords) {
- int phoneId = SubscriptionManager.getPhoneId(subId);
if (validatePhoneId(phoneId)) {
mPhysicalChannelConfigs.set(phoneId, configs);
for (Record r : mRecords) {
@@ -2861,7 +2861,14 @@
intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, phoneId);
intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, phoneId);
+ // Send the broadcast twice -- once for all apps with READ_PHONE_STATE, then again
+ // for all apps with READ_PRIV but not READ_PHONE_STATE. This ensures that any app holding
+ // either READ_PRIV or READ_PHONE get this broadcast exactly once.
mContext.sendBroadcastAsUser(intent, UserHandle.ALL, Manifest.permission.READ_PHONE_STATE);
+ mContext.createContextAsUser(UserHandle.ALL, 0)
+ .sendBroadcastMultiplePermissions(intent,
+ new String[] { Manifest.permission.READ_PRIVILEGED_PHONE_STATE },
+ new String[] { Manifest.permission.READ_PHONE_STATE });
}
private void broadcastSignalStrengthChanged(SignalStrength signalStrength, int phoneId,
@@ -2988,7 +2995,14 @@
getApnTypesStringFromBitmask(pdcs.getApnSetting().getApnTypeBitmask()));
intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, slotIndex);
intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId);
+ // Send the broadcast twice -- once for all apps with READ_PHONE_STATE, then again
+ // for all apps with READ_PRIV but not READ_PHONE_STATE. This ensures that any app holding
+ // either READ_PRIV or READ_PHONE get this broadcast exactly once.
mContext.sendBroadcastAsUser(intent, UserHandle.ALL, Manifest.permission.READ_PHONE_STATE);
+ mContext.createContextAsUser(UserHandle.ALL, 0)
+ .sendBroadcastMultiplePermissions(intent,
+ new String[] { Manifest.permission.READ_PRIVILEGED_PHONE_STATE },
+ new String[] { Manifest.permission.READ_PHONE_STATE });
}
/**
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 039f4d9..4b52057 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -729,7 +729,7 @@
// If multiple subscription IDs exist, they MUST all point to the same subscription
// group. Otherwise undefined behavior may occur.
- for (int subId : networkCapabilities.getSubIds()) {
+ for (int subId : networkCapabilities.getSubscriptionIds()) {
// Verify that all subscriptions point to the same group
if (subGrp != null && !subGrp.equals(snapshot.getGroupForSubId(subId))) {
Slog.wtf(TAG, "Got multiple subscription groups for a single network");
@@ -1003,14 +1003,14 @@
}
private boolean requiresRestartForCarrierWifi(NetworkCapabilities caps) {
- if (!caps.hasTransport(TRANSPORT_WIFI) || caps.getSubIds() == null) {
+ if (!caps.hasTransport(TRANSPORT_WIFI) || caps.getSubscriptionIds() == null) {
return false;
}
synchronized (mCaps) {
for (NetworkCapabilities existing : mCaps.values()) {
if (existing.hasTransport(TRANSPORT_WIFI)
- && caps.getSubIds().equals(existing.getSubIds())) {
+ && caps.getSubscriptionIds().equals(existing.getSubscriptionIds())) {
// Restart if any immutable capabilities have changed
return existing.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
!= caps.hasCapability(NET_CAPABILITY_NOT_RESTRICTED);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 4324717..5a1a505 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -3039,7 +3039,7 @@
try {
r.mRecentCallerApplicationInfo =
mAm.mContext.getPackageManager().getApplicationInfoAsUser(callingPackage,
- 0, userId);
+ 0, UserHandle.getUserId(callingUid));
} catch (PackageManager.NameNotFoundException e) {
}
if (!mAm.validateAssociationAllowedLocked(callingPackage, callingUid, r.packageName,
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index b103def..b7ef10a 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -199,13 +199,12 @@
@Override
public void onPropertiesChanged(Properties properties) {
synchronized (mDeviceConfigLock) {
- for (String key : properties.getKeyset()) {
+ for (final String packageName : properties.getKeyset()) {
try {
// Check if the package is installed before caching it.
- final String packageName = keyToPackageName(key);
mPackageManager.getPackageInfo(packageName, 0);
final GamePackageConfiguration config =
- GamePackageConfiguration.fromProperties(key, properties);
+ GamePackageConfiguration.fromProperties(packageName, properties);
if (config.isValid()) {
putConfig(config);
} else {
@@ -290,8 +289,8 @@
private final String mPackageName;
private final ArrayMap<Integer, GameModeConfiguration> mModeConfigs;
- private GamePackageConfiguration(String keyName) {
- mPackageName = keyToPackageName(keyName);
+ private GamePackageConfiguration(String packageName) {
+ mPackageName = packageName;
mModeConfigs = new ArrayMap<>();
}
@@ -563,9 +562,9 @@
}
}
- private void loadDeviceConfigLocked() {
+ void loadDeviceConfigLocked() {
final List<PackageInfo> packages = mPackageManager.getInstalledPackages(0);
- final String[] packageNames = packages.stream().map(e -> packageNameToKey(e.packageName))
+ final String[] packageNames = packages.stream().map(e -> e.packageName)
.toArray(String[]::new);
synchronized (mDeviceConfigLock) {
final Properties properties = DeviceConfig.getProperties(
@@ -680,8 +679,7 @@
case ACTION_PACKAGE_CHANGED:
synchronized (mDeviceConfigLock) {
Properties properties = DeviceConfig.getProperties(
- DeviceConfig.NAMESPACE_GAME_OVERLAY,
- packageNameToKey(packageName));
+ DeviceConfig.NAMESPACE_GAME_OVERLAY, packageName);
for (String key : properties.getKeyset()) {
GamePackageConfiguration config =
GamePackageConfiguration.fromProperties(key,
@@ -692,7 +690,9 @@
break;
case ACTION_PACKAGE_REMOVED:
disableCompatScale(packageName);
- mConfigs.remove(packageName);
+ synchronized (mDeviceConfigLock) {
+ mConfigs.remove(packageName);
+ }
break;
default:
// do nothing
@@ -710,23 +710,6 @@
mDeviceConfigListener = new DeviceConfigListener();
}
- /**
- * Valid package name characters are [a-zA-Z0-9_] with a '.' delimiter. Policy keys can only use
- * [a-zA-Z0-9_] so we must handle periods. We do this by appending a '_' to any existing
- * sequence of '_', then we replace all '.' chars with '_';
- */
- private static String packageNameToKey(String name) {
- return name.replaceAll("(_+)", "_$1").replaceAll("\\.", "_");
- }
-
- /**
- * Replace the last '_' in a sequence with '.' (this can be one or more chars), then replace the
- * resulting special case '_.' with just '_' to get the original package name.
- */
- private static String keyToPackageName(String key) {
- return key.replaceAll("(_)(?!\\1)", ".").replaceAll("_\\.", "_");
- }
-
private String dumpDeviceConfigs() {
StringBuilder out = new StringBuilder();
for (String key : mConfigs.keySet()) {
diff --git a/services/core/java/com/android/server/apphibernation/AppHibernationService.java b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
index 540589b..fd829fa 100644
--- a/services/core/java/com/android/server/apphibernation/AppHibernationService.java
+++ b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
@@ -109,7 +109,7 @@
private final boolean mOatArtifactDeletionEnabled;
@VisibleForTesting
- boolean mIsServiceEnabled;
+ static boolean sIsServiceEnabled;
/**
* Initializes the system service.
@@ -165,7 +165,7 @@
});
}
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
- mIsServiceEnabled = isAppHibernationEnabled();
+ sIsServiceEnabled = isDeviceConfigAppHibernationEnabled();
DeviceConfig.addOnPropertiesChangedListener(
NAMESPACE_APP_HIBERNATION,
ActivityThread.currentApplication().getMainExecutor(),
@@ -536,7 +536,7 @@
private void onDeviceConfigChanged(Properties properties) {
for (String key : properties.getKeyset()) {
if (TextUtils.equals(KEY_APP_HIBERNATION_ENABLED, key)) {
- mIsServiceEnabled = isAppHibernationEnabled();
+ sIsServiceEnabled = isDeviceConfigAppHibernationEnabled();
break;
}
}
@@ -574,10 +574,10 @@
}
private boolean checkHibernationEnabled(String methodName) {
- if (!mIsServiceEnabled) {
+ if (!sIsServiceEnabled) {
Slog.w(TAG, String.format("Attempted to call %s on unsupported device.", methodName));
}
- return mIsServiceEnabled;
+ return sIsServiceEnabled;
}
private void dump(PrintWriter pw) {
@@ -725,6 +725,10 @@
* @return true if enabled, false otherwise
*/
public static boolean isAppHibernationEnabled() {
+ return sIsServiceEnabled;
+ }
+
+ private static boolean isDeviceConfigAppHibernationEnabled() {
return DeviceConfig.getBoolean(
NAMESPACE_APP_HIBERNATION,
KEY_APP_HIBERNATION_ENABLED,
diff --git a/services/core/java/com/android/server/connectivity/FullScore.java b/services/core/java/com/android/server/connectivity/FullScore.java
index 52da566..14cec09 100644
--- a/services/core/java/com/android/server/connectivity/FullScore.java
+++ b/services/core/java/com/android/server/connectivity/FullScore.java
@@ -259,6 +259,14 @@
}
/**
+ * Returns this score but validated.
+ */
+ public FullScore asValidated() {
+ return new FullScore(mLegacyInt, mPolicies | (1L << POLICY_IS_VALIDATED),
+ mKeepConnectedReason);
+ }
+
+ /**
* For backward compatibility, get the legacy int.
* This will be removed before S is published.
*/
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 584174e..18becd4 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -950,6 +950,26 @@
}
/**
+ * Returns a Scoreable identical to this NAI, but validated.
+ *
+ * This is useful to probe what scoring would be if this network validated, to know
+ * whether to provisionally keep a network that may or may not validate.
+ *
+ * @return a Scoreable identical to this NAI, but validated.
+ */
+ public NetworkRanker.Scoreable getValidatedScoreable() {
+ return new NetworkRanker.Scoreable() {
+ @Override public FullScore getScore() {
+ return mScore.asValidated();
+ }
+
+ @Override public NetworkCapabilities getCapsNoCopy() {
+ return networkCapabilities;
+ }
+ };
+ }
+
+ /**
* Return a {@link NetworkStateSnapshot} for this network.
*/
@NonNull
diff --git a/services/core/java/com/android/server/connectivity/NetworkRanker.java b/services/core/java/com/android/server/connectivity/NetworkRanker.java
index 2b345e5..346af44 100644
--- a/services/core/java/com/android/server/connectivity/NetworkRanker.java
+++ b/services/core/java/com/android/server/connectivity/NetworkRanker.java
@@ -234,16 +234,17 @@
NetworkAgentInfo bestNetwork = null;
int bestScore = Integer.MIN_VALUE;
for (final NetworkAgentInfo nai : nais) {
- if (nai.getCurrentScore() > bestScore) {
+ final int naiScore = nai.getCurrentScore();
+ if (naiScore > bestScore) {
bestNetwork = nai;
- bestScore = nai.getCurrentScore();
+ bestScore = naiScore;
}
}
return bestNetwork;
}
/**
- * Returns whether an offer has a chance to beat a champion network for a request.
+ * Returns whether a {@link Scoreable} has a chance to beat a champion network for a request.
*
* Offers are sent by network providers when they think they might be able to make a network
* with the characteristics contained in the offer. If the offer has no chance to beat
@@ -257,15 +258,15 @@
*
* @param request The request to evaluate against.
* @param champion The currently best network for this request.
- * @param offer The offer.
+ * @param contestant The offer.
* @return Whether the offer stands a chance to beat the champion.
*/
public boolean mightBeat(@NonNull final NetworkRequest request,
@Nullable final NetworkAgentInfo champion,
- @NonNull final NetworkOffer offer) {
+ @NonNull final Scoreable contestant) {
// If this network can't even satisfy the request then it can't beat anything, not
// even an absence of network. It can't satisfy it anyway.
- if (!request.canBeSatisfiedBy(offer.caps)) return false;
+ if (!request.canBeSatisfiedBy(contestant.getCapsNoCopy())) return false;
// If there is no satisfying network, then this network can beat, because some network
// is always better than no network.
if (null == champion) return true;
@@ -274,25 +275,24 @@
// Otherwise rank them.
final ArrayList<Scoreable> candidates = new ArrayList<>();
candidates.add(champion);
- candidates.add(offer);
- return offer == getBestNetworkByPolicy(candidates, champion);
+ candidates.add(contestant);
+ return contestant == getBestNetworkByPolicy(candidates, champion);
} else {
- return mightBeatByLegacyInt(request, champion.getScore(), offer);
+ return mightBeatByLegacyInt(champion.getScore(), contestant);
}
}
/**
- * Returns whether an offer might beat a champion according to the legacy int.
+ * Returns whether a contestant might beat a champion according to the legacy int.
*/
- public boolean mightBeatByLegacyInt(@NonNull final NetworkRequest request,
- @Nullable final FullScore championScore,
- @NonNull final NetworkOffer offer) {
+ private boolean mightBeatByLegacyInt(@Nullable final FullScore championScore,
+ @NonNull final Scoreable contestant) {
final int offerIntScore;
- if (offer.caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
+ if (contestant.getCapsNoCopy().hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
// If the offer might have Internet access, then it might validate.
- offerIntScore = offer.score.getLegacyIntAsValidated();
+ offerIntScore = contestant.getScore().getLegacyIntAsValidated();
} else {
- offerIntScore = offer.score.getLegacyInt();
+ offerIntScore = contestant.getScore().getLegacyInt();
}
return championScore.getLegacyInt() < offerIntScore;
}
diff --git a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
index fb14fbd..c0ab093 100644
--- a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
+++ b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
@@ -502,8 +502,8 @@
Slog.e(TAG, "Failed to lookup font file that has " + font.getPostScriptName());
return null;
}
- resolvedFonts.add(new FontConfig.Font(info.mFile, null, font.getFontStyle(),
- font.getIndex(), font.getFontVariationSettings(), null));
+ resolvedFonts.add(new FontConfig.Font(info.mFile, null, info.getPostScriptName(),
+ font.getFontStyle(), font.getIndex(), font.getFontVariationSettings(), null));
}
return new FontConfig.FontFamily(resolvedFonts, fontFamily.getName(),
null, FontConfig.FontFamily.VARIANT_DEFAULT);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 3678b19..6114094 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -222,7 +222,6 @@
super.disableDevice(initiatedByCec, callback);
assertRunOnServiceThread();
mService.unregisterTvInputCallback(mTvInputCallback);
- // TODO(b/129088603): check disableDevice and onStandby behaviors per spec
}
@Override
@@ -847,7 +846,6 @@
}
protected void switchToAudioInput() {
- // TODO(b/111396634): switch input according to PROPERTY_SYSTEM_AUDIO_MODE_AUDIO_PORT
}
protected boolean isDirectConnectToTv() {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 7994fcc..94a5099 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -3177,7 +3177,7 @@
@BinderThread
@Override
- public void reportPerceptible(IBinder windowToken, boolean perceptible) {
+ public void reportPerceptibleAsync(IBinder windowToken, boolean perceptible) {
Objects.requireNonNull(windowToken, "windowToken must not be null");
int uid = Binder.getCallingUid();
synchronized (mMethodMap) {
@@ -5992,9 +5992,8 @@
@BinderThread
@Override
- public void reportStartInput(IBinder startInputToken, IVoidResultCallback resultCallback) {
- CallbackUtils.onResult(resultCallback,
- () -> mImms.reportStartInput(mToken, startInputToken));
+ public void reportStartInputAsync(IBinder startInputToken) {
+ mImms.reportStartInput(mToken, startInputToken);
}
@BinderThread
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index 6244743..885093d 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -1840,7 +1840,7 @@
@BinderThread
@Override
- public void reportPerceptible(IBinder windowClient, boolean perceptible) {
+ public void reportPerceptibleAsync(IBinder windowClient, boolean perceptible) {
reportNotSupported();
}
diff --git a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
index 045e06d0..2ffc62a 100644
--- a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
+++ b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java
@@ -178,8 +178,9 @@
}
/** Logs that a provider has entered or exited stationary throttling. */
- public void logProviderStationaryThrottled(String provider, boolean throttled) {
- addLogEvent(EVENT_PROVIDER_STATIONARY_THROTTLED, provider, throttled);
+ public void logProviderStationaryThrottled(String provider, boolean throttled,
+ ProviderRequest request) {
+ addLogEvent(EVENT_PROVIDER_STATIONARY_THROTTLED, provider, throttled, request);
}
/** Logs that the location power save mode has changed. */
@@ -217,7 +218,7 @@
(Integer) args[1], (CallerIdentity) args[2]);
case EVENT_PROVIDER_STATIONARY_THROTTLED:
return new ProviderStationaryThrottledEvent(timeDelta, (String) args[0],
- (Boolean) args[1]);
+ (Boolean) args[1], (ProviderRequest) args[2]);
case EVENT_LOCATION_POWER_SAVE_MODE_CHANGE:
return new LocationPowerSaveModeEvent(timeDelta, (Integer) args[0]);
default:
@@ -355,17 +356,19 @@
private static final class ProviderStationaryThrottledEvent extends ProviderEvent {
private final boolean mStationaryThrottled;
+ private final ProviderRequest mRequest;
ProviderStationaryThrottledEvent(long timeDelta, String provider,
- boolean stationaryThrottled) {
+ boolean stationaryThrottled, ProviderRequest request) {
super(timeDelta, provider);
mStationaryThrottled = stationaryThrottled;
+ mRequest = request;
}
@Override
public String getLogString() {
return mProvider + " provider stationary/idle " + (mStationaryThrottled ? "throttled"
- : "unthrottled");
+ : "unthrottled") + ", request = " + mRequest;
}
}
diff --git a/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java b/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java
index ab7e526..22a675a 100644
--- a/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java
+++ b/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java
@@ -206,7 +206,7 @@
if (D) {
Log.d(TAG, mName + " provider stationary throttled");
}
- EVENT_LOG.logProviderStationaryThrottled(mName, true);
+ EVENT_LOG.logProviderStationaryThrottled(mName, true, mOutgoingRequest);
}
if (mDeliverLastLocationCallback != null) {
@@ -224,7 +224,7 @@
}
} else {
if (oldThrottlingIntervalMs != INTERVAL_DISABLED) {
- EVENT_LOG.logProviderStationaryThrottled(mName, false);
+ EVENT_LOG.logProviderStationaryThrottled(mName, false, mOutgoingRequest);
if (D) {
Log.d(TAG, mName + " provider stationary unthrottled");
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 59f00a2..6cded50 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1261,7 +1261,8 @@
return getCredentialTypeInternal(userId) != CREDENTIAL_TYPE_NONE;
}
- private void setKeystorePassword(byte[] password, int userHandle) {
+ @VisibleForTesting /** Note: this method is overridden in unit tests */
+ void setKeystorePassword(byte[] password, int userHandle) {
AndroidKeyStoreMaintenance.onUserPasswordChanged(userHandle, password);
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 05922b3..7e4e29e 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -2016,7 +2016,7 @@
if (LOGV) Slog.v(TAG, "updateNetworkRulesNL()");
Trace.traceBegin(TRACE_TAG_NETWORK, "updateNetworkRulesNL");
- final List<NetworkStateSnapshot> snapshots = mConnManager.getAllNetworkStateSnapshot();
+ final List<NetworkStateSnapshot> snapshots = mConnManager.getAllNetworkStateSnapshots();
// First, generate identities of all connected networks so we can
// quickly compare them against all defined policies below.
diff --git a/services/core/java/com/android/server/net/TEST_MAPPING b/services/core/java/com/android/server/net/TEST_MAPPING
index f707597..02095eb 100644
--- a/services/core/java/com/android/server/net/TEST_MAPPING
+++ b/services/core/java/com/android/server/net/TEST_MAPPING
@@ -1,5 +1,5 @@
{
- "presubmit": [
+ "presubmit-large": [
{
"name": "CtsHostsideNetworkTests",
"file_patterns": ["(/|^)NetworkPolicy[^/]*\\.java"],
@@ -14,7 +14,9 @@
"exclude-annotation": "android.platform.test.annotations.FlakyTest"
}
]
- },
+ }
+ ],
+ "presubmit": [
{
"name": "FrameworksServicesTests",
"file_patterns": ["(/|^)NetworkPolicy[^/]*\\.java"],
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
index 8bd3b1e..42b7c9d3 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
@@ -100,7 +100,7 @@
IntentFilter deletionFilter = new IntentFilter(ACTION_HISTORY_DELETION);
deletionFilter.addDataScheme(SCHEME_DELETION);
- mContext.registerReceiver(mFileCleaupReceiver, deletionFilter);
+ mContext.registerReceiver(mFileCleanupReceiver, deletionFilter);
}
public void init() {
@@ -273,13 +273,36 @@
}
}
+ /**
+ * Remove the first entry from the list of history files whose file matches the given file path.
+ *
+ * This method is necessary for anything that only has an absolute file path rather than an
+ * AtomicFile object from the list of history files.
+ *
+ * filePath should be an absolute path.
+ */
+ void removeFilePathFromHistory(String filePath) {
+ if (filePath == null) {
+ return;
+ }
+
+ Iterator<AtomicFile> historyFileItr = mHistoryFiles.iterator();
+ while (historyFileItr.hasNext()) {
+ final AtomicFile af = historyFileItr.next();
+ if (af != null && filePath.equals(af.getBaseFile().getAbsolutePath())) {
+ historyFileItr.remove();
+ return;
+ }
+ }
+ }
+
private void deleteFile(AtomicFile file) {
if (DEBUG) {
Slog.d(TAG, "Removed " + file.getBaseFile().getName());
}
file.delete();
// TODO: delete all relevant bitmaps, once they exist
- mHistoryFiles.remove(file);
+ removeFilePathFromHistory(file.getBaseFile().getAbsolutePath());
}
private void scheduleDeletion(File file, long creationTime, int retentionDays) {
@@ -342,7 +365,7 @@
}
}
- private final BroadcastReceiver mFileCleaupReceiver = new BroadcastReceiver() {
+ private final BroadcastReceiver mFileCleanupReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
@@ -358,7 +381,7 @@
Slog.d(TAG, "Removed " + fileToDelete.getBaseFile().getName());
}
fileToDelete.delete();
- mHistoryFiles.remove(fileToDelete);
+ removeFilePathFromHistory(filePath);
}
} catch (Exception e) {
Slog.e(TAG, "Failed to delete notification history file", e);
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index dd80e16..edd43af 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -1043,22 +1043,24 @@
return false;
}
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
final int callingUid = injectBinderCallingUid();
+ final int state = pmInt.getComponentEnabledSetting(component, callingUid,
+ user.getIdentifier());
+ switch (state) {
+ case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
+ break; // Need to check the manifest's enabled state.
+ case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
+ return true;
+ case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
+ case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
+ case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
+ return false;
+ }
+
final long ident = Binder.clearCallingIdentity();
try {
- final int state = mIPM.getComponentEnabledSetting(component, user.getIdentifier());
- switch (state) {
- case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
- break; // Need to check the manifest's enabled state.
- case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
- return true;
- case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
- case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
- case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
- return false;
- }
- final PackageManagerInternal pmInt =
- LocalServices.getService(PackageManagerInternal.class);
ActivityInfo info = pmInt.getActivityInfo(component,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 0a484e2..27077b6 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -527,6 +527,14 @@
throw new SecurityException("User restriction prevents installing");
}
+ if (params.dataLoaderParams != null
+ && mContext.checkCallingOrSelfPermission(Manifest.permission.USE_INSTALLER_V2)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("You need the "
+ + "com.android.permission.USE_INSTALLER_V2 permission "
+ + "to use a data loader");
+ }
+
// INSTALL_REASON_ROLLBACK allows an app to be rolled back without requiring the ROLLBACK
// capability; ensure if this is set as the install reason the app has one of the necessary
// signature permissions to perform the rollback.
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index e532790..b6a65dd 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -3636,12 +3636,14 @@
@Override
public DataLoaderParamsParcel getDataLoaderParams() {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.USE_INSTALLER_V2, null);
return params.dataLoaderParams != null ? params.dataLoaderParams.getData() : null;
}
@Override
public void addFile(int location, String name, long lengthBytes, byte[] metadata,
byte[] signature) {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.USE_INSTALLER_V2, null);
if (!isDataLoaderInstallation()) {
throw new IllegalStateException(
"Cannot add files to non-data loader installation session.");
@@ -3674,6 +3676,7 @@
@Override
public void removeFile(int location, String name) {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.USE_INSTALLER_V2, null);
if (!isDataLoaderInstallation()) {
throw new IllegalStateException(
"Cannot add files to non-data loader installation session.");
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 59039ba..6b364bd 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -23616,11 +23616,17 @@
@Override
public int getComponentEnabledSetting(@NonNull ComponentName component, int userId) {
- if (component == null) return COMPONENT_ENABLED_STATE_DEFAULT;
- if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
int callingUid = Binder.getCallingUid();
enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
false /*checkShell*/, "getComponentEnabled");
+ return getComponentEnabledSettingInternal(component, callingUid, userId);
+ }
+
+ private int getComponentEnabledSettingInternal(ComponentName component, int callingUid,
+ int userId) {
+ if (component == null) return COMPONENT_ENABLED_STATE_DEFAULT;
+ if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
+
synchronized (mLock) {
try {
if (shouldFilterApplicationLocked(
@@ -27066,6 +27072,13 @@
}
@Override
+ public @PackageManager.EnabledState int getComponentEnabledSetting(
+ @NonNull ComponentName componentName, int callingUid, int userId) {
+ return PackageManagerService.this.getComponentEnabledSettingInternal(componentName,
+ callingUid, userId);
+ }
+
+ @Override
public void setEnableRollbackCode(int token, int enableRollbackCode) {
PackageManagerService.this.setEnableRollbackCode(token, enableRollbackCode);
}
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index c462a6c..c6d98e7 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -663,12 +663,14 @@
});
// Then, update the pinned state if necessary.
final List<ShortcutInfo> pinned = getShortcutById(pinnedShortcuts);
- pinned.forEach(si -> {
- if (!si.isPinned()) {
- si.addFlags(ShortcutInfo.FLAG_PINNED);
- }
- });
- saveShortcut(pinned);
+ if (pinned != null) {
+ pinned.forEach(si -> {
+ if (!si.isPinned()) {
+ si.addFlags(ShortcutInfo.FLAG_PINNED);
+ }
+ });
+ saveShortcut(pinned);
+ }
forEachShortcutMutateIf(AppSearchShortcutInfo.QUERY_IS_PINNED, si -> {
if (!pinnedShortcuts.contains(si.getId()) && si.isPinned()) {
si.clearFlags(ShortcutInfo.FLAG_PINNED);
@@ -826,9 +828,11 @@
: s.getLauncherShortcutsLocked(callingLauncher, getPackageUserId(), launcherUserId)
.getPinnedShortcutIds(getPackageName(), getPackageUserId());
final List<ShortcutInfo> shortcuts = getShortcutById(ids);
- for (ShortcutInfo si : shortcuts) {
- filter(result, query, cloneFlag, callingLauncher, pinnedByCallerSet,
- getPinnedByAnyLauncher, si);
+ if (shortcuts != null) {
+ for (ShortcutInfo si : shortcuts) {
+ filter(result, query, cloneFlag, callingLauncher, pinnedByCallerSet,
+ getPinnedByAnyLauncher, si);
+ }
}
}
@@ -1903,7 +1907,8 @@
final ShortcutPackage ret = new ShortcutPackage(shortcutUser,
shortcutUser.getUserId(), packageName);
- ret.mIsInitilized = ShortcutService.parseIntAttribute(parser, ATTR_SCHEMA_VERSON, 0) > 0;
+ ret.mIsInitilized = ShortcutService.parseIntAttribute(parser, ATTR_SCHEMA_VERSON, 0)
+ == AppSearchShortcutInfo.SCHEMA_VERSION;
ret.mApiCallCount =
ShortcutService.parseIntAttribute(parser, ATTR_CALL_COUNT);
ret.mLastResetTime =
diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
index f0fdad0..a3e1a9c 100644
--- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
+++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
@@ -892,7 +892,7 @@
boolean hasAutoVerifyDomains = newDomainsSize > 0;
boolean needsBroadcast =
- applyImmutableState(pkgName, newStateMap, newAutoVerifyDomains);
+ applyImmutableState(newPkgSetting, newStateMap, newAutoVerifyDomains);
sendBroadcast = hasAutoVerifyDomains && needsBroadcast;
@@ -943,7 +943,8 @@
pkgState = new DomainVerificationPkgState(pkgName, domainSetId, hasAutoVerifyDomains);
}
- boolean needsBroadcast = applyImmutableState(pkgState, domains);
+ boolean needsBroadcast =
+ applyImmutableState(newPkgSetting, pkgState.getStateMap(), domains);
if (needsBroadcast && !isPendingOrRestored) {
// TODO(b/159952358): Test this behavior
// Attempt to preserve user experience by automatically verifying all domains from
@@ -990,22 +991,17 @@
}
}
- private boolean applyImmutableState(@NonNull DomainVerificationPkgState pkgState,
- @NonNull ArraySet<String> autoVerifyDomains) {
- return applyImmutableState(pkgState.getPackageName(), pkgState.getStateMap(),
- autoVerifyDomains);
- }
-
/**
* Applies any immutable state as the final step when adding or migrating state. Currently only
- * applies {@link SystemConfig#getLinkedApps()}, which approves all domains for a package.
+ * applies {@link SystemConfig#getLinkedApps()}, which approves all domains for a system app.
*
* @return whether or not a broadcast is necessary for this package
*/
- private boolean applyImmutableState(@NonNull String packageName,
+ private boolean applyImmutableState(@NonNull PackageSetting pkgSetting,
@NonNull ArrayMap<String, Integer> stateMap,
@NonNull ArraySet<String> autoVerifyDomains) {
- if (mSystemConfig.getLinkedApps().contains(packageName)) {
+ if (pkgSetting.isSystem()
+ && mSystemConfig.getLinkedApps().contains(pkgSetting.getName())) {
int domainsSize = autoVerifyDomains.size();
for (int index = 0; index < domainsSize; index++) {
stateMap.put(autoVerifyDomains.valueAt(index),
@@ -1318,7 +1314,7 @@
if (pkgSetting == null || pkgSetting.getPkg() == null) {
continue;
}
- resetDomainState(pkgState, pkgSetting.getPkg());
+ resetDomainState(pkgState.getStateMap(), pkgSetting);
}
} else {
int size = packageNames.size();
@@ -1329,7 +1325,7 @@
if (pkgSetting == null || pkgSetting.getPkg() == null) {
continue;
}
- resetDomainState(pkgState, pkgSetting.getPkg());
+ resetDomainState(pkgState.getStateMap(), pkgSetting);
}
}
}
@@ -1341,9 +1337,8 @@
/**
* Reset states that are mutable by the domain verification agent.
*/
- private void resetDomainState(@NonNull DomainVerificationPkgState pkgState,
- @NonNull AndroidPackage pkg) {
- ArrayMap<String, Integer> stateMap = pkgState.getStateMap();
+ private void resetDomainState(@NonNull ArrayMap<String, Integer> stateMap,
+ @NonNull PackageSetting pkgSetting) {
int size = stateMap.size();
for (int index = size - 1; index >= 0; index--) {
Integer state = stateMap.valueAt(index);
@@ -1363,7 +1358,8 @@
}
}
- applyImmutableState(pkgState, mCollector.collectValidAutoVerifyDomains(pkg));
+ applyImmutableState(pkgSetting, stateMap,
+ mCollector.collectValidAutoVerifyDomains(pkgSetting.getPkg()));
}
@Override
diff --git a/services/core/java/com/android/server/rotationresolver/RemoteRotationResolverService.java b/services/core/java/com/android/server/rotationresolver/RemoteRotationResolverService.java
index 189f47f..35aff8d 100644
--- a/services/core/java/com/android/server/rotationresolver/RemoteRotationResolverService.java
+++ b/services/core/java/com/android/server/rotationresolver/RemoteRotationResolverService.java
@@ -21,8 +21,8 @@
import static android.service.rotationresolver.RotationResolverService.ROTATION_RESULT_FAILURE_CANCELLED;
import static android.service.rotationresolver.RotationResolverService.ROTATION_RESULT_FAILURE_TIMED_OUT;
-import static com.android.server.rotationresolver.RotationResolverManagerService.RESOLUTION_FAILURE;
-import static com.android.server.rotationresolver.RotationResolverManagerService.logRotationStats;
+import static com.android.server.rotationresolver.RotationResolverManagerService.errorCodeToProto;
+import static com.android.server.rotationresolver.RotationResolverManagerService.surfaceRotationToProto;
import android.annotation.NonNull;
import android.content.ComponentName;
@@ -173,8 +173,10 @@
request.mCallbackInternal.onSuccess(rotation);
final long timeToCalculate =
SystemClock.elapsedRealtime() - request.mRequestStartTimeMillis;
- logRotationStats(request.mRemoteRequest.getProposedRotation(),
- request.mRemoteRequest.getCurrentRotation(), rotation, timeToCalculate);
+ RotationResolverManagerService.logRotationStatsWithTimeToCalculate(
+ request.mRemoteRequest.getProposedRotation(),
+ request.mRemoteRequest.getCurrentRotation(),
+ surfaceRotationToProto(rotation), timeToCalculate);
Slog.d(TAG, "onSuccess:" + rotation);
Slog.d(TAG, "timeToCalculate:" + timeToCalculate);
}
@@ -192,8 +194,9 @@
request.mCallbackInternal.onFailure(error);
final long timeToCalculate =
SystemClock.elapsedRealtime() - request.mRequestStartTimeMillis;
- logRotationStats(request.mRemoteRequest.getProposedRotation(),
- request.mRemoteRequest.getCurrentRotation(), RESOLUTION_FAILURE,
+ RotationResolverManagerService.logRotationStatsWithTimeToCalculate(
+ request.mRemoteRequest.getProposedRotation(),
+ request.mRemoteRequest.getCurrentRotation(), errorCodeToProto(error),
timeToCalculate);
Slog.d(TAG, "onFailure:" + error);
Slog.d(TAG, "timeToCalculate:" + timeToCalculate);
diff --git a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java
index a749d18..19a246e 100644
--- a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java
+++ b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java
@@ -18,6 +18,9 @@
import static android.provider.DeviceConfig.NAMESPACE_ROTATION_RESOLVER;
import static android.service.rotationresolver.RotationResolverService.ROTATION_RESULT_FAILURE_CANCELLED;
+import static android.service.rotationresolver.RotationResolverService.ROTATION_RESULT_FAILURE_NOT_SUPPORTED;
+import static android.service.rotationresolver.RotationResolverService.ROTATION_RESULT_FAILURE_PREEMPTED;
+import static android.service.rotationresolver.RotationResolverService.ROTATION_RESULT_FAILURE_TIMED_OUT;
import static com.android.internal.util.FrameworkStatsLog.AUTO_ROTATE_REPORTED__PROPOSED_ORIENTATION__ROTATION_0;
import static com.android.internal.util.FrameworkStatsLog.AUTO_ROTATE_REPORTED__PROPOSED_ORIENTATION__ROTATION_180;
@@ -37,6 +40,7 @@
import android.provider.DeviceConfig;
import android.rotationresolver.RotationResolverInternal;
import android.service.rotationresolver.RotationResolutionRequest;
+import android.service.rotationresolver.RotationResolverService;
import android.text.TextUtils;
import android.util.IndentingPrintWriter;
import android.util.Slog;
@@ -217,24 +221,37 @@
}
}
- static void logRotationStats(int proposedRotation, int currentRotation,
- int resolvedRotation, long timeToCalculate) {
+ static void logRotationStatsWithTimeToCalculate(int proposedRotation, int currentRotation,
+ int result, long timeToCalculate) {
FrameworkStatsLog.write(FrameworkStatsLog.AUTO_ROTATE_REPORTED,
/* previous_orientation= */ surfaceRotationToProto(currentRotation),
/* proposed_orientation= */ surfaceRotationToProto(proposedRotation),
- /* resolved_orientation= */ surfaceRotationToProto(resolvedRotation),
+ result,
/* process_duration_millis= */ timeToCalculate);
}
static void logRotationStats(int proposedRotation, int currentRotation,
- int resolvedRotation) {
+ int result) {
FrameworkStatsLog.write(FrameworkStatsLog.AUTO_ROTATE_REPORTED,
/* previous_orientation= */ surfaceRotationToProto(currentRotation),
/* proposed_orientation= */ surfaceRotationToProto(proposedRotation),
- /* resolved_orientation= */ surfaceRotationToProto(resolvedRotation));
+ result);
}
- private static int surfaceRotationToProto(@Surface.Rotation int rotationPoseResult) {
+ static int errorCodeToProto(@RotationResolverService.FailureCodes int error) {
+ switch (error) {
+ case ROTATION_RESULT_FAILURE_NOT_SUPPORTED:
+ return RESOLUTION_UNAVAILABLE;
+ case ROTATION_RESULT_FAILURE_TIMED_OUT:
+ case ROTATION_RESULT_FAILURE_PREEMPTED:
+ case ROTATION_RESULT_FAILURE_CANCELLED:
+ return ORIENTATION_UNKNOWN;
+ default:
+ return RESOLUTION_FAILURE;
+ }
+ }
+
+ static int surfaceRotationToProto(@Surface.Rotation int rotationPoseResult) {
switch (rotationPoseResult) {
case Surface.ROTATION_0:
return AUTO_ROTATE_REPORTED__PROPOSED_ORIENTATION__ROTATION_0;
@@ -245,7 +262,8 @@
case Surface.ROTATION_270:
return AUTO_ROTATE_REPORTED__PROPOSED_ORIENTATION__ROTATION_270;
default:
- return ORIENTATION_UNKNOWN;
+ // Should not reach here.
+ return RESOLUTION_FAILURE;
}
}
}
diff --git a/services/core/java/com/android/server/timedetector/EnvironmentImpl.java b/services/core/java/com/android/server/timedetector/EnvironmentImpl.java
index 072cc16f..7649958 100644
--- a/services/core/java/com/android/server/timedetector/EnvironmentImpl.java
+++ b/services/core/java/com/android/server/timedetector/EnvironmentImpl.java
@@ -82,6 +82,9 @@
handleAutoTimeDetectionChangedOnHandlerThread();
}
});
+ mServiceConfigAccessor.addListener(
+ () -> mHandler.post(
+ EnvironmentImpl.this::handleAutoTimeDetectionChangedOnHandlerThread));
}
/** Internal method for handling the auto time setting being changed. */
diff --git a/services/core/java/com/android/server/timedetector/ServerFlags.java b/services/core/java/com/android/server/timedetector/ServerFlags.java
index d91e9c2..7145f5e 100644
--- a/services/core/java/com/android/server/timedetector/ServerFlags.java
+++ b/services/core/java/com/android/server/timedetector/ServerFlags.java
@@ -30,7 +30,9 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.time.DateTimeException;
import java.time.Duration;
+import java.time.Instant;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
@@ -62,6 +64,8 @@
KEY_LOCATION_TIME_ZONE_DETECTION_UNCERTAINTY_DELAY_MILLIS,
KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_OVERRIDE,
KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT,
+ KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE,
+ KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE,
})
@Retention(RetentionPolicy.SOURCE)
@interface DeviceConfigKey {}
@@ -135,6 +139,23 @@
public static final String KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT =
"location_time_zone_detection_setting_enabled_default";
+ /**
+ * The key to override the time detector origin priorities configuration. A comma-separated list
+ * of strings that will be passed to {@link TimeDetectorStrategy#stringToOrigin(String)}.
+ * All values must be recognized or the override value will be ignored.
+ */
+ @DeviceConfigKey
+ public static final String KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE =
+ "time_detector_origin_priorities_override";
+
+ /**
+ * The key to override the time detector lower bound configuration. The values is the number of
+ * milliseconds since the beginning of the Unix epoch.
+ */
+ @DeviceConfigKey
+ public static final String KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE =
+ "time_detector_lower_bound_millis_override";
+
@GuardedBy("mListeners")
private final ArrayMap<ConfigurationChangeListener, Set<String>> mListeners = new ArrayMap<>();
@@ -209,6 +230,38 @@
}
/**
+ * Returns an optional string array value from {@link DeviceConfig} from the system_time
+ * namespace, returns {@link Optional#empty()} if there is no explicit value set.
+ */
+ @NonNull
+ public Optional<String[]> getOptionalStringArray(@DeviceConfigKey String key) {
+ Optional<String> string = getOptionalString(key);
+ if (!string.isPresent()) {
+ return Optional.empty();
+ }
+ return Optional.of(string.get().split(","));
+ }
+
+ /**
+ * Returns an {@link Instant} from {@link DeviceConfig} from the system_time
+ * namespace, returns the {@code defaultValue} if the value is missing or invalid.
+ */
+ @NonNull
+ public Optional<Instant> getOptionalInstant(@DeviceConfigKey String key) {
+ String value = DeviceConfig.getProperty(NAMESPACE_SYSTEM_TIME, key);
+ if (value == null) {
+ return Optional.empty();
+ }
+
+ try {
+ long millis = Long.parseLong(value);
+ return Optional.of(Instant.ofEpochMilli(millis));
+ } catch (DateTimeException | NumberFormatException e) {
+ return Optional.empty();
+ }
+ }
+
+ /**
* Returns an optional boolean value from {@link DeviceConfig} from the system_time
* namespace, returns {@link Optional#empty()} if there is no explicit value set.
*/
diff --git a/services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java b/services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java
index be4432a..dac8a0a 100644
--- a/services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java
+++ b/services/core/java/com/android/server/timedetector/ServiceConfigAccessor.java
@@ -15,9 +15,10 @@
*/
package com.android.server.timedetector;
+import static com.android.server.timedetector.ServerFlags.KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE;
+import static com.android.server.timedetector.ServerFlags.KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE;
import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_NETWORK;
import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_TELEPHONY;
-import static com.android.server.timedetector.TimeDetectorStrategy.stringToOrigin;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -28,12 +29,17 @@
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+import com.android.server.timedetector.TimeDetectorStrategy.Origin;
import com.android.server.timezonedetector.ConfigurationChangeListener;
import java.time.Instant;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
+import java.util.function.Supplier;
/**
* A singleton that provides access to service configuration for time detection. This hides how
@@ -48,7 +54,7 @@
* By default telephony and network only suggestions are accepted and telephony takes
* precedence over network.
*/
- private static final @TimeDetectorStrategy.Origin int[]
+ private static final @Origin int[]
DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES = { ORIGIN_TELEPHONY, ORIGIN_NETWORK };
/**
@@ -60,6 +66,8 @@
private static final Set<String> SERVER_FLAGS_KEYS_TO_WATCH = Collections.unmodifiableSet(
new ArraySet<>(new String[] {
+ KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE,
+ KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE,
}));
private static final Object SLOCK = new Object();
@@ -70,8 +78,9 @@
private static ServiceConfigAccessor sInstance;
@NonNull private final Context mContext;
+ @NonNull private final ConfigOriginPrioritiesSupplier mConfigOriginPrioritiesSupplier;
+ @NonNull private final ServerFlagsOriginPrioritiesSupplier mServerFlagsOriginPrioritiesSupplier;
@NonNull private final ServerFlags mServerFlags;
- @NonNull private final int[] mOriginPriorities;
/**
* If a newly calculated system clock time and the current system clock time differs by this or
@@ -83,7 +92,9 @@
private ServiceConfigAccessor(@NonNull Context context) {
mContext = Objects.requireNonNull(context);
mServerFlags = ServerFlags.getInstance(mContext);
- mOriginPriorities = getOriginPrioritiesInternal();
+ mConfigOriginPrioritiesSupplier = new ConfigOriginPrioritiesSupplier(context);
+ mServerFlagsOriginPrioritiesSupplier =
+ new ServerFlagsOriginPrioritiesSupplier(mServerFlags);
mSystemClockUpdateThresholdMillis =
SystemProperties.getInt("ro.sys.time_detector_update_diff",
SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT);
@@ -111,31 +122,109 @@
}
@NonNull
- int[] getOriginPriorities() {
- return mOriginPriorities;
+ @Origin int[] getOriginPriorities() {
+ int[] serverFlagsValue = mServerFlagsOriginPrioritiesSupplier.get();
+ if (serverFlagsValue != null) {
+ return serverFlagsValue;
+ }
+
+ int[] configValue = mConfigOriginPrioritiesSupplier.get();
+ if (configValue != null) {
+ return configValue;
+ }
+ return DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES;
}
int systemClockUpdateThresholdMillis() {
return mSystemClockUpdateThresholdMillis;
}
+ @NonNull
Instant autoTimeLowerBound() {
- return TIME_LOWER_BOUND_DEFAULT;
+ return mServerFlags.getOptionalInstant(KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE)
+ .orElse(TIME_LOWER_BOUND_DEFAULT);
}
- private int[] getOriginPrioritiesInternal() {
- String[] originStrings =
- mContext.getResources().getStringArray(R.array.config_autoTimeSourcesPriority);
- if (originStrings.length == 0) {
- return DEFAULT_AUTOMATIC_TIME_ORIGIN_PRIORITIES;
- } else {
- int[] origins = new int[originStrings.length];
- for (int i = 0; i < originStrings.length; i++) {
- int origin = stringToOrigin(originStrings[i]);
- origins[i] = origin;
- }
+ /**
+ * A base supplier of an array of time origin integers in priority order.
+ * It handles memoization of the result to avoid repeated string parsing when nothing has
+ * changed.
+ */
+ private abstract static class BaseOriginPrioritiesSupplier implements Supplier<@Origin int[]> {
+ @GuardedBy("this") @Nullable private String[] mLastPriorityStrings;
+ @GuardedBy("this") @Nullable private int[] mLastPriorityInts;
- return origins;
+ /** Returns an array of {@code ORIGIN_*} values, or {@code null}. */
+ @Override
+ @Nullable
+ public @Origin int[] get() {
+ String[] priorityStrings = lookupPriorityStrings();
+ synchronized (this) {
+ if (Arrays.equals(mLastPriorityStrings, priorityStrings)) {
+ return mLastPriorityInts;
+ }
+
+ int[] priorityInts = null;
+ if (priorityStrings != null && priorityStrings.length > 0) {
+ priorityInts = new int[priorityStrings.length];
+ try {
+ for (int i = 0; i < priorityInts.length; i++) {
+ String priorityString = priorityStrings[i];
+ Preconditions.checkArgument(priorityString != null);
+
+ priorityString = priorityString.trim();
+ priorityInts[i] = TimeDetectorStrategy.stringToOrigin(priorityString);
+ }
+ } catch (IllegalArgumentException e) {
+ // If any strings were bad and they were ignored then the semantics of the
+ // whole list could change, so return null.
+ priorityInts = null;
+ }
+ }
+ mLastPriorityStrings = priorityStrings;
+ mLastPriorityInts = priorityInts;
+ return priorityInts;
+ }
+ }
+
+ @Nullable
+ protected abstract String[] lookupPriorityStrings();
+ }
+
+ /** Supplies origin priorities from config_autoTimeSourcesPriority. */
+ private static class ConfigOriginPrioritiesSupplier extends BaseOriginPrioritiesSupplier {
+
+ @NonNull private final Context mContext;
+
+ private ConfigOriginPrioritiesSupplier(Context context) {
+ mContext = Objects.requireNonNull(context);
+ }
+
+ @Override
+ @Nullable
+ protected String[] lookupPriorityStrings() {
+ return mContext.getResources().getStringArray(R.array.config_autoTimeSourcesPriority);
+ }
+ }
+
+ /**
+ * Supplies origin priorities from device_config (server flags), see
+ * {@link ServerFlags#KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE}.
+ */
+ private static class ServerFlagsOriginPrioritiesSupplier extends BaseOriginPrioritiesSupplier {
+
+ @NonNull private final ServerFlags mServerFlags;
+
+ private ServerFlagsOriginPrioritiesSupplier(ServerFlags serverFlags) {
+ mServerFlags = Objects.requireNonNull(serverFlags);
+ }
+
+ @Override
+ @Nullable
+ protected String[] lookupPriorityStrings() {
+ Optional<String[]> priorityStrings = mServerFlags.getOptionalStringArray(
+ KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE);
+ return priorityStrings.orElse(null);
}
}
}
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
index 14cab38..0f14af4 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
@@ -30,6 +30,8 @@
import android.content.Context;
import android.os.Binder;
import android.os.Handler;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
import android.util.IndentingPrintWriter;
import com.android.internal.annotations.VisibleForTesting;
@@ -100,6 +102,7 @@
}
@Override
+ @NonNull
public TimeCapabilitiesAndConfig getCapabilitiesAndConfig() {
int userId = mCallerIdentityInjector.getCallingUserId();
return getTimeCapabilitiesAndConfig(userId);
@@ -119,7 +122,7 @@
}
@Override
- public boolean updateConfiguration(TimeConfiguration timeConfiguration) {
+ public boolean updateConfiguration(@NonNull TimeConfiguration timeConfiguration) {
enforceManageTimeDetectorPermission();
// TODO(b/172891783) Add actual logic
return false;
@@ -180,6 +183,13 @@
ipw.flush();
}
+ @Override
+ public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+ String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
+ new TimeDetectorShellCommand(this).exec(
+ this, in, out, err, args, callback, resultReceiver);
+ }
+
private void enforceSuggestTelephonyTimePermission() {
mContext.enforceCallingPermission(
android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE,
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java b/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
new file mode 100644
index 0000000..233cc57
--- /dev/null
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorShellCommand.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.timedetector;
+
+import static android.app.timedetector.TimeDetector.SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED;
+import static android.provider.DeviceConfig.NAMESPACE_SYSTEM_TIME;
+
+import static com.android.server.timedetector.ServerFlags.KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE;
+import static com.android.server.timedetector.ServerFlags.KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE;
+
+import android.os.ShellCommand;
+
+import java.io.PrintWriter;
+
+/** Implements the shell command interface for {@link TimeDetectorService}. */
+class TimeDetectorShellCommand extends ShellCommand {
+
+ private final TimeDetectorService mInterface;
+
+ TimeDetectorShellCommand(TimeDetectorService timeDetectorService) {
+ mInterface = timeDetectorService;
+ }
+
+ @Override
+ public int onCommand(String cmd) {
+ if (cmd == null) {
+ return handleDefaultCommands(cmd);
+ }
+
+ switch (cmd) {
+ case SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED:
+ return runIsAutoDetectionEnabled();
+ default: {
+ return handleDefaultCommands(cmd);
+ }
+ }
+ }
+
+ private int runIsAutoDetectionEnabled() {
+ final PrintWriter pw = getOutPrintWriter();
+ boolean enabled = mInterface.getCapabilitiesAndConfig()
+ .getTimeConfiguration()
+ .isAutoDetectionEnabled();
+ pw.println(enabled);
+ return 0;
+ }
+
+ @Override
+ public void onHelp() {
+ final PrintWriter pw = getOutPrintWriter();
+ pw.println("Time Detector (time_detector) commands:");
+ pw.println(" help");
+ pw.println(" Print this help text.");
+ pw.printf(" %s\n", SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED);
+ pw.println(" Prints true/false according to the automatic time detection setting");
+ pw.println();
+ pw.printf("This service is also affected by the following device_config flags in the"
+ + " %s namespace:\n", NAMESPACE_SYSTEM_TIME);
+ pw.printf(" %s - the lower bound used to validate time suggestions when they are"
+ + " received.\n", KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE);
+ pw.println(" Specified in milliseconds since the start of the Unix epoch.");
+ pw.printf(" %s - [default=null], a comma separated list of origins. See"
+ + " TimeDetectorStrategy for details\n",
+ KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE);
+ pw.println();
+ pw.println("Example:");
+ pw.printf(" $ adb shell cmd device_config put %s %s %s\n",
+ NAMESPACE_SYSTEM_TIME, KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE,
+ "external");
+ pw.println("See adb shell cmd device_config for more information.");
+ pw.println();
+ }
+}
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
index be382f0..ff5060e 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
@@ -27,10 +27,13 @@
import android.os.TimestampedValue;
import android.util.IndentingPrintWriter;
+import com.android.internal.util.Preconditions;
import com.android.server.timezonedetector.Dumpable;
+import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* The interface for the class that implements the time detection algorithm used by the
@@ -44,9 +47,9 @@
*/
public interface TimeDetectorStrategy extends Dumpable {
- @IntDef({ ORIGIN_TELEPHONY, ORIGIN_MANUAL, ORIGIN_NETWORK, ORIGIN_GNSS,
- ORIGIN_EXTERNAL })
+ @IntDef({ ORIGIN_TELEPHONY, ORIGIN_MANUAL, ORIGIN_NETWORK, ORIGIN_GNSS, ORIGIN_EXTERNAL })
@Retention(RetentionPolicy.SOURCE)
+ @Target({ ElementType.TYPE_USE, ElementType.TYPE_PARAMETER })
@interface Origin {}
/** Used when a time value originated from a telephony signal. */
@@ -126,9 +129,11 @@
/**
* Converts a human readable config string to one of the {@code ORIGIN_} constants.
- * Throws an {@link IllegalArgumentException} if the value is unrecognized.
+ * Throws an {@link IllegalArgumentException} if the value is unrecognized or {@code null}.
*/
static @Origin int stringToOrigin(String originString) {
+ Preconditions.checkArgument(originString != null);
+
switch (originString) {
case "manual":
return ORIGIN_MANUAL;
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
index db8a59e..357c232 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
@@ -325,9 +325,9 @@
ipw.println("mEnvironment.systemClockMillis()=" + mEnvironment.systemClockMillis());
ipw.println("mEnvironment.systemClockUpdateThresholdMillis()="
+ mEnvironment.systemClockUpdateThresholdMillis());
+ Instant autoTimeLowerBound = mEnvironment.autoTimeLowerBound();
ipw.printf("mEnvironment.autoTimeLowerBound()=%s(%s)\n",
- mEnvironment.autoTimeLowerBound(),
- mEnvironment.autoTimeLowerBound().toEpochMilli());
+ autoTimeLowerBound, autoTimeLowerBound.toEpochMilli());
String priorities =
Arrays.stream(mEnvironment.autoOriginPriorities())
.mapToObj(TimeDetectorStrategy::originToString)
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
index c20400a..457dc43 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
@@ -321,6 +321,13 @@
ipw.flush();
}
+ @Override
+ public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+ String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
+ new TimeZoneDetectorShellCommand(this).exec(
+ this, in, out, err, args, callback, resultReceiver);
+ }
+
private void enforceManageTimeZoneDetectorPermission() {
mContext.enforceCallingPermission(
android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION,
@@ -346,13 +353,5 @@
android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE,
"suggest manual time and time zone");
}
-
- @Override
- public void onShellCommand(FileDescriptor in, FileDescriptor out,
- FileDescriptor err, String[] args, ShellCallback callback,
- ResultReceiver resultReceiver) {
- new TimeZoneDetectorShellCommand(this).exec(
- this, in, out, err, args, callback, resultReceiver);
- }
}
diff --git a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
index 48ccad33..8818023 100644
--- a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
+++ b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
@@ -154,14 +154,14 @@
* Builds the Route selection request
*
* <p>This request is guaranteed to select carrier-owned, non-VCN underlying networks by virtue
- * of a populated set of subIds as expressed in NetworkCapabilities#getSubIds(). Only carrier
- * owned networks may be selected, as the request specifies only subIds in the VCN's
+ * of a populated set of subIds as expressed in NetworkCapabilities#getSubscriptionIds(). Only
+ * carrier owned networks may be selected, as the request specifies only subIds in the VCN's
* subscription group, while the VCN networks are excluded by virtue of not having subIds set on
* the VCN-exposed networks.
*/
private NetworkRequest getRouteSelectionRequest() {
return getBaseNetworkRequestBuilder()
- .setSubIds(mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup))
+ .setSubscriptionIds(mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup))
.build();
}
@@ -177,7 +177,7 @@
private NetworkRequest getWifiNetworkRequest() {
return getBaseNetworkRequestBuilder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
- .setSubIds(mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup))
+ .setSubscriptionIds(mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup))
.build();
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 89b7bbd..9acbdcc 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -2378,6 +2378,46 @@
}
}
+ /**
+ * Propagate a wake event to the wallpaper engine.
+ */
+ public void notifyWakingUp(int x, int y, @NonNull Bundle extras) {
+ synchronized (mLock) {
+ final WallpaperData data = mWallpaperMap.get(mCurrentUserId);
+ data.connection.forEachDisplayConnector(
+ displayConnector -> {
+ if (displayConnector.mEngine != null) {
+ try {
+ displayConnector.mEngine.dispatchWallpaperCommand(
+ WallpaperManager.COMMAND_WAKING_UP, x, y, -1, extras);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Propagate a sleep event to the wallpaper engine.
+ */
+ public void notifyGoingToSleep(int x, int y, @NonNull Bundle extras) {
+ synchronized (mLock) {
+ final WallpaperData data = mWallpaperMap.get(mCurrentUserId);
+ data.connection.forEachDisplayConnector(
+ displayConnector -> {
+ if (displayConnector.mEngine != null) {
+ try {
+ displayConnector.mEngine.dispatchWallpaperCommand(
+ WallpaperManager.COMMAND_GOING_TO_SLEEP, x, y, -1, extras);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+ }
+
@Override
public boolean setLockWallpaperCallback(IWallpaperManagerCallback cb) {
checkPermission(android.Manifest.permission.INTERNAL_SYSTEM_WINDOW);
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index e4dc8c2..561f1ad 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -96,6 +96,8 @@
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices;
+import com.android.server.apphibernation.AppHibernationManagerInternal;
+import com.android.server.apphibernation.AppHibernationService;
import java.util.ArrayList;
import java.util.LinkedList;
@@ -163,6 +165,8 @@
*/
private final LaunchObserverRegistryImpl mLaunchObserver;
@VisibleForTesting static final int LAUNCH_OBSERVER_ACTIVITY_RECORD_PROTO_CHUNK_SIZE = 512;
+ private final ArrayMap<String, Boolean> mLastHibernationStates = new ArrayMap<>();
+ private AppHibernationManagerInternal mAppHibernationManagerInternal;
/**
* The information created when an intent is incoming but we do not yet know whether it will be
@@ -789,6 +793,27 @@
}
}
+ @Nullable
+ private AppHibernationManagerInternal getAppHibernationManagerInternal() {
+ if (!AppHibernationService.isAppHibernationEnabled()) return null;
+ if (mAppHibernationManagerInternal == null) {
+ mAppHibernationManagerInternal =
+ LocalServices.getService(AppHibernationManagerInternal.class);
+ }
+ return mAppHibernationManagerInternal;
+ }
+
+ /**
+ * Notifies the tracker before the package is unstopped because of launching activity.
+ * @param packageName The package to be unstopped.
+ */
+ void notifyBeforePackageUnstopped(@NonNull String packageName) {
+ final AppHibernationManagerInternal ahmInternal = getAppHibernationManagerInternal();
+ if (ahmInternal != null) {
+ mLastHibernationStates.put(packageName, ahmInternal.isHibernatingGlobally(packageName));
+ }
+ }
+
/**
* Notifies the tracker that we called immediately before we call bindApplication on the client.
*
@@ -823,6 +848,8 @@
}
stopLaunchTrace(info);
+ final Boolean isHibernating =
+ mLastHibernationStates.remove(info.mLastLaunchedActivity.packageName);
if (abort) {
mSupervisor.stopWaitingForActivityVisible(info.mLastLaunchedActivity);
launchObserverNotifyActivityLaunchCancelled(info);
@@ -830,7 +857,7 @@
if (info.isInterestingToLoggerAndObserver()) {
launchObserverNotifyActivityLaunchFinished(info, timestampNs);
}
- logAppTransitionFinished(info);
+ logAppTransitionFinished(info, isHibernating != null ? isHibernating : false);
}
info.mPendingDrawActivities.clear();
mTransitionInfoList.remove(info);
@@ -859,7 +886,7 @@
}
}
- private void logAppTransitionFinished(@NonNull TransitionInfo info) {
+ private void logAppTransitionFinished(@NonNull TransitionInfo info, boolean isHibernating) {
if (DEBUG_METRICS) Slog.i(TAG, "logging finished transition " + info);
// Take a snapshot of the transition info before sending it to the handler for logging.
@@ -868,7 +895,7 @@
if (info.isInterestingToLoggerAndObserver()) {
BackgroundThread.getHandler().post(() -> logAppTransition(
info.mCurrentTransitionDeviceUptime, info.mCurrentTransitionDelayMs,
- infoSnapshot));
+ infoSnapshot, isHibernating));
}
BackgroundThread.getHandler().post(() -> logAppDisplayed(infoSnapshot));
if (info.mPendingFullyDrawn != null) {
@@ -880,7 +907,7 @@
// This gets called on a background thread without holding the activity manager lock.
private void logAppTransition(int currentTransitionDeviceUptime, int currentTransitionDelayMs,
- TransitionInfoSnapshot info) {
+ TransitionInfoSnapshot info, boolean isHibernating) {
final LogMaker builder = new LogMaker(APP_TRANSITION);
builder.setPackageName(info.packageName);
builder.setType(info.type);
@@ -933,7 +960,8 @@
packageOptimizationInfo.getCompilationReason(),
packageOptimizationInfo.getCompilationFilter(),
info.sourceType,
- info.sourceEventDelayMs);
+ info.sourceEventDelayMs,
+ isHibernating);
if (DEBUG_METRICS) {
Slog.i(TAG, String.format("APP_START_OCCURRED(%s, %s, %s, %s, %s)",
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 6d72999..c39358e 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -189,6 +189,7 @@
import static com.android.server.wm.IdentifierProto.HASH_CODE;
import static com.android.server.wm.IdentifierProto.TITLE;
import static com.android.server.wm.IdentifierProto.USER_ID;
+import static com.android.server.wm.LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
@@ -215,14 +216,8 @@
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
-import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
-import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_SOLID_COLOR;
-import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_WALLPAPER;
-import static com.android.server.wm.WindowManagerService.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
-import static com.android.server.wm.WindowManagerService.letterboxBackgroundTypeToString;
import static com.android.server.wm.WindowState.LEGACY_POLICY_VISIBILITY;
import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_BEFORE_ANIM;
@@ -268,7 +263,6 @@
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
@@ -344,7 +338,6 @@
import com.android.server.wm.SurfaceAnimator.AnimationType;
import com.android.server.wm.Task.ActivityState;
import com.android.server.wm.WindowManagerService.H;
-import com.android.server.wm.WindowManagerService.LetterboxBackgroundType;
import com.android.server.wm.utils.InsetUtils;
import com.google.android.collect.Sets;
@@ -587,10 +580,6 @@
AnimatingActivityRegistry mAnimatingActivityRegistry;
- // Set whenever the ActivityRecord gets reparented to a Task so we can know the last known
- // parent was when the ActivityRecord is detached from the hierarchy
- private Task mLastKnownParent;
-
// Set to the previous Task parent of the ActivityRecord when it is reparented to a new Task
// due to picture-in-picture. This gets cleared whenever this activity or the Task
// it references to gets removed. This should also be cleared when we move out of pip.
@@ -649,7 +638,8 @@
*/
private boolean mWillCloseOrEnterPip;
- private Letterbox mLetterbox;
+ @VisibleForTesting
+ final LetterboxUiController mLetterboxUiController;
/**
* The scale to fit at least one side of the activity to its parent. If the activity uses
@@ -678,8 +668,6 @@
@Nullable
private Rect mLetterboxBoundsForFixedOrientationAndAspectRatio;
- private boolean mShowWallpaperForLetterboxBackground;
-
// activity is not displayed?
// TODO: rename to mNoDisplay
@VisibleForTesting
@@ -1107,61 +1095,7 @@
pw.println(prefix + "lastParentTaskIdBeforePip=" + mLastParentBeforePip.mTaskId);
}
- dumpLetterboxInfo(pw, prefix);
- }
-
- private void dumpLetterboxInfo(PrintWriter pw, String prefix) {
- final WindowState mainWin = findMainWindow();
- if (mainWin == null) {
- return;
- }
-
- boolean areBoundsLetterboxed = mainWin.isLetterboxedAppWindow();
- pw.println(prefix + "areBoundsLetterboxed=" + areBoundsLetterboxed);
- if (!areBoundsLetterboxed) {
- return;
- }
-
- pw.println(prefix + " letterboxReason=" + getLetterboxReasonString(mainWin));
- pw.println(prefix + " letterboxAspectRatio=" + computeAspectRatio(getBounds()));
-
- boolean isLetterboxUiShown = isLetterboxed(mainWin);
- pw.println(prefix + "isLetterboxUiShown=" + isLetterboxUiShown);
-
- if (!isLetterboxUiShown) {
- return;
- }
- pw.println(prefix + " letterboxBackgroundColor=" + Integer.toHexString(
- getLetterboxBackgroundColor().toArgb()));
- pw.println(prefix + " letterboxBackgroundType="
- + letterboxBackgroundTypeToString(mWmService.getLetterboxBackgroundType()));
- if (mWmService.getLetterboxBackgroundType() == LETTERBOX_BACKGROUND_WALLPAPER) {
- pw.println(prefix + " isLetterboxWallpaperBlurSupported="
- + isLetterboxWallpaperBlurSupported());
- pw.println(prefix + " letterboxBackgroundWallpaperDarkScrimAlpha="
- + getLetterboxWallpaperDarkScrimAlpha());
- pw.println(prefix + " letterboxBackgroundWallpaperBlurRadius="
- + getLetterboxWallpaperBlurRadius());
- }
- pw.println(prefix + " letterboxHorizontalPositionMultiplier="
- + mWmService.getLetterboxHorizontalPositionMultiplier());
- }
-
- /**
- * Returns a string representing the reason for letterboxing. This method assumes the activity
- * is letterboxed.
- */
- private String getLetterboxReasonString(WindowState mainWin) {
- if (inSizeCompatMode()) {
- return "SIZE_COMPAT_MODE";
- }
- if (isLetterboxedForFixedOrientationAndAspectRatio()) {
- return "FIXED_ORIENTATION";
- }
- if (mainWin.isLetterboxedForDisplayCutout()) {
- return "DISPLAY_CUTOUT";
- }
- return "UNKNOWN_REASON";
+ mLetterboxUiController.dump(pw, prefix);
}
void setAppTimeTracker(AppTimeTracker att) {
@@ -1361,7 +1295,7 @@
if (getDisplayContent() != null) {
getDisplayContent().mClosingApps.remove(this);
}
- } else if (mLastKnownParent != null && mLastKnownParent.getRootTask() != null) {
+ } else if (oldTask != null && oldTask.getRootTask() != null) {
task.getRootTask().mExitingActivities.remove(this);
}
final Task rootTask = getRootTask();
@@ -1374,8 +1308,7 @@
? rootTask.getAnimatingActivityRegistry()
: null;
- mLastKnownParent = task;
- if (mLastKnownParent == mLastParentBeforePip) {
+ if (task == mLastParentBeforePip) {
// Activity's reparented back from pip, clear the links once established
clearLastParentBeforePip();
}
@@ -1451,183 +1384,29 @@
}
}
- if (mLetterbox != null) {
- mLetterbox.onMovedToDisplay(mDisplayContent.getDisplayId());
- }
+ mLetterboxUiController.onMovedToDisplay(mDisplayContent.getDisplayId());
}
- // TODO(b/183754168): Move letterbox UI logic into a separate class.
void layoutLetterbox(WindowState winHint) {
- final WindowState w = findMainWindow();
- if (w == null || winHint != null && w != winHint) {
- return;
- }
- final boolean surfaceReady = w.isDrawn() // Regular case
- || w.isDragResizeChanged(); // Waiting for relayoutWindow to call preserveSurface.
- final boolean needsLetterbox = surfaceReady && isLetterboxed(w);
- updateRoundedCorners(w);
- updateWallpaperForLetterbox(w);
- if (needsLetterbox) {
- if (mLetterbox == null) {
- mLetterbox = new Letterbox(() -> makeChildSurface(null),
- mWmService.mTransactionFactory,
- mWmService::isLetterboxActivityCornersRounded,
- this::getLetterboxBackgroundColor,
- this::hasWallpaperBackgroudForLetterbox,
- this::getLetterboxWallpaperBlurRadius,
- this::getLetterboxWallpaperDarkScrimAlpha);
- mLetterbox.attachInput(w);
- }
- getPosition(mTmpPoint);
- // Get the bounds of the "space-to-fill". The transformed bounds have the highest
- // priority because the activity is launched in a rotated environment. In multi-window
- // mode, the task-level represents this. In fullscreen-mode, the task container does
- // (since the orientation letterbox is also applied to the task).
- final Rect transformedBounds = getFixedRotationTransformDisplayBounds();
- final Rect spaceToFill = transformedBounds != null
- ? transformedBounds
- : inMultiWindowMode()
- ? getRootTask().getBounds()
- : getRootTask().getParent().getBounds();
- mLetterbox.layout(spaceToFill, w.getFrame(), mTmpPoint);
- } else if (mLetterbox != null) {
- mLetterbox.hide();
- }
- }
-
- private Color getLetterboxBackgroundColor() {
- final WindowState w = findMainWindow();
- if (w == null || w.isLetterboxedForDisplayCutout()) {
- return Color.valueOf(Color.BLACK);
- }
- @LetterboxBackgroundType int letterboxBackgroundType =
- mWmService.getLetterboxBackgroundType();
- switch (letterboxBackgroundType) {
- case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING:
- if (taskDescription != null && taskDescription.getBackgroundColorFloating() != 0) {
- return Color.valueOf(taskDescription.getBackgroundColorFloating());
- }
- break;
- case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND:
- if (taskDescription != null && taskDescription.getBackgroundColor() != 0) {
- return Color.valueOf(taskDescription.getBackgroundColor());
- }
- break;
- case LETTERBOX_BACKGROUND_WALLPAPER:
- if (hasWallpaperBackgroudForLetterbox()) {
- // Color is used for translucent scrim that dims wallpaper.
- return Color.valueOf(Color.BLACK);
- }
- Slog.w(TAG, "Wallpaper option is selected for letterbox background but "
- + "blur is not supported by a device or not supported in the current "
- + "window configuration or both alpha scrim and blur radius aren't "
- + "provided so using solid color background");
- break;
- case LETTERBOX_BACKGROUND_SOLID_COLOR:
- return mWmService.getLetterboxBackgroundColor();
- default:
- throw new AssertionError(
- "Unexpected letterbox background type: " + letterboxBackgroundType);
- }
- // If picked option configured incorrectly or not supported then default to a solid color
- // background.
- return mWmService.getLetterboxBackgroundColor();
- }
-
- /**
- * @return {@code true} when the main window is letterboxed, this activity isn't transparent
- * and doesn't show a wallpaper.
- */
- @VisibleForTesting
- boolean isLetterboxed(WindowState mainWindow) {
- return mainWindow.isLetterboxedAppWindow() && fillsParent()
- // Check for FLAG_SHOW_WALLPAPER explicitly instead of using
- // WindowContainer#showWallpaper because the later will return true when this
- // activity is using blurred wallpaper for letterbox backgroud.
- && (mainWindow.mAttrs.flags & FLAG_SHOW_WALLPAPER) == 0;
- }
-
- private void updateRoundedCorners(WindowState mainWindow) {
- int cornersRadius =
- // Don't round corners if letterboxed only for display cutout.
- isLetterboxed(mainWindow) && !mainWindow.isLetterboxedForDisplayCutout()
- ? Math.max(0, mWmService.getLetterboxActivityCornersRadius()) : 0;
- setCornersRadius(mainWindow, cornersRadius);
- }
-
- private void setCornersRadius(WindowState mainWindow, int cornersRadius) {
- final SurfaceControl windowSurface = mainWindow.getClientViewRootSurface();
- if (windowSurface != null && windowSurface.isValid()) {
- Transaction transaction = getSyncTransaction();
- transaction.setCornerRadius(windowSurface, cornersRadius);
- }
+ mLetterboxUiController.layoutLetterbox(winHint);
}
boolean hasWallpaperBackgroudForLetterbox() {
- return mShowWallpaperForLetterboxBackground;
- }
-
- private void updateWallpaperForLetterbox(WindowState mainWindow) {
- @LetterboxBackgroundType int letterboxBackgroundType =
- mWmService.getLetterboxBackgroundType();
- boolean wallpaperShouldBeShown =
- letterboxBackgroundType == LETTERBOX_BACKGROUND_WALLPAPER
- && isLetterboxed(mainWindow)
- // Don't use wallpaper as a background if letterboxed for display cutout.
- && !mainWindow.isLetterboxedForDisplayCutout()
- // Check that dark scrim alpha or blur radius are provided
- && (getLetterboxWallpaperBlurRadius() > 0
- || getLetterboxWallpaperDarkScrimAlpha() > 0)
- // Check that blur is supported by a device if blur radius is provided.
- && (getLetterboxWallpaperBlurRadius() <= 0
- || isLetterboxWallpaperBlurSupported());
- if (mShowWallpaperForLetterboxBackground != wallpaperShouldBeShown) {
- mShowWallpaperForLetterboxBackground = wallpaperShouldBeShown;
- requestUpdateWallpaperIfNeeded();
- }
- }
-
- private int getLetterboxWallpaperBlurRadius() {
- int blurRadius = mWmService.getLetterboxBackgroundWallpaperBlurRadius();
- return blurRadius < 0 ? 0 : blurRadius;
- }
-
- private float getLetterboxWallpaperDarkScrimAlpha() {
- float alpha = mWmService.getLetterboxBackgroundWallpaperDarkScrimAlpha();
- // No scrim by default.
- return (alpha < 0 || alpha >= 1) ? 0.0f : alpha;
- }
-
- private boolean isLetterboxWallpaperBlurSupported() {
- return mWmService.mContext.getSystemService(WindowManager.class).isCrossWindowBlurEnabled();
+ return mLetterboxUiController.hasWallpaperBackgroudForLetterbox();
}
void updateLetterboxSurface(WindowState winHint) {
- final WindowState w = findMainWindow();
- if (w != winHint && winHint != null && w != null) {
- return;
- }
- layoutLetterbox(winHint);
- if (mLetterbox != null && mLetterbox.needsApplySurfaceChanges()) {
- mLetterbox.applySurfaceChanges(getSyncTransaction());
- }
+ mLetterboxUiController.updateLetterboxSurface(winHint);
}
+ /** Gets the letterbox insets. The insets will be empty if there is no letterbox. */
Rect getLetterboxInsets() {
- if (mLetterbox != null) {
- return mLetterbox.getInsets();
- } else {
- return new Rect();
- }
+ return mLetterboxUiController.getLetterboxInsets();
}
/** Gets the inner bounds of letterbox. The bounds will be empty if there is no letterbox. */
void getLetterboxInnerBounds(Rect outBounds) {
- if (mLetterbox != null) {
- outBounds.set(mLetterbox.getInnerFrame());
- } else {
- outBounds.setEmpty();
- }
+ mLetterboxUiController.getLetterboxInnerBounds(outBounds);
}
/**
@@ -1635,7 +1414,7 @@
* when the current activity is displayed.
*/
boolean isFullyTransparentBarAllowed(Rect rect) {
- return mLetterbox == null || mLetterbox.notIntersectsOrFullyContains(rect);
+ return mLetterboxUiController.isFullyTransparentBarAllowed(rect);
}
/**
@@ -1643,7 +1422,7 @@
* the given {@code rect}.
*/
boolean isLetterboxOverlappingWith(Rect rect) {
- return mLetterbox != null && mLetterbox.isOverlappingWith(rect);
+ return mLetterboxUiController.isLetterboxOverlappingWith(rect);
}
static class Token extends IApplicationToken.Stub {
@@ -1892,6 +1671,9 @@
mPersistentState = persistentState;
taskDescription = _taskDescription;
+
+ mLetterboxUiController = new LetterboxUiController(mWmService, this);
+
if (_createTime > 0) {
createTime = _createTime;
}
@@ -2144,12 +1926,16 @@
}
void scheduleAddStartingWindow() {
- // Note: we really want to do sendMessageAtFrontOfQueue() because we
- // want to process the message ASAP, before any other queued
- // messages.
- if (!mWmService.mAnimationHandler.hasCallbacks(mAddStartingWindow)) {
- ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Enqueueing ADD_STARTING");
- mWmService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow);
+ if (StartingSurfaceController.DEBUG_ENABLE_SHELL_DRAWER) {
+ mAddStartingWindow.run();
+ } else {
+ // Note: we really want to do sendMessageAtFrontOfQueue() because we
+ // want to process the message ASAP, before any other queued
+ // messages.
+ if (!mWmService.mAnimationHandler.hasCallbacks(mAddStartingWindow)) {
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Enqueueing ADD_STARTING");
+ mWmService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow);
+ }
}
}
@@ -2161,7 +1947,9 @@
final StartingData startingData;
synchronized (mWmService.mGlobalLock) {
// There can only be one adding request, silly caller!
- mWmService.mAnimationHandler.removeCallbacks(this);
+ if (!StartingSurfaceController.DEBUG_ENABLE_SHELL_DRAWER) {
+ mWmService.mAnimationHandler.removeCallbacks(this);
+ }
if (mStartingData == null) {
// Animation has been canceled... do nothing.
@@ -2176,7 +1964,6 @@
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Add starting %s: startingData=%s",
this, startingData);
-
WindowManagerPolicy.StartingSurface surface = null;
try {
surface = startingData.createStartingSurface(ActivityRecord.this);
@@ -2411,17 +2198,22 @@
+ " startingView=%s Callers=%s", this, mStartingWindow, mStartingSurface,
Debug.getCallers(5));
-
- // Use the same thread to remove the window as we used to add it, as otherwise we end up
- // with things in the view hierarchy being called from different threads.
- mWmService.mAnimationHandler.post(() -> {
+ final Runnable removeSurface = () -> {
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Removing startingView=%s", surface);
try {
surface.remove(prepareAnimation);
} catch (Exception e) {
Slog.w(TAG_WM, "Exception when removing starting window", e);
}
- });
+ };
+
+ if (StartingSurfaceController.DEBUG_ENABLE_SHELL_DRAWER) {
+ removeSurface.run();
+ } else {
+ // Use the same thread to remove the window as we used to add it, as otherwise we end up
+ // with things in the view hierarchy being called from different threads.
+ mWmService.mAnimationHandler.post(removeSurface);
+ }
}
private void removeAppTokenFromDisplay() {
@@ -3724,10 +3516,8 @@
dc.setFocusedApp(null);
mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
}
- if (mLetterbox != null) {
- mLetterbox.destroy();
- mLetterbox = null;
- }
+
+ mLetterboxUiController.destroy();
if (!delayed) {
updateReportedVisibilityLocked();
@@ -7155,7 +6945,8 @@
offsetX = getHorizontalCenterOffset(
parentAppBounds.width(), screenResolvedBounds.width());
} else {
- float positionMultiplier = mWmService.getLetterboxHorizontalPositionMultiplier();
+ float positionMultiplier =
+ mWmService.mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier();
positionMultiplier =
(positionMultiplier < 0.0f || positionMultiplier > 1.0f)
// Default to central position if invalid value is provided.
@@ -7228,7 +7019,7 @@
// Override from config_fixedOrientationLetterboxAspectRatio or via ADB with
// set-fixed-orientation-letterbox-aspect-ratio.
final float letterboxAspectRatioOverride =
- mWmService.getFixedOrientationLetterboxAspectRatio();
+ mWmService.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
aspect = letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO
? letterboxAspectRatioOverride : aspect;
@@ -7746,7 +7537,7 @@
/**
* Returns the aspect ratio of the given {@code rect}.
*/
- private static float computeAspectRatio(Rect rect) {
+ static float computeAspectRatio(Rect rect) {
final int width = rect.width();
final int height = rect.height();
if (width == 0 || height == 0) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index a0beee4..b83945e 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -4514,11 +4514,9 @@
.setContentTitle(text)
.setContentText(
mContext.getText(R.string.heavy_weight_notification_detail))
- // TODO(b/175194709) Please replace FLAG_MUTABLE_UNAUDITED below
- // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
.setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT
- | PendingIntent.FLAG_MUTABLE_UNAUDITED, null,
+ | PendingIntent.FLAG_IMMUTABLE, null,
new UserHandle(userId)))
.build();
try {
diff --git a/services/core/java/com/android/server/wm/DisplayHashController.java b/services/core/java/com/android/server/wm/DisplayHashController.java
index 5a8af45..af0c3e3 100644
--- a/services/core/java/com/android/server/wm/DisplayHashController.java
+++ b/services/core/java/com/android/server/wm/DisplayHashController.java
@@ -16,8 +16,8 @@
package com.android.server.wm;
-import static android.service.displayhash.DisplayHasherService.EXTRA_VERIFIED_DISPLAY_HASH;
-import static android.service.displayhash.DisplayHasherService.SERVICE_META_DATA;
+import static android.service.displayhash.DisplayHashingService.EXTRA_VERIFIED_DISPLAY_HASH;
+import static android.service.displayhash.DisplayHashingService.SERVICE_META_DATA;
import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_INVALID_HASH_ALGORITHM;
import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_TOO_MANY_REQUESTS;
import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_UNKNOWN;
@@ -52,8 +52,8 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.service.displayhash.DisplayHashParams;
-import android.service.displayhash.DisplayHasherService;
-import android.service.displayhash.IDisplayHasherService;
+import android.service.displayhash.DisplayHashingService;
+import android.service.displayhash.IDisplayHashingService;
import android.util.AttributeSet;
import android.util.Size;
import android.util.Slog;
@@ -79,7 +79,7 @@
import java.util.function.BiConsumer;
/**
- * Handles requests into {@link android.service.displayhash.DisplayHasherService}
+ * Handles requests into {@link DisplayHashingService}
*
* Do not hold the {@link WindowManagerService#mGlobalLock} when calling methods since they are
* blocking calls into another service.
@@ -91,7 +91,7 @@
private final Object mServiceConnectionLock = new Object();
@GuardedBy("mServiceConnectionLock")
- private DisplayHasherServiceConnection mServiceConnection;
+ private DisplayHashingServiceConnection mServiceConnection;
private final Context mContext;
@@ -150,7 +150,7 @@
private boolean mDisplayHashThrottlingEnabled = true;
private interface Command {
- void run(IDisplayHasherService service) throws RemoteException;
+ void run(IDisplayHashingService service) throws RemoteException;
}
DisplayHashController(Context context) {
@@ -233,7 +233,7 @@
(float) size.getHeight() / boundsInWindow.height());
}
- args.setGrayscale(displayHashParams.isGrayscaleBuffer());
+ args.setGrayscale(displayHashParams.isUseGrayscale());
SurfaceControl.ScreenshotHardwareBuffer screenshotHardwareBuffer =
SurfaceControl.captureLayers(args.build());
@@ -405,9 +405,9 @@
}
}
- TypedArray sa = res.obtainAttributes(attrs, R.styleable.DisplayHasherService);
+ TypedArray sa = res.obtainAttributes(attrs, R.styleable.DisplayHashingService);
mThrottleDurationMillis = sa.getInt(
- R.styleable.DisplayHasherService_throttleDurationMillis, 0);
+ R.styleable.DisplayHashingService_throttleDurationMillis, 0);
sa.recycle();
mParsedXml = true;
return true;
@@ -424,7 +424,7 @@
if (DEBUG) Slog.v(TAG, "creating connection");
// Create the connection
- mServiceConnection = new DisplayHasherServiceConnection();
+ mServiceConnection = new DisplayHashingServiceConnection();
final ComponentName component = getServiceComponentName();
if (DEBUG) Slog.v(TAG, "binding to: " + component);
@@ -455,7 +455,7 @@
return null;
}
- final Intent intent = new Intent(DisplayHasherService.SERVICE_INTERFACE);
+ final Intent intent = new Intent(DisplayHashingService.SERVICE_INTERFACE);
intent.setPackage(packageName);
final ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent,
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
@@ -472,10 +472,10 @@
if (serviceInfo == null) return null;
final ComponentName name = new ComponentName(serviceInfo.packageName, serviceInfo.name);
- if (!Manifest.permission.BIND_DISPLAY_HASHER_SERVICE
+ if (!Manifest.permission.BIND_DISPLAY_HASHING_SERVICE
.equals(serviceInfo.permission)) {
Slog.w(TAG, name.flattenToShortString() + " requires permission "
- + Manifest.permission.BIND_DISPLAY_HASHER_SERVICE);
+ + Manifest.permission.BIND_DISPLAY_HASHING_SERVICE);
return null;
}
@@ -488,7 +488,7 @@
private Bundle mResult;
private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
- public Bundle run(BiConsumer<IDisplayHasherService, RemoteCallback> func) {
+ public Bundle run(BiConsumer<IDisplayHashingService, RemoteCallback> func) {
connectAndRun(service -> {
RemoteCallback callback = new RemoteCallback(result -> {
mResult = result;
@@ -507,9 +507,9 @@
}
}
- private class DisplayHasherServiceConnection implements ServiceConnection {
+ private class DisplayHashingServiceConnection implements ServiceConnection {
@GuardedBy("mServiceConnectionLock")
- private IDisplayHasherService mRemoteService;
+ private IDisplayHashingService mRemoteService;
@GuardedBy("mServiceConnectionLock")
private ArrayList<Command> mQueuedCommands;
@@ -518,7 +518,7 @@
public void onServiceConnected(ComponentName name, IBinder service) {
if (DEBUG) Slog.v(TAG, "onServiceConnected(): " + name);
synchronized (mServiceConnectionLock) {
- mRemoteService = IDisplayHasherService.Stub.asInterface(service);
+ mRemoteService = IDisplayHashingService.Stub.asInterface(service);
if (mQueuedCommands != null) {
final int size = mQueuedCommands.size();
if (DEBUG) Slog.d(TAG, "running " + size + " queued commands");
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
new file mode 100644
index 0000000..eb7087c
--- /dev/null
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.annotation.IntDef;
+import android.content.Context;
+import android.graphics.Color;
+
+import com.android.internal.R;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/** Reads letterbox configs from resources and controls their overrides at runtime. */
+final class LetterboxConfiguration {
+
+ /**
+ * Override of aspect ratio for fixed orientation letterboxing that is set via ADB with
+ * set-fixed-orientation-letterbox-aspect-ratio or via {@link
+ * com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio} will be ignored
+ * if it is <= this value.
+ */
+ static final float MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO = 1.0f;
+
+ /** Enum for Letterbox background type. */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({LETTERBOX_BACKGROUND_SOLID_COLOR, LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND,
+ LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING, LETTERBOX_BACKGROUND_WALLPAPER})
+ @interface LetterboxBackgroundType {};
+ /** Solid background using color specified in R.color.config_letterboxBackgroundColor. */
+ static final int LETTERBOX_BACKGROUND_SOLID_COLOR = 0;
+
+ /** Color specified in R.attr.colorBackground for the letterboxed application. */
+ static final int LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND = 1;
+
+ /** Color specified in R.attr.colorBackgroundFloating for the letterboxed application. */
+ static final int LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING = 2;
+
+ /** Using wallpaper as a background which can be blurred or dimmed with dark scrim. */
+ static final int LETTERBOX_BACKGROUND_WALLPAPER = 3;
+
+ final Context mContext;
+
+ // Aspect ratio of letterbox for fixed orientation, values <=
+ // MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO will be ignored.
+ private float mFixedOrientationLetterboxAspectRatio;
+
+ // Corners radius for activities presented in the letterbox mode, values < 0 will be ignored.
+ private int mLetterboxActivityCornersRadius;
+
+ // Color for {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} letterbox background type.
+ private Color mLetterboxBackgroundColor;
+
+ @LetterboxBackgroundType
+ private int mLetterboxBackgroundType;
+
+ // Blur radius for LETTERBOX_BACKGROUND_WALLPAPER option in mLetterboxBackgroundType.
+ // Values <= 0 are ignored and 0 is used instead.
+ private int mLetterboxBackgroundWallpaperBlurRadius;
+
+ // Alpha of a black scrim shown over wallpaper letterbox background when
+ // LETTERBOX_BACKGROUND_WALLPAPER option is selected for mLetterboxBackgroundType.
+ // Values < 0 or >= 1 are ignored and 0.0 (transparent) is used instead.
+ private float mLetterboxBackgroundWallpaperDarkScrimAlpha;
+
+ // Horizontal position of a center of the letterboxed app window. 0 corresponds to the left
+ // side of the screen and 1.0 to the right side.
+ private float mLetterboxHorizontalPositionMultiplier;
+
+ LetterboxConfiguration(Context context) {
+ mContext = context;
+ mFixedOrientationLetterboxAspectRatio = context.getResources().getFloat(
+ R.dimen.config_fixedOrientationLetterboxAspectRatio);
+ mLetterboxActivityCornersRadius = context.getResources().getInteger(
+ R.integer.config_letterboxActivityCornersRadius);
+ mLetterboxBackgroundColor = Color.valueOf(context.getResources().getColor(
+ R.color.config_letterboxBackgroundColor));
+ mLetterboxBackgroundType = readLetterboxBackgroundTypeFromConfig(context);
+ mLetterboxBackgroundWallpaperBlurRadius = context.getResources().getDimensionPixelSize(
+ R.dimen.config_letterboxBackgroundWallpaperBlurRadius);
+ mLetterboxBackgroundWallpaperDarkScrimAlpha = context.getResources().getFloat(
+ R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
+ mLetterboxHorizontalPositionMultiplier = context.getResources().getFloat(
+ R.dimen.config_letterboxHorizontalPositionMultiplier);
+ }
+
+ /**
+ * Overrides the aspect ratio of letterbox for fixed orientation. If given value is <= {@link
+ * #MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO}, both it and a value of {@link
+ * com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio} will be ignored and
+ * the framework implementation will be used to determine the aspect ratio.
+ */
+ void setFixedOrientationLetterboxAspectRatio(float aspectRatio) {
+ mFixedOrientationLetterboxAspectRatio = aspectRatio;
+ }
+
+ /**
+ * Resets the aspect ratio of letterbox for fixed orientation to {@link
+ * com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}.
+ */
+ void resetFixedOrientationLetterboxAspectRatio() {
+ mFixedOrientationLetterboxAspectRatio = mContext.getResources().getFloat(
+ com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio);
+ }
+
+ /**
+ * Gets the aspect ratio of letterbox for fixed orientation.
+ */
+ float getFixedOrientationLetterboxAspectRatio() {
+ return mFixedOrientationLetterboxAspectRatio;
+ }
+
+ /**
+ * Overrides corners raidus for activities presented in the letterbox mode. If given value < 0,
+ * both it and a value of {@link
+ * com.android.internal.R.integer.config_letterboxActivityCornersRadius} will be ignored and
+ * and corners of the activity won't be rounded.
+ */
+ void setLetterboxActivityCornersRadius(int cornersRadius) {
+ mLetterboxActivityCornersRadius = cornersRadius;
+ }
+
+ /**
+ * Resets corners raidus for activities presented in the letterbox mode to {@link
+ * com.android.internal.R.integer.config_letterboxActivityCornersRadius}.
+ */
+ void resetLetterboxActivityCornersRadius() {
+ mLetterboxActivityCornersRadius = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_letterboxActivityCornersRadius);
+ }
+
+ /**
+ * Whether corners of letterboxed activities are rounded.
+ */
+ boolean isLetterboxActivityCornersRounded() {
+ return getLetterboxActivityCornersRadius() > 0;
+ }
+
+ /**
+ * Gets corners raidus for activities presented in the letterbox mode.
+ */
+ int getLetterboxActivityCornersRadius() {
+ return mLetterboxActivityCornersRadius;
+ }
+
+ /**
+ * Gets color of letterbox background which is used when {@link
+ * #getLetterboxBackgroundType()} is {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} or as
+ * fallback for other backfround types.
+ */
+ Color getLetterboxBackgroundColor() {
+ return mLetterboxBackgroundColor;
+ }
+
+
+ /**
+ * Sets color of letterbox background which is used when {@link
+ * #getLetterboxBackgroundType()} is {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} or as
+ * fallback for other backfround types.
+ */
+ void setLetterboxBackgroundColor(Color color) {
+ mLetterboxBackgroundColor = color;
+ }
+
+ /**
+ * Resets color of letterbox background to {@link
+ * com.android.internal.R.color.config_letterboxBackgroundColor}.
+ */
+ void resetLetterboxBackgroundColor() {
+ mLetterboxBackgroundColor = Color.valueOf(mContext.getResources().getColor(
+ com.android.internal.R.color.config_letterboxBackgroundColor));
+ }
+
+ /**
+ * Gets {@link LetterboxBackgroundType} specified in {@link
+ * com.android.internal.R.integer.config_letterboxBackgroundType} or over via ADB command.
+ */
+ @LetterboxBackgroundType
+ int getLetterboxBackgroundType() {
+ return mLetterboxBackgroundType;
+ }
+
+ /** Sets letterbox background type. */
+ void setLetterboxBackgroundType(@LetterboxBackgroundType int backgroundType) {
+ mLetterboxBackgroundType = backgroundType;
+ }
+
+ /**
+ * Resets cletterbox background type to {@link
+ * com.android.internal.R.integer.config_letterboxBackgroundType}.
+ */
+ void resetLetterboxBackgroundType() {
+ mLetterboxBackgroundType = readLetterboxBackgroundTypeFromConfig(mContext);
+ }
+
+ /** Returns a string representing the given {@link LetterboxBackgroundType}. */
+ static String letterboxBackgroundTypeToString(
+ @LetterboxBackgroundType int backgroundType) {
+ switch (backgroundType) {
+ case LETTERBOX_BACKGROUND_SOLID_COLOR:
+ return "LETTERBOX_BACKGROUND_SOLID_COLOR";
+ case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND:
+ return "LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND";
+ case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING:
+ return "LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING";
+ case LETTERBOX_BACKGROUND_WALLPAPER:
+ return "LETTERBOX_BACKGROUND_WALLPAPER";
+ default:
+ return "unknown=" + backgroundType;
+ }
+ }
+
+ @LetterboxBackgroundType
+ private static int readLetterboxBackgroundTypeFromConfig(Context context) {
+ int backgroundType = context.getResources().getInteger(
+ com.android.internal.R.integer.config_letterboxBackgroundType);
+ return backgroundType == LETTERBOX_BACKGROUND_SOLID_COLOR
+ || backgroundType == LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND
+ || backgroundType == LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING
+ || backgroundType == LETTERBOX_BACKGROUND_WALLPAPER
+ ? backgroundType : LETTERBOX_BACKGROUND_SOLID_COLOR;
+ }
+
+ /**
+ * Overrides alpha of a black scrim shown over wallpaper for {@link
+ * #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link mLetterboxBackgroundType}.
+ *
+ * <p>If given value is < 0 or >= 1, both it and a value of {@link
+ * com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha} are ignored
+ * and 0.0 (transparent) is instead.
+ */
+ void setLetterboxBackgroundWallpaperDarkScrimAlpha(float alpha) {
+ mLetterboxBackgroundWallpaperDarkScrimAlpha = alpha;
+ }
+
+ /**
+ * Resets alpha of a black scrim shown over wallpaper letterbox background to {@link
+ * com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha}.
+ */
+ void resetLetterboxBackgroundWallpaperDarkScrimAlpha() {
+ mLetterboxBackgroundWallpaperDarkScrimAlpha = mContext.getResources().getFloat(
+ com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
+ }
+
+ /**
+ * Gets alpha of a black scrim shown over wallpaper letterbox background.
+ */
+ float getLetterboxBackgroundWallpaperDarkScrimAlpha() {
+ return mLetterboxBackgroundWallpaperDarkScrimAlpha;
+ }
+
+ /**
+ * Overrides blur radius for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in
+ * {@link mLetterboxBackgroundType}.
+ *
+ * <p> If given value <= 0, both it and a value of {@link
+ * com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius} are ignored
+ * and 0 is used instead.
+ */
+ void setLetterboxBackgroundWallpaperBlurRadius(int radius) {
+ mLetterboxBackgroundWallpaperBlurRadius = radius;
+ }
+
+ /**
+ * Resets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
+ * mLetterboxBackgroundType} to {@link
+ * com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius}.
+ */
+ void resetLetterboxBackgroundWallpaperBlurRadius() {
+ mLetterboxBackgroundWallpaperBlurRadius = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius);
+ }
+
+ /**
+ * Gets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
+ * mLetterboxBackgroundType}.
+ */
+ int getLetterboxBackgroundWallpaperBlurRadius() {
+ return mLetterboxBackgroundWallpaperBlurRadius;
+ }
+
+ /*
+ * Gets horizontal position of a center of the letterboxed app window specified
+ * in {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}
+ * or via an ADB command. 0 corresponds to the left side of the screen and 1 to the
+ * right side.
+ *
+ * <p>This value can be outside of [0, 1] range so clients need to check and default to the
+ * central position (0.5).
+ */
+ float getLetterboxHorizontalPositionMultiplier() {
+ return mLetterboxHorizontalPositionMultiplier;
+ }
+
+ /**
+ * Overrides horizontal position of a center of the letterboxed app window. If given value < 0
+ * or > 1, then it and a value of {@link
+ * com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier} are ignored and
+ * central position (0.5) is used.
+ */
+ void setLetterboxHorizontalPositionMultiplier(float multiplier) {
+ mLetterboxHorizontalPositionMultiplier = multiplier;
+ }
+
+ /**
+ * Resets horizontal position of a center of the letterboxed app window to {@link
+ * com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}.
+ */
+ void resetLetterboxHorizontalPositionMultiplier() {
+ mLetterboxHorizontalPositionMultiplier = mContext.getResources().getFloat(
+ com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier);
+ }
+
+}
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
new file mode 100644
index 0000000..130f680
--- /dev/null
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_WALLPAPER;
+import static com.android.server.wm.LetterboxConfiguration.letterboxBackgroundTypeToString;
+
+import android.annotation.Nullable;
+import android.app.ActivityManager.TaskDescription;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.util.Slog;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
+import android.view.WindowManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
+
+import java.io.PrintWriter;
+
+/** Controls behaviour of the letterbox UI for {@link mActivityRecord}. */
+// TODO(b/185262487): Improve test coverage of this class. Parts of it are tested in
+// SizeCompatTests and LetterboxTests but not all.
+// TODO(b/185264020): Consider making LetterboxUiController applicable to any level of the
+// hierarchy in addition to ActivityRecord (Task, DisplayArea, ...).
+final class LetterboxUiController {
+
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "LetterboxUiController" : TAG_ATM;
+
+ private final Point mTmpPoint = new Point();
+
+ private final LetterboxConfiguration mLetterboxConfiguration;
+ private final ActivityRecord mActivityRecord;
+
+ private boolean mShowWallpaperForLetterboxBackground;
+
+ @Nullable
+ private Letterbox mLetterbox;
+
+ LetterboxUiController(WindowManagerService wmService, ActivityRecord activityRecord) {
+ mLetterboxConfiguration = wmService.mLetterboxConfiguration;
+ // Given activityRecord may not be fully constructed since LetterboxUiController
+ // is created in its constructor. It shouldn't be used in this constructor but it's safe
+ // to use it after since controller is only used in ActivityRecord.
+ mActivityRecord = activityRecord;
+ }
+
+ /** Cleans up {@link Letterbox} if it exists.*/
+ void destroy() {
+ if (mLetterbox != null) {
+ mLetterbox.destroy();
+ mLetterbox = null;
+ }
+ }
+
+ void onMovedToDisplay(int displayId) {
+ if (mLetterbox != null) {
+ mLetterbox.onMovedToDisplay(displayId);
+ }
+ }
+
+ boolean hasWallpaperBackgroudForLetterbox() {
+ return mShowWallpaperForLetterboxBackground;
+ }
+
+ /** Gets the letterbox insets. The insets will be empty if there is no letterbox. */
+ Rect getLetterboxInsets() {
+ if (mLetterbox != null) {
+ return mLetterbox.getInsets();
+ } else {
+ return new Rect();
+ }
+ }
+
+ /** Gets the inner bounds of letterbox. The bounds will be empty if there is no letterbox. */
+ void getLetterboxInnerBounds(Rect outBounds) {
+ if (mLetterbox != null) {
+ outBounds.set(mLetterbox.getInnerFrame());
+ } else {
+ outBounds.setEmpty();
+ }
+ }
+
+ /**
+ * @return {@code true} if bar shown within a given rectangle is allowed to be fully transparent
+ * when the current activity is displayed.
+ */
+ boolean isFullyTransparentBarAllowed(Rect rect) {
+ return mLetterbox == null || mLetterbox.notIntersectsOrFullyContains(rect);
+ }
+
+ /**
+ * @return {@code true} if there is a letterbox and any part of that letterbox overlaps with
+ * the given {@code rect}.
+ */
+ boolean isLetterboxOverlappingWith(Rect rect) {
+ return mLetterbox != null && mLetterbox.isOverlappingWith(rect);
+ }
+
+ void updateLetterboxSurface(WindowState winHint) {
+ final WindowState w = mActivityRecord.findMainWindow();
+ if (w != winHint && winHint != null && w != null) {
+ return;
+ }
+ layoutLetterbox(winHint);
+ if (mLetterbox != null && mLetterbox.needsApplySurfaceChanges()) {
+ mLetterbox.applySurfaceChanges(mActivityRecord.getSyncTransaction());
+ }
+ }
+
+ void layoutLetterbox(WindowState winHint) {
+ final WindowState w = mActivityRecord.findMainWindow();
+ if (w == null || winHint != null && w != winHint) {
+ return;
+ }
+ final boolean surfaceReady = w.isDrawn() // Regular case
+ || w.isDragResizeChanged(); // Waiting for relayoutWindow to call preserveSurface.
+ final boolean needsLetterbox = surfaceReady && isLetterboxed(w);
+ updateRoundedCorners(w);
+ updateWallpaperForLetterbox(w);
+ if (needsLetterbox) {
+ if (mLetterbox == null) {
+ mLetterbox = new Letterbox(() -> mActivityRecord.makeChildSurface(null),
+ mActivityRecord.mWmService.mTransactionFactory,
+ mLetterboxConfiguration::isLetterboxActivityCornersRounded,
+ this::getLetterboxBackgroundColor,
+ this::hasWallpaperBackgroudForLetterbox,
+ this::getLetterboxWallpaperBlurRadius,
+ this::getLetterboxWallpaperDarkScrimAlpha);
+ mLetterbox.attachInput(w);
+ }
+ mActivityRecord.getPosition(mTmpPoint);
+ // Get the bounds of the "space-to-fill". The transformed bounds have the highest
+ // priority because the activity is launched in a rotated environment. In multi-window
+ // mode, the task-level represents this. In fullscreen-mode, the task container does
+ // (since the orientation letterbox is also applied to the task).
+ final Rect transformedBounds = mActivityRecord.getFixedRotationTransformDisplayBounds();
+ final Rect spaceToFill = transformedBounds != null
+ ? transformedBounds
+ : mActivityRecord.inMultiWindowMode()
+ ? mActivityRecord.getRootTask().getBounds()
+ : mActivityRecord.getRootTask().getParent().getBounds();
+ mLetterbox.layout(spaceToFill, w.getFrame(), mTmpPoint);
+ } else if (mLetterbox != null) {
+ mLetterbox.hide();
+ }
+ }
+
+ /**
+ * @return {@code true} when the main window is letterboxed, this activity isn't transparent
+ * and doesn't show a wallpaper.
+ */
+ @VisibleForTesting
+ boolean isLetterboxed(WindowState mainWindow) {
+ return mainWindow.isLetterboxedAppWindow() && mActivityRecord.fillsParent()
+ // Check for FLAG_SHOW_WALLPAPER explicitly instead of using
+ // WindowContainer#showWallpaper because the later will return true when this
+ // activity is using blurred wallpaper for letterbox backgroud.
+ && (mainWindow.mAttrs.flags & FLAG_SHOW_WALLPAPER) == 0;
+ }
+
+ private Color getLetterboxBackgroundColor() {
+ final WindowState w = mActivityRecord.findMainWindow();
+ if (w == null || w.isLetterboxedForDisplayCutout()) {
+ return Color.valueOf(Color.BLACK);
+ }
+ @LetterboxBackgroundType int letterboxBackgroundType =
+ mLetterboxConfiguration.getLetterboxBackgroundType();
+ TaskDescription taskDescription = mActivityRecord.taskDescription;
+ switch (letterboxBackgroundType) {
+ case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING:
+ if (taskDescription != null && taskDescription.getBackgroundColorFloating() != 0) {
+ return Color.valueOf(taskDescription.getBackgroundColorFloating());
+ }
+ break;
+ case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND:
+ if (taskDescription != null && taskDescription.getBackgroundColor() != 0) {
+ return Color.valueOf(taskDescription.getBackgroundColor());
+ }
+ break;
+ case LETTERBOX_BACKGROUND_WALLPAPER:
+ if (hasWallpaperBackgroudForLetterbox()) {
+ // Color is used for translucent scrim that dims wallpaper.
+ return Color.valueOf(Color.BLACK);
+ }
+ Slog.w(TAG, "Wallpaper option is selected for letterbox background but "
+ + "blur is not supported by a device or not supported in the current "
+ + "window configuration or both alpha scrim and blur radius aren't "
+ + "provided so using solid color background");
+ break;
+ case LETTERBOX_BACKGROUND_SOLID_COLOR:
+ return mLetterboxConfiguration.getLetterboxBackgroundColor();
+ default:
+ throw new AssertionError(
+ "Unexpected letterbox background type: " + letterboxBackgroundType);
+ }
+ // If picked option configured incorrectly or not supported then default to a solid color
+ // background.
+ return mLetterboxConfiguration.getLetterboxBackgroundColor();
+ }
+
+ private void updateRoundedCorners(WindowState mainWindow) {
+ int cornersRadius =
+ // Don't round corners if letterboxed only for display cutout.
+ isLetterboxed(mainWindow)
+ && !mainWindow.isLetterboxedForDisplayCutout()
+ ? Math.max(0, mLetterboxConfiguration.getLetterboxActivityCornersRadius())
+ : 0;
+ setCornersRadius(mainWindow, cornersRadius);
+ }
+
+ private void setCornersRadius(WindowState mainWindow, int cornersRadius) {
+ final SurfaceControl windowSurface = mainWindow.getClientViewRootSurface();
+ if (windowSurface != null && windowSurface.isValid()) {
+ Transaction transaction = mActivityRecord.getSyncTransaction();
+ transaction.setCornerRadius(windowSurface, cornersRadius);
+ }
+ }
+
+ private void updateWallpaperForLetterbox(WindowState mainWindow) {
+ @LetterboxBackgroundType int letterboxBackgroundType =
+ mLetterboxConfiguration.getLetterboxBackgroundType();
+ boolean wallpaperShouldBeShown =
+ letterboxBackgroundType == LETTERBOX_BACKGROUND_WALLPAPER
+ && isLetterboxed(mainWindow)
+ // Don't use wallpaper as a background if letterboxed for display cutout.
+ && !mainWindow.isLetterboxedForDisplayCutout()
+ // Check that dark scrim alpha or blur radius are provided
+ && (getLetterboxWallpaperBlurRadius() > 0
+ || getLetterboxWallpaperDarkScrimAlpha() > 0)
+ // Check that blur is supported by a device if blur radius is provided.
+ && (getLetterboxWallpaperBlurRadius() <= 0
+ || isLetterboxWallpaperBlurSupported());
+ if (mShowWallpaperForLetterboxBackground != wallpaperShouldBeShown) {
+ mShowWallpaperForLetterboxBackground = wallpaperShouldBeShown;
+ mActivityRecord.requestUpdateWallpaperIfNeeded();
+ }
+ }
+
+ private int getLetterboxWallpaperBlurRadius() {
+ int blurRadius = mLetterboxConfiguration.getLetterboxBackgroundWallpaperBlurRadius();
+ return blurRadius < 0 ? 0 : blurRadius;
+ }
+
+ private float getLetterboxWallpaperDarkScrimAlpha() {
+ float alpha = mLetterboxConfiguration.getLetterboxBackgroundWallpaperDarkScrimAlpha();
+ // No scrim by default.
+ return (alpha < 0 || alpha >= 1) ? 0.0f : alpha;
+ }
+
+ private boolean isLetterboxWallpaperBlurSupported() {
+ return mLetterboxConfiguration.mContext.getSystemService(WindowManager.class)
+ .isCrossWindowBlurEnabled();
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ final WindowState mainWin = mActivityRecord.findMainWindow();
+ if (mainWin == null) {
+ return;
+ }
+
+ boolean areBoundsLetterboxed = mainWin.isLetterboxedAppWindow();
+ pw.println(prefix + "areBoundsLetterboxed=" + areBoundsLetterboxed);
+ if (!areBoundsLetterboxed) {
+ return;
+ }
+
+ pw.println(prefix + " letterboxReason=" + getLetterboxReasonString(mainWin));
+ pw.println(prefix + " letterboxAspectRatio="
+ + mActivityRecord.computeAspectRatio(mActivityRecord.getBounds()));
+
+ boolean isLetterboxUiShown = isLetterboxed(mainWin);
+ pw.println(prefix + "isLetterboxUiShown=" + isLetterboxUiShown);
+
+ if (!isLetterboxUiShown) {
+ return;
+ }
+ pw.println(prefix + " letterboxBackgroundColor=" + Integer.toHexString(
+ getLetterboxBackgroundColor().toArgb()));
+ pw.println(prefix + " letterboxBackgroundType="
+ + letterboxBackgroundTypeToString(
+ mLetterboxConfiguration.getLetterboxBackgroundType()));
+ if (mLetterboxConfiguration.getLetterboxBackgroundType()
+ == LETTERBOX_BACKGROUND_WALLPAPER) {
+ pw.println(prefix + " isLetterboxWallpaperBlurSupported="
+ + isLetterboxWallpaperBlurSupported());
+ pw.println(prefix + " letterboxBackgroundWallpaperDarkScrimAlpha="
+ + getLetterboxWallpaperDarkScrimAlpha());
+ pw.println(prefix + " letterboxBackgroundWallpaperBlurRadius="
+ + getLetterboxWallpaperBlurRadius());
+ }
+ pw.println(prefix + " letterboxHorizontalPositionMultiplier="
+ + mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier());
+ }
+
+ /**
+ * Returns a string representing the reason for letterboxing. This method assumes the activity
+ * is letterboxed.
+ */
+ private String getLetterboxReasonString(WindowState mainWin) {
+ if (mActivityRecord.inSizeCompatMode()) {
+ return "SIZE_COMPAT_MODE";
+ }
+ if (mActivityRecord.isLetterboxedForFixedOrientationAndAspectRatio()) {
+ return "FIXED_ORIENTATION";
+ }
+ if (mainWin.isLetterboxedForDisplayCutout()) {
+ return "DISPLAY_CUTOUT";
+ }
+ return "UNKNOWN_REASON";
+ }
+
+}
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 4bb48b0b..9f9ac3e 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -1436,20 +1436,18 @@
/** @return whether the given task can be trimmed even if it is outside the visible range. */
protected boolean isTrimmable(Task task) {
- final Task rootTask = task.getRootTask();
-
- // No stack for task, just trim it
- if (rootTask == null) {
+ // The task was detached, just trim it.
+ if (!task.isAttached()) {
return true;
}
// Ignore tasks from different displays
// TODO (b/115289124): No Recents on non-default displays.
- if (!rootTask.isOnHomeDisplay()) {
+ if (!task.isOnHomeDisplay()) {
return false;
}
- final Task rootHomeTask = rootTask.getDisplayArea().getRootHomeTask();
+ final Task rootHomeTask = task.getDisplayArea().getRootHomeTask();
// Home task does not exist. Don't trim the task.
if (rootHomeTask == null) {
return false;
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 129a6ce..19c2e73 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -675,6 +675,8 @@
}
final SurfaceControl.Transaction t = mDisplayContent.getPendingTransaction();
final WindowContainer parent = navToken.getParent();
+ t.setLayer(navToken.getSurfaceControl(), navToken.getLastLayer());
+
if (animate) {
final NavBarFadeAnimationController navBarFadeAnimationController =
mDisplayContent.getDisplayPolicy().getNavBarFadeAnimationController();
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 95a4f69e..fb66c04 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -36,9 +36,11 @@
import android.animation.ArgbEvaluator;
import android.content.Context;
import android.graphics.Color;
+import android.graphics.GraphicBuffer;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
+import android.hardware.HardwareBuffer;
import android.os.Trace;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
@@ -210,9 +212,9 @@
String name = "RotationLayer";
mScreenshotLayer = displayContent.makeOverlay()
.setName(name)
- .setBufferSize(mWidth, mHeight)
.setSecure(isSecure)
.setCallsite("ScreenRotationAnimation")
+ .setBLASTLayer()
.build();
// This is the way to tell the input system to exclude this surface from occlusion
// detection since we don't have a window for it. We do this because this window is
@@ -225,32 +227,29 @@
.setCallsite("ScreenRotationAnimation")
.build();
- final Surface surface = mService.mSurfaceFactory.get();
- // In case display bounds change, screenshot buffer and surface may mismatch so
- // set a scaling mode.
- surface.copyFrom(mScreenshotLayer);
- surface.setScalingMode(Surface.SCALING_MODE_SCALE_TO_WINDOW);
-
+ HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer();
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
"ScreenRotationAnimation#getMedianBorderLuma");
- mStartLuma = RotationAnimationUtils.getMedianBorderLuma(
- screenshotBuffer.getHardwareBuffer(), screenshotBuffer.getColorSpace());
+ mStartLuma = RotationAnimationUtils.getMedianBorderLuma(hardwareBuffer,
+ screenshotBuffer.getColorSpace());
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
- try {
- surface.attachAndQueueBufferWithColorSpace(screenshotBuffer.getHardwareBuffer(),
- screenshotBuffer.getColorSpace());
- } catch (RuntimeException e) {
- Slog.w(TAG, "Failed to attach screenshot - " + e.getMessage());
- }
+
+ GraphicBuffer buffer = GraphicBuffer.createFromHardwareBuffer(
+ screenshotBuffer.getHardwareBuffer());
+ // Scale the layer to the display size.
+ float dsdx = (float) mWidth / hardwareBuffer.getWidth();
+ float dsdy = (float) mHeight / hardwareBuffer.getHeight();
t.setLayer(mScreenshotLayer, SCREEN_FREEZE_LAYER_BASE);
t.reparent(mBackColorSurface, displayContent.getSurfaceControl());
t.setLayer(mBackColorSurface, -1);
t.setColor(mBackColorSurface, new float[]{mStartLuma, mStartLuma, mStartLuma});
t.setAlpha(mBackColorSurface, 1);
+ t.setBuffer(mScreenshotLayer, buffer);
+ t.setColorSpace(mScreenshotLayer, screenshotBuffer.getColorSpace());
+ t.setMatrix(mScreenshotLayer, dsdx, 0, 0, dsdy);
t.show(mScreenshotLayer);
t.show(mBackColorSurface);
- surface.destroy();
} catch (OutOfResourcesException e) {
Slog.w(TAG, "Unable to allocate freeze surface", e);
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index b82a308..c6cd560 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -640,9 +640,16 @@
}
}
- void windowAddedLocked(String packageName) {
- mPackageName = packageName;
- mRelayoutTag = "relayoutWindow: " + mPackageName;
+ void windowAddedLocked() {
+ if (mPackageName == null) {
+ final WindowProcessController wpc = mService.mAtmService.mProcessMap.getProcess(mPid);
+ if (wpc != null) {
+ mPackageName = wpc.mInfo.packageName;
+ mRelayoutTag = "relayoutWindow: " + mPackageName;
+ } else {
+ Slog.e(TAG_WM, "Unknown process pid=" + mPid);
+ }
+ }
if (mSurfaceSession == null) {
if (DEBUG) {
Slog.v(TAG_WM, "First window added to " + this + ", creating SurfaceSession");
diff --git a/services/core/java/com/android/server/wm/StartingSurfaceController.java b/services/core/java/com/android/server/wm/StartingSurfaceController.java
index 140ae3e..a9b06ca 100644
--- a/services/core/java/com/android/server/wm/StartingSurfaceController.java
+++ b/services/core/java/com/android/server/wm/StartingSurfaceController.java
@@ -58,10 +58,12 @@
overrideConfig, displayId);
}
- final Task task = activity.getTask();
- if (task != null && mService.mAtmService.mTaskOrganizerController.addStartingWindow(task,
- activity.token, theme)) {
- return new ShellStartingSurface(task);
+ synchronized (mService.mGlobalLock) {
+ final Task task = activity.getTask();
+ if (task != null && mService.mAtmService.mTaskOrganizerController.addStartingWindow(
+ task, activity.token, theme, null /* taskSnapshot */)) {
+ return new ShellStartingSurface(task);
+ }
}
return null;
}
@@ -124,14 +126,13 @@
activity.mDisplayContent.handleTopActivityLaunchingInDifferentOrientation(
topFullscreenActivity, false /* checkOpening */);
}
+ if (DEBUG_ENABLE_SHELL_DRAWER) {
+ mService.mAtmService.mTaskOrganizerController.addStartingWindow(task,
+ activity.token, 0 /* launchTheme */, taskSnapshot);
+ return new ShellStartingSurface(task);
+ }
}
- if (!DEBUG_ENABLE_SHELL_DRAWER) {
- return mService.mTaskSnapshotController
- .createStartingSurface(activity, taskSnapshot);
- }
- mService.mAtmService.mTaskOrganizerController.addStartingWindow(task, activity.token,
- 0 /* launchTheme */);
- return new ShellStartingSurface(task);
+ return mService.mTaskSnapshotController.createStartingSurface(activity, taskSnapshot);
}
@@ -144,8 +145,9 @@
@Override
public void remove(boolean animate) {
- mService.mAtmService.mTaskOrganizerController.removeStartingWindow(mTask,
- animate);
+ synchronized (mService.mGlobalLock) {
+ mService.mAtmService.mTaskOrganizerController.removeStartingWindow(mTask, animate);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/wm/SurfaceFreezer.java b/services/core/java/com/android/server/wm/SurfaceFreezer.java
index 6f434e0..e0a791e 100644
--- a/services/core/java/com/android/server/wm/SurfaceFreezer.java
+++ b/services/core/java/com/android/server/wm/SurfaceFreezer.java
@@ -22,6 +22,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.graphics.GraphicBuffer;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
@@ -153,29 +154,24 @@
*/
Snapshot(Supplier<Surface> surfaceFactory, SurfaceControl.Transaction t,
SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer, SurfaceControl parent) {
- Surface drawSurface = surfaceFactory.get();
// We can't use a delegating constructor since we need to
// reference this::onAnimationFinished
- HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer();
- final int width = hardwareBuffer.getWidth();
- final int height = hardwareBuffer.getHeight();
+ GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer(
+ screenshotBuffer.getHardwareBuffer());
mSurfaceControl = mAnimatable.makeAnimationLeash()
.setName("snapshot anim: " + mAnimatable.toString())
- .setBufferSize(width, height)
.setFormat(PixelFormat.TRANSLUCENT)
.setParent(parent)
.setSecure(screenshotBuffer.containsSecureLayers())
.setCallsite("SurfaceFreezer.Snapshot")
+ .setBLASTLayer()
.build();
ProtoLog.i(WM_SHOW_TRANSACTIONS, " THUMBNAIL %s: CREATE", mSurfaceControl);
- // Transfer the thumbnail to the surface
- drawSurface.copyFrom(mSurfaceControl);
- drawSurface.attachAndQueueBufferWithColorSpace(hardwareBuffer,
- screenshotBuffer.getColorSpace());
- drawSurface.release();
+ t.setBuffer(mSurfaceControl, graphicBuffer);
+ t.setColorSpace(mSurfaceControl, screenshotBuffer.getColorSpace());
t.show(mSurfaceControl);
// We parent the thumbnail to the container, and just place it on top of anything else
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 07f81c7..858d9f3 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -6309,6 +6309,8 @@
// Launching this app's activity, make sure the app is no longer
// considered stopped.
try {
+ mTaskSupervisor.getActivityMetricsLogger()
+ .notifyBeforePackageUnstopped(next.packageName);
mAtmService.getPackageManager().setPackageStoppedState(
next.packageName, false, next.mUserId); /* TODO: Verify if correct userid */
} catch (RemoteException e1) {
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index dff621c..625cff3 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -439,6 +439,13 @@
taskDisplayArea = mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
}
+ // Re-route to default display if the home activity doesn't support multi-display
+ if (taskDisplayArea != null && activityRecord.isActivityTypeHome()
+ && !mSupervisor.mRootWindowContainer.canStartHomeOnDisplayArea(activityRecord.info,
+ taskDisplayArea, false /* allowInstrumenting */)) {
+ taskDisplayArea = mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
+ }
+
return (taskDisplayArea != null)
? taskDisplayArea
: getFallbackDisplayAreaForActivity(activityRecord, request);
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 565804f..ccc0916 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -43,6 +43,7 @@
import android.window.ITaskOrganizerController;
import android.window.StartingWindowInfo;
import android.window.TaskAppearedInfo;
+import android.window.TaskSnapshot;
import android.window.WindowContainerToken;
import com.android.internal.annotations.VisibleForTesting;
@@ -118,25 +119,25 @@
return mTaskOrganizer.asBinder();
}
- void addStartingWindow(Task task, IBinder appToken, int launchTheme) {
+ void addStartingWindow(Task task, IBinder appToken, int launchTheme,
+ TaskSnapshot taskSnapshot) {
final StartingWindowInfo info = task.getStartingWindowInfo();
if (launchTheme != 0) {
info.splashScreenThemeResId = launchTheme;
}
- mDeferTaskOrgCallbacksConsumer.accept(() -> {
- try {
- mTaskOrganizer.addStartingWindow(info, appToken);
- } catch (RemoteException e) {
- Slog.e(TAG, "Exception sending onTaskStart callback", e);
- }
- });
+ info.mTaskSnapshot = taskSnapshot;
+ // make this happen prior than prepare surface
+ try {
+ mTaskOrganizer.addStartingWindow(info, appToken);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Exception sending onTaskStart callback", e);
+ }
}
void removeStartingWindow(Task task, boolean prepareAnimation) {
- mDeferTaskOrgCallbacksConsumer.accept(() -> {
- SurfaceControl firstWindowLeash = null;
- Rect mainFrame = null;
- // TODO enable shift up animation once we fix flicker test
+ SurfaceControl firstWindowLeash = null;
+ Rect mainFrame = null;
+ // TODO enable shift up animation once we fix flicker test
// final boolean playShiftUpAnimation = !task.inMultiWindowMode();
// if (prepareAnimation && playShiftUpAnimation) {
// final ActivityRecord topActivity = task.topActivityWithStartingWindow();
@@ -144,32 +145,29 @@
// final WindowState mainWindow =
// topActivity.findMainWindow(false/* includeStartingApp */);
// if (mainWindow != null) {
- // TODO create proper leash instead of the copied SC
+ // TODO create proper leash instead of the copied SC
// firstWindowLeash = new SurfaceControl(mainWindow.getSurfaceControl(),
// "TaskOrganizerController.removeStartingWindow");
// mainFrame = mainWindow.getRelativeFrame();
// }
// }
// }
- try {
- mTaskOrganizer.removeStartingWindow(task.mTaskId, firstWindowLeash, mainFrame,
- /* TODO(183004107) Revert this when jankiness is solved
- prepareAnimation); */ false);
+ try {
+ mTaskOrganizer.removeStartingWindow(task.mTaskId, firstWindowLeash, mainFrame,
+ /* TODO(183004107) Revert this when jankiness is solved
+ prepareAnimation); */ false);
- } catch (RemoteException e) {
- Slog.e(TAG, "Exception sending onStartTaskFinished callback", e);
- }
- });
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Exception sending onStartTaskFinished callback", e);
+ }
}
void copySplashScreenView(Task task) {
- mDeferTaskOrgCallbacksConsumer.accept(() -> {
- try {
- mTaskOrganizer.copySplashScreenView(task.mTaskId);
- } catch (RemoteException e) {
- Slog.e(TAG, "Exception sending copyStartingWindowView callback", e);
- }
- });
+ try {
+ mTaskOrganizer.copySplashScreenView(task.mTaskId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Exception sending copyStartingWindowView callback", e);
+ }
}
SurfaceControl prepareLeash(Task task, boolean visible, String reason) {
@@ -266,8 +264,9 @@
mUid = uid;
}
- void addStartingWindow(Task t, IBinder appToken, int launchTheme) {
- mOrganizer.addStartingWindow(t, appToken, launchTheme);
+ void addStartingWindow(Task t, IBinder appToken, int launchTheme,
+ TaskSnapshot taskSnapshot) {
+ mOrganizer.addStartingWindow(t, appToken, launchTheme, taskSnapshot);
}
void removeStartingWindow(Task t, boolean prepareAnimation) {
@@ -505,14 +504,15 @@
return !ArrayUtils.contains(UNSUPPORTED_WINDOWING_MODES, winMode);
}
- boolean addStartingWindow(Task task, IBinder appToken, int launchTheme) {
+ boolean addStartingWindow(Task task, IBinder appToken, int launchTheme,
+ TaskSnapshot taskSnapshot) {
final Task rootTask = task.getRootTask();
if (rootTask == null || rootTask.mTaskOrganizer == null) {
return false;
}
final TaskOrganizerState state =
mTaskOrganizerStates.get(rootTask.mTaskOrganizer.asBinder());
- state.addStartingWindow(task, appToken, launchTheme);
+ state.addStartingWindow(task, appToken, launchTheme, taskSnapshot);
return true;
}
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index a467d82..d49b6a0 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -486,7 +486,7 @@
return builder.build();
}
- private boolean shouldDisableSnapshots() {
+ boolean shouldDisableSnapshots() {
return mIsRunningOnWear || mIsRunningOnTv || mIsRunningOnIoT;
}
diff --git a/services/core/java/com/android/server/wm/WindowContextListenerController.java b/services/core/java/com/android/server/wm/WindowContextListenerController.java
index 5e75996..0bb56e4 100644
--- a/services/core/java/com/android/server/wm/WindowContextListenerController.java
+++ b/services/core/java/com/android/server/wm/WindowContextListenerController.java
@@ -231,7 +231,7 @@
}
@Override
- public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {
+ public void onMergedOverrideConfigurationChanged(Configuration mergedOverrideConfig) {
reportConfigToWindowTokenClient();
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0c9473a..61fce88 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -159,7 +159,6 @@
import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.graphics.Bitmap;
-import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Point;
@@ -977,56 +976,7 @@
private boolean mAnimationsDisabled = false;
boolean mPointerLocationEnabled = false;
- /**
- * Override of aspect ratio for fixed orientation letterboxing that is set via ADB with
- * set-fixed-orientation-letterbox-aspect-ratio or via {@link
- * com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio} will be ignored
- * if it is <= this value.
- */
- static final float MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO = 1.0f;
-
- /** Enum for Letterbox background type. */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({LETTERBOX_BACKGROUND_SOLID_COLOR, LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND,
- LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING, LETTERBOX_BACKGROUND_WALLPAPER})
- @interface LetterboxBackgroundType {};
- /** Solid background using color specified in R.color.config_letterboxBackgroundColor. */
- static final int LETTERBOX_BACKGROUND_SOLID_COLOR = 0;
-
- /** Color specified in R.attr.colorBackground for the letterboxed application. */
- static final int LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND = 1;
-
- /** Color specified in R.attr.colorBackgroundFloating for the letterboxed application. */
- static final int LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING = 2;
-
- /** Using wallpaper as a background which can be blurred or dimmed with dark scrim. */
- static final int LETTERBOX_BACKGROUND_WALLPAPER = 3;
-
- // Aspect ratio of letterbox for fixed orientation, values <=
- // MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO will be ignored.
- private float mFixedOrientationLetterboxAspectRatio;
-
- // Corners radius for activities presented in the letterbox mode, values < 0 will be ignored.
- private int mLetterboxActivityCornersRadius;
-
- // Color for {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} letterbox background type.
- private Color mLetterboxBackgroundColor;
-
- @LetterboxBackgroundType
- private int mLetterboxBackgroundType;
-
- // Blur radius for LETTERBOX_BACKGROUND_WALLPAPER option in mLetterboxBackgroundType.
- // Values <= 0 are ignored and 0 is used instead.
- private int mLetterboxBackgroundWallpaperBlurRadius;
-
- // Alpha of a black scrim shown over wallpaper letterbox background when
- // LETTERBOX_BACKGROUND_WALLPAPER option is selected for mLetterboxBackgroundType.
- // Values < 0 or >= 1 are ignored and 0.0 (transparent) is used instead.
- private float mLetterboxBackgroundWallpaperDarkScrimAlpha;
-
- // horizontal position of a center of the letterboxed app window. 0 corresponds to the left
- // side of the screen and 1.0 to the right side.
- private float mLetterboxHorizontalPositionMultiplier;
+ final LetterboxConfiguration mLetterboxConfiguration;
final InputManagerService mInputManager;
final DisplayManagerInternal mDisplayManagerInternal;
@@ -1258,19 +1208,7 @@
mAssistantOnTopOfDream = context.getResources().getBoolean(
com.android.internal.R.bool.config_assistantOnTopOfDream);
- mFixedOrientationLetterboxAspectRatio = context.getResources().getFloat(
- com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio);
- mLetterboxActivityCornersRadius = context.getResources().getInteger(
- com.android.internal.R.integer.config_letterboxActivityCornersRadius);
- mLetterboxBackgroundColor = Color.valueOf(context.getResources().getColor(
- com.android.internal.R.color.config_letterboxBackgroundColor));
- mLetterboxBackgroundType = readLetterboxBackgroundTypeFromConfig(context);
- mLetterboxBackgroundWallpaperBlurRadius = context.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius);
- mLetterboxBackgroundWallpaperDarkScrimAlpha = context.getResources().getFloat(
- com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
- mLetterboxHorizontalPositionMultiplier = context.getResources().getFloat(
- com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier);
+ mLetterboxConfiguration = new LetterboxConfiguration(context);
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
@@ -3869,233 +3807,6 @@
}
}
- /**
- * Overrides the aspect ratio of letterbox for fixed orientation. If given value is <= {@link
- * #MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO}, both it and a value of {@link
- * com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio} will be ignored and
- * the framework implementation will be used to determine the aspect ratio.
- */
- void setFixedOrientationLetterboxAspectRatio(float aspectRatio) {
- mFixedOrientationLetterboxAspectRatio = aspectRatio;
- }
-
- /**
- * Resets the aspect ratio of letterbox for fixed orientation to {@link
- * com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}.
- */
- void resetFixedOrientationLetterboxAspectRatio() {
- mFixedOrientationLetterboxAspectRatio = mContext.getResources().getFloat(
- com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio);
- }
-
- /**
- * Gets the aspect ratio of letterbox for fixed orientation.
- */
- float getFixedOrientationLetterboxAspectRatio() {
- return mFixedOrientationLetterboxAspectRatio;
- }
-
- /**
- * Overrides corners raidus for activities presented in the letterbox mode. If given value < 0,
- * both it and a value of {@link
- * com.android.internal.R.integer.config_letterboxActivityCornersRadius} will be ignored and
- * and corners of the activity won't be rounded.
- */
- void setLetterboxActivityCornersRadius(int cornersRadius) {
- mLetterboxActivityCornersRadius = cornersRadius;
- }
-
- /**
- * Resets corners raidus for activities presented in the letterbox mode to {@link
- * com.android.internal.R.integer.config_letterboxActivityCornersRadius}.
- */
- void resetLetterboxActivityCornersRadius() {
- mLetterboxActivityCornersRadius = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_letterboxActivityCornersRadius);
- }
-
- /**
- * Whether corners of letterboxed activities are rounded.
- */
- boolean isLetterboxActivityCornersRounded() {
- return getLetterboxActivityCornersRadius() > 0;
- }
-
- /**
- * Gets corners raidus for activities presented in the letterbox mode.
- */
- int getLetterboxActivityCornersRadius() {
- return mLetterboxActivityCornersRadius;
- }
-
- /**
- * Gets color of letterbox background which is used when {@link
- * #getLetterboxBackgroundType()} is {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} or as
- * fallback for other backfround types.
- */
- Color getLetterboxBackgroundColor() {
- return mLetterboxBackgroundColor;
- }
-
-
- /**
- * Sets color of letterbox background which is used when {@link
- * #getLetterboxBackgroundType()} is {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} or as
- * fallback for other backfround types.
- */
- void setLetterboxBackgroundColor(Color color) {
- mLetterboxBackgroundColor = color;
- }
-
- /**
- * Resets color of letterbox background to {@link
- * com.android.internal.R.color.config_letterboxBackgroundColor}.
- */
- void resetLetterboxBackgroundColor() {
- mLetterboxBackgroundColor = Color.valueOf(mContext.getResources().getColor(
- com.android.internal.R.color.config_letterboxBackgroundColor));
- }
-
- /**
- * Gets {@link LetterboxBackgroundType} specified in {@link
- * com.android.internal.R.integer.config_letterboxBackgroundType} or over via ADB command.
- */
- @LetterboxBackgroundType
- int getLetterboxBackgroundType() {
- return mLetterboxBackgroundType;
- }
-
- /** Sets letterbox background type. */
- void setLetterboxBackgroundType(@LetterboxBackgroundType int backgroundType) {
- mLetterboxBackgroundType = backgroundType;
- }
-
- /**
- * Resets cletterbox background type to {@link
- * com.android.internal.R.integer.config_letterboxBackgroundType}.
- */
- void resetLetterboxBackgroundType() {
- mLetterboxBackgroundType = readLetterboxBackgroundTypeFromConfig(mContext);
- }
-
- @LetterboxBackgroundType
- private static int readLetterboxBackgroundTypeFromConfig(Context context) {
- int backgroundType = context.getResources().getInteger(
- com.android.internal.R.integer.config_letterboxBackgroundType);
- return backgroundType == LETTERBOX_BACKGROUND_SOLID_COLOR
- || backgroundType == LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND
- || backgroundType == LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING
- || backgroundType == LETTERBOX_BACKGROUND_WALLPAPER
- ? backgroundType : LETTERBOX_BACKGROUND_SOLID_COLOR;
- }
-
- /** Returns a string representing the given {@link LetterboxBackgroundType}. */
- static String letterboxBackgroundTypeToString(
- @LetterboxBackgroundType int backgroundType) {
- switch (backgroundType) {
- case LETTERBOX_BACKGROUND_SOLID_COLOR:
- return "LETTERBOX_BACKGROUND_SOLID_COLOR";
- case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND:
- return "LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND";
- case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING:
- return "LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING";
- case LETTERBOX_BACKGROUND_WALLPAPER:
- return "LETTERBOX_BACKGROUND_WALLPAPER";
- default:
- return "unknown=" + backgroundType;
- }
- }
-
- /**
- * Overrides alpha of a black scrim shown over wallpaper for {@link
- * #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link mLetterboxBackgroundType}.
- *
- * <p>If given value is < 0 or >= 1, both it and a value of {@link
- * com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha} are ignored
- * and 0.0 (transparent) is instead.
- */
- void setLetterboxBackgroundWallpaperDarkScrimAlpha(float alpha) {
- mLetterboxBackgroundWallpaperDarkScrimAlpha = alpha;
- }
-
- /**
- * Resets alpha of a black scrim shown over wallpaper letterbox background to {@link
- * com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha}.
- */
- void resetLetterboxBackgroundWallpaperDarkScrimAlpha() {
- mLetterboxBackgroundWallpaperDarkScrimAlpha = mContext.getResources().getFloat(
- com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
- }
-
- /**
- * Gets alpha of a black scrim shown over wallpaper letterbox background.
- */
- float getLetterboxBackgroundWallpaperDarkScrimAlpha() {
- return mLetterboxBackgroundWallpaperDarkScrimAlpha;
- }
-
- /**
- * Overrides blur radius for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in
- * {@link mLetterboxBackgroundType}.
- *
- * <p> If given value <= 0, both it and a value of {@link
- * com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius} are ignored
- * and 0 is used instead.
- */
- void setLetterboxBackgroundWallpaperBlurRadius(int radius) {
- mLetterboxBackgroundWallpaperBlurRadius = radius;
- }
-
- /**
- * Resets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
- * mLetterboxBackgroundType} to {@link
- * com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius}.
- */
- void resetLetterboxBackgroundWallpaperBlurRadius() {
- mLetterboxBackgroundWallpaperBlurRadius = mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius);
- }
-
- /**
- * Gets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
- * mLetterboxBackgroundType}.
- */
- int getLetterboxBackgroundWallpaperBlurRadius() {
- return mLetterboxBackgroundWallpaperBlurRadius;
- }
-
- /*
- * Gets horizontal position of a center of the letterboxed app window specified
- * in {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}
- * or via an ADB command. 0 corresponds to the left side of the screen and 1 to the
- * right side.
- *
- * <p>This value can be outside of [0, 1] range so clients need to check and default to the
- * central position (0.5).
- */
- float getLetterboxHorizontalPositionMultiplier() {
- return mLetterboxHorizontalPositionMultiplier;
- }
-
- /**
- * Overrides horizontal position of a center of the letterboxed app window. If given value < 0
- * or > 1, then it and a value of {@link
- * com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier} are ignored and
- * central position (0.5) is used.
- */
- void setLetterboxHorizontalPositionMultiplier(float multiplier) {
- mLetterboxHorizontalPositionMultiplier = multiplier;
- }
-
- /**
- * Resets horizontal position of a center of the letterboxed app window to {@link
- * com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}.
- */
- void resetLetterboxHorizontalPositionMultiplier() {
- mLetterboxHorizontalPositionMultiplier = mContext.getResources().getFloat(
- com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier);
- }
-
@Override
public void setIgnoreOrientationRequest(int displayId, boolean ignoreOrientationRequest) {
if (!checkCallingPermission(
@@ -8787,6 +8498,13 @@
mDisplayHashController.setDisplayHashThrottlingEnabled(enable);
}
+ @Override
+ public boolean isTaskSnapshotSupported() {
+ synchronized (mGlobalLock) {
+ return !mTaskSnapshotController.shouldDisableSnapshots();
+ }
+ }
+
void generateDisplayHash(Session session, IWindow window, Rect boundsInWindow,
String hashAlgorithm, RemoteCallback callback) {
final SurfaceControl displaySurfaceControl;
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 68257d4..1b578d1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -19,10 +19,10 @@
import static android.os.Build.IS_USER;
import static android.view.CrossWindowBlurListeners.CROSS_WINDOW_BLUR_SUPPORTED;
-import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
-import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
-import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_SOLID_COLOR;
-import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_WALLPAPER;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_WALLPAPER;
import android.graphics.Color;
import android.graphics.Point;
@@ -41,7 +41,7 @@
import com.android.internal.protolog.ProtoLogImpl;
import com.android.server.LocalServices;
import com.android.server.statusbar.StatusBarManagerInternal;
-import com.android.server.wm.WindowManagerService.LetterboxBackgroundType;
+import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
import java.io.IOException;
import java.io.PrintWriter;
@@ -64,10 +64,12 @@
// Internal service impl -- must perform security checks before touching.
private final WindowManagerService mInternal;
+ private final LetterboxConfiguration mLetterboxConfiguration;
public WindowManagerShellCommand(WindowManagerService service) {
mInterface = service;
mInternal = service;
+ mLetterboxConfiguration = service.mLetterboxConfiguration;
}
@Override
@@ -119,34 +121,12 @@
return runGetIgnoreOrientationRequest(pw);
case "dump-visible-window-views":
return runDumpVisibleWindowViews(pw);
- case "set-fixed-orientation-letterbox-aspect-ratio":
- return runSetFixedOrientationLetterboxAspectRatio(pw);
- case "get-fixed-orientation-letterbox-aspect-ratio":
- return runGetFixedOrientationLetterboxAspectRatio(pw);
- case "set-letterbox-activity-corners-radius":
- return runSetLetterboxActivityCornersRadius(pw);
- case "get-letterbox-activity-corners-radius":
- return runGetLetterboxActivityCornersRadius(pw);
- case "set-letterbox-background-type":
- return runSetLetterboxBackgroundType(pw);
- case "get-letterbox-background-type":
- return runGetLetterboxBackgroundType(pw);
- case "set-letterbox-background-color":
- return runSetLetterboxBackgroundColor(pw);
- case "get-letterbox-background-color":
- return runGetLetterboxBackgroundColor(pw);
- case "set-letterbox-background-wallpaper-blur-radius":
- return runSetLetterboxBackgroundWallpaperBlurRadius(pw);
- case "get-letterbox-background-wallpaper-blur-radius":
- return runGetLetterboxBackgroundWallpaperBlurRadius(pw);
- case "set-letterbox-background-wallpaper-dark-scrim-alpha":
- return runSetLetterboxBackgroundWallpaperDarkScrimAlpha(pw);
- case "get-letterbox-background-wallpaper-dark-scrim-alpha":
- return runGetLetterboxBackgroundWallpaperDarkScrimAlpha(pw);
- case "set-letterbox-horizontal-position-multiplier":
- return runSeLetterboxHorizontalPositionMultiplier(pw);
- case "get-letterbox-horizontal-position-multiplier":
- return runGetLetterboxHorizontalPositionMultiplier(pw);
+ case "set-letterbox-style":
+ return runSetLetterboxStyle(pw);
+ case "get-letterbox-style":
+ return runGetLetterboxStyle(pw);
+ case "reset-letterbox-style":
+ return runResetLetterboxStyle(pw);
case "set-sandbox-display-apis":
return runSandboxDisplayApis(pw);
case "reset":
@@ -611,12 +591,6 @@
final float aspectRatio;
try {
String arg = getNextArgRequired();
- if ("reset".equals(arg)) {
- synchronized (mInternal.mGlobalLock) {
- mInternal.resetFixedOrientationLetterboxAspectRatio();
- }
- return 0;
- }
aspectRatio = Float.parseFloat(arg);
} catch (NumberFormatException e) {
getErrPrintWriter().println("Error: bad aspect ratio format " + e);
@@ -627,19 +601,7 @@
return -1;
}
synchronized (mInternal.mGlobalLock) {
- mInternal.setFixedOrientationLetterboxAspectRatio(aspectRatio);
- }
- return 0;
- }
-
- private int runGetFixedOrientationLetterboxAspectRatio(PrintWriter pw) throws RemoteException {
- synchronized (mInternal.mGlobalLock) {
- final float aspectRatio = mInternal.getFixedOrientationLetterboxAspectRatio();
- if (aspectRatio <= WindowManagerService.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO) {
- pw.println("Letterbox aspect ratio is not set");
- } else {
- pw.println("Letterbox aspect ratio is " + aspectRatio);
- }
+ mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(aspectRatio);
}
return 0;
}
@@ -648,12 +610,6 @@
final int cornersRadius;
try {
String arg = getNextArgRequired();
- if ("reset".equals(arg)) {
- synchronized (mInternal.mGlobalLock) {
- mInternal.resetLetterboxActivityCornersRadius();
- }
- return 0;
- }
cornersRadius = Integer.parseInt(arg);
} catch (NumberFormatException e) {
getErrPrintWriter().println("Error: bad corners radius format " + e);
@@ -664,110 +620,59 @@
return -1;
}
synchronized (mInternal.mGlobalLock) {
- mInternal.setLetterboxActivityCornersRadius(cornersRadius);
- }
- return 0;
- }
-
- private int runGetLetterboxActivityCornersRadius(PrintWriter pw) throws RemoteException {
- synchronized (mInternal.mGlobalLock) {
- final int cornersRadius = mInternal.getLetterboxActivityCornersRadius();
- if (cornersRadius < 0) {
- pw.println("Letterbox corners radius is not set");
- } else {
- pw.println("Letterbox corners radius is " + cornersRadius);
- }
+ mLetterboxConfiguration.setLetterboxActivityCornersRadius(cornersRadius);
}
return 0;
}
private int runSetLetterboxBackgroundType(PrintWriter pw) throws RemoteException {
@LetterboxBackgroundType final int backgroundType;
-
- String arg = getNextArgRequired();
- if ("reset".equals(arg)) {
- synchronized (mInternal.mGlobalLock) {
- mInternal.resetLetterboxBackgroundType();
- }
- return 0;
- }
- switch (arg) {
- case "solid_color":
- backgroundType = LETTERBOX_BACKGROUND_SOLID_COLOR;
- break;
- case "app_color_background":
- backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
- break;
- case "app_color_background_floating":
- backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
- break;
- case "wallpaper":
- backgroundType = LETTERBOX_BACKGROUND_WALLPAPER;
- break;
- default:
- getErrPrintWriter().println(
- "Error: 'reset', 'solid_color', 'app_color_background' or "
- + "'wallpaper' should be provided as an argument");
- return -1;
- }
- synchronized (mInternal.mGlobalLock) {
- mInternal.setLetterboxBackgroundType(backgroundType);
- }
- return 0;
- }
-
- private int runGetLetterboxBackgroundType(PrintWriter pw) throws RemoteException {
- synchronized (mInternal.mGlobalLock) {
- @LetterboxBackgroundType final int backgroundType =
- mInternal.getLetterboxBackgroundType();
- switch (backgroundType) {
- case LETTERBOX_BACKGROUND_SOLID_COLOR:
- pw.println("Letterbox background type is 'solid_color'");
+ try {
+ String arg = getNextArgRequired();
+ switch (arg) {
+ case "solid_color":
+ backgroundType = LETTERBOX_BACKGROUND_SOLID_COLOR;
break;
- case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND:
- pw.println("Letterbox background type is 'app_color_background'");
+ case "app_color_background":
+ backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
break;
- case LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING:
- pw.println("Letterbox background type is 'app_color_background_floating'");
+ case "app_color_background_floating":
+ backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
break;
- case LETTERBOX_BACKGROUND_WALLPAPER:
- pw.println("Letterbox background type is 'wallpaper'");
+ case "wallpaper":
+ backgroundType = LETTERBOX_BACKGROUND_WALLPAPER;
break;
default:
- throw new AssertionError(
- "Unexpected letterbox background type: " + backgroundType);
+ getErrPrintWriter().println(
+ "Error: 'reset', 'solid_color', 'app_color_background' or "
+ + "'wallpaper' should be provided as an argument");
+ return -1;
}
+ } catch (IllegalArgumentException e) {
+ getErrPrintWriter().println(
+ "Error: 'reset', 'solid_color', 'app_color_background' or "
+ + "'wallpaper' should be provided as an argument" + e);
+ return -1;
+ }
+ synchronized (mInternal.mGlobalLock) {
+ mLetterboxConfiguration.setLetterboxBackgroundType(backgroundType);
}
return 0;
}
private int runSetLetterboxBackgroundColor(PrintWriter pw) throws RemoteException {
final Color color;
- String arg = getNextArgRequired();
try {
- if ("reset".equals(arg)) {
- synchronized (mInternal.mGlobalLock) {
- mInternal.resetLetterboxBackgroundColor();
- }
- return 0;
- }
+ String arg = getNextArgRequired();
color = Color.valueOf(Color.parseColor(arg));
} catch (IllegalArgumentException e) {
getErrPrintWriter().println(
"Error: 'reset' or color in #RRGGBB format should be provided as "
- + "an argument " + e + " but got " + arg);
+ + "an argument " + e);
return -1;
}
synchronized (mInternal.mGlobalLock) {
- mInternal.setLetterboxBackgroundColor(color);
- }
- return 0;
- }
-
- private int runGetLetterboxBackgroundColor(PrintWriter pw) throws RemoteException {
- synchronized (mInternal.mGlobalLock) {
- final Color color = mInternal.getLetterboxBackgroundColor();
- pw.println("Letterbox background color is " + Integer.toHexString(color.toArgb()));
+ mLetterboxConfiguration.setLetterboxBackgroundColor(color);
}
return 0;
}
@@ -777,12 +682,6 @@
final int radius;
try {
String arg = getNextArgRequired();
- if ("reset".equals(arg)) {
- synchronized (mInternal.mGlobalLock) {
- mInternal.resetLetterboxBackgroundWallpaperBlurRadius();
- }
- return 0;
- }
radius = Integer.parseInt(arg);
} catch (NumberFormatException e) {
getErrPrintWriter().println("Error: blur radius format " + e);
@@ -793,20 +692,7 @@
return -1;
}
synchronized (mInternal.mGlobalLock) {
- mInternal.setLetterboxBackgroundWallpaperBlurRadius(radius);
- }
- return 0;
- }
-
- private int runGetLetterboxBackgroundWallpaperBlurRadius(PrintWriter pw)
- throws RemoteException {
- synchronized (mInternal.mGlobalLock) {
- final int radius = mInternal.getLetterboxBackgroundWallpaperBlurRadius();
- if (radius <= 0) {
- pw.println("Letterbox background wallpaper blur radius is not set");
- } else {
- pw.println("Letterbox background wallpaper blur radius is " + radius);
- }
+ mLetterboxConfiguration.setLetterboxBackgroundWallpaperBlurRadius(radius);
}
return 0;
}
@@ -816,12 +702,6 @@
final float alpha;
try {
String arg = getNextArgRequired();
- if ("reset".equals(arg)) {
- synchronized (mInternal.mGlobalLock) {
- mInternal.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
- }
- return 0;
- }
alpha = Float.parseFloat(arg);
} catch (NumberFormatException e) {
getErrPrintWriter().println("Error: bad alpha format " + e);
@@ -832,20 +712,7 @@
return -1;
}
synchronized (mInternal.mGlobalLock) {
- mInternal.setLetterboxBackgroundWallpaperDarkScrimAlpha(alpha);
- }
- return 0;
- }
-
- private int runGetLetterboxBackgroundWallpaperDarkScrimAlpha(PrintWriter pw)
- throws RemoteException {
- synchronized (mInternal.mGlobalLock) {
- final float alpha = mInternal.getLetterboxBackgroundWallpaperDarkScrimAlpha();
- if (alpha < 0 || alpha >= 1) {
- pw.println("Letterbox dark scrim alpha is not set");
- } else {
- pw.println("Letterbox dark scrim alpha is " + alpha);
- }
+ mLetterboxConfiguration.setLetterboxBackgroundWallpaperDarkScrimAlpha(alpha);
}
return 0;
}
@@ -854,12 +721,6 @@
final float multiplier;
try {
String arg = getNextArgRequired();
- if ("reset".equals(arg)) {
- synchronized (mInternal.mGlobalLock) {
- mInternal.resetLetterboxHorizontalPositionMultiplier();
- }
- return 0;
- }
multiplier = Float.parseFloat(arg);
} catch (NumberFormatException e) {
getErrPrintWriter().println("Error: bad multiplier format " + e);
@@ -870,23 +731,121 @@
return -1;
}
synchronized (mInternal.mGlobalLock) {
- mInternal.setLetterboxHorizontalPositionMultiplier(multiplier);
+ mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(multiplier);
}
return 0;
}
- private int runGetLetterboxHorizontalPositionMultiplier(PrintWriter pw) throws RemoteException {
- synchronized (mInternal.mGlobalLock) {
- final float multiplier = mInternal.getLetterboxHorizontalPositionMultiplier();
- if (multiplier < 0) {
- pw.println("Letterbox horizontal position multiplier is not set");
- } else {
- pw.println("Letterbox horizontal position multiplier is " + multiplier);
+ private int runSetLetterboxStyle(PrintWriter pw) throws RemoteException {
+ if (peekNextArg() == null) {
+ getErrPrintWriter().println("Error: No arguments provided.");
+ }
+ while (peekNextArg() != null) {
+ String arg = getNextArg();
+ switch (arg) {
+ case "--aspectRatio":
+ runSetFixedOrientationLetterboxAspectRatio(pw);
+ break;
+ case "--cornerRadius":
+ runSetLetterboxActivityCornersRadius(pw);
+ break;
+ case "--backgroundType":
+ runSetLetterboxBackgroundType(pw);
+ break;
+ case "--backgroundColor":
+ runSetLetterboxBackgroundColor(pw);
+ break;
+ case "--wallpaperBlurRadius":
+ runSetLetterboxBackgroundWallpaperBlurRadius(pw);
+ break;
+ case "--wallpaperDarkScrimAlpha":
+ runSetLetterboxBackgroundWallpaperDarkScrimAlpha(pw);
+ break;
+ case "--horizontalPositionMultiplier":
+ runSeLetterboxHorizontalPositionMultiplier(pw);
+ break;
+ default:
+ getErrPrintWriter().println(
+ "Error: Unrecognized letterbox style option: " + arg);
+ return -1;
}
}
return 0;
}
+ private int runResetLetterboxStyle(PrintWriter pw) throws RemoteException {
+ if (peekNextArg() == null) {
+ resetLetterboxStyle();
+ }
+ synchronized (mInternal.mGlobalLock) {
+ while (peekNextArg() != null) {
+ String arg = getNextArg();
+ switch (arg) {
+ case "aspectRatio":
+ mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio();
+ break;
+ case "cornerRadius":
+ mLetterboxConfiguration.resetLetterboxActivityCornersRadius();
+ break;
+ case "backgroundType":
+ mLetterboxConfiguration.resetLetterboxBackgroundType();
+ break;
+ case "backgroundColor":
+ mLetterboxConfiguration.resetLetterboxBackgroundColor();
+ break;
+ case "wallpaperBlurRadius":
+ mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadius();
+ break;
+ case "wallpaperDarkScrimAlpha":
+ mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
+ break;
+ case "horizontalPositionMultiplier":
+ mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
+ break;
+ default:
+ getErrPrintWriter().println(
+ "Error: Unrecognized letterbox style option: " + arg);
+ return -1;
+ }
+ }
+ }
+ return 0;
+ }
+
+ private void resetLetterboxStyle() {
+ synchronized (mInternal.mGlobalLock) {
+ mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio();
+ mLetterboxConfiguration.resetLetterboxActivityCornersRadius();
+ mLetterboxConfiguration.resetLetterboxBackgroundType();
+ mLetterboxConfiguration.resetLetterboxBackgroundColor();
+ mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadius();
+ mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
+ mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
+ }
+ }
+
+ private int runGetLetterboxStyle(PrintWriter pw) throws RemoteException {
+ synchronized (mInternal.mGlobalLock) {
+ pw.println("Corner radius: "
+ + mLetterboxConfiguration.getLetterboxActivityCornersRadius());
+ pw.println("Horizontal position multiplier: "
+ + mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier());
+ pw.println("Aspect ratio: "
+ + mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio());
+
+ pw.println("Background type: "
+ + LetterboxConfiguration.letterboxBackgroundTypeToString(
+ mLetterboxConfiguration.getLetterboxBackgroundType()));
+ pw.println(" Background color: " + Integer.toHexString(
+ mLetterboxConfiguration.getLetterboxBackgroundColor().toArgb()));
+ pw.println(" Wallpaper blur radius: "
+ + mLetterboxConfiguration.getLetterboxBackgroundWallpaperBlurRadius());
+ pw.println(" Wallpaper dark scrim alpha: "
+ + mLetterboxConfiguration.getLetterboxBackgroundWallpaperDarkScrimAlpha());
+ }
+ return 0;
+ }
+
private int runReset(PrintWriter pw) throws RemoteException {
int displayId = getDisplayId(getNextArg());
@@ -911,26 +870,8 @@
// set-ignore-orientation-request
mInterface.setIgnoreOrientationRequest(displayId, false /* ignoreOrientationRequest */);
- // set-fixed-orientation-letterbox-aspect-ratio
- mInternal.resetFixedOrientationLetterboxAspectRatio();
-
- // set-letterbox-activity-corners-radius
- mInternal.resetLetterboxActivityCornersRadius();
-
- // set-letterbox-background-type
- mInternal.resetLetterboxBackgroundType();
-
- // set-letterbox-background-color
- mInternal.resetLetterboxBackgroundColor();
-
- // set-letterbox-background-wallpaper-blur-radius
- mInternal.resetLetterboxBackgroundWallpaperBlurRadius();
-
- // set-letterbox-background-wallpaper-dark-scrim-alpha
- mInternal.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
-
- // set-letterbox-horizontal-position-multiplier
- mInternal.resetLetterboxHorizontalPositionMultiplier();
+ // set-letterbox-style
+ resetLetterboxStyle();
// set-sandbox-display-apis
mInternal.setSandboxDisplayApis(displayId, /* sandboxDisplayApis= */ true);
@@ -966,47 +907,13 @@
pw.println(" set-ignore-orientation-request [-d DISPLAY_ID] [true|1|false|0]");
pw.println(" get-ignore-orientation-request [-d DISPLAY_ID] ");
pw.println(" If app requested orientation should be ignored.");
- pw.println(" set-fixed-orientation-letterbox-aspect-ratio [reset|aspectRatio]");
- pw.println(" get-fixed-orientation-letterbox-aspect-ratio");
- pw.println(" Aspect ratio of letterbox for fixed orientation. If aspectRatio <= "
- + WindowManagerService.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO);
- pw.println(" both it and R.dimen.config_fixedOrientationLetterboxAspectRatio will be");
- pw.println(" ignored and framework implementation will determine aspect ratio.");
- pw.println(" set-letterbox-activity-corners-radius [reset|cornersRadius]");
- pw.println(" get-letterbox-activity-corners-radius");
- pw.println(" Corners radius for activities in the letterbox mode. If radius < 0,");
- pw.println(" both it and R.integer.config_letterboxActivityCornersRadius will be");
- pw.println(" ignored and corners of the activity won't be rounded.");
- pw.println(" set-letterbox-background-color [reset|colorName|'\\#RRGGBB']");
- pw.println(" get-letterbox-background-color");
- pw.println(" Color of letterbox background which is be used when letterbox background");
- pw.println(" type is 'solid-color'. Use get(set)-letterbox-background-type to check");
- pw.println(" and control letterbox background type. See Color#parseColor for allowed");
- pw.println(" color formats (#RRGGBB and some colors by name, e.g. magenta or olive). ");
- pw.println(" set-letterbox-background-type [reset|solid_color|app_color_background");
- pw.println(" |app_color_background_floating|wallpaper]");
- pw.println(" get-letterbox-background-type");
- pw.println(" Type of background used in the letterbox mode.");
- pw.println(" set-letterbox-background-wallpaper-blur-radius [reset|radius]");
- pw.println(" get-letterbox-background-wallpaper-blur-radius");
- pw.println(" Blur radius for 'wallpaper' letterbox background. If radius <= 0");
- pw.println(" both it and R.dimen.config_letterboxBackgroundWallpaperBlurRadius are ");
- pw.println(" ignored and 0 is used.");
- pw.println(" set-letterbox-background-wallpaper-dark-scrim-alpha [reset|alpha]");
- pw.println(" get-letterbox-background-wallpaper-dark-scrim-alpha");
- pw.println(" Alpha of a black translucent scrim shown over 'wallpaper'");
- pw.println(" letterbox background. If alpha < 0 or >= 1 both it and");
- pw.println(" R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha are ignored and ");
- pw.println(" 0.0 (transparent) is used instead.");
- pw.println(" set-letterbox-horizontal-position-multiplier [reset|multiplier]");
- pw.println(" get-letterbox-horizontal-position-multiplier");
- pw.println(" horizontal position of a center of a letterboxed app. If it < 0 or > 1");
- pw.println(" then both it and R.dimen.config_letterboxHorizontalPositionMultiplier");
- pw.println(" are ignored and central position (0.5) is used.");
pw.println(" set-sandbox-display-apis [true|1|false|0]");
pw.println(" Sets override of Display APIs getRealSize / getRealMetrics to reflect ");
pw.println(" DisplayArea of the activity, or the window bounds if in letterbox or");
pw.println(" Size Compat Mode.");
+
+ printLetterboxHelp(pw);
+
pw.println(" reset [-d DISPLAY_ID]");
pw.println(" Reset all override settings.");
if (!IS_USER) {
@@ -1016,4 +923,47 @@
pw.println(" Logging settings.");
}
}
+
+ private void printLetterboxHelp(PrintWriter pw) {
+ pw.println(" set-letterbox-style");
+ pw.println(" Sets letterbox style using the following options:");
+ pw.println(" --aspectRatio aspectRatio");
+ pw.println(" Aspect ratio of letterbox for fixed orientation. If aspectRatio <= "
+ + LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO);
+ pw.println(" both it and R.dimen.config_fixedOrientationLetterboxAspectRatio will");
+ pw.println(" be ignored and framework implementation will determine aspect ratio.");
+ pw.println(" --cornerRadius radius");
+ pw.println(" Corners radius for activities in the letterbox mode. If radius < 0,");
+ pw.println(" both it and R.integer.config_letterboxActivityCornersRadius will be");
+ pw.println(" ignored and corners of the activity won't be rounded.");
+ pw.println(" --backgroundType [reset|solid_color|app_color_background");
+ pw.println(" |app_color_background_floating|wallpaper]");
+ pw.println(" Type of background used in the letterbox mode.");
+ pw.println(" --backgroundColor color");
+ pw.println(" Color of letterbox which is be used when letterbox background type");
+ pw.println(" is 'solid-color'. Use (set)get-letterbox-style to check and control");
+ pw.println(" letterbox background type. See Color#parseColor for allowed color");
+ pw.println(" formats (#RRGGBB and some colors by name, e.g. magenta or olive).");
+ pw.println(" --wallpaperBlurRadius radius");
+ pw.println(" Blur radius for 'wallpaper' letterbox background. If radius <= 0");
+ pw.println(" both it and R.dimen.config_letterboxBackgroundWallpaperBlurRadius");
+ pw.println(" are ignored and 0 is used.");
+ pw.println(" --wallpaperDarkScrimAlpha alpha");
+ pw.println(" Alpha of a black translucent scrim shown over 'wallpaper'");
+ pw.println(" letterbox background. If alpha < 0 or >= 1 both it and");
+ pw.println(" R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha are ignored");
+ pw.println(" and 0.0 (transparent) is used instead.");
+ pw.println(" --horizontalPositionMultiplier multiplier");
+ pw.println(" Horizontal position of app window center. If multiplier < 0 or > 1,");
+ pw.println(" both it and R.dimen.config_letterboxHorizontalPositionMultiplier");
+ pw.println(" are ignored and central position (0.5) is used.");
+ pw.println(" reset-letterbox-style [aspectRatio|cornerRadius|backgroundType");
+ pw.println(" |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha");
+ pw.println(" |horizontalPositionMultiplier]");
+ pw.println(" Resets overrides to default values for specified properties separated");
+ pw.println(" by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'.");
+ pw.println(" If no arguments provided, all values will be reset.");
+ pw.println(" get-letterbox-style");
+ pw.println(" Prints letterbox style configuration.");
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 2e37fee..9382b8e 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -36,6 +36,7 @@
import android.app.WindowConfiguration;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
+import android.graphics.GraphicBuffer;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.Binder;
@@ -45,7 +46,6 @@
import android.os.RemoteException;
import android.util.ArraySet;
import android.util.Slog;
-import android.view.Surface;
import android.view.SurfaceControl;
import android.window.IDisplayAreaOrganizerController;
import android.window.ITaskOrganizerController;
@@ -766,18 +766,21 @@
return false;
}
+ GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer(
+ buffer.getHardwareBuffer());
SurfaceControl screenshot = mService.mWindowManager.mSurfaceControlFactory.apply(null)
.setName(wc.getName() + " - Organizer Screenshot")
- .setBufferSize(bounds.width(), bounds.height())
.setFormat(PixelFormat.TRANSLUCENT)
.setParent(wc.getParentSurfaceControl())
+ .setSecure(buffer.containsSecureLayers())
.setCallsite("WindowOrganizerController.takeScreenshot")
+ .setBLASTLayer()
.build();
- Surface surface = new Surface();
- surface.copyFrom(screenshot);
- surface.attachAndQueueBufferWithColorSpace(buffer.getHardwareBuffer(), null);
- surface.release();
+ SurfaceControl.Transaction transaction = mService.mWindowManager.mTransactionFactory.get();
+ transaction.setBuffer(screenshot, graphicBuffer);
+ transaction.setColorSpace(screenshot, buffer.getColorSpace());
+ transaction.apply();
outSurfaceControl.copyFrom(screenshot, "WindowOrganizerController.takeScreenshot");
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 46d923b..1a5042f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1140,7 +1140,7 @@
void attach() {
if (DEBUG) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
- mSession.windowAddedLocked(mAttrs.packageName);
+ mSession.windowAddedLocked();
}
/**
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index a99679a..74fbb42 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -190,7 +190,6 @@
shared_libs: [
"libarcbridge",
"libarcbridgeservice",
- "libarctimer",
"libbase",
"libcap",
"libchrome",
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index cf9b88a..6283b4e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -96,6 +96,7 @@
import static android.app.admin.DevicePolicyManager.PROVISIONING_RESULT_SETTING_PROFILE_OWNER_FAILED;
import static android.app.admin.DevicePolicyManager.PROVISIONING_RESULT_SET_DEVICE_OWNER_FAILED;
import static android.app.admin.DevicePolicyManager.PROVISIONING_RESULT_STARTING_PROFILE_FAILED;
+import static android.app.admin.DevicePolicyManager.STATE_USER_UNMANAGED;
import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE;
import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA;
@@ -8735,7 +8736,8 @@
final CallerIdentity caller = getCallerIdentity();
if (userHandle != mOwners.getDeviceOwnerUserId() && !mOwners.hasProfileOwner(userHandle)
- && getManagedUserId(userHandle) == -1) {
+ && getManagedUserId(userHandle) == -1
+ && newState != STATE_USER_UNMANAGED) {
// No managed device, user or profile, so setting provisioning state makes no sense.
throw new IllegalStateException("Not allowed to change provisioning state unless a "
+ "device or profile owner is set.");
@@ -8798,6 +8800,12 @@
case DevicePolicyManager.STATE_USER_SETUP_FINALIZED:
// Cannot transition out of finalized.
break;
+ case DevicePolicyManager.STATE_USER_PROFILE_FINALIZED:
+ // Should only move to an unmanaged state after removing the work profile.
+ if (newState == DevicePolicyManager.STATE_USER_UNMANAGED) {
+ return;
+ }
+ break;
}
// Didn't meet any of the accepted state transition checks above, throw appropriate error.
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 9f24d9a..d913d4e 100644
--- a/services/people/java/com/android/server/people/data/DataManager.java
+++ b/services/people/java/com/android/server/people/data/DataManager.java
@@ -111,7 +111,8 @@
private static final long RECENT_NOTIFICATIONS_MAX_AGE_MS = 10 * DateUtils.DAY_IN_MILLIS;
private static final long QUERY_EVENTS_MAX_AGE_MS = 5L * DateUtils.MINUTE_IN_MILLIS;
private static final long USAGE_STATS_QUERY_INTERVAL_SEC = 120L;
- @VisibleForTesting static final int MAX_CACHED_RECENT_SHORTCUTS = 30;
+ @VisibleForTesting
+ static final int MAX_CACHED_RECENT_SHORTCUTS = 30;
private final Context mContext;
private final Injector mInjector;
@@ -256,14 +257,23 @@
@Nullable
private ConversationChannel getConversationChannel(String packageName, int userId,
String shortcutId, ConversationInfo conversationInfo) {
+ ShortcutInfo shortcutInfo = getShortcut(packageName, userId, shortcutId);
+ return getConversationChannel(shortcutInfo, conversationInfo);
+ }
+
+ @Nullable
+ private ConversationChannel getConversationChannel(ShortcutInfo shortcutInfo,
+ ConversationInfo conversationInfo) {
if (conversationInfo == null) {
return null;
}
- ShortcutInfo shortcutInfo = getShortcut(packageName, userId, shortcutId);
if (shortcutInfo == null) {
- Slog.e(TAG, " Shortcut no longer found: " + shortcutId);
+ Slog.e(TAG, " Shortcut no longer found");
return null;
}
+ String packageName = shortcutInfo.getPackage();
+ String shortcutId = shortcutInfo.getId();
+ int userId = shortcutInfo.getUserId();
int uid = mPackageManagerInternal.getPackageUid(packageName, 0, userId);
NotificationChannel parentChannel =
mNotificationManagerInternal.getNotificationChannel(packageName, uid,
@@ -363,7 +373,9 @@
}
}
builder.setStatuses(newStatuses);
- cs.addOrUpdate(builder.build());
+ updateConversationStoreThenNotifyListeners(cs, builder.build(),
+ packageData.getPackageName(),
+ packageData.getUserId());
});
});
}
@@ -397,11 +409,7 @@
ConversationInfo convToModify = getConversationInfoOrThrow(cs, conversationId);
ConversationInfo.Builder builder = new ConversationInfo.Builder(convToModify);
builder.addOrUpdateStatus(status);
- ConversationInfo modifiedConv = builder.build();
- cs.addOrUpdate(modifiedConv);
- ConversationChannel conversation = getConversationChannel(packageName, userId,
- conversationId, modifiedConv);
- notifyConversationsListeners(Arrays.asList(conversation));
+ updateConversationStoreThenNotifyListeners(cs, builder.build(), packageName, userId);
if (status.getEndTimeMillis() >= 0) {
mStatusExpReceiver.scheduleExpiration(
@@ -416,7 +424,7 @@
ConversationInfo convToModify = getConversationInfoOrThrow(cs, conversationId);
ConversationInfo.Builder builder = new ConversationInfo.Builder(convToModify);
builder.clearStatus(statusId);
- cs.addOrUpdate(builder.build());
+ updateConversationStoreThenNotifyListeners(cs, builder.build(), packageName, userId);
}
public void clearStatuses(String packageName, int userId, String conversationId) {
@@ -424,7 +432,7 @@
ConversationInfo convToModify = getConversationInfoOrThrow(cs, conversationId);
ConversationInfo.Builder builder = new ConversationInfo.Builder(convToModify);
builder.setStatuses(null);
- cs.addOrUpdate(builder.build());
+ updateConversationStoreThenNotifyListeners(cs, builder.build(), packageName, userId);
}
public @NonNull List<ConversationStatus> getStatuses(String packageName, int userId,
@@ -882,7 +890,8 @@
}
}
}
- conversationStore.addOrUpdate(builder.build());
+ updateConversationStoreThenNotifyListeners(conversationStore, builder.build(),
+ shortcutInfo);
}
@VisibleForTesting
@@ -945,6 +954,7 @@
conversationSelector.mConversationStore =
packageData.getConversationStore();
conversationSelector.mConversationInfo = ci;
+ conversationSelector.mPackageName = packageData.getPackageName();
}
});
if (conversationSelector.mConversationInfo == null) {
@@ -955,13 +965,16 @@
new ConversationInfo.Builder(conversationSelector.mConversationInfo);
builder.setContactStarred(helper.isStarred());
builder.setContactPhoneNumber(helper.getPhoneNumber());
- conversationSelector.mConversationStore.addOrUpdate(builder.build());
+ updateConversationStoreThenNotifyListeners(conversationSelector.mConversationStore,
+ builder.build(),
+ conversationSelector.mPackageName, userId);
mLastUpdatedTimestamp = helper.getLastUpdatedTimestamp();
}
private class ConversationSelector {
private ConversationStore mConversationStore = null;
private ConversationInfo mConversationInfo = null;
+ private String mPackageName = null;
}
}
@@ -1140,6 +1153,7 @@
.setLastEventTimestamp(sbn.getPostTime())
.setParentNotificationChannelId(sbn.getNotification().getChannelId())
.build();
+ // Don't update listeners on notifications posted.
packageData.getConversationStore().addOrUpdate(updated);
EventHistoryImpl eventHistory = packageData.getEventStore().getOrCreateEventHistory(
@@ -1215,7 +1229,8 @@
builder.setBubbled(false);
break;
}
- conversationStore.addOrUpdate(builder.build());
+ updateConversationStoreThenNotifyListeners(conversationStore, builder.build(), pkg,
+ packageData.getUserId());
}
synchronized boolean hasActiveNotifications(String packageName, String shortcutId) {
@@ -1253,7 +1268,9 @@
ConversationInfo updated = new ConversationInfo.Builder(conversationInfo)
.setLastEventTimestamp(event.getTimestamp())
.build();
- packageData.getConversationStore().addOrUpdate(updated);
+ updateConversationStoreThenNotifyListeners(packageData.getConversationStore(),
+ updated,
+ packageData.getPackageName(), packageData.getUserId());
}
}
}
@@ -1266,7 +1283,27 @@
}
}
- // TODO(b/178792356): Trigger ConversationsListener on all-related data changes.
+ private void updateConversationStoreThenNotifyListeners(ConversationStore cs,
+ ConversationInfo modifiedConv,
+ String packageName, int userId) {
+ cs.addOrUpdate(modifiedConv);
+ ConversationChannel channel = getConversationChannel(packageName, userId,
+ modifiedConv.getShortcutId(), modifiedConv);
+ if (channel != null) {
+ notifyConversationsListeners(Arrays.asList(channel));
+ }
+ }
+
+ private void updateConversationStoreThenNotifyListeners(ConversationStore cs,
+ ConversationInfo modifiedConv, ShortcutInfo shortcutInfo) {
+ cs.addOrUpdate(modifiedConv);
+ ConversationChannel channel = getConversationChannel(shortcutInfo, modifiedConv);
+ if (channel != null) {
+ notifyConversationsListeners(Arrays.asList(channel));
+ }
+ }
+
+
@VisibleForTesting
void notifyConversationsListeners(
@Nullable final List<ConversationChannel> changedConversations) {
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt
index 2d852e5..886b2e0 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt
@@ -338,6 +338,7 @@
whenever(readUserState(0)) { PackageUserState() }
whenever(readUserState(1)) { PackageUserState() }
whenever(getInstantApp(anyInt())) { false }
+ whenever(isSystem()) { false }
}
}
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerApiTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerApiTest.kt
index 3838f68..0fe3913 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerApiTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerApiTest.kt
@@ -527,6 +527,7 @@
whenever(firstInstallTime) { 0L }
whenever(readUserState(0)) { pkgUserState0() }
whenever(readUserState(1)) { pkgUserState1() }
+ whenever(isSystem()) { false }
}
private fun DomainVerificationService.addPackages(vararg pkgSettings: PackageSetting) =
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationPackageTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationPackageTest.kt
index 1097c45..8540b8a 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationPackageTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationPackageTest.kt
@@ -101,6 +101,70 @@
}
@Test
+ fun addPackageSystemConfigured() {
+ val pkg1 = mockPkgSetting(PKG_ONE, UUID_ONE, SIGNATURE_ONE, isSystemApp = false)
+ val pkg2 = mockPkgSetting(PKG_TWO, UUID_TWO, SIGNATURE_TWO, isSystemApp = true)
+
+ val service = makeService(
+ systemConfiguredPackageNames = ArraySet(setOf(pkg1.getName(), pkg2.getName())),
+ pkg1, pkg2
+ )
+ service.addPackage(pkg1)
+ service.addPackage(pkg2)
+
+ service.getInfo(pkg1.getName()).apply {
+ assertThat(packageName).isEqualTo(pkg1.getName())
+ assertThat(identifier).isEqualTo(pkg1.domainSetId)
+ assertThat(hostToStateMap).containsExactlyEntriesIn(
+ mapOf(
+ DOMAIN_1 to STATE_NO_RESPONSE,
+ DOMAIN_2 to STATE_NO_RESPONSE,
+ )
+ )
+ }
+
+ service.getUserState(pkg1.getName()).apply {
+ assertThat(packageName).isEqualTo(pkg1.getName())
+ assertThat(identifier).isEqualTo(pkg1.domainSetId)
+ assertThat(isLinkHandlingAllowed).isEqualTo(true)
+ assertThat(user.identifier).isEqualTo(USER_ID)
+ assertThat(hostToStateMap).containsExactlyEntriesIn(
+ mapOf(
+ DOMAIN_1 to DOMAIN_STATE_NONE,
+ DOMAIN_2 to DOMAIN_STATE_NONE,
+ )
+ )
+ }
+
+ service.getInfo(pkg2.getName()).apply {
+ assertThat(packageName).isEqualTo(pkg2.getName())
+ assertThat(identifier).isEqualTo(pkg2.domainSetId)
+ assertThat(hostToStateMap).containsExactlyEntriesIn(
+ mapOf(
+ DOMAIN_1 to STATE_UNMODIFIABLE,
+ DOMAIN_2 to STATE_UNMODIFIABLE,
+ )
+ )
+ }
+
+ service.getUserState(pkg2.getName()).apply {
+ assertThat(packageName).isEqualTo(pkg2.getName())
+ assertThat(identifier).isEqualTo(pkg2.domainSetId)
+ assertThat(isLinkHandlingAllowed).isEqualTo(true)
+ assertThat(user.identifier).isEqualTo(USER_ID)
+ assertThat(hostToStateMap).containsExactlyEntriesIn(
+ mapOf(
+ DOMAIN_1 to DOMAIN_STATE_VERIFIED,
+ DOMAIN_2 to DOMAIN_STATE_VERIFIED,
+ )
+ )
+ }
+
+ assertThat(service.queryValidVerificationPackageNames())
+ .containsExactly(pkg1.getName(), pkg2.getName())
+ }
+
+ @Test
fun addPackageRestoredMatchingSignature() {
// language=XML
val xml = """
@@ -457,42 +521,52 @@
getDomainVerificationUserState(pkgName, USER_ID)
.also { assertThat(it).isNotNull() }!!
+ private fun makeService(
+ systemConfiguredPackageNames: ArraySet<String> = ArraySet(),
+ vararg pkgSettings: PackageSetting
+ ) = makeService(systemConfiguredPackageNames = systemConfiguredPackageNames) {
+ pkgName -> pkgSettings.find { pkgName == it.getName() }
+ }
+
private fun makeService(vararg pkgSettings: PackageSetting) =
- makeService { pkgName -> pkgSettings.find { pkgName == it.getName()} }
+ makeService { pkgName -> pkgSettings.find { pkgName == it.getName() } }
- private fun makeService(pkgSettingFunction: (String) -> PackageSetting? = { null }) =
- DomainVerificationService(mockThrowOnUnmocked {
- // Assume the test has every permission necessary
- whenever(enforcePermission(anyString(), anyInt(), anyInt(), anyString()))
- whenever(checkPermission(anyString(), anyInt(), anyInt())) {
- PackageManager.PERMISSION_GRANTED
- }
- }, mockThrowOnUnmocked {
- whenever(linkedApps) { ArraySet<String>() }
- }, mockThrowOnUnmocked {
- whenever(isChangeEnabledInternalNoLogging(anyLong(), any())) { true }
- }).apply {
- setConnection(mockThrowOnUnmocked {
- whenever(filterAppAccess(anyString(), anyInt(), anyInt())) { false }
- whenever(doesUserExist(0)) { true }
- whenever(doesUserExist(1)) { true }
- whenever(scheduleWriteSettings())
-
- // Need to provide an internal UID so some permission checks are ignored
- whenever(callingUid) { Process.ROOT_UID }
- whenever(callingUserId) { 0 }
-
- mockPackageSettings {
- pkgSettingFunction(it)
- }
- })
+ private fun makeService(
+ systemConfiguredPackageNames: ArraySet<String> = ArraySet(),
+ pkgSettingFunction: (String) -> PackageSetting? = { null }
+ ) = DomainVerificationService(mockThrowOnUnmocked {
+ // Assume the test has every permission necessary
+ whenever(enforcePermission(anyString(), anyInt(), anyInt(), anyString()))
+ whenever(checkPermission(anyString(), anyInt(), anyInt())) {
+ PackageManager.PERMISSION_GRANTED
}
+ }, mockThrowOnUnmocked {
+ whenever(this.linkedApps) { systemConfiguredPackageNames }
+ }, mockThrowOnUnmocked {
+ whenever(isChangeEnabledInternalNoLogging(anyLong(), any())) { true }
+ }).apply {
+ setConnection(mockThrowOnUnmocked {
+ whenever(filterAppAccess(anyString(), anyInt(), anyInt())) { false }
+ whenever(doesUserExist(0)) { true }
+ whenever(doesUserExist(1)) { true }
+ whenever(scheduleWriteSettings())
+
+ // Need to provide an internal UID so some permission checks are ignored
+ whenever(callingUid) { Process.ROOT_UID }
+ whenever(callingUserId) { 0 }
+
+ mockPackageSettings {
+ pkgSettingFunction(it)
+ }
+ })
+ }
private fun mockPkgSetting(
pkgName: String,
domainSetId: UUID,
signature: String,
- domains: List<String> = listOf(DOMAIN_1, DOMAIN_2)
+ domains: List<String> = listOf(DOMAIN_1, DOMAIN_2),
+ isSystemApp: Boolean = false
) = mockThrowOnUnmocked<PackageSetting> {
val pkg = mockThrowOnUnmocked<AndroidPackage> {
whenever(packageName) { pkgName }
@@ -528,5 +602,6 @@
whenever(firstInstallTime) { 0L }
whenever(readUserState(USER_ID)) { PackageUserState() }
whenever(signatures) { arrayOf(Signature(signature)) }
+ whenever(isSystem) { isSystemApp }
}
}
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt
index 26e8d28..6a75795 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt
@@ -238,6 +238,7 @@
whenever(readUserState(0)) { PackageUserState() }
whenever(readUserState(10)) { PackageUserState() }
whenever(getInstantApp(anyInt())) { false }
+ whenever(isSystem()) { false }
}
}
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationUserSelectionOverrideTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationUserSelectionOverrideTest.kt
index 52ae7a5..3e2853c 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationUserSelectionOverrideTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationUserSelectionOverrideTest.kt
@@ -145,6 +145,7 @@
whenever(firstInstallTime) { 0L }
whenever(readUserState(0)) { PackageUserState() }
whenever(readUserState(1)) { PackageUserState() }
+ whenever(isSystem()) { false }
}
@Test
diff --git a/services/tests/mockingservicestests/AndroidManifest.xml b/services/tests/mockingservicestests/AndroidManifest.xml
index e4b650c..17a5dcc 100644
--- a/services/tests/mockingservicestests/AndroidManifest.xml
+++ b/services/tests/mockingservicestests/AndroidManifest.xml
@@ -28,6 +28,8 @@
<uses-permission android:name="android.permission.MANAGE_APPOPS"/>
<uses-permission android:name="android.permission.MONITOR_DEVICE_CONFIG_ACCESS"/>
<uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG"/>
+ <uses-permission
+ android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"/>
<!-- needed by MasterClearReceiverTest to display a system dialog -->
<uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"/>
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 7654093..d55bbd1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -468,8 +468,9 @@
TEST_CALLING_UID);
}
- private void setPrioritizedAlarm(int type, long triggerTime, IAlarmListener listener) {
- mService.setImpl(type, triggerTime, WINDOW_EXACT, 0, null, listener, "test",
+ private void setPrioritizedAlarm(int type, long triggerTime, long windowLength,
+ IAlarmListener listener) {
+ mService.setImpl(type, triggerTime, windowLength, 0, null, listener, "test",
FLAG_STANDALONE | FLAG_PRIORITIZE, null, null, TEST_CALLING_UID,
TEST_CALLING_PACKAGE, null);
}
@@ -1685,7 +1686,7 @@
final int numAlarms = 10;
for (int i = 0; i < numAlarms; i++) {
setPrioritizedAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i,
- new IAlarmListener.Stub() {
+ 0, new IAlarmListener.Stub() {
@Override
public void doAlarm(IAlarmCompleteListener callback)
throws RemoteException {
@@ -1720,7 +1721,7 @@
final int numAlarms = 10;
for (int i = 0; i < numAlarms; i++) {
setPrioritizedAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i,
- new IAlarmListener.Stub() {
+ 0, new IAlarmListener.Stub() {
@Override
public void doAlarm(IAlarmCompleteListener callback)
throws RemoteException {
@@ -1738,12 +1739,12 @@
}
assertEquals(numAlarms, alarmsFired.get());
- setPrioritizedAlarm(ELAPSED_REALTIME_WAKEUP, idleUntil - 3, new IAlarmListener.Stub() {
+ setPrioritizedAlarm(ELAPSED_REALTIME_WAKEUP, idleUntil - 3, 0, new IAlarmListener.Stub() {
@Override
public void doAlarm(IAlarmCompleteListener callback) throws RemoteException {
}
});
- setPrioritizedAlarm(ELAPSED_REALTIME_WAKEUP, idleUntil - 2, new IAlarmListener.Stub() {
+ setPrioritizedAlarm(ELAPSED_REALTIME_WAKEUP, idleUntil - 2, 0, new IAlarmListener.Stub() {
@Override
public void doAlarm(IAlarmCompleteListener callback) throws RemoteException {
}
@@ -2263,6 +2264,28 @@
}
@Test
+ public void minWindowPriorityAlarm() {
+ doReturn(true).when(
+ () -> CompatChanges.isChangeEnabled(
+ eq(AlarmManager.ENFORCE_MINIMUM_WINDOW_ON_INEXACT_ALARMS),
+ anyString(), any(UserHandle.class)));
+ final long minWindow = 73;
+ setDeviceConfigLong(KEY_MIN_WINDOW, minWindow);
+
+ // 0 is WINDOW_EXACT and < 0 is WINDOW_HEURISTIC.
+ for (int window = 1; window <= minWindow; window++) {
+ setPrioritizedAlarm(ELAPSED_REALTIME, 0, window, new IAlarmListener.Stub() {
+ @Override
+ public void doAlarm(IAlarmCompleteListener callback) throws RemoteException {
+ }
+ });
+ assertEquals(1, mService.mAlarmStore.size());
+ final Alarm a = mService.mAlarmStore.remove(unused -> true).get(0);
+ assertEquals(window, a.windowLength);
+ }
+ }
+
+ @Test
public void denyListPackagesAdded() {
mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[]{"p1", "p2", "p3"});
setDeviceConfigString(KEY_EXACT_ALARM_DENY_LIST, "p2,p4,p5");
diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
new file mode 100644
index 0000000..a8d8a90
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
@@ -0,0 +1,488 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.app;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
+
+import android.Manifest;
+import android.app.GameManager;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.platform.test.annotations.Presubmit;
+import android.provider.DeviceConfig;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.function.Supplier;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class GameManagerServiceTests {
+ @Mock MockContext mMockContext;
+ private static final String TAG = "GameServiceTests";
+ private static final String PACKAGE_NAME_INVALID = "com.android.app";
+ private static final int USER_ID_1 = 1001;
+ private static final int USER_ID_2 = 1002;
+
+ private MockitoSession mMockingSession;
+ private String mPackageName;
+ @Mock
+ private PackageManager mMockPackageManager;
+
+ // Stolen from ConnectivityServiceTest.MockContext
+ class MockContext extends ContextWrapper {
+ private static final String TAG = "MockContext";
+
+ // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant
+ private final HashMap<String, Integer> mMockedPermissions = new HashMap<>();
+
+ MockContext(Context base) {
+ super(base);
+ }
+
+ /**
+ * Mock checks for the specified permission, and have them behave as per {@code granted}.
+ *
+ * <p>Passing null reverts to default behavior, which does a real permission check on the
+ * test package.
+ *
+ * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or
+ * {@link PackageManager#PERMISSION_DENIED}.
+ */
+ public void setPermission(String permission, Integer granted) {
+ mMockedPermissions.put(permission, granted);
+ }
+
+ private int checkMockedPermission(String permission, Supplier<Integer> ifAbsent) {
+ final Integer granted = mMockedPermissions.get(permission);
+ return granted != null ? granted : ifAbsent.get();
+ }
+
+ @Override
+ public int checkPermission(String permission, int pid, int uid) {
+ return checkMockedPermission(
+ permission, () -> super.checkPermission(permission, pid, uid));
+ }
+
+ @Override
+ public int checkCallingOrSelfPermission(String permission) {
+ return checkMockedPermission(
+ permission, () -> super.checkCallingOrSelfPermission(permission));
+ }
+
+ @Override
+ public void enforceCallingOrSelfPermission(String permission, String message) {
+ final Integer granted = mMockedPermissions.get(permission);
+ if (granted == null) {
+ super.enforceCallingOrSelfPermission(permission, message);
+ return;
+ }
+
+ if (!granted.equals(PackageManager.PERMISSION_GRANTED)) {
+ throw new SecurityException("[Test] permission denied: " + permission);
+ }
+ }
+
+ @Override
+ public PackageManager getPackageManager() {
+ return mMockPackageManager;
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ mMockingSession = mockitoSession()
+ .initMocks(this)
+ .mockStatic(DeviceConfig.class)
+ .strictness(Strictness.WARN)
+ .startMocking();
+ mMockContext = new MockContext(InstrumentationRegistry.getContext());
+ mPackageName = mMockContext.getPackageName();
+ final ApplicationInfo applicationInfo = new ApplicationInfo();
+ applicationInfo.category = ApplicationInfo.CATEGORY_GAME;
+ final PackageInfo pi = new PackageInfo();
+ pi.packageName = mPackageName;
+ final List<PackageInfo> packages = new ArrayList<>();
+ packages.add(pi);
+ when(mMockPackageManager.getInstalledPackages(anyInt())).thenReturn(packages);
+ when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
+ .thenReturn(applicationInfo);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (mMockingSession != null) {
+ mMockingSession.finishMocking();
+ }
+ }
+
+ private void mockModifyGameModeGranted() {
+ mMockContext.setPermission(Manifest.permission.MANAGE_GAME_MODE,
+ PackageManager.PERMISSION_GRANTED);
+ }
+
+ private void mockModifyGameModeDenied() {
+ mMockContext.setPermission(Manifest.permission.MANAGE_GAME_MODE,
+ PackageManager.PERMISSION_DENIED);
+ }
+
+ private void mockDeviceConfigDefault() {
+ DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
+ DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, "").build();
+ when(DeviceConfig.getProperties(anyString(), anyString()))
+ .thenReturn(properties);
+ }
+
+ private void mockDeviceConfigNone() {
+ DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
+ DeviceConfig.NAMESPACE_GAME_OVERLAY).build();
+ when(DeviceConfig.getProperties(anyString(), anyString()))
+ .thenReturn(properties);
+ }
+
+ private void mockDeviceConfigPerformance() {
+ String configString = "mode=2,downscaleFactor=0.5";
+ DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
+ DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, configString).build();
+ when(DeviceConfig.getProperties(anyString(), anyString()))
+ .thenReturn(properties);
+ }
+
+ private void mockDeviceConfigBattery() {
+ String configString = "mode=3,downscaleFactor=0.7";
+ DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
+ DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, configString).build();
+ when(DeviceConfig.getProperties(anyString(), anyString()))
+ .thenReturn(properties);
+ }
+
+ private void mockDeviceConfigAll() {
+ String configString = "mode=3,downscaleFactor=0.7:mode=2,downscaleFactor=0.5";
+ DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
+ DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, configString).build();
+ when(DeviceConfig.getProperties(anyString(), anyString()))
+ .thenReturn(properties);
+ }
+
+ private void mockDeviceConfigInvalid() {
+ String configString = "mode=2,downscaleFactor=0.55";
+ DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
+ DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, configString).build();
+ when(DeviceConfig.getProperties(anyString(), anyString()))
+ .thenReturn(properties);
+ }
+
+ private void mockDeviceConfigMalformed() {
+ String configString = "adsljckv=nin3rn9hn1231245:8795tq=21ewuydg";
+ DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
+ DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, configString).build();
+ when(DeviceConfig.getProperties(anyString(), anyString()))
+ .thenReturn(properties);
+ }
+
+ /**
+ * By default game mode is not supported.
+ */
+ @Test
+ public void testGameModeDefaultValue() {
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.onUserStarting(USER_ID_1);
+
+ mockModifyGameModeGranted();
+
+ assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
+ gameManagerService.getGameMode(mPackageName, USER_ID_1));
+ }
+
+ /**
+ * Test the default behaviour for a nonexistent user.
+ */
+ @Test
+ public void testDefaultValueForNonexistentUser() {
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.onUserStarting(USER_ID_1);
+
+ mockModifyGameModeGranted();
+
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_2);
+ assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
+ gameManagerService.getGameMode(mPackageName, USER_ID_2));
+ }
+
+ /**
+ * Test getter and setter of game modes.
+ */
+ @Test
+ public void testGameMode() {
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.onUserStarting(USER_ID_1);
+
+ mockModifyGameModeGranted();
+
+ assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
+ gameManagerService.getGameMode(mPackageName, USER_ID_1));
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
+ assertEquals(GameManager.GAME_MODE_STANDARD,
+ gameManagerService.getGameMode(mPackageName, USER_ID_1));
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE,
+ USER_ID_1);
+ assertEquals(GameManager.GAME_MODE_PERFORMANCE,
+ gameManagerService.getGameMode(mPackageName, USER_ID_1));
+ }
+
+ /**
+ * Test permission.MANAGE_GAME_MODE is checked
+ */
+ @Test
+ public void testGetGameModeInvalidPackageName() {
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.onUserStarting(USER_ID_1);
+ try {
+ assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
+ gameManagerService.getGameMode(PACKAGE_NAME_INVALID,
+ USER_ID_1));
+
+ fail("GameManagerService failed to generate SecurityException when "
+ + "permission.MANAGE_GAME_MODE is not granted.");
+ } catch (SecurityException ignored) {
+ }
+
+ // The test should throw an exception, so the test is passing if we get here.
+ }
+
+ /**
+ * Test permission.MANAGE_GAME_MODE is checked
+ */
+ @Test
+ public void testSetGameModePermissionDenied() {
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.onUserStarting(USER_ID_1);
+
+ // Update the game mode so we can read back something valid.
+ mockModifyGameModeGranted();
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
+ assertEquals(GameManager.GAME_MODE_STANDARD,
+ gameManagerService.getGameMode(mPackageName, USER_ID_1));
+
+ // Deny permission.MANAGE_GAME_MODE and verify the game mode is not updated.
+ mockModifyGameModeDenied();
+ try {
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE,
+ USER_ID_1);
+
+ fail("GameManagerService failed to generate SecurityException when "
+ + "permission.MANAGE_GAME_MODE is denied.");
+ } catch (SecurityException ignored) {
+ }
+
+ // The test should throw an exception, so the test is passing if we get here.
+ mockModifyGameModeGranted();
+ // Verify that the Game Mode value wasn't updated.
+ assertEquals(GameManager.GAME_MODE_STANDARD,
+ gameManagerService.getGameMode(mPackageName, USER_ID_1));
+ }
+
+ /**
+ * Test game modes are user-specific.
+ */
+ @Test
+ public void testGameModeMultipleUsers() {
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.onUserStarting(USER_ID_1);
+ gameManagerService.onUserStarting(USER_ID_2);
+
+ mockModifyGameModeGranted();
+
+ // Set User 1 to Standard
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
+ assertEquals(GameManager.GAME_MODE_STANDARD,
+ gameManagerService.getGameMode(mPackageName, USER_ID_1));
+
+ // Set User 2 to Performance and verify User 1 is still Standard
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE,
+ USER_ID_2);
+ assertEquals(GameManager.GAME_MODE_PERFORMANCE,
+ gameManagerService.getGameMode(mPackageName, USER_ID_2));
+ assertEquals(GameManager.GAME_MODE_STANDARD,
+ gameManagerService.getGameMode(mPackageName, USER_ID_1));
+
+ // Set User 1 to Battery and verify User 2 is still Performance
+ gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_BATTERY,
+ USER_ID_1);
+ assertEquals(GameManager.GAME_MODE_BATTERY,
+ gameManagerService.getGameMode(mPackageName, USER_ID_1));
+ assertEquals(GameManager.GAME_MODE_PERFORMANCE,
+ gameManagerService.getGameMode(mPackageName, USER_ID_2));
+ }
+
+ /**
+ * Phonesky device config exists, but is only propagating the default value.
+ */
+ @Test
+ public void testDeviceConfigDefault() {
+ mockDeviceConfigDefault();
+ mockModifyGameModeGranted();
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.onUserStarting(USER_ID_1);
+ gameManagerService.loadDeviceConfigLocked();
+
+ int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
+ assertEquals(modes.length, 1);
+ assertEquals(modes[0], GameManager.GAME_MODE_UNSUPPORTED);
+ }
+
+ /**
+ * Phonesky device config does not exists.
+ */
+ @Test
+ public void testDeviceConfigNone() {
+ mockDeviceConfigNone();
+ mockModifyGameModeGranted();
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.onUserStarting(USER_ID_1);
+ gameManagerService.loadDeviceConfigLocked();
+
+ int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
+ assertEquals(modes.length, 1);
+ assertEquals(modes[0], GameManager.GAME_MODE_UNSUPPORTED);
+ }
+
+ /**
+ * Phonesky device config for performance mode exists and is valid.
+ */
+ @Test
+ public void testDeviceConfigPerformance() {
+ mockDeviceConfigPerformance();
+ mockModifyGameModeGranted();
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.onUserStarting(USER_ID_1);
+ gameManagerService.loadDeviceConfigLocked();
+
+ boolean perfModeExists = false;
+ int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
+ for (int mode : modes) {
+ if (mode == GameManager.GAME_MODE_PERFORMANCE) {
+ perfModeExists = true;
+ }
+ }
+ assertEquals(modes.length, 1);
+ assertTrue(perfModeExists);
+ }
+
+ /**
+ * Phonesky device config for battery mode exists and is valid.
+ */
+ @Test
+ public void testDeviceConfigBattery() {
+ mockDeviceConfigBattery();
+ mockModifyGameModeGranted();
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.onUserStarting(USER_ID_1);
+ gameManagerService.loadDeviceConfigLocked();
+
+ boolean batteryModeExists = false;
+ int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
+ for (int mode : modes) {
+ if (mode == GameManager.GAME_MODE_BATTERY) {
+ batteryModeExists = true;
+ }
+ }
+ assertEquals(modes.length, 1);
+ assertTrue(batteryModeExists);
+ }
+
+ /**
+ * Phonesky device configs for both battery and performance modes exists and are valid.
+ */
+ @Test
+ public void testDeviceConfigAll() {
+ mockDeviceConfigAll();
+ mockModifyGameModeGranted();
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.onUserStarting(USER_ID_1);
+ gameManagerService.loadDeviceConfigLocked();
+
+ boolean batteryModeExists = false;
+ boolean perfModeExists = false;
+ int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
+ for (int mode : modes) {
+ if (mode == GameManager.GAME_MODE_BATTERY) {
+ batteryModeExists = true;
+ } else if (mode == GameManager.GAME_MODE_PERFORMANCE) {
+ perfModeExists = true;
+ }
+ }
+ assertTrue(batteryModeExists);
+ assertTrue(perfModeExists);
+ }
+
+ /**
+ * Phonesky device config contains values that parse correctly but are not valid in game mode.
+ */
+ @Test
+ public void testDeviceConfigInvalid() {
+ mockDeviceConfigInvalid();
+ mockModifyGameModeGranted();
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.onUserStarting(USER_ID_1);
+ gameManagerService.loadDeviceConfigLocked();
+
+ int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
+ assertEquals(modes.length, 1);
+ assertEquals(modes[0], GameManager.GAME_MODE_UNSUPPORTED);
+ }
+
+ /**
+ * Phonesky device config is garbage.
+ */
+ @Test
+ public void testDeviceConfigMalformed() {
+ mockDeviceConfigMalformed();
+ mockModifyGameModeGranted();
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.onUserStarting(USER_ID_1);
+ gameManagerService.loadDeviceConfigLocked();
+
+ int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
+ assertEquals(modes.length, 1);
+ assertEquals(modes[0], GameManager.GAME_MODE_UNSUPPORTED);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index bcc756a..2a5bb18 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -157,7 +157,7 @@
new Object(),
mMockSecurityPolicy,
mMockSystemSupport,
- mA11yms,
+ mA11yms.getTraceManager(),
mMockWindowManagerService,
mMockSystemActionPerformer,
mMockA11yWindowManager,
diff --git a/services/tests/servicestests/src/com/android/server/app/GameManagerServiceTests.java b/services/tests/servicestests/src/com/android/server/app/GameManagerServiceTests.java
deleted file mode 100644
index edc0d46..0000000
--- a/services/tests/servicestests/src/com/android/server/app/GameManagerServiceTests.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.app;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.Manifest;
-import android.app.GameManager;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.pm.PackageManager;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-
-import java.util.HashMap;
-import java.util.function.Supplier;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-@Presubmit
-public class GameManagerServiceTests {
-
- private static final String TAG = "GameServiceTests";
- private static final String PACKAGE_NAME_INVALID = "com.android.app";
- private static final int USER_ID_1 = 1001;
- private static final int USER_ID_2 = 1002;
-
- // Stolen from ConnectivityServiceTest.MockContext
- static class MockContext extends ContextWrapper {
- private static final String TAG = "MockContext";
-
- // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant
- private final HashMap<String, Integer> mMockedPermissions = new HashMap<>();
-
- @Mock
- private final MockPackageManager mMockPackageManager;
-
- MockContext(Context base) {
- super(base);
- mMockPackageManager = new MockPackageManager();
- }
-
- /**
- * Mock checks for the specified permission, and have them behave as per {@code granted}.
- *
- * <p>Passing null reverts to default behavior, which does a real permission check on the
- * test package.
- *
- * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or
- * {@link PackageManager#PERMISSION_DENIED}.
- */
- public void setPermission(String permission, Integer granted) {
- mMockedPermissions.put(permission, granted);
- }
-
- private int checkMockedPermission(String permission, Supplier<Integer> ifAbsent) {
- final Integer granted = mMockedPermissions.get(permission);
- return granted != null ? granted : ifAbsent.get();
- }
-
- @Override
- public int checkPermission(String permission, int pid, int uid) {
- return checkMockedPermission(
- permission, () -> super.checkPermission(permission, pid, uid));
- }
-
- @Override
- public int checkCallingOrSelfPermission(String permission) {
- return checkMockedPermission(
- permission, () -> super.checkCallingOrSelfPermission(permission));
- }
-
- @Override
- public void enforceCallingOrSelfPermission(String permission, String message) {
- final Integer granted = mMockedPermissions.get(permission);
- if (granted == null) {
- super.enforceCallingOrSelfPermission(permission, message);
- return;
- }
-
- if (!granted.equals(PackageManager.PERMISSION_GRANTED)) {
- throw new SecurityException("[Test] permission denied: " + permission);
- }
- }
-
- @Override
- public PackageManager getPackageManager() {
- return mMockPackageManager;
- }
- }
-
- @Mock
- private MockContext mMockContext;
-
- private String mPackageName;
-
- @Before
- public void setUp() throws Exception {
- mMockContext = new MockContext(InstrumentationRegistry.getContext());
- mPackageName = mMockContext.getPackageName();
- }
-
- private void mockModifyGameModeGranted() {
- mMockContext.setPermission(Manifest.permission.MANAGE_GAME_MODE,
- PackageManager.PERMISSION_GRANTED);
- }
-
- private void mockModifyGameModeDenied() {
- mMockContext.setPermission(Manifest.permission.MANAGE_GAME_MODE,
- PackageManager.PERMISSION_DENIED);
- }
-
- /**
- * By default game mode is not supported.
- */
- @Test
- public void testGameModeDefaultValue() {
- GameManagerService gameManagerService = new GameManagerService(mMockContext);
- gameManagerService.onUserStarting(USER_ID_1);
-
- mockModifyGameModeGranted();
-
- assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
- gameManagerService.getGameMode(mPackageName, USER_ID_1));
- }
-
- /**
- * Test the default behaviour for a nonexistent user.
- */
- @Test
- public void testDefaultValueForNonexistentUser() {
- GameManagerService gameManagerService = new GameManagerService(mMockContext);
- gameManagerService.onUserStarting(USER_ID_1);
-
- mockModifyGameModeGranted();
-
- gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_2);
- assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
- gameManagerService.getGameMode(mPackageName, USER_ID_2));
- }
-
- /**
- * Test getter and setter of game modes.
- */
- @Test
- public void testGameMode() {
- GameManagerService gameManagerService = new GameManagerService(mMockContext);
- gameManagerService.onUserStarting(USER_ID_1);
-
- mockModifyGameModeGranted();
-
- assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
- gameManagerService.getGameMode(mPackageName, USER_ID_1));
- gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
- assertEquals(GameManager.GAME_MODE_STANDARD,
- gameManagerService.getGameMode(mPackageName, USER_ID_1));
- gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE,
- USER_ID_1);
- assertEquals(GameManager.GAME_MODE_PERFORMANCE,
- gameManagerService.getGameMode(mPackageName, USER_ID_1));
- }
-
- /**
- * Test permission.MANAGE_GAME_MODE is checked
- */
- @Test
- public void testGetGameModeInvalidPackageName() {
- GameManagerService gameManagerService = new GameManagerService(mMockContext);
- gameManagerService.onUserStarting(USER_ID_1);
-
- try {
- assertEquals(GameManager.GAME_MODE_UNSUPPORTED,
- gameManagerService.getGameMode(PACKAGE_NAME_INVALID,
- USER_ID_1));
-
- fail("GameManagerService failed to generate SecurityException when "
- + "permission.MANAGE_GAME_MODE is not granted.");
- } catch (SecurityException ignored) {
- }
-
- // The test should throw an exception, so the test is passing if we get here.
- }
-
- /**
- * Test permission.MANAGE_GAME_MODE is checked
- */
- @Test
- public void testSetGameModePermissionDenied() {
- GameManagerService gameManagerService = new GameManagerService(mMockContext);
- gameManagerService.onUserStarting(USER_ID_1);
-
- // Update the game mode so we can read back something valid.
- mockModifyGameModeGranted();
- gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
- assertEquals(GameManager.GAME_MODE_STANDARD,
- gameManagerService.getGameMode(mPackageName, USER_ID_1));
-
- // Deny permission.MANAGE_GAME_MODE and verify the game mode is not updated.
- mockModifyGameModeDenied();
- try {
- gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE,
- USER_ID_1);
-
- fail("GameManagerService failed to generate SecurityException when "
- + "permission.MANAGE_GAME_MODE is denied.");
- } catch (SecurityException ignored) {
- }
-
- // The test should throw an exception, so the test is passing if we get here.
- mockModifyGameModeGranted();
- // Verify that the Game Mode value wasn't updated.
- assertEquals(GameManager.GAME_MODE_STANDARD,
- gameManagerService.getGameMode(mPackageName, USER_ID_1));
- }
-
- /**
- * Test game modes are user-specific.
- */
- @Test
- public void testGameModeMultipleUsers() {
- GameManagerService gameManagerService = new GameManagerService(mMockContext);
- gameManagerService.onUserStarting(USER_ID_1);
- gameManagerService.onUserStarting(USER_ID_2);
-
- mockModifyGameModeGranted();
-
- // Set User 1 to Standard
- gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_STANDARD, USER_ID_1);
- assertEquals(GameManager.GAME_MODE_STANDARD,
- gameManagerService.getGameMode(mPackageName, USER_ID_1));
-
- // Set User 2 to Performance and verify User 1 is still Standard
- gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_PERFORMANCE,
- USER_ID_2);
- assertEquals(GameManager.GAME_MODE_PERFORMANCE,
- gameManagerService.getGameMode(mPackageName, USER_ID_2));
- assertEquals(GameManager.GAME_MODE_STANDARD,
- gameManagerService.getGameMode(mPackageName, USER_ID_1));
-
- // Set User 1 to Battery and verify User 2 is still Performance
- gameManagerService.setGameMode(mPackageName, GameManager.GAME_MODE_BATTERY,
- USER_ID_1);
- assertEquals(GameManager.GAME_MODE_BATTERY,
- gameManagerService.getGameMode(mPackageName, USER_ID_1));
- assertEquals(GameManager.GAME_MODE_PERFORMANCE,
- gameManagerService.getGameMode(mPackageName, USER_ID_2));
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
index 9a430e4..f280aea 100644
--- a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
@@ -123,7 +123,7 @@
doReturn(true).when(mUserManager).isUserUnlockingOrUnlocked(USER_ID_1);
mAppHibernationService.onUserUnlocking(new SystemService.TargetUser(userInfo));
- mAppHibernationService.mIsServiceEnabled = true;
+ mAppHibernationService.sIsServiceEnabled = true;
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 89798ce..1b42dfa 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -3179,6 +3179,16 @@
}
@Test
+ public void testSetUserProvisioningState_profileFinalized_canTransitionToUserUnmanaged()
+ throws Exception {
+ setupProfileOwner();
+
+ exerciseUserProvisioningTransitions(CALLER_USER_HANDLE,
+ DevicePolicyManager.STATE_USER_PROFILE_FINALIZED,
+ DevicePolicyManager.STATE_USER_UNMANAGED);
+ }
+
+ @Test
public void testSetUserProvisioningState_illegalTransitionToAnotherInProgressState()
throws Exception {
setupProfileOwner();
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
index 679d690..d62f83c 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
@@ -36,9 +36,7 @@
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.hardware.authsecret.V1_0.IAuthSecret;
-import android.hardware.face.Face;
import android.hardware.face.FaceManager;
-import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.os.FileUtils;
import android.os.IProgressListener;
@@ -261,13 +259,12 @@
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
- Fingerprint fp = (Fingerprint) invocation.getArguments()[0];
FingerprintManager.RemovalCallback callback =
- (FingerprintManager.RemovalCallback) invocation.getArguments()[2];
- callback.onRemovalSucceeded(fp, 0);
+ (FingerprintManager.RemovalCallback) invocation.getArguments()[1];
+ callback.onRemovalSucceeded(null, 0);
return null;
}
- }).when(mFingerprintManager).remove(any(), eq(userId), any());
+ }).when(mFingerprintManager).removeAll(eq(userId), any());
// Hardware must be detected and templates must be enrolled
@@ -277,13 +274,12 @@
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
- Face face = (Face) invocation.getArguments()[0];
FaceManager.RemovalCallback callback =
- (FaceManager.RemovalCallback) invocation.getArguments()[2];
- callback.onRemovalSucceeded(face, 0);
+ (FaceManager.RemovalCallback) invocation.getArguments()[1];
+ callback.onRemovalSucceeded(null, 0);
return null;
}
- }).when(mFaceManager).remove(any(), eq(userId), any());
+ }).when(mFaceManager).removeAll(eq(userId), any());
}
@After
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
index 4a42940..5d60a89 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -208,4 +208,9 @@
parcel.recycle();
}
}
-}
+
+ @Override
+ void setKeystorePassword(byte[] password, int userHandle) {
+
+ }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
index 2b9a05c..efa1b04 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
@@ -20,11 +20,16 @@
import android.app.NotificationManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
+import android.os.Handler;
+import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
@@ -94,4 +99,11 @@
public int checkCallingOrSelfPermission(String permission) {
return PackageManager.PERMISSION_GRANTED;
}
+
+ @Override
+ public Intent registerReceiverAsUser(BroadcastReceiver receiver,
+ UserHandle user, IntentFilter filter, String broadcastPermission,
+ Handler scheduler) {
+ return null;
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index 352832b..da6c30e 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -1093,7 +1093,7 @@
// first, pretend that wifi network comes online. no policy active,
// which means we shouldn't push limit to interface.
snapshots = List.of(buildWifi());
- when(mConnManager.getAllNetworkStateSnapshot()).thenReturn(snapshots);
+ when(mConnManager.getAllNetworkStateSnapshots()).thenReturn(snapshots);
mPolicyListener.expect().onMeteredIfacesChanged(any());
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
@@ -1101,7 +1101,7 @@
// now change cycle to be on 15th, and test in early march, to verify we
// pick cycle day in previous month.
- when(mConnManager.getAllNetworkStateSnapshot()).thenReturn(snapshots);
+ when(mConnManager.getAllNetworkStateSnapshots()).thenReturn(snapshots);
// pretend that 512 bytes total have happened
stats = new NetworkStats(getElapsedRealtime(), 1)
@@ -1362,7 +1362,7 @@
.insertEntry(TEST_IFACE, 0L, 0L, 0L, 0L);
{
- when(mConnManager.getAllNetworkStateSnapshot()).thenReturn(snapshots);
+ when(mConnManager.getAllNetworkStateSnapshots()).thenReturn(snapshots);
when(mStatsService.getNetworkTotalBytes(sTemplateWifi, TIME_FEB_15,
currentTimeMillis())).thenReturn(stats.getTotalBytes());
@@ -1485,7 +1485,7 @@
}
private PersistableBundle setupUpdateMobilePolicyCycleTests() throws RemoteException {
- when(mConnManager.getAllNetworkStateSnapshot())
+ when(mConnManager.getAllNetworkStateSnapshots())
.thenReturn(new ArrayList<NetworkStateSnapshot>());
setupTelephonySubscriptionManagers(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
@@ -1498,7 +1498,7 @@
@Test
public void testUpdateMobilePolicyCycleWithNullConfig() throws RemoteException {
- when(mConnManager.getAllNetworkStateSnapshot())
+ when(mConnManager.getAllNetworkStateSnapshots())
.thenReturn(new ArrayList<NetworkStateSnapshot>());
setupTelephonySubscriptionManagers(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
@@ -2089,7 +2089,7 @@
TEST_NETWORK,
buildNetworkCapabilities(TEST_SUB_ID, roaming),
buildLinkProperties(TEST_IFACE), TEST_IMSI, TYPE_MOBILE));
- when(mConnManager.getAllNetworkStateSnapshot()).thenReturn(snapshots);
+ when(mConnManager.getAllNetworkStateSnapshots()).thenReturn(snapshots);
}
private void expectDefaultCarrierConfig() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
index 7709edb..6c1e915b 100644
--- a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
@@ -135,24 +135,41 @@
private static final String PARENT_NOTIFICATION_CHANNEL_ID = "test";
private static final long MILLIS_PER_MINUTE = 1000L * 60L;
- @Mock private Context mContext;
- @Mock private ShortcutServiceInternal mShortcutServiceInternal;
- @Mock private UsageStatsManagerInternal mUsageStatsManagerInternal;
- @Mock private PackageManagerInternal mPackageManagerInternal;
- @Mock private NotificationManagerInternal mNotificationManagerInternal;
- @Mock private UserManager mUserManager;
- @Mock private PackageManager mPackageManager;
- @Mock private TelephonyManager mTelephonyManager;
- @Mock private TelecomManager mTelecomManager;
- @Mock private ContentResolver mContentResolver;
- @Mock private JobScheduler mJobScheduler;
- @Mock private StatusBarNotification mStatusBarNotification;
- @Mock private Notification mNotification;
- @Mock private AlarmManager mAlarmManager;
+ @Mock
+ private Context mContext;
+ @Mock
+ private ShortcutServiceInternal mShortcutServiceInternal;
+ @Mock
+ private UsageStatsManagerInternal mUsageStatsManagerInternal;
+ @Mock
+ private PackageManagerInternal mPackageManagerInternal;
+ @Mock
+ private NotificationManagerInternal mNotificationManagerInternal;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private PackageManager mPackageManager;
+ @Mock
+ private TelephonyManager mTelephonyManager;
+ @Mock
+ private TelecomManager mTelecomManager;
+ @Mock
+ private ContentResolver mContentResolver;
+ @Mock
+ private JobScheduler mJobScheduler;
+ @Mock
+ private StatusBarNotification mStatusBarNotification;
+ @Mock
+ private Notification mNotification;
+ @Mock
+ private AlarmManager mAlarmManager;
- @Captor private ArgumentCaptor<ShortcutChangeCallback> mShortcutChangeCallbackCaptor;
- @Captor private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
- @Captor private ArgumentCaptor<Integer> mQueryFlagsCaptor;
+ @Captor
+ private ArgumentCaptor<ShortcutChangeCallback> mShortcutChangeCallbackCaptor;
+ @Captor
+ private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
+ @Captor
+ private ArgumentCaptor<Integer> mQueryFlagsCaptor;
private ScheduledExecutorService mExecutorService;
private NotificationChannel mNotificationChannel;
@@ -556,6 +573,7 @@
TEST_SHORTCUT_ID_2,
buildPerson());
mDataManager.addOrUpdateConversationInfo(shortcut2);
+ mLooper.dispatchAll();
ConversationChannel conversationChannel2 = mDataManager.getConversation(TEST_PKG_NAME,
USER_ID_PRIMARY,
TEST_SHORTCUT_ID_2);
@@ -583,6 +601,7 @@
ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
buildPerson());
mDataManager.addOrUpdateConversationInfo(shortcut);
+ mLooper.dispatchAll();
PeopleService.ConversationsListener listener = mock(
PeopleService.ConversationsListener.class);
mDataManager.addConversationsListener(listener);
@@ -631,7 +650,7 @@
public void testGetConversation() {
mDataManager.onUserUnlocked(USER_ID_PRIMARY);
assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
- TEST_SHORTCUT_ID)).isNull();
+ TEST_SHORTCUT_ID)).isNull();
ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
buildPerson());
@@ -781,16 +800,25 @@
@Test
public void testShortcutAddedOrUpdated() {
mDataManager.onUserUnlocked(USER_ID_PRIMARY);
+ PeopleService.ConversationsListener listener = mock(
+ PeopleService.ConversationsListener.class);
+ mDataManager.addConversationsListener(listener);
ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
buildPerson());
mShortcutChangeCallback.onShortcutsAddedOrUpdated(TEST_PKG_NAME,
Collections.singletonList(shortcut), UserHandle.of(USER_ID_PRIMARY));
+ mLooper.dispatchAll();
List<ConversationInfo> conversations = getConversationsInPrimary();
assertEquals(1, conversations.size());
assertEquals(TEST_SHORTCUT_ID, conversations.get(0).getShortcutId());
+ ArgumentCaptor<List<ConversationChannel>> capturedConversation = ArgumentCaptor.forClass(
+ List.class);
+ verify(listener, times(1)).onConversationsUpdate(capturedConversation.capture());
+ ConversationChannel result = Iterables.getOnlyElement(capturedConversation.getValue());
+ assertEquals(result.getShortcutInfo().getId(), TEST_SHORTCUT_ID);
}
@Test
@@ -978,8 +1006,13 @@
mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs1);
mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs2);
mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs3);
+ mLooper.dispatchAll();
+ PeopleService.ConversationsListener listener = mock(
+ PeopleService.ConversationsListener.class);
+ mDataManager.addConversationsListener(listener);
mDataManager.pruneDataForUser(USER_ID_PRIMARY, mCancellationSignal);
+ mLooper.dispatchAll();
assertThat(mDataManager.getStatuses(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID))
.doesNotContain(cs1);
@@ -987,6 +1020,13 @@
.contains(cs2);
assertThat(mDataManager.getStatuses(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID))
.contains(cs3);
+ ArgumentCaptor<List<ConversationChannel>> capturedConversation = ArgumentCaptor.forClass(
+ List.class);
+ verify(listener, times(1)).onConversationsUpdate(capturedConversation.capture());
+ List<ConversationChannel> results = capturedConversation.getValue();
+ ConversationChannel result = Iterables.getOnlyElement(capturedConversation.getValue());
+ // CHeck cs1 has been removed and only cs2 and cs3 remain.
+ assertThat(result.getStatuses()).containsExactly(cs2, cs3);
}
@Test
@@ -1236,13 +1276,23 @@
ConversationStatus cs2 = new ConversationStatus.Builder("id2", ACTIVITY_GAME).build();
mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs);
mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs2);
+ mLooper.dispatchAll();
+ PeopleService.ConversationsListener listener = mock(
+ PeopleService.ConversationsListener.class);
+ mDataManager.addConversationsListener(listener);
mDataManager.clearStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs2.getId());
+ mLooper.dispatchAll();
assertThat(mDataManager.getStatuses(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID))
.contains(cs);
assertThat(mDataManager.getStatuses(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID))
.doesNotContain(cs2);
+ ArgumentCaptor<List<ConversationChannel>> capturedConversation = ArgumentCaptor.forClass(
+ List.class);
+ verify(listener, times(1)).onConversationsUpdate(capturedConversation.capture());
+ ConversationChannel result = Iterables.getOnlyElement(capturedConversation.getValue());
+ assertThat(result.getStatuses()).containsExactly(cs);
}
@Test
@@ -1257,11 +1307,21 @@
ConversationStatus cs2 = new ConversationStatus.Builder("id2", ACTIVITY_GAME).build();
mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs);
mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs2);
+ mLooper.dispatchAll();
+ PeopleService.ConversationsListener listener = mock(
+ PeopleService.ConversationsListener.class);
+ mDataManager.addConversationsListener(listener);
mDataManager.clearStatuses(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID);
+ mLooper.dispatchAll();
assertThat(mDataManager.getStatuses(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID))
.isEmpty();
+ ArgumentCaptor<List<ConversationChannel>> capturedConversation = ArgumentCaptor.forClass(
+ List.class);
+ verify(listener, times(1)).onConversationsUpdate(capturedConversation.capture());
+ ConversationChannel result = Iterables.getOnlyElement(capturedConversation.getValue());
+ assertThat(result.getStatuses()).isEmpty();
}
@Test
@@ -1403,7 +1463,7 @@
.setLongLived(true)
.setIntent(new Intent("TestIntent"));
if (person != null) {
- builder.setPersons(new Person[] {person});
+ builder.setPersons(new Person[]{person});
}
return builder.build();
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 198fb4f..b9f70da 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -125,6 +125,7 @@
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -2598,6 +2599,13 @@
}).when(mMockPackageManagerInternal).getHomeActivitiesAsUser(any(List.class), eq(userId));
}
+ protected void prepareIntentActivities(ComponentName cn) {
+ when(mMockPackageManagerInternal.queryIntentActivities(
+ anyOrNull(Intent.class), anyStringOrNull(), anyInt(), anyInt(), anyInt()))
+ .thenReturn(Collections.singletonList(
+ ri(cn.getPackageName(), cn.getClassName(), false, 0)));
+ }
+
protected static ComponentName cn(String packageName, String name) {
return new ComponentName(packageName, name);
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest10.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest10.java
index eceb17a..e92c849 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest10.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest10.java
@@ -159,6 +159,7 @@
public void testStartConfigActivity_defaultLauncher() {
LauncherActivityInfo info = setupMockActivityInfo();
+ prepareIntentActivities(info.getComponentName());
setDefaultLauncher(USER_0, LAUNCHER_1);
runWithCaller(LAUNCHER_1, USER_0, () ->
assertNotNull(mLauncherApps.getShortcutConfigActivityIntent(info))
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
index 809b6d5..182848b4 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
@@ -123,6 +123,7 @@
for (long i = cal.getTimeInMillis(); i >= 5; i--) {
File file = mock(File.class);
when(file.getName()).thenReturn(String.valueOf(i));
+ when(file.getAbsolutePath()).thenReturn(String.valueOf(i));
AtomicFile af = new AtomicFile(file);
expectedFiles.add(af);
mDataBase.mHistoryFiles.addLast(af);
@@ -133,6 +134,7 @@
for (int i = 5; i >= 0; i--) {
File file = mock(File.class);
when(file.getName()).thenReturn(String.valueOf(cal.getTimeInMillis() - i));
+ when(file.getAbsolutePath()).thenReturn(String.valueOf(cal.getTimeInMillis() - i));
AtomicFile af = new AtomicFile(file);
mDataBase.mHistoryFiles.addLast(af);
}
@@ -158,6 +160,7 @@
for (long i = cal.getTimeInMillis(); i >= 5; i--) {
File file = mock(File.class);
when(file.getName()).thenReturn(i + ".bak");
+ when(file.getAbsolutePath()).thenReturn(i + ".bak");
AtomicFile af = new AtomicFile(file);
mDataBase.mHistoryFiles.addLast(af);
}
@@ -415,4 +418,36 @@
assertThat(mDataBase.mBuffer).isNotEqualTo(nh);
verify(mAlarmManager, times(1)).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
}
+
+ @Test
+ public void testRemoveFilePathFromHistory_hasMatch() throws Exception {
+ for (int i = 0; i < 5; i++) {
+ AtomicFile af = mock(AtomicFile.class);
+ when(af.getBaseFile()).thenReturn(new File(mRootDir, "af" + i));
+ mDataBase.mHistoryFiles.addLast(af);
+ }
+ // Baseline size of history files
+ assertThat(mDataBase.mHistoryFiles.size()).isEqualTo(5);
+
+ // Remove only file number 3
+ String filePathToRemove = new File(mRootDir, "af3").getAbsolutePath();
+ mDataBase.removeFilePathFromHistory(filePathToRemove);
+ assertThat(mDataBase.mHistoryFiles.size()).isEqualTo(4);
+ }
+
+ @Test
+ public void testRemoveFilePathFromHistory_noMatch() throws Exception {
+ for (int i = 0; i < 5; i++) {
+ AtomicFile af = mock(AtomicFile.class);
+ when(af.getBaseFile()).thenReturn(new File(mRootDir, "af" + i));
+ mDataBase.mHistoryFiles.addLast(af);
+ }
+ // Baseline size of history files
+ assertThat(mDataBase.mHistoryFiles.size()).isEqualTo(5);
+
+ // Attempt to remove a filename that doesn't exist, expect nothing to break or change
+ String filePathToRemove = new File(mRootDir, "af.thisfileisfake").getAbsolutePath();
+ mDataBase.removeFilePathFromHistory(filePathToRemove);
+ assertThat(mDataBase.mHistoryFiles.size()).isEqualTo(5);
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 124f6dd..8cede6d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -2358,21 +2358,6 @@
}
@Test
- public void testAddRemoveRace() {
- registerTestStartingWindowOrganizer();
- // There was once a race condition between adding and removing starting windows
- final ActivityRecord appToken = new ActivityBuilder(mAtm).setCreateTask(true).build();
- for (int i = 0; i < 1000; i++) {
- appToken.addStartingWindow(mPackageName,
- android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
- false, false);
- appToken.removeStartingWindow();
- waitUntilHandlersIdle();
- assertNoStartingWindow(appToken);
- }
- }
-
- @Test
public void testTransferStartingWindow() {
registerTestStartingWindowOrganizer();
final ActivityRecord activity1 = new ActivityBuilder(mAtm).setCreateTask(true).build();
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 0afd39f..2f52352 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -1971,7 +1971,8 @@
// test misc display overrides
assertEquals(ignoreOrientationRequests, testDisplayContent.mIgnoreOrientationRequest);
- assertEquals(fixedOrientationLetterboxRatio, mWm.getFixedOrientationLetterboxAspectRatio(),
+ assertEquals(fixedOrientationLetterboxRatio,
+ mWm.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(),
0 /* delta */);
}
@@ -2011,7 +2012,8 @@
// test misc display overrides
assertEquals(ignoreOrientationRequests, testDisplayContent.mIgnoreOrientationRequest);
- assertEquals(fixedOrientationLetterboxRatio, mWm.getFixedOrientationLetterboxAspectRatio(),
+ assertEquals(fixedOrientationLetterboxRatio,
+ mWm.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(),
0 /* delta */);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 5d6a5c0..73404eb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -641,7 +641,6 @@
@Test
public void testVisibleTasks_excludedFromRecents() {
- mRecentTasks.setOnlyTestVisibleRange();
mRecentTasks.setParameters(-1 /* min */, 4 /* max */, -1 /* ms */);
Task excludedTask1 = createTaskBuilder(".ExcludedTask1")
@@ -650,15 +649,26 @@
Task excludedTask2 = createTaskBuilder(".ExcludedTask2")
.setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
.build();
+ Task detachedExcludedTask = createTaskBuilder(".DetachedExcludedTask")
+ .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+ .build();
+ // Move home to front so other task can satisfy the condition in RecentTasks#isTrimmable.
+ mRootWindowContainer.getDefaultTaskDisplayArea().getRootHomeTask().moveToFront("test");
+ // Avoid Task#autoRemoveFromRecents when removing from parent.
+ detachedExcludedTask.setHasBeenVisible(true);
+ detachedExcludedTask.removeImmediately();
+ assertFalse(detachedExcludedTask.isAttached());
+
+ mRecentTasks.add(detachedExcludedTask);
mRecentTasks.add(excludedTask1);
mRecentTasks.add(mTasks.get(0));
mRecentTasks.add(mTasks.get(1));
mRecentTasks.add(mTasks.get(2));
mRecentTasks.add(excludedTask2);
- // The last excluded task should be trimmed, while the first-most excluded task should not
- triggerTrimAndAssertTrimmed(excludedTask1);
+ // Except the first-most excluded task, other excluded tasks should be trimmed.
+ triggerTrimAndAssertTrimmed(excludedTask1, detachedExcludedTask);
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 153fd3a..23d57b8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -518,6 +518,7 @@
verify(mController.mStatusBar).setNavigationBarLumaSamplingEnabled(
mDefaultDisplay.mDisplayId, false);
verify(transaction).reparent(navToken.getSurfaceControl(), activity.getSurfaceControl());
+ verify(transaction).setLayer(navToken.getSurfaceControl(), Integer.MAX_VALUE);
final WindowContainer parent = navToken.getParent();
final NavBarFadeAnimationController navBarFadeAnimationController =
@@ -526,6 +527,7 @@
mController.cleanupAnimation(REORDER_MOVE_TO_TOP);
verify(mController.mStatusBar).setNavigationBarLumaSamplingEnabled(
mDefaultDisplay.mDisplayId, true);
+ verify(transaction).setLayer(navToken.getSurfaceControl(), 0);
verify(transaction).reparent(navToken.getSurfaceControl(), parent.getSurfaceControl());
verify(navBarFadeAnimationController).fadeWindowToken(true);
}
@@ -543,6 +545,7 @@
verify(mController.mStatusBar).setNavigationBarLumaSamplingEnabled(
mDefaultDisplay.mDisplayId, false);
verify(transaction).reparent(navToken.getSurfaceControl(), activity.getSurfaceControl());
+ verify(transaction).setLayer(navToken.getSurfaceControl(), Integer.MAX_VALUE);
final WindowContainer parent = navToken.getParent();
final NavBarFadeAnimationController navBarFadeAnimationController =
@@ -551,6 +554,7 @@
mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
verify(mController.mStatusBar).setNavigationBarLumaSamplingEnabled(
mDefaultDisplay.mDisplayId, true);
+ verify(transaction).setLayer(navToken.getSurfaceControl(), 0);
verify(transaction).reparent(navToken.getSurfaceControl(), parent.getSurfaceControl());
verify(navBarFadeAnimationController, never()).fadeWindowToken(anyBoolean());
}
@@ -579,6 +583,7 @@
verify(mController.mStatusBar).setNavigationBarLumaSamplingEnabled(
mDefaultDisplay.mDisplayId, false);
verify(transaction).reparent(navToken.getSurfaceControl(), activity.getSurfaceControl());
+ verify(transaction).setLayer(navToken.getSurfaceControl(), Integer.MAX_VALUE);
final WindowContainer parent = navToken.getParent();
final NavBarFadeAnimationController navBarFadeAnimationController =
@@ -591,6 +596,7 @@
mController.cleanupAnimation(REORDER_MOVE_TO_TOP);
verify(mController.mStatusBar).setNavigationBarLumaSamplingEnabled(
mDefaultDisplay.mDisplayId, true);
+ verify(transaction).setLayer(navToken.getSurfaceControl(), 0);
verify(mockController).setOnShowRunnable(any());
verify(transaction, times(0)).reparent(navToken.getSurfaceControl(),
parent.getSurfaceControl());
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index ee1d393..95b7443 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -335,11 +335,11 @@
final WindowState window = createWindow(null, TYPE_BASE_APPLICATION, mActivity, "window");
assertEquals(window, mActivity.findMainWindow());
- assertTrue(mActivity.isLetterboxed(mActivity.findMainWindow()));
+ assertTrue(mActivity.mLetterboxUiController.isLetterboxed(mActivity.findMainWindow()));
window.mAttrs.flags |= FLAG_SHOW_WALLPAPER;
- assertFalse(mActivity.isLetterboxed(mActivity.findMainWindow()));
+ assertFalse(mActivity.mLetterboxUiController.isLetterboxed(mActivity.findMainWindow()));
}
@Test
@@ -1023,7 +1023,7 @@
// Portrait fixed app with min aspect ratio higher that aspect ratio override for fixed
// orientation letterbox.
- mActivity.mWmService.setFixedOrientationLetterboxAspectRatio(1.1f);
+ mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(1.1f);
mActivity.info.setMinAspectRatio(3);
prepareUnresizable(mActivity, /* maxAspect= */ 0, SCREEN_ORIENTATION_PORTRAIT);
@@ -1054,7 +1054,7 @@
// Portrait fixed app with max aspect ratio lower that aspect ratio override for fixed
// orientation letterbox.
- mActivity.mWmService.setFixedOrientationLetterboxAspectRatio(3);
+ mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(3);
prepareUnresizable(mActivity, /* maxAspect= */ 2, SCREEN_ORIENTATION_PORTRAIT);
final Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
@@ -1085,7 +1085,7 @@
// Portrait fixed app with min aspect ratio higher that aspect ratio override for fixed
// orientation letterbox.
final float fixedOrientationLetterboxAspectRatio = 1.1f;
- mActivity.mWmService.setFixedOrientationLetterboxAspectRatio(
+ mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(
fixedOrientationLetterboxAspectRatio);
prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
@@ -1586,7 +1586,7 @@
setUpDisplaySizeWithApp(2800, 1400);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
- mActivity.mWmService.setLetterboxHorizontalPositionMultiplier(
+ mActivity.mWmService.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
letterboxHorizontalPositionMultiplier);
prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
@@ -1624,7 +1624,7 @@
setUpDisplaySizeWithApp(2800, 1400);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
- mActivity.mWmService.setLetterboxHorizontalPositionMultiplier(
+ mActivity.mWmService.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
letterboxHorizontalPositionMultiplier);
prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
diff --git a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
index f3616da6c..619aee6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
+++ b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
@@ -17,6 +17,8 @@
package com.android.server.wm;
import android.annotation.NonNull;
+import android.graphics.ColorSpace;
+import android.graphics.GraphicBuffer;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.Region;
@@ -253,4 +255,14 @@
public SurfaceControl.Transaction unsetFixedTransformHint(@NonNull SurfaceControl sc) {
return this;
}
+
+ @Override
+ public SurfaceControl.Transaction setBuffer(SurfaceControl sc, GraphicBuffer buffer) {
+ return this;
+ }
+
+ @Override
+ public SurfaceControl.Transaction setColorSpace(SurfaceControl sc, ColorSpace colorSpace) {
+ return this;
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index ae12062..2d4e4ef 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -208,11 +208,11 @@
// Ensure letterbox aspect ratio is not overridden on any device target.
// {@link com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}, is set
// on some device form factors.
- mAtm.mWindowManager.setFixedOrientationLetterboxAspectRatio(0);
+ mAtm.mWindowManager.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(0);
// Ensure letterbox position multiplier is not overridden on any device target.
// {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier},
// may be set on some device form factors.
- mAtm.mWindowManager.setLetterboxHorizontalPositionMultiplier(0.5f);
+ mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(0.5f);
checkDeviceSpecificOverridesNotApplied();
}
@@ -220,10 +220,10 @@
@After
public void tearDown() throws Exception {
// Revert back to device overrides.
- mAtm.mWindowManager.setFixedOrientationLetterboxAspectRatio(
+ mAtm.mWindowManager.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(
mContext.getResources().getFloat(
com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio));
- mAtm.mWindowManager.setLetterboxHorizontalPositionMultiplier(
+ mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
mContext.getResources().getFloat(
com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier));
}
@@ -235,7 +235,8 @@
private void checkDeviceSpecificOverridesNotApplied() {
// Check global overrides
if (!sGlobalOverridesChecked) {
- assertEquals(0, mWm.getFixedOrientationLetterboxAspectRatio(), 0 /* delta */);
+ assertEquals(0, mWm.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(),
+ 0 /* delta */);
sGlobalOverridesChecked = true;
}
// Check display-specific overrides
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 6f701f7..ba7aaab 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -24,6 +24,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
+import android.content.ContentCaptureOptions;
import android.content.Context;
import android.content.Intent;
import android.hardware.soundtrigger.IRecognitionStatusCallback;
@@ -34,10 +35,12 @@
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SharedMemory;
import android.service.voice.HotwordDetectedResult;
import android.service.voice.HotwordDetectionService;
@@ -47,6 +50,7 @@
import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
import android.util.Pair;
import android.util.Slog;
+import android.view.contentcapture.IContentCaptureManager;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IHotwordRecognitionStatusCallback;
@@ -135,6 +139,7 @@
return;
}
updateStateWithCallbackLocked(options, sharedMemory, callback);
+ updateContentCaptureManager();
}
private void updateStateWithCallbackLocked(PersistableBundle options,
@@ -193,6 +198,15 @@
});
}
+ private void updateContentCaptureManager() {
+ IBinder b = ServiceManager
+ .getService(Context.CONTENT_CAPTURE_MANAGER_SERVICE);
+ IContentCaptureManager binderService = IContentCaptureManager.Stub.asInterface(b);
+ mRemoteHotwordDetectionService.post(
+ service -> service.updateContentCaptureManager(binderService,
+ new ContentCaptureOptions(null)));
+ }
+
private boolean isBound() {
synchronized (mLock) {
return mBound;
diff --git a/telephony/common/com/android/internal/telephony/SmsApplication.java b/telephony/common/com/android/internal/telephony/SmsApplication.java
index 32533cb..0d6cd5a 100644
--- a/telephony/common/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/common/com/android/internal/telephony/SmsApplication.java
@@ -760,6 +760,7 @@
private static void assignExclusiveSmsPermissionsToSystemApp(Context context,
PackageManager packageManager, AppOpsManager appOps, String packageName,
boolean sigatureMatch) {
+ if (packageName == null) return;
// First check package signature matches the caller's package signature.
// Since this class is only used internally by the system, this check makes sure
// the package signature matches system signature.
diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java
index 96e715e..1d7a476 100644
--- a/telephony/java/android/telephony/AccessNetworkConstants.java
+++ b/telephony/java/android/telephony/AccessNetworkConstants.java
@@ -62,6 +62,7 @@
switch (transportType) {
case TRANSPORT_TYPE_WWAN: return "WWAN";
case TRANSPORT_TYPE_WLAN: return "WLAN";
+ case TRANSPORT_TYPE_INVALID: return "INVALID";
default: return Integer.toString(transportType);
}
}
diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java
index bde62fb..ac01afa 100644
--- a/telephony/java/android/telephony/CellSignalStrengthNr.java
+++ b/telephony/java/android/telephony/CellSignalStrengthNr.java
@@ -134,7 +134,7 @@
*
* Range [0, 15] for each CQI.
*/
- private List<Integer> mCsiCqiReport;;
+ private List<Integer> mCsiCqiReport;
private int mSsRsrp;
private int mSsRsrq;
private int mSsSinr;
@@ -172,13 +172,13 @@
* @hide
*/
public CellSignalStrengthNr(int csiRsrp, int csiRsrq, int csiSinr, int csiCqiTableIndex,
- List<Integer> csiCqiReport, int ssRsrp, int ssRsrq, int ssSinr) {
+ List<Byte> csiCqiReport, int ssRsrp, int ssRsrq, int ssSinr) {
mCsiRsrp = inRangeOrUnavailable(csiRsrp, -140, -44);
mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3);
mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23);
mCsiCqiTableIndex = inRangeOrUnavailable(csiCqiTableIndex, 1, 3);
- mCsiCqiReport = csiCqiReport.stream()
- .map(cqi -> new Integer(inRangeOrUnavailable(cqi.intValue(), 1, 3)))
+ mCsiCqiReport = csiCqiReport.stream()
+ .map(cqi -> new Integer(inRangeOrUnavailable(Byte.toUnsignedInt(cqi), 1, 3)))
.collect(Collectors.toList());
mSsRsrp = inRangeOrUnavailable(ssRsrp, -140, -44);
mSsRsrq = inRangeOrUnavailable(ssRsrq, -43, 20);
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
index c8ed82c..4d5b6ac 100644
--- a/telephony/java/android/telephony/DataFailCause.java
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -1055,6 +1055,20 @@
*/
public static final int HANDOVER_FAILED = 0x10006;
+ /**
+ * Enterprise setup failure: duplicate CID in DataCallResponse.
+ *
+ * @hide
+ */
+ public static final int DUPLICATE_CID = 0x10007;
+
+ /**
+ * Enterprise setup failure: no default data connection set up yet.
+ *
+ * @hide
+ */
+ public static final int NO_DEFAULT_DATA = 0x10008;
+
private static final Map<Integer, String> sFailCauseMap;
static {
sFailCauseMap = new HashMap<>();
@@ -1426,6 +1440,8 @@
sFailCauseMap.put(IPV6_PREFIX_UNAVAILABLE, "IPV6_PREFIX_UNAVAILABLE");
sFailCauseMap.put(HANDOFF_PREFERENCE_CHANGED, "HANDOFF_PREFERENCE_CHANGED");
sFailCauseMap.put(SLICE_REJECTED, "SLICE_REJECTED");
+ sFailCauseMap.put(MATCH_ALL_RULE_NOT_ALLOWED, "MATCH_ALL_RULE_NOT_ALLOWED");
+ sFailCauseMap.put(ALL_MATCHING_RULES_FAILED, "ALL_MATCHING_RULES_FAILED");
sFailCauseMap.put(IWLAN_PDN_CONNECTION_REJECTION, "IWLAN_PDN_CONNECTION_REJECTION");
sFailCauseMap.put(IWLAN_MAX_CONNECTION_REACHED, "IWLAN_MAX_CONNECTION_REACHED");
sFailCauseMap.put(IWLAN_SEMANTIC_ERROR_IN_THE_TFT_OPERATION,
@@ -1481,6 +1497,9 @@
sFailCauseMap.put(UNACCEPTABLE_NETWORK_PARAMETER,
"UNACCEPTABLE_NETWORK_PARAMETER");
sFailCauseMap.put(LOST_CONNECTION, "LOST_CONNECTION");
+ sFailCauseMap.put(HANDOVER_FAILED, "HANDOVER_FAILED");
+ sFailCauseMap.put(DUPLICATE_CID, "DUPLICATE_CID");
+ sFailCauseMap.put(NO_DEFAULT_DATA, "NO_DEFAULT_DATA");
}
private DataFailCause() {
@@ -1580,6 +1599,9 @@
add(RADIO_NOT_AVAILABLE);
add(UNACCEPTABLE_NETWORK_PARAMETER);
add(SIGNAL_LOST);
+ add(DUPLICATE_CID);
+ add(MATCH_ALL_RULE_NOT_ALLOWED);
+ add(ALL_MATCHING_RULES_FAILED);
}
};
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index d8ac082..2616ec8 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -2785,7 +2785,8 @@
* @param subId the subscriber this override applies to.
* @param overrideUnmetered set if the billing relationship should be
* considered unmetered.
- * @param networkTypes the network types this override applies to.
+ * @param networkTypes the network types this override applies to. If no
+ * network types are specified, override values will be ignored.
* {@see TelephonyManager#getAllNetworkTypes()}
* @param timeoutMillis the timeout after which the requested override will
* be automatically cleared, or {@code 0} to leave in the
@@ -2849,7 +2850,8 @@
* @param subId the subscriber this override applies to.
* @param overrideCongested set if the subscription should be considered
* congested.
- * @param networkTypes the network types this override applies to.
+ * @param networkTypes the network types this override applies to. If no
+ * network types are specified, override values will be ignored.
* {@see TelephonyManager#getAllNetworkTypes()}
* @param timeoutMillis the timeout after which the requested override will
* be automatically cleared, or {@code 0} to leave in the
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index f0771be..c525118 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -64,7 +64,6 @@
import android.os.ParcelUuid;
import android.os.Parcelable;
import android.os.PersistableBundle;
-import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SystemProperties;
@@ -90,7 +89,7 @@
import android.telephony.VisualVoicemailService.VisualVoicemailTask;
import android.telephony.data.ApnSetting;
import android.telephony.data.ApnSetting.MvnoType;
-import android.telephony.data.SlicingConfig;
+import android.telephony.data.NetworkSlicingConfig;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
import android.telephony.gba.UaSecurityProtocolIdentifier;
@@ -428,10 +427,6 @@
return null;
}
- private boolean isSystemProcess() {
- return Process.myUid() == Process.SYSTEM_UID;
- }
-
/**
* Post a runnable to the BackgroundThread.
*
@@ -4205,19 +4200,12 @@
try {
IPhoneSubInfo info = getSubscriberInfoService();
if (info == null) {
- Rlog.e(TAG, "IMSI error: Subscriber Info is null");
- if (!isSystemProcess()) {
- throw new RuntimeException("IMSI error: Subscriber Info is null");
- }
- return;
+ throw new RuntimeException("IMSI error: Subscriber Info is null");
}
int subId = getSubId(SubscriptionManager.getDefaultDataSubscriptionId());
info.resetCarrierKeysForImsiEncryption(subId, mContext.getOpPackageName());
} catch (RemoteException ex) {
- Rlog.e(TAG, "getCarrierInfoForImsiEncryption RemoteException" + ex);
- if (!isSystemProcess()) {
- ex.rethrowAsRuntimeException();
- }
+ Rlog.e(TAG, "Telephony#getCarrierInfoForImsiEncryption RemoteException" + ex);
}
}
@@ -4885,8 +4873,9 @@
* Return the set of IMSIs that should be considered "merged together" for data usage
* purposes. This API merges IMSIs based on subscription grouping: IMSI of those in the same
* group will all be returned.
- * Return the current IMSI if there is no subscription group. See
- * {@link SubscriptionManager#createSubscriptionGroup(List)} for the definition of a group.
+ * Return the current IMSI if there is no subscription group, see
+ * {@link SubscriptionManager#createSubscriptionGroup(List)} for the definition of a group,
+ * otherwise return an empty array if there is a failure.
*
* @hide
*/
@@ -5611,17 +5600,11 @@
try {
final ITelephony telephony = getITelephony();
if (telephony == null) {
- if (!isSystemProcess()) {
- throw new RuntimeException("Telephony service unavailable");
- }
return;
}
telephony.sendDialerSpecialCode(mContext.getOpPackageName(), inputCode);
} catch (RemoteException ex) {
- // This could happen if binder process crashes.
- if (!isSystemProcess()) {
- ex.rethrowAsRuntimeException();
- }
+ Rlog.e(TAG, "Telephony#sendDialerSpecialCode RemoteException" + ex);
}
}
@@ -9940,9 +9923,7 @@
throw new IllegalStateException("telephony service is null.");
}
} catch (RemoteException ex) {
- if (!isSystemProcess()) {
- ex.rethrowAsRuntimeException();
- }
+ Rlog.e(TAG, "Telephony#getMobileProvisioningUrl RemoteException" + ex);
}
return null;
}
@@ -13926,9 +13907,7 @@
return service.isDataEnabledForApn(apnType, getSubId(), pkgForDebug);
}
} catch (RemoteException ex) {
- if (!isSystemProcess()) {
- ex.rethrowAsRuntimeException();
- }
+ Rlog.e(TAG, "Telephony#isDataEnabledForApn RemoteException" + ex);
}
return false;
}
@@ -13948,9 +13927,7 @@
return service.isApnMetered(apnType, getSubId());
}
} catch (RemoteException ex) {
- if (!isSystemProcess()) {
- ex.rethrowAsRuntimeException();
- }
+ Rlog.e(TAG, "Telephony#isApnMetered RemoteException" + ex);
}
return true;
}
@@ -14010,9 +13987,7 @@
service.setSystemSelectionChannels(specifiers, getSubId(), aidlConsumer);
}
} catch (RemoteException ex) {
- if (!isSystemProcess()) {
- ex.rethrowAsRuntimeException();
- }
+ Rlog.e(TAG, "Telephony#setSystemSelectionChannels RemoteException" + ex);
}
}
@@ -14040,9 +14015,7 @@
throw new IllegalStateException("telephony service is null.");
}
} catch (RemoteException ex) {
- if (!isSystemProcess()) {
- ex.rethrowAsRuntimeException();
- }
+ Rlog.e(TAG, "Telephony#getSystemSelectionChannels RemoteException" + ex);
}
return new ArrayList<>();
}
@@ -14071,9 +14044,7 @@
return service.isMvnoMatched(getSubId(), mvnoType, mvnoMatchData);
}
} catch (RemoteException ex) {
- if (!isSystemProcess()) {
- ex.rethrowAsRuntimeException();
- }
+ Rlog.e(TAG, "Telephony#matchesCurrentSimOperator RemoteException" + ex);
}
return false;
}
@@ -14474,10 +14445,7 @@
service.setMobileDataPolicyEnabled(getSubId(), policy, enabled);
}
} catch (RemoteException ex) {
- // This could happen if binder process crashes.
- if (!isSystemProcess()) {
- ex.rethrowAsRuntimeException();
- }
+ Rlog.e(TAG, "Telephony#setMobileDataPolicyEnabled RemoteException" + ex);
}
}
@@ -14497,10 +14465,7 @@
return service.isMobileDataPolicyEnabled(getSubId(), policy);
}
} catch (RemoteException ex) {
- // This could happen if binder process crashes.
- if (!isSystemProcess()) {
- ex.rethrowAsRuntimeException();
- }
+ Rlog.e(TAG, "Telephony#isMobileDataPolicyEnabled RemoteException" + ex);
}
return false;
}
@@ -15004,9 +14969,7 @@
throw new IllegalStateException("telephony service is null.");
}
} catch (RemoteException ex) {
- if (!isSystemProcess()) {
- ex.rethrowAsRuntimeException();
- }
+ Rlog.e(TAG, "Telephony#getEquivalentHomePlmns RemoteException" + ex);
}
return Collections.emptyList();
@@ -15064,13 +15027,20 @@
public static final String CAPABILITY_SLICING_CONFIG_SUPPORTED =
"CAPABILITY_SLICING_CONFIG_SUPPORTED";
- /** @hide */
+ /**
+ * A list of the radio interface capability values with public valid constants.
+ *
+ * Here is a related list for the systemapi-only valid constants:
+ * CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE
+ * CAPABILITY_ALLOWED_NETWORK_TYPES_USED
+ * CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE
+ * CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING
+ *
+ * @hide
+ * TODO(b/185508047): Doc generation for mixed public/systemapi StringDefs formats badly.
+ */
@Retention(RetentionPolicy.SOURCE)
@StringDef(prefix = "CAPABILITY_", value = {
- CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE,
- CAPABILITY_ALLOWED_NETWORK_TYPES_USED,
- CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE,
- CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING,
CAPABILITY_SLICING_CONFIG_SUPPORTED,
})
public @interface RadioInterfaceCapability {}
@@ -15082,10 +15052,7 @@
*
* @param capability the name of the capability to check for
* @return the availability of the capability
- *
- * @hide
*/
- @SystemApi
public boolean isRadioInterfaceCapabilitySupported(
@NonNull @RadioInterfaceCapability String capability) {
try {
@@ -15098,9 +15065,7 @@
throw new IllegalStateException("telephony service is null.");
}
} catch (RemoteException ex) {
- if (!isSystemProcess()) {
- ex.rethrowAsRuntimeException();
- }
+ Rlog.e(TAG, "Telephony#isRadioInterfaceCapabilitySupported RemoteException" + ex);
}
return false;
}
@@ -15669,7 +15634,7 @@
* Exception that may be supplied to the callback in {@link #getNetworkSlicingConfiguration} if
* something goes awry.
*/
- public static class SlicingException extends Exception {
+ public static class NetworkSlicingException extends Exception {
/**
* Getting the current slicing configuration successfully. Used internally only.
* @hide
@@ -15678,11 +15643,13 @@
/**
* The system timed out waiting for a response from the Radio.
+ * @hide
*/
public static final int ERROR_TIMEOUT = 1;
/**
* The modem returned a failure.
+ * @hide
*/
public static final int ERROR_MODEM_ERROR = 2;
@@ -15692,20 +15659,44 @@
ERROR_MODEM_ERROR,
})
@Retention(RetentionPolicy.SOURCE)
- public @interface SlicingError {}
+ public @interface NetworkSlicingError {}
private final int mErrorCode;
- public SlicingException(@SlicingError int errorCode) {
+ /** @hide */
+ public NetworkSlicingException(@NetworkSlicingError int errorCode) {
mErrorCode = errorCode;
}
- /**
- * Fetches the error code associated with this exception.
- * @return An error code.
- */
- public @SlicingError int getErrorCode() {
- return mErrorCode;
+ @Override
+ public String toString() {
+ switch (mErrorCode) {
+ case ERROR_TIMEOUT: return "ERROR_TIMEOUT";
+ case ERROR_MODEM_ERROR: return "ERROR_MODEM_ERROR";
+ default: return "UNDEFINED";
+ }
+ }
+ }
+
+ /**
+ * Exception that is supplied to the callback in {@link #getNetworkSlicingConfiguration} if the
+ * system timed out waiting for a response from the Radio.
+ */
+ public class TimeoutException extends NetworkSlicingException {
+ /** @hide */
+ public TimeoutException(int errorCode) {
+ super(errorCode);
+ }
+ }
+
+ /**
+ * Exception that is supplied to the callback in {@link #getNetworkSlicingConfiguration} if the
+ * modem returned a failure.
+ */
+ public class ModemErrorException extends NetworkSlicingException {
+ /** @hide */
+ public ModemErrorException(int errorCode) {
+ super(errorCode);
}
}
@@ -15736,7 +15727,7 @@
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void getNetworkSlicingConfiguration(
@NonNull @CallbackExecutor Executor executor,
- @NonNull OutcomeReceiver<SlicingConfig, SlicingException> callback) {
+ @NonNull OutcomeReceiver<NetworkSlicingConfig, NetworkSlicingException> callback) {
Objects.requireNonNull(executor);
Objects.requireNonNull(callback);
@@ -15748,12 +15739,17 @@
telephony.getSlicingConfig(new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle result) {
- if (resultCode != SlicingException.SUCCESS) {
+ if (resultCode == NetworkSlicingException.ERROR_TIMEOUT) {
executor.execute(() -> callback.onError(
- new SlicingException(resultCode)));
+ new TimeoutException(resultCode)));
+ return;
+ } else if (resultCode == NetworkSlicingException.ERROR_MODEM_ERROR) {
+ executor.execute(() -> callback.onError(
+ new ModemErrorException(resultCode)));
return;
}
- SlicingConfig slicingConfig =
+
+ NetworkSlicingConfig slicingConfig =
result.getParcelable(KEY_SLICING_CONFIG_HANDLE);
executor.execute(() -> callback.onResult(slicingConfig));
}
diff --git a/telephony/java/android/telephony/data/SlicingConfig.aidl b/telephony/java/android/telephony/data/NetworkSlicingConfig.aidl
similarity index 95%
rename from telephony/java/android/telephony/data/SlicingConfig.aidl
rename to telephony/java/android/telephony/data/NetworkSlicingConfig.aidl
index ad93d8c..cd4a8f1e4 100644
--- a/telephony/java/android/telephony/data/SlicingConfig.aidl
+++ b/telephony/java/android/telephony/data/NetworkSlicingConfig.aidl
@@ -16,4 +16,4 @@
package android.telephony.data;
-parcelable SlicingConfig;
+parcelable NetworkSlicingConfig;
diff --git a/telephony/java/android/telephony/data/SlicingConfig.java b/telephony/java/android/telephony/data/NetworkSlicingConfig.java
similarity index 83%
rename from telephony/java/android/telephony/data/SlicingConfig.java
rename to telephony/java/android/telephony/data/NetworkSlicingConfig.java
index 990e4d2..dec787f 100644
--- a/telephony/java/android/telephony/data/SlicingConfig.java
+++ b/telephony/java/android/telephony/data/NetworkSlicingConfig.java
@@ -28,22 +28,22 @@
/**
* Represents a slicing configuration
*/
-public final class SlicingConfig implements Parcelable {
+public final class NetworkSlicingConfig implements Parcelable {
private final List<UrspRule> mUrspRules;
private final List<NetworkSliceInfo> mSliceInfo;
- public SlicingConfig() {
+ public NetworkSlicingConfig() {
mUrspRules = new ArrayList<UrspRule>();
mSliceInfo = new ArrayList<NetworkSliceInfo>();
}
/** @hide */
- public SlicingConfig(android.hardware.radio.V1_6.SlicingConfig sc) {
+ public NetworkSlicingConfig(android.hardware.radio.V1_6.SlicingConfig sc) {
this(sc.urspRules, sc.sliceInfo);
}
/** @hide */
- public SlicingConfig(List<android.hardware.radio.V1_6.UrspRule> urspRules,
+ public NetworkSlicingConfig(List<android.hardware.radio.V1_6.UrspRule> urspRules,
List<android.hardware.radio.V1_6.SliceInfo> sliceInfo) {
mUrspRules = new ArrayList<UrspRule>();
for (android.hardware.radio.V1_6.UrspRule ur : urspRules) {
@@ -69,7 +69,7 @@
}
/** @hide */
- public SlicingConfig(Parcel p) {
+ public NetworkSlicingConfig(Parcel p) {
mUrspRules = p.createTypedArrayList(UrspRule.CREATOR);
mSliceInfo = p.createTypedArrayList(NetworkSliceInfo.CREATOR);
}
@@ -96,16 +96,16 @@
dest.writeTypedList(mSliceInfo, flags);
}
- public static final @NonNull Parcelable.Creator<SlicingConfig> CREATOR =
- new Parcelable.Creator<SlicingConfig>() {
+ public static final @NonNull Parcelable.Creator<NetworkSlicingConfig> CREATOR =
+ new Parcelable.Creator<NetworkSlicingConfig>() {
@Override
- public SlicingConfig createFromParcel(Parcel source) {
- return new SlicingConfig(source);
+ public NetworkSlicingConfig createFromParcel(Parcel source) {
+ return new NetworkSlicingConfig(source);
}
@Override
- public SlicingConfig[] newArray(int size) {
- return new SlicingConfig[size];
+ public NetworkSlicingConfig[] newArray(int size) {
+ return new NetworkSlicingConfig[size];
}
};
@@ -118,7 +118,7 @@
public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
- SlicingConfig that = (SlicingConfig) o;
+ NetworkSlicingConfig that = (NetworkSlicingConfig) o;
return mUrspRules.size() == that.mUrspRules.size()
&& mUrspRules.containsAll(that.mUrspRules)
&& mSliceInfo.size() == that.mSliceInfo.size()
diff --git a/telephony/java/android/telephony/data/QosBearerFilter.java b/telephony/java/android/telephony/data/QosBearerFilter.java
index 6c1c653..5642549 100644
--- a/telephony/java/android/telephony/data/QosBearerFilter.java
+++ b/telephony/java/android/telephony/data/QosBearerFilter.java
@@ -31,7 +31,6 @@
import java.util.List;
import java.util.Objects;
-
/**
* Class that stores QOS filter parameters as defined in
* 3gpp 24.008 10.5.6.12 and 3gpp 24.501 9.11.4.13.
diff --git a/telephony/java/android/telephony/data/TrafficDescriptor.java b/telephony/java/android/telephony/data/TrafficDescriptor.java
index d813bc5..f400a5e 100644
--- a/telephony/java/android/telephony/data/TrafficDescriptor.java
+++ b/telephony/java/android/telephony/data/TrafficDescriptor.java
@@ -21,6 +21,7 @@
import android.os.Parcel;
import android.os.Parcelable;
+import java.util.Arrays;
import java.util.Objects;
/**
@@ -31,11 +32,11 @@
*/
public final class TrafficDescriptor implements Parcelable {
private final String mDnn;
- private final String mOsAppId;
+ private final byte[] mOsAppId;
private TrafficDescriptor(@NonNull Parcel in) {
mDnn = in.readString();
- mOsAppId = in.readString();
+ mOsAppId = in.createByteArray();
}
/**
@@ -45,14 +46,15 @@
*
* @hide
*/
- public TrafficDescriptor(String dnn, String osAppId) {
+ public TrafficDescriptor(String dnn, byte[] osAppId) {
mDnn = dnn;
mOsAppId = osAppId;
}
/**
* DNN stands for Data Network Name and represents an APN as defined in 3GPP TS 23.003.
- * @return the DNN of this traffic descriptor.
+ * @return the DNN of this traffic descriptor if one is included by the network, null
+ * otherwise.
*/
public @Nullable String getDataNetworkName() {
return mDnn;
@@ -60,10 +62,11 @@
/**
* OsAppId is the app id as defined in 3GPP TS 24.526 Section 5.2, and it identifies a traffic
- * category.
- * @return the OS App ID of this traffic descriptor.
+ * category. It includes the OS Id component of the field as defined in the specs.
+ * @return the OS App ID of this traffic descriptor if one is included by the network, null
+ * otherwise.
*/
- public @Nullable String getOsAppId() {
+ public @Nullable byte[] getOsAppId() {
return mOsAppId;
}
@@ -80,7 +83,7 @@
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString(mDnn);
- dest.writeString(mOsAppId);
+ dest.writeByteArray(mOsAppId);
}
public static final @NonNull Parcelable.Creator<TrafficDescriptor> CREATOR =
@@ -101,7 +104,7 @@
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TrafficDescriptor that = (TrafficDescriptor) o;
- return Objects.equals(mDnn, that.mDnn) && Objects.equals(mOsAppId, that.mOsAppId);
+ return Objects.equals(mDnn, that.mDnn) && Arrays.equals(mOsAppId, that.mOsAppId);
}
@Override
@@ -121,10 +124,12 @@
* .setDnn("")
* .build();
* </code></pre>
+ *
+ * @hide
*/
public static final class Builder {
private String mDnn = null;
- private String mOsAppId = null;
+ private byte[] mOsAppId = null;
/**
* Default constructor for Builder.
@@ -144,12 +149,12 @@
}
/**
- * Set the OS App ID.
+ * Set the OS App ID (including OS Id as defind in the specs).
*
* @return The same instance of the builder.
*/
@NonNull
- public Builder setOsAppId(@NonNull String osAppId) {
+ public Builder setOsAppId(@NonNull byte[] osAppId) {
this.mOsAppId = osAppId;
return this;
}
diff --git a/telephony/java/android/telephony/data/UrspRule.java b/telephony/java/android/telephony/data/UrspRule.java
index e2c47fd..fbe1999 100644
--- a/telephony/java/android/telephony/data/UrspRule.java
+++ b/telephony/java/android/telephony/data/UrspRule.java
@@ -84,8 +84,8 @@
android.hardware.radio.V1_6.TrafficDescriptor td) {
String dnn = td.dnn.getDiscriminator() == OptionalDnn.hidl_discriminator.noinit
? null : td.dnn.value();
- String osAppId = td.osAppId.getDiscriminator() == OptionalOsAppId.hidl_discriminator.noinit
- ? null : new String(arrayListToPrimitiveArray(td.osAppId.value().osAppId));
+ byte[] osAppId = td.osAppId.getDiscriminator() == OptionalOsAppId.hidl_discriminator.noinit
+ ? null : arrayListToPrimitiveArray(td.osAppId.value().osAppId);
TrafficDescriptor.Builder builder = new TrafficDescriptor.Builder();
if (dnn != null) {
builder.setDataNetworkName(dnn);
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
index 0593615..a540dff 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -23,7 +23,7 @@
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper.Companion.STATUS_BAR_LAYER_NAME
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper.Companion.STATUS_BAR_WINDOW_NAME
-val LAUNCHER_TITLE = arrayOf("Wallpaper", "Launcher", "com.google.android.googlequicksearchbox")
+val HOME_WINDOW_TITLE = arrayOf("Wallpaper", "Launcher")
fun FlickerTestParameter.statusBarWindowIsAlwaysVisible() {
assertWm {
@@ -41,23 +41,23 @@
assertWm {
this.showsAppWindowOnTop(testApp.getPackage())
.then()
- .showsAppWindowOnTop(*LAUNCHER_TITLE)
+ .showsAppWindowOnTop(*HOME_WINDOW_TITLE)
}
}
fun FlickerTestParameter.launcherWindowBecomesVisible() {
assertWm {
- this.hidesBelowAppWindow(*LAUNCHER_TITLE)
+ this.hidesBelowAppWindow(*HOME_WINDOW_TITLE)
.then()
- .showsBelowAppWindow(*LAUNCHER_TITLE)
+ .showsBelowAppWindow(*HOME_WINDOW_TITLE)
}
}
fun FlickerTestParameter.launcherWindowBecomesInvisible() {
assertWm {
- this.showsBelowAppWindow(*LAUNCHER_TITLE)
+ this.showsBelowAppWindow(*HOME_WINDOW_TITLE)
.then()
- .hidesBelowAppWindow(*LAUNCHER_TITLE)
+ .hidesBelowAppWindow(*HOME_WINDOW_TITLE)
}
}
@@ -179,7 +179,7 @@
fun FlickerTestParameter.appLayerReplacesLauncher(appName: String) {
assertLayers {
- this.isVisible(*LAUNCHER_TITLE)
+ this.isVisible(*HOME_WINDOW_TITLE)
.then()
.isVisible(appName)
}
@@ -190,7 +190,7 @@
this.isVisible(testApp.getPackage())
.then()
.isInvisible(testApp.getPackage())
- .isVisible(*LAUNCHER_TITLE)
+ .isVisible(*HOME_WINDOW_TITLE)
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/CommonAssertions.kt
index 6a7309c..01e34d9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/CommonAssertions.kt
@@ -18,11 +18,11 @@
import android.platform.helpers.IAppHelper
import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.LAUNCHER_TITLE
+import com.android.server.wm.flicker.HOME_WINDOW_TITLE
fun FlickerTestParameter.appWindowReplacesLauncherAsTopWindow(testApp: IAppHelper) {
assertWm {
- this.showsAppWindowOnTop(*LAUNCHER_TITLE)
+ this.showsAppWindowOnTop(*HOME_WINDOW_TITLE)
.then()
.showsAppWindowOnTop("Snapshot", testApp.getPackage())
}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/RippleActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/RippleActivity.java
index f6d9a73..487c856 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/RippleActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/RippleActivity.java
@@ -56,6 +56,7 @@
CanvasProperty<Float> mY;
CanvasProperty<Float> mRadius;
CanvasProperty<Float> mProgress;
+ CanvasProperty<Float> mNoisePhase;
CanvasProperty<Paint> mPaint;
RuntimeShader mRuntimeShader;
@@ -99,6 +100,7 @@
mY = CanvasProperty.createFloat(200.0f);
mRadius = CanvasProperty.createFloat(150.0f);
mProgress = CanvasProperty.createFloat(0.0f);
+ mNoisePhase = CanvasProperty.createFloat(0.0f);
Paint p = new Paint();
p.setAntiAlias(true);
@@ -115,7 +117,8 @@
if (canvas.isHardwareAccelerated()) {
RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
- recordingCanvas.drawRipple(mX, mY, mRadius, mPaint, mProgress, mRuntimeShader);
+ recordingCanvas.drawRipple(mX, mY, mRadius, mPaint, mProgress, mNoisePhase,
+ mRuntimeShader);
}
}
@@ -141,6 +144,9 @@
mProgress, mToggle ? 1.0f : 0.0f));
mRunningAnimations.add(new RenderNodeAnimator(
+ mNoisePhase, DURATION));
+
+ mRunningAnimations.add(new RenderNodeAnimator(
mPaint, RenderNodeAnimator.PAINT_ALPHA, 64.0f));
// Will be "chained" to run after the above
diff --git a/tests/net/common/java/ParseExceptionTest.kt b/tests/net/common/java/ParseExceptionTest.kt
new file mode 100644
index 0000000..f17715a
--- /dev/null
+++ b/tests/net/common/java/ParseExceptionTest.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import android.net.ParseException
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import junit.framework.Assert.assertEquals
+import junit.framework.Assert.assertNull
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ParseExceptionTest {
+ @Test
+ fun testConstructor_WithCause() {
+ val testMessage = "Test message"
+ val base = Exception("Test")
+ val exception = ParseException(testMessage, base)
+
+ assertEquals(testMessage, exception.response)
+ assertEquals(base, exception.cause)
+ }
+
+ @Test
+ fun testConstructor_NoCause() {
+ val testMessage = "Test message"
+ val exception = ParseException(testMessage)
+
+ assertEquals(testMessage, exception.response)
+ assertNull(exception.cause)
+ }
+}
\ No newline at end of file
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index 6d852bf..9b74583 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -312,7 +312,7 @@
.addCapability(NET_CAPABILITY_EIMS)
.addCapability(NET_CAPABILITY_NOT_METERED);
if (isAtLeastS()) {
- netCap.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2));
+ netCap.setSubscriptionIds(Set.of(TEST_SUBID1, TEST_SUBID2));
netCap.setUids(uids);
}
if (isAtLeastR()) {
@@ -642,16 +642,16 @@
assertTrue(nc2.appliesToUid(22));
// Verify the subscription id list can be combined only when they are equal.
- nc1.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2));
- nc2.setSubIds(Set.of(TEST_SUBID2));
+ nc1.setSubscriptionIds(Set.of(TEST_SUBID1, TEST_SUBID2));
+ nc2.setSubscriptionIds(Set.of(TEST_SUBID2));
assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1));
- nc2.setSubIds(Set.of());
+ nc2.setSubscriptionIds(Set.of());
assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1));
- nc2.setSubIds(Set.of(TEST_SUBID2, TEST_SUBID1));
+ nc2.setSubscriptionIds(Set.of(TEST_SUBID2, TEST_SUBID1));
nc2.combineCapabilities(nc1);
- assertEquals(Set.of(TEST_SUBID2, TEST_SUBID1), nc2.getSubIds());
+ assertEquals(Set.of(TEST_SUBID2, TEST_SUBID1), nc2.getSubscriptionIds());
}
}
@@ -806,20 +806,20 @@
assertEquals(nc1, nc2);
if (isAtLeastS()) {
- assertThrows(NullPointerException.class, () -> nc1.setSubIds(null));
- nc1.setSubIds(Set.of());
+ assertThrows(NullPointerException.class, () -> nc1.setSubscriptionIds(null));
+ nc1.setSubscriptionIds(Set.of());
nc2.set(nc1);
assertEquals(nc1, nc2);
- nc1.setSubIds(Set.of(TEST_SUBID1));
+ nc1.setSubscriptionIds(Set.of(TEST_SUBID1));
nc2.set(nc1);
assertEquals(nc1, nc2);
- nc2.setSubIds(Set.of(TEST_SUBID2, TEST_SUBID1));
+ nc2.setSubscriptionIds(Set.of(TEST_SUBID2, TEST_SUBID1));
nc2.set(nc1);
assertEquals(nc1, nc2);
- nc2.setSubIds(Set.of(TEST_SUBID3, TEST_SUBID2));
+ nc2.setSubscriptionIds(Set.of(TEST_SUBID3, TEST_SUBID2));
assertNotEquals(nc1, nc2);
}
}
@@ -908,8 +908,8 @@
// satisfy these requests.
final NetworkCapabilities nc = new NetworkCapabilities.Builder()
.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
- .setSubIds(new ArraySet<>(subIds)).build();
- assertEquals(new ArraySet<>(subIds), nc.getSubIds());
+ .setSubscriptionIds(new ArraySet<>(subIds)).build();
+ assertEquals(new ArraySet<>(subIds), nc.getSubscriptionIds());
return nc;
}
@@ -921,11 +921,11 @@
final NetworkCapabilities ncWithoutRequestedIds = capsWithSubIds(TEST_SUBID3);
final NetworkRequest requestWithoutId = new NetworkRequest.Builder().build();
- assertEmpty(requestWithoutId.networkCapabilities.getSubIds());
+ assertEmpty(requestWithoutId.networkCapabilities.getSubscriptionIds());
final NetworkRequest requestWithIds = new NetworkRequest.Builder()
- .setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2)).build();
+ .setSubscriptionIds(Set.of(TEST_SUBID1, TEST_SUBID2)).build();
assertEquals(Set.of(TEST_SUBID1, TEST_SUBID2),
- requestWithIds.networkCapabilities.getSubIds());
+ requestWithIds.networkCapabilities.getSubscriptionIds());
assertFalse(requestWithIds.canBeSatisfiedBy(ncWithoutId));
assertTrue(requestWithIds.canBeSatisfiedBy(ncWithOtherIds));
@@ -1138,8 +1138,8 @@
if (isAtLeastS()) {
final NetworkCapabilities nc2 = new NetworkCapabilities.Builder()
- .setSubIds(Set.of(TEST_SUBID1)).build();
- assertEquals(Set.of(TEST_SUBID1), nc2.getSubIds());
+ .setSubscriptionIds(Set.of(TEST_SUBID1)).build();
+ assertEquals(Set.of(TEST_SUBID1), nc2.getSubscriptionIds());
}
}
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 039ce2f..7ebed39 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -1791,7 +1791,7 @@
assertNull(mCm.getActiveNetworkForUid(Process.myUid()));
// Test getAllNetworks()
assertEmpty(mCm.getAllNetworks());
- assertEmpty(mCm.getAllNetworkStateSnapshot());
+ assertEmpty(mCm.getAllNetworkStateSnapshots());
}
/**
@@ -2668,25 +2668,6 @@
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
- // Bring up wifi with a score of 70.
- // Cell is lingered because it would not satisfy any request, even if it validated.
- mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
- mWiFiNetworkAgent.adjustScore(50);
- mWiFiNetworkAgent.connect(false); // Score: 70
- callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
- defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
- assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
-
- // Tear down wifi.
- mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
- assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
- assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
-
// Bring up wifi, then validate it. Previous versions would immediately tear down cell, but
// it's arguably correct to linger it, since it was the default network before it validated.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
@@ -2991,11 +2972,17 @@
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
- // BUG: the network will no longer linger, even though it's validated and outscored.
- // TODO: fix this.
mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET);
mEthernetNetworkAgent.connect(true);
+ // BUG: with the legacy int-based scoring code, the network will no longer linger, even
+ // though it's validated and outscored.
+ // The new policy-based scoring code fixes this.
+ // TODO: remove the line below and replace with the three commented lines when
+ // the policy-based scoring code is turned on.
callback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent);
+ // callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent);
+ // callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent);
+ // callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent);
assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());
callback.assertNoCallback();
@@ -12029,7 +12016,7 @@
}
@Test
- public void testGetAllNetworkStateSnapshot() throws Exception {
+ public void testGetAllNetworkStateSnapshots() throws Exception {
verifyNoNetwork();
// Setup test cellular network with specified LinkProperties and NetworkCapabilities,
@@ -12053,7 +12040,7 @@
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp, cellNcTemplate);
mCellNetworkAgent.connect(true);
cellCb.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
- List<NetworkStateSnapshot> snapshots = mCm.getAllNetworkStateSnapshot();
+ List<NetworkStateSnapshot> snapshots = mCm.getAllNetworkStateSnapshots();
assertLength(1, snapshots);
// Compose the expected cellular snapshot for verification.
@@ -12075,7 +12062,7 @@
mWiFiNetworkAgent.getNetwork(), wifiNc, new LinkProperties(), null,
ConnectivityManager.TYPE_WIFI);
- snapshots = mCm.getAllNetworkStateSnapshot();
+ snapshots = mCm.getAllNetworkStateSnapshots();
assertLength(2, snapshots);
assertContainsAll(snapshots, cellSnapshot, wifiSnapshot);
@@ -12084,20 +12071,20 @@
// temporary shortage of connectivity of a connected network.
mCellNetworkAgent.suspend();
waitForIdle();
- snapshots = mCm.getAllNetworkStateSnapshot();
+ snapshots = mCm.getAllNetworkStateSnapshots();
assertLength(1, snapshots);
assertEquals(wifiSnapshot, snapshots.get(0));
// Disconnect wifi, verify the snapshots contain nothing.
mWiFiNetworkAgent.disconnect();
waitForIdle();
- snapshots = mCm.getAllNetworkStateSnapshot();
+ snapshots = mCm.getAllNetworkStateSnapshots();
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertLength(0, snapshots);
mCellNetworkAgent.resume();
waitForIdle();
- snapshots = mCm.getAllNetworkStateSnapshot();
+ snapshots = mCm.getAllNetworkStateSnapshots();
assertLength(1, snapshots);
assertEquals(cellSnapshot, snapshots.get(0));
@@ -12602,12 +12589,12 @@
public void testSubIdsClearedWithoutNetworkFactoryPermission() throws Exception {
mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED);
final NetworkCapabilities nc = new NetworkCapabilities();
- nc.setSubIds(Collections.singleton(Process.myUid()));
+ nc.setSubscriptionIds(Collections.singleton(Process.myUid()));
final NetworkCapabilities result =
mService.networkCapabilitiesRestrictedForCallerPermissions(
nc, Process.myPid(), Process.myUid());
- assertTrue(result.getSubIds().isEmpty());
+ assertTrue(result.getSubscriptionIds().isEmpty());
}
@Test
@@ -12616,17 +12603,17 @@
final Set<Integer> subIds = Collections.singleton(Process.myUid());
final NetworkCapabilities nc = new NetworkCapabilities();
- nc.setSubIds(subIds);
+ nc.setSubscriptionIds(subIds);
final NetworkCapabilities result =
mService.networkCapabilitiesRestrictedForCallerPermissions(
nc, Process.myPid(), Process.myUid());
- assertEquals(subIds, result.getSubIds());
+ assertEquals(subIds, result.getSubscriptionIds());
}
private NetworkRequest getRequestWithSubIds() {
return new NetworkRequest.Builder()
- .setSubIds(Collections.singleton(Process.myUid()))
+ .setSubscriptionIds(Collections.singleton(Process.myUid()))
.build();
}
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 9a66343..907cb46 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -696,7 +696,7 @@
.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
.addTransportType(transport);
if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
- ncBuilder.setSubIds(Collections.singleton(subId));
+ ncBuilder.setSubscriptionIds(Collections.singleton(subId));
}
return ncBuilder;
diff --git a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
index 0c7363e..8289e85 100644
--- a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
@@ -189,7 +189,7 @@
private NetworkRequest getWifiRequest(Set<Integer> netCapsSubIds) {
return getExpectedRequestBase()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
- .setSubIds(netCapsSubIds)
+ .setSubscriptionIds(netCapsSubIds)
.build();
}
@@ -201,7 +201,7 @@
}
private NetworkRequest getRouteSelectionRequest(Set<Integer> netCapsSubIds) {
- return getExpectedRequestBase().setSubIds(netCapsSubIds).build();
+ return getExpectedRequestBase().setSubscriptionIds(netCapsSubIds).build();
}
private NetworkRequest.Builder getExpectedRequestBase() {
diff --git a/tools/fonts/fontchain_linter.py b/tools/fonts/fontchain_linter.py
index f0b7595..1d308df 100755
--- a/tools/fonts/fontchain_linter.py
+++ b/tools/fonts/fontchain_linter.py
@@ -4,6 +4,7 @@
import copy
import glob
from os import path
+import re
import sys
from xml.etree import ElementTree
@@ -199,8 +200,9 @@
class FontRecord(object):
- def __init__(self, name, scripts, variant, weight, style, fallback_for, font):
+ def __init__(self, name, psName, scripts, variant, weight, style, fallback_for, font):
self.name = name
+ self.psName = psName
self.scripts = scripts
self.variant = variant
self.weight = weight
@@ -236,6 +238,7 @@
assert variant in {None, 'elegant', 'compact'}, (
'Unexpected value for variant: %s' % variant)
+ trim_re = re.compile(r"^[ \n\r\t]*(.+)[ \n\r\t]*$")
for family in families:
name = family.get('name')
variant = family.get('variant')
@@ -251,6 +254,10 @@
assert child.tag == 'font', (
'Unknown tag <%s>' % child.tag)
font_file = child.text.rstrip()
+
+ m = trim_re.match(font_file)
+ font_file = m.group(1)
+
weight = int(child.get('weight'))
assert weight % 100 == 0, (
'Font weight "%d" is not a multiple of 100.' % weight)
@@ -270,11 +277,12 @@
if index:
index = int(index)
- if not path.exists(path.join(_fonts_dir, font_file)):
+ if not path.exists(path.join(_fonts_dir, m.group(1))):
continue # Missing font is a valid case. Just ignore the missing font files.
record = FontRecord(
name,
+ child.get('postScriptName'),
frozenset(scripts),
variant,
weight,
@@ -664,6 +672,37 @@
break
assert_font_supports_none_of_chars(record.font, cjk_punctuation, name)
+def getPostScriptName(font):
+ font_file, index = font
+ font_path = path.join(_fonts_dir, font_file)
+ if index is not None:
+ # Use the first font file in the collection for resolving post script name.
+ ttf = ttLib.TTFont(font_path, fontNumber=0)
+ else:
+ ttf = ttLib.TTFont(font_path)
+
+ nameTable = ttf['name']
+ for name in nameTable.names:
+ if (name.nameID == 6 and name.platformID == 3 and name.platEncID == 1
+ and name.langID == 0x0409):
+ return str(name)
+
+def check_canonical_name():
+ for record in _all_fonts:
+ file_name, index = record.font
+
+ psName = getPostScriptName(record.font)
+ if record.psName:
+ # If fonts element has postScriptName attribute, it should match with the PostScript
+ # name in the name table.
+ assert psName == record.psName, ('postScriptName attribute %s should match with %s' % (
+ record.psName, psName))
+ else:
+ # If fonts element doesn't have postScriptName attribute, the file name should match
+ # with the PostScript name in the name table.
+ assert psName == file_name[:-4], ('file name %s should match with %s' % (
+ file_name, psName))
+
def main():
global _fonts_dir
@@ -682,6 +721,8 @@
check_cjk_punctuation()
+ check_canonical_name()
+
check_emoji = sys.argv[2]
if check_emoji == 'true':
ucd_path = sys.argv[3]
diff --git a/tools/hiddenapi/checksorted_sha.sh b/tools/hiddenapi/checksorted_sha.sh
deleted file mode 100755
index 72fb867..0000000
--- a/tools/hiddenapi/checksorted_sha.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-set -e
-LOCAL_DIR="$( dirname ${BASH_SOURCE} )"
-git show --name-only --pretty=format: $1 | grep "hiddenapi/hiddenapi-.*txt" | while read file; do
- diff <(git show $1:$file) <(git show $1:$file | $LOCAL_DIR/sort_api.sh ) || {
- echo -e "\e[1m\e[31m$file $1 is not sorted or contains duplicates. To sort it correctly:\e[0m"
- echo -e "\e[33m${LOCAL_DIR}/sort_api.sh $PWD/$file\e[0m"
- exit 1
- }
-done
diff --git a/tools/hiddenapi/sort_api.sh b/tools/hiddenapi/sort_api.sh
deleted file mode 100755
index 710da40..0000000
--- a/tools/hiddenapi/sort_api.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-set -e
-if [ -z "$1" ]; then
- source_list=/dev/stdin
- dest_list=/dev/stdout
-else
- source_list="$1"
- dest_list="$1"
-fi
-# Load the file
-readarray A < "$source_list"
-# Sort
-IFS=$'\n'
-# Stash away comments
-C=( $(grep -E '^#' <<< "${A[*]}" || :) )
-A=( $(grep -v -E '^#' <<< "${A[*]}" || :) )
-# Sort entries
-A=( $(LC_COLLATE=C sort -f <<< "${A[*]}") )
-A=( $(uniq <<< "${A[*]}") )
-# Concatenate comments and entries
-A=( ${C[*]} ${A[*]} )
-unset IFS
-# Dump array back into the file
-if [ ${#A[@]} -ne 0 ]; then
- printf '%s\n' "${A[@]}" > "$dest_list"
-fi
diff --git a/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
index da0571ba..3b75660 100644
--- a/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
+++ b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
@@ -117,13 +117,13 @@
/**
* Interface used to listen country code event
*/
- public interface CountryCodeChangeListener {
+ public interface CountryCodeChangedListener {
/**
* Called when country code changed.
*
- * @param countryCode A new country code which is 2-Character alphanumeric.
+ * @param countryCode An ISO-3166-alpha2 country code which is 2-Character alphanumeric.
*/
- void onChanged(@NonNull String countryCode);
+ void onCountryCodeChanged(@NonNull String countryCode);
}
/**
@@ -163,27 +163,27 @@
/** @hide */
@VisibleForTesting
public class WificondEventHandler extends IWificondEventCallback.Stub {
- private Map<CountryCodeChangeListener, Executor> mCountryCodeChangeListenerHolder =
+ private Map<CountryCodeChangedListener, Executor> mCountryCodeChangedListenerHolder =
new HashMap<>();
/**
- * Register CountryCodeChangeListener with pid.
+ * Register CountryCodeChangedListener with pid.
*
* @param executor The Executor on which to execute the callbacks.
* @param listener listener for country code changed events.
*/
- public void registerCountryCodeChangeListener(Executor executor,
- CountryCodeChangeListener listener) {
- mCountryCodeChangeListenerHolder.put(listener, executor);
+ public void registerCountryCodeChangedListener(Executor executor,
+ CountryCodeChangedListener listener) {
+ mCountryCodeChangedListenerHolder.put(listener, executor);
}
/**
- * Unregister CountryCodeChangeListener with pid.
+ * Unregister CountryCodeChangedListener with pid.
*
* @param listener listener which registered country code changed events.
*/
- public void unregisterCountryCodeChangeListener(CountryCodeChangeListener listener) {
- mCountryCodeChangeListenerHolder.remove(listener);
+ public void unregisterCountryCodeChangedListener(CountryCodeChangedListener listener) {
+ mCountryCodeChangedListenerHolder.remove(listener);
}
@Override
@@ -191,8 +191,8 @@
Log.d(TAG, "OnRegDomainChanged " + countryCode);
final long token = Binder.clearCallingIdentity();
try {
- mCountryCodeChangeListenerHolder.forEach((listener, executor) -> {
- executor.execute(() -> listener.onChanged(countryCode));
+ mCountryCodeChangedListenerHolder.forEach((listener, executor) -> {
+ executor.execute(() -> listener.onCountryCodeChanged(countryCode));
});
} finally {
Binder.restoreCallingIdentity(token);
@@ -1240,25 +1240,25 @@
* @param listener listener for country code changed events.
* @return true on success, false on failure.
*/
- public boolean registerCountryCodeChangeListener(@NonNull @CallbackExecutor Executor executor,
- @NonNull CountryCodeChangeListener listener) {
+ public boolean registerCountryCodeChangedListener(@NonNull @CallbackExecutor Executor executor,
+ @NonNull CountryCodeChangedListener listener) {
if (!retrieveWificondAndRegisterForDeath()) {
return false;
}
Log.d(TAG, "registerCountryCodeEventListener called");
- mWificondEventHandler.registerCountryCodeChangeListener(executor, listener);
+ mWificondEventHandler.registerCountryCodeChangedListener(executor, listener);
return true;
}
/**
- * Unregister CountryCodeChangeListener with pid.
+ * Unregister CountryCodeChangedListener with pid.
*
* @param listener listener which registered country code changed events.
*/
- public void unregisterCountryCodeChangeListener(@NonNull CountryCodeChangeListener listener) {
+ public void unregisterCountryCodeChangedListener(@NonNull CountryCodeChangedListener listener) {
Log.d(TAG, "unregisterCountryCodeEventListener called");
- mWificondEventHandler.unregisterCountryCodeChangeListener(listener);
+ mWificondEventHandler.unregisterCountryCodeChangedListener(listener);
}
/**
diff --git a/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java b/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java
index 98a0042..3fb2301 100644
--- a/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/nl80211/WifiNl80211ManagerTest.java
@@ -98,9 +98,9 @@
@Mock
private WifiNl80211Manager.PnoScanRequestCallback mPnoScanRequestCallback;
@Mock
- private WifiNl80211Manager.CountryCodeChangeListener mCountryCodeChangeListener;
+ private WifiNl80211Manager.CountryCodeChangedListener mCountryCodeChangedListener;
@Mock
- private WifiNl80211Manager.CountryCodeChangeListener mCountryCodeChangeListener2;
+ private WifiNl80211Manager.CountryCodeChangedListener mCountryCodeChangedListener2;
@Mock
private Context mContext;
private TestLooper mLooper;
@@ -768,25 +768,25 @@
}
/**
- * Ensures callback works after register CountryCodeChangeListener.
+ * Ensures callback works after register CountryCodeChangedListener.
*/
@Test
- public void testCountryCodeChangeListenerInvocation() throws Exception {
- assertTrue(mWificondControl.registerCountryCodeChangeListener(
- Runnable::run, mCountryCodeChangeListener));
- assertTrue(mWificondControl.registerCountryCodeChangeListener(
- Runnable::run, mCountryCodeChangeListener2));
+ public void testCountryCodeChangedListenerInvocation() throws Exception {
+ assertTrue(mWificondControl.registerCountryCodeChangedListener(
+ Runnable::run, mCountryCodeChangedListener));
+ assertTrue(mWificondControl.registerCountryCodeChangedListener(
+ Runnable::run, mCountryCodeChangedListener2));
mWificondEventHandler.OnRegDomainChanged(TEST_COUNTRY_CODE);
- verify(mCountryCodeChangeListener).onChanged(TEST_COUNTRY_CODE);
- verify(mCountryCodeChangeListener2).onChanged(TEST_COUNTRY_CODE);
+ verify(mCountryCodeChangedListener).onCountryCodeChanged(TEST_COUNTRY_CODE);
+ verify(mCountryCodeChangedListener2).onCountryCodeChanged(TEST_COUNTRY_CODE);
- reset(mCountryCodeChangeListener);
- reset(mCountryCodeChangeListener2);
- mWificondControl.unregisterCountryCodeChangeListener(mCountryCodeChangeListener2);
+ reset(mCountryCodeChangedListener);
+ reset(mCountryCodeChangedListener2);
+ mWificondControl.unregisterCountryCodeChangedListener(mCountryCodeChangedListener2);
mWificondEventHandler.OnRegDomainChanged(TEST_COUNTRY_CODE);
- verify(mCountryCodeChangeListener).onChanged(TEST_COUNTRY_CODE);
- verify(mCountryCodeChangeListener2, never()).onChanged(TEST_COUNTRY_CODE);
+ verify(mCountryCodeChangedListener).onCountryCodeChanged(TEST_COUNTRY_CODE);
+ verify(mCountryCodeChangedListener2, never()).onCountryCodeChanged(TEST_COUNTRY_CODE);
}
/**