Merge "Drop prebuilt files to android source tree." into sc-dev
diff --git a/.prebuilt_info/OWNERS b/.prebuilt_info/OWNERS
new file mode 100644
index 0000000..eb8b89b
--- /dev/null
+++ b/.prebuilt_info/OWNERS
@@ -0,0 +1 @@
+per-file prebuilt_info_packages_CtsShim_*.asciipb = file:/packages/CtsShim/OWNERS
diff --git a/Android.bp b/Android.bp
index c5980b9..622b2c6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -584,7 +584,7 @@
"android.hardware.vibrator-V2-java",
"android.security.apc-java",
"android.security.authorization-java",
- "android.security.usermanager-java",
+ "android.security.maintenance-java",
"android.security.vpnprofilestore-java",
"android.system.keystore2-V1-java",
"android.system.suspend.control.internal-java",
diff --git a/TEST_MAPPING b/TEST_MAPPING
index d08c527..9ceef6b 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -82,5 +82,65 @@
{
"name": "ManagedProfileLifecycleStressTest"
}
- ]
+ ],
+ "auto-postsubmit": [
+ // Test tag for automotive targets. These are only running in postsubmit so as to harden the
+ // automotive targets to avoid introducing additional test flake and build time. The plan for
+ // presubmit testing for auto is to augment the existing tests to cover auto use cases as well.
+ // Additionally, this tag is used in targeted test suites to limit resource usage on the test
+ // infra during the hardening phase.
+ // TODO: this tag to be removed once the above is no longer an issue.
+ {
+ "name": "FrameworksUiServicesTests",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
+ "name": "ExtServicesUnitTests",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
+ "name": "TestablesTests",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
+ "name": "FrameworksCoreTests",
+ "options": [
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ }
+ ]
+ },
+ {
+ "name": "FrameworksServicesTests",
+ "options": [
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ }
+ ]
+ }
+ ]
}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
index da446bf..a62bb50 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
@@ -19,19 +19,10 @@
import android.annotation.NonNull;
import android.annotation.SystemService;
import android.content.Context;
-import android.os.Bundle;
-import android.os.ParcelableException;
-import android.os.RemoteException;
-import com.android.internal.infra.AndroidFuture;
import com.android.internal.util.Preconditions;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
import java.util.Objects;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -246,349 +237,9 @@
mService, mContext.getUserId(), getPackageName(), executor, callback);
}
- /**
- * Sets the schema being used by documents provided to the {@link #putDocuments} method.
- *
- * <p>The schema provided here is compared to the stored copy of the schema previously supplied
- * to {@link #setSchema}, if any, to determine how to treat existing documents. The following
- * types of schema modifications are always safe and are made without deleting any existing
- * documents:
- *
- * <ul>
- * <li>Addition of new types
- * <li>Addition of new {@link
- * android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} or
- * {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED
- * REPEATED} properties to a type
- * <li>Changing the cardinality of a data type to be less restrictive (e.g. changing an {@link
- * android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL}
- * property into a {@link
- * android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED REPEATED}
- * property.
- * </ul>
- *
- * <p>The following types of schema changes are not backwards-compatible:
- *
- * <ul>
- * <li>Removal of an existing type
- * <li>Removal of a property from a type
- * <li>Changing the data type ({@code boolean}, {@code long}, etc.) of an existing property
- * <li>For properties of {@code GenericDocument} type, changing the schema type of {@code
- * GenericDocument}s of that property
- * <li>Changing the cardinality of a data type to be more restrictive (e.g. changing an {@link
- * android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL}
- * property into a {@link
- * android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED REQUIRED}
- * property).
- * <li>Adding a {@link
- * android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED REQUIRED}
- * property.
- * </ul>
- *
- * <p>Supplying a schema with such changes will result in this call returning an {@link
- * AppSearchResult} with a code of {@link AppSearchResult#RESULT_INVALID_SCHEMA} and an error
- * message describing the incompatibility. In this case the previously set schema will remain
- * active.
- *
- * <p>If you need to make non-backwards-compatible changes as described above, instead use the
- * {@link #setSchema(List, boolean)} method with the {@code forceOverride} parameter set to
- * {@code true}.
- *
- * <p>It is a no-op to set the same schema as has been previously set; this is handled
- * efficiently.
- *
- * @param request The schema update request.
- * @return the result of performing this operation.
- * @hide
- * @deprecated use {@link AppSearchSession#setSchema} instead.
- */
- @NonNull
- public AppSearchResult<Void> setSchema(@NonNull SetSchemaRequest request) {
- Preconditions.checkNotNull(request);
- // TODO: This should use com.android.internal.infra.RemoteStream or another mechanism to
- // avoid binder limits.
- List<Bundle> schemaBundles = new ArrayList<>(request.getSchemas().size());
- for (AppSearchSchema schema : request.getSchemas()) {
- schemaBundles.add(schema.getBundle());
- }
- AndroidFuture<AppSearchResult> future = new AndroidFuture<>();
- try {
- mService.setSchema(
- getPackageName(),
- DEFAULT_DATABASE_NAME,
- schemaBundles,
- new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
- /*schemasPackageAccessible=*/ Collections.emptyMap(),
- request.isForceOverride(),
- mContext.getUserId(),
- new IAppSearchResultCallback.Stub() {
- public void onResult(AppSearchResult result) {
- future.complete(result);
- }
- });
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- return getFutureOrThrow(future);
- }
-
- /**
- * Index {@link GenericDocument}s into AppSearch.
- *
- * <p>You should not call this method directly; instead, use the {@code
- * AppSearch#putDocuments()} API provided by JetPack.
- *
- * <p>Each {@link GenericDocument}'s {@code schemaType} field must be set to the name of a
- * schema type previously registered via the {@link #setSchema} method.
- *
- * @param request {@link PutDocumentsRequest} containing documents to be indexed
- * @return The pending result of performing this operation. The keys of the returned {@link
- * AppSearchBatchResult} are the URIs of the input documents. The values are {@code null} if
- * they were successfully indexed, or a failed {@link AppSearchResult} otherwise.
- * @throws RuntimeException If an error occurred during the execution.
- * @hide
- * @deprecated use {@link AppSearchSession#put} instead.
- */
- public AppSearchBatchResult<String, Void> putDocuments(@NonNull PutDocumentsRequest request) {
- // TODO(b/146386470): Transmit these documents as a RemoteStream instead of sending them in
- // one big list.
- List<GenericDocument> documents = request.getGenericDocuments();
- List<Bundle> documentBundles = new ArrayList<>(documents.size());
- for (int i = 0; i < documents.size(); i++) {
- documentBundles.add(documents.get(i).getBundle());
- }
- AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
- try {
- mService.putDocuments(
- getPackageName(),
- DEFAULT_DATABASE_NAME,
- documentBundles,
- mContext.getUserId(),
- new IAppSearchBatchResultCallback.Stub() {
- public void onResult(AppSearchBatchResult result) {
- future.complete(result);
- }
-
- public void onSystemError(ParcelableException exception) {
- future.completeExceptionally(exception);
- }
- });
- } catch (RemoteException e) {
- future.completeExceptionally(e);
- }
- return getFutureOrThrow(future);
- }
-
- /**
- * Retrieves {@link GenericDocument}s by URI.
- *
- * <p>You should not call this method directly; instead, use the {@code
- * AppSearch#getDocuments()} API provided by JetPack.
- *
- * @param request {@link GetByUriRequest} containing URIs to be retrieved.
- * @return The pending result of performing this operation. The keys of the returned {@link
- * AppSearchBatchResult} are the input URIs. The values are the returned {@link
- * GenericDocument}s on success, or a failed {@link AppSearchResult} otherwise. URIs that
- * are not found will return a failed {@link AppSearchResult} with a result code of {@link
- * AppSearchResult#RESULT_NOT_FOUND}.
- * @throws RuntimeException If an error occurred during the execution.
- * @hide
- * @deprecated use {@link AppSearchSession#getByUri} instead.
- */
- public AppSearchBatchResult<String, GenericDocument> getByUri(
- @NonNull GetByUriRequest request) {
- // TODO(b/146386470): Transmit the result documents as a RemoteStream instead of sending
- // them in one big list.
- List<String> uris = new ArrayList<>(request.getUris());
- AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
- try {
- mService.getDocuments(
- getPackageName(),
- DEFAULT_DATABASE_NAME,
- request.getNamespace(),
- uris,
- request.getProjectionsInternal(),
- mContext.getUserId(),
- new IAppSearchBatchResultCallback.Stub() {
- public void onResult(AppSearchBatchResult result) {
- future.complete(result);
- }
-
- public void onSystemError(ParcelableException exception) {
- future.completeExceptionally(exception);
- }
- });
- } catch (RemoteException e) {
- future.completeExceptionally(e);
- }
-
- // Translate from document bundles to GenericDocument instances
- AppSearchBatchResult<String, Bundle> bundleResult = getFutureOrThrow(future);
- AppSearchBatchResult.Builder<String, GenericDocument> documentResultBuilder =
- new AppSearchBatchResult.Builder<>();
-
- // Translate successful results
- for (Map.Entry<String, Bundle> bundleEntry : bundleResult.getSuccesses().entrySet()) {
- GenericDocument document;
- try {
- document = new GenericDocument(bundleEntry.getValue());
- } catch (Throwable t) {
- // These documents went through validation, so how could this fail? We must have
- // done something wrong.
- documentResultBuilder.setFailure(
- bundleEntry.getKey(),
- AppSearchResult.RESULT_INTERNAL_ERROR,
- t.getMessage());
- continue;
- }
- documentResultBuilder.setSuccess(bundleEntry.getKey(), document);
- }
-
- // Translate failed results
- for (Map.Entry<String, AppSearchResult<Bundle>> bundleEntry :
- bundleResult.getFailures().entrySet()) {
- documentResultBuilder.setFailure(
- bundleEntry.getKey(),
- bundleEntry.getValue().getResultCode(),
- bundleEntry.getValue().getErrorMessage());
- }
-
- return documentResultBuilder.build();
- }
-
- /**
- * Searches a document based on a given query string.
- *
- * <p>You should not call this method directly; instead, use the {@code AppSearch#query()} API
- * provided by JetPack.
- *
- * <p>Currently we support following features in the raw query format:
- *
- * <ul>
- * <li>AND
- * <p>AND joins (e.g. “match documents that have both the terms ‘dog’ and ‘cat’”).
- * Example: hello world matches documents that have both ‘hello’ and ‘world’
- * <li>OR
- * <p>OR joins (e.g. “match documents that have either the term ‘dog’ or ‘cat’”). Example:
- * dog OR puppy
- * <li>Exclusion
- * <p>Exclude a term (e.g. “match documents that do not have the term ‘dog’”). Example:
- * -dog excludes the term ‘dog’
- * <li>Grouping terms
- * <p>Allow for conceptual grouping of subqueries to enable hierarchical structures (e.g.
- * “match documents that have either ‘dog’ or ‘puppy’, and either ‘cat’ or ‘kitten’”).
- * Example: (dog puppy) (cat kitten) two one group containing two terms.
- * <li>Property restricts
- * <p>Specifies which properties of a document to specifically match terms in (e.g. “match
- * documents where the ‘subject’ property contains ‘important’”). Example:
- * subject:important matches documents with the term ‘important’ in the ‘subject’ property
- * <li>Schema type restricts
- * <p>This is similar to property restricts, but allows for restricts on top-level
- * document fields, such as schema_type. Clients should be able to limit their query to
- * documents of a certain schema_type (e.g. “match documents that are of the ‘Email’
- * schema_type”). Example: { schema_type_filters: “Email”, “Video”,query: “dog” } will
- * match documents that contain the query term ‘dog’ and are of either the ‘Email’ schema
- * type or the ‘Video’ schema type.
- * </ul>
- *
- * @param queryExpression Query String to search.
- * @param searchSpec Spec for setting filters, raw query etc.
- * @throws RuntimeException If an error occurred during the execution.
- * @hide
- * @deprecated use AppSearchSession#query instead.
- */
- @NonNull
- public AppSearchResult<List<SearchResult>> query(
- @NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
- // TODO(b/146386470): Transmit the result documents as a RemoteStream instead of sending
- // them in one big list.
- AndroidFuture<AppSearchResult> future = new AndroidFuture<>();
- try {
- mService.query(
- getPackageName(),
- DEFAULT_DATABASE_NAME,
- queryExpression,
- searchSpec.getBundle(),
- mContext.getUserId(),
- new IAppSearchResultCallback.Stub() {
- public void onResult(AppSearchResult result) {
- future.complete(result);
- }
- });
- AppSearchResult<Bundle> bundleResult = getFutureOrThrow(future);
- if (!bundleResult.isSuccess()) {
- return AppSearchResult.newFailedResult(
- bundleResult.getResultCode(), bundleResult.getErrorMessage());
- }
- SearchResultPage searchResultPage = new SearchResultPage(bundleResult.getResultValue());
- return AppSearchResult.newSuccessfulResult(searchResultPage.getResults());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- } catch (Throwable t) {
- return AppSearchResult.throwableToFailedResult(t);
- }
- }
-
- /**
- * Removes {@link GenericDocument}s by URI.
- *
- * <p>You should not call this method directly; instead, use the {@code AppSearch#delete()} API
- * provided by JetPack.
- *
- * @param request Request containing URIs to be removed.
- * @return The pending result of performing this operation. The keys of the returned {@link
- * AppSearchBatchResult} are the input URIs. The values are {@code null} on success, or a
- * failed {@link AppSearchResult} otherwise. URIs that are not found will return a failed
- * {@link AppSearchResult} with a result code of {@link AppSearchResult#RESULT_NOT_FOUND}.
- * @throws RuntimeException If an error occurred during the execution.
- * @hide
- * @deprecated use {@link AppSearchSession#remove} instead.
- */
- public AppSearchBatchResult<String, Void> removeByUri(@NonNull RemoveByUriRequest request) {
- List<String> uris = new ArrayList<>(request.getUris());
- AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>();
- try {
- mService.removeByUri(
- getPackageName(),
- DEFAULT_DATABASE_NAME,
- request.getNamespace(),
- uris,
- mContext.getUserId(),
- new IAppSearchBatchResultCallback.Stub() {
- public void onResult(AppSearchBatchResult result) {
- future.complete(result);
- }
-
- public void onSystemError(ParcelableException exception) {
- future.completeExceptionally(exception);
- }
- });
- } catch (RemoteException e) {
- future.completeExceptionally(e);
- }
- return getFutureOrThrow(future);
- }
-
/** Returns the package name that should be used for uid verification. */
@NonNull
private String getPackageName() {
return mContext.getOpPackageName();
}
-
- private static <T> T getFutureOrThrow(@NonNull AndroidFuture<T> future) {
- try {
- return future.get();
- } catch (Throwable e) {
- if (e instanceof ExecutionException) {
- e = e.getCause();
- }
- if (e instanceof RuntimeException) {
- throw (RuntimeException) e;
- }
- if (e instanceof Error) {
- throw (Error) e;
- }
- throw new RuntimeException(e);
- }
- }
}
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreIdleJobService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreIdleJobService.java
index 4b0f719..999860f 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreIdleJobService.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreIdleJobService.java
@@ -42,7 +42,7 @@
blobStoreManagerInternal.onIdleMaintenance();
jobFinished(params, false);
});
- return false;
+ return true;
}
@Override
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index b7a3f10..6967d81 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -59,6 +59,9 @@
* constraint on the JobInfo object that you are creating. Otherwise, the builder would throw an
* exception when building. From Android version {@link Build.VERSION_CODES#Q} and onwards, it is
* valid to schedule jobs with no constraints.
+ * <p> Prior to Android version {@link Build.VERSION_CODES#S}, jobs could only have a maximum of 100
+ * jobs scheduled at a time. Starting with Android version {@link Build.VERSION_CODES#S}, that limit
+ * has been increased to 150. Expedited jobs also count towards the limit.
* <p> In Android version {@link Build.VERSION_CODES#LOLLIPOP}, jobs had a maximum execution time
* of one minute. Starting with Android version {@link Build.VERSION_CODES#M} and ending with
* Android version {@link Build.VERSION_CODES#R}, jobs had a maximum execution time of 10 minutes.
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java b/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java
index 0c4fcb4..6e4a5a0 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.os.DeviceIdleManager;
import android.os.IDeviceIdleController;
+import android.os.PowerExemptionManager;
import android.os.PowerWhitelistManager;
/**
@@ -52,5 +53,8 @@
SystemServiceRegistry.registerContextAwareService(
Context.POWER_WHITELIST_MANAGER, PowerWhitelistManager.class,
PowerWhitelistManager::new);
+ SystemServiceRegistry.registerContextAwareService(
+ Context.POWER_EXEMPTION_SERVICE, PowerExemptionManager.class,
+ PowerExemptionManager::new);
}
}
diff --git a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
new file mode 100644
index 0000000..8445335
--- /dev/null
+++ b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
@@ -0,0 +1,626 @@
+/*
+ * 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.os;
+
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
+import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT;
+import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI;
+import static android.app.ActivityManager.PROCESS_STATE_TOP;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.content.Context;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Interface to access and modify the permanent and temporary power save allow list. The two lists
+ * are kept separately. Apps placed on the permanent allow list are only removed via an explicit
+ * {@link #removeFromAllowList(String)} call. Apps allow-listed by default by the system cannot be
+ * removed. Apps placed on the temporary allow list are removed from that allow list after a
+ * predetermined amount of time.
+ *
+ * @hide
+ */
+@SystemApi
+@SystemService(Context.POWER_EXEMPTION_SERVICE)
+public class PowerExemptionManager {
+ private final Context mContext;
+ // Proxy to DeviceIdleController for now
+ // TODO: migrate to PowerExemptionController
+ private final IDeviceIdleController mService;
+
+ /**
+ * Indicates that an unforeseen event has occurred and the app should be allow-listed to handle
+ * it.
+ */
+ public static final int EVENT_UNSPECIFIED = 0;
+
+ /**
+ * Indicates that an SMS event has occurred and the app should be allow-listed to handle it.
+ */
+ public static final int EVENT_SMS = 1;
+
+ /**
+ * Indicates that an MMS event has occurred and the app should be allow-listed to handle it.
+ */
+ public static final int EVENT_MMS = 2;
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"EVENT_"}, value = {
+ EVENT_UNSPECIFIED,
+ EVENT_SMS,
+ EVENT_MMS,
+ })
+ public @interface AllowListEvent {
+ }
+
+ /**
+ * Allow the temp allow list behavior, plus allow foreground service start from background.
+ */
+ public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED = 0;
+ /**
+ * Only allow the temp allow list behavior, not allow foreground service start from background.
+ */
+ public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED = 1;
+
+ /**
+ * The list of temp allow list types.
+ * @hide
+ */
+ @IntDef(flag = true, prefix = { "TEMPORARY_ALLOW_LIST_TYPE_" }, value = {
+ TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
+ TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TempAllowListType {}
+
+ /* Reason codes for BG-FGS-launch. */
+ /**
+ * BG-FGS-launch is denied.
+ * @hide
+ */
+ public static final int REASON_DENIED = -1;
+
+ /* Reason code range 0-9 are reserved for default reasons */
+ /**
+ * The default reason code if reason is unknown.
+ */
+ public static final int REASON_UNKNOWN = 0;
+ /**
+ * Use REASON_OTHER if there is no better choice.
+ */
+ public static final int REASON_OTHER = 1;
+
+ /* Reason code range 10-49 are reserved for BG-FGS-launch allowed proc states */
+ /** @hide */
+ public static final int REASON_PROC_STATE_PERSISTENT = 10;
+ /** @hide */
+ public static final int REASON_PROC_STATE_PERSISTENT_UI = 11;
+ /** @hide */
+ public static final int REASON_PROC_STATE_TOP = 12;
+ /** @hide */
+ public static final int REASON_PROC_STATE_BTOP = 13;
+ /** @hide */
+ public static final int REASON_PROC_STATE_FGS = 14;
+ /** @hide */
+ public static final int REASON_PROC_STATE_BFGS = 15;
+
+ /* Reason code range 50-99 are reserved for BG-FGS-launch allowed reasons */
+ /** @hide */
+ public static final int REASON_UID_VISIBLE = 50;
+ /** @hide */
+ public static final int REASON_SYSTEM_UID = 51;
+ /** @hide */
+ public static final int REASON_ACTIVITY_STARTER = 52;
+ /** @hide */
+ public static final int REASON_START_ACTIVITY_FLAG = 53;
+ /** @hide */
+ public static final int REASON_FGS_BINDING = 54;
+ /** @hide */
+ public static final int REASON_DEVICE_OWNER = 55;
+ /** @hide */
+ public static final int REASON_PROFILE_OWNER = 56;
+ /** @hide */
+ public static final int REASON_COMPANION_DEVICE_MANAGER = 57;
+ /**
+ * START_ACTIVITIES_FROM_BACKGROUND permission.
+ * @hide
+ */
+ public static final int REASON_BACKGROUND_ACTIVITY_PERMISSION = 58;
+ /**
+ * START_FOREGROUND_SERVICES_FROM_BACKGROUND permission.
+ * @hide
+ */
+ public static final int REASON_BACKGROUND_FGS_PERMISSION = 59;
+ /** @hide */
+ public static final int REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION = 60;
+ /** @hide */
+ public static final int REASON_INSTR_BACKGROUND_FGS_PERMISSION = 61;
+ /** @hide */
+ public static final int REASON_SYSTEM_ALERT_WINDOW_PERMISSION = 62;
+ /** @hide */
+ public static final int REASON_DEVICE_DEMO_MODE = 63;
+ /** @hide */
+ public static final int REASON_EXEMPTED_PACKAGE = 64;
+ /** @hide */
+ public static final int REASON_ALLOWLISTED_PACKAGE = 65;
+ /** @hide */
+ public static final int REASON_APPOP = 66;
+
+ /* BG-FGS-launch is allowed by temp-allow-list or system-allow-list.
+ Reason code for temp and system allow list starts here.
+ Reason code range 100-199 are reserved for public reasons. */
+ /**
+ * Set temp-allow-list for location geofence purpose.
+ */
+ public static final int REASON_GEOFENCING = 100;
+ /**
+ * Set temp-allow-list for server push messaging.
+ */
+ public static final int REASON_PUSH_MESSAGING = 101;
+ /**
+ * Set temp-allow-list for server push messaging over the quota.
+ */
+ public static final int REASON_PUSH_MESSAGING_OVER_QUOTA = 102;
+ /**
+ * Set temp-allow-list for activity recognition.
+ */
+ public static final int REASON_ACTIVITY_RECOGNITION = 103;
+
+ /* Reason code range 200-299 are reserved for broadcast actions */
+ /**
+ * Broadcast ACTION_BOOT_COMPLETED.
+ * @hide
+ */
+ public static final int REASON_BOOT_COMPLETED = 200;
+ /**
+ * Broadcast ACTION_PRE_BOOT_COMPLETED.
+ * @hide
+ */
+ public static final int REASON_PRE_BOOT_COMPLETED = 201;
+ /**
+ * Broadcast ACTION_LOCKED_BOOT_COMPLETED.
+ * @hide
+ */
+ public static final int REASON_LOCKED_BOOT_COMPLETED = 202;
+
+ /* Reason code range 300-399 are reserved for other internal reasons */
+ /**
+ * Device idle system allow list, including EXCEPT-IDLE
+ * @hide
+ */
+ public static final int REASON_SYSTEM_ALLOW_LISTED = 300;
+ /** @hide */
+ public static final int REASON_ALARM_MANAGER_ALARM_CLOCK = 301;
+ /**
+ * AlarmManagerService.
+ * @hide
+ */
+ public static final int REASON_ALARM_MANAGER_WHILE_IDLE = 302;
+ /**
+ * ActiveServices.
+ * @hide
+ */
+ public static final int REASON_SERVICE_LAUNCH = 303;
+ /**
+ * KeyChainSystemService.
+ * @hide
+ */
+ public static final int REASON_KEY_CHAIN = 304;
+ /**
+ * PackageManagerService.
+ * @hide
+ */
+ public static final int REASON_PACKAGE_VERIFIER = 305;
+ /**
+ * SyncManager.
+ * @hide
+ */
+ public static final int REASON_SYNC_MANAGER = 306;
+ /**
+ * DomainVerificationProxyV1.
+ * @hide
+ */
+ public static final int REASON_DOMAIN_VERIFICATION_V1 = 307;
+ /**
+ * DomainVerificationProxyV2.
+ * @hide
+ */
+ public static final int REASON_DOMAIN_VERIFICATION_V2 = 308;
+ /** @hide */
+ public static final int REASON_VPN = 309;
+ /**
+ * NotificationManagerService.
+ * @hide
+ */
+ public static final int REASON_NOTIFICATION_SERVICE = 310;
+ /**
+ * Broadcast ACTION_MY_PACKAGE_REPLACED.
+ * @hide
+ */
+ public static final int REASON_PACKAGE_REPLACED = 311;
+ /**
+ * LocationProviderManager.
+ * @hide
+ */
+ public static final int REASON_LOCATION_PROVIDER = 312;
+ /**
+ * MediaButtonReceiver.
+ * @hide
+ */
+ public static final int REASON_MEDIA_BUTTON = 313;
+ /**
+ * InboundSmsHandler.
+ * @hide
+ */
+ public static final int REASON_EVENT_SMS = 314;
+ /**
+ * InboundSmsHandler.
+ * @hide
+ */
+ public static final int REASON_EVENT_MMS = 315;
+ /**
+ * Shell app.
+ * @hide
+ */
+ public static final int REASON_SHELL = 316;
+
+ /**
+ * The list of BG-FGS-Launch and temp-allow-list reason code.
+ * @hide
+ */
+ @IntDef(flag = true, prefix = { "REASON_" }, value = {
+ // BG-FGS-Launch reasons.
+ REASON_DENIED,
+ REASON_UNKNOWN,
+ REASON_OTHER,
+ REASON_PROC_STATE_PERSISTENT,
+ REASON_PROC_STATE_PERSISTENT_UI,
+ REASON_PROC_STATE_TOP,
+ REASON_PROC_STATE_BTOP,
+ REASON_PROC_STATE_FGS,
+ REASON_PROC_STATE_BFGS,
+ REASON_UID_VISIBLE,
+ REASON_SYSTEM_UID,
+ REASON_ACTIVITY_STARTER,
+ REASON_START_ACTIVITY_FLAG,
+ REASON_FGS_BINDING,
+ REASON_DEVICE_OWNER,
+ REASON_PROFILE_OWNER,
+ REASON_COMPANION_DEVICE_MANAGER,
+ REASON_BACKGROUND_ACTIVITY_PERMISSION,
+ REASON_BACKGROUND_FGS_PERMISSION,
+ REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION,
+ REASON_INSTR_BACKGROUND_FGS_PERMISSION,
+ REASON_SYSTEM_ALERT_WINDOW_PERMISSION,
+ REASON_DEVICE_DEMO_MODE,
+ REASON_EXEMPTED_PACKAGE,
+ REASON_ALLOWLISTED_PACKAGE,
+ REASON_APPOP,
+ // temp and system allow list reasons.
+ REASON_GEOFENCING,
+ REASON_PUSH_MESSAGING,
+ REASON_PUSH_MESSAGING_OVER_QUOTA,
+ REASON_ACTIVITY_RECOGNITION,
+ REASON_BOOT_COMPLETED,
+ REASON_PRE_BOOT_COMPLETED,
+ REASON_LOCKED_BOOT_COMPLETED,
+ REASON_SYSTEM_ALLOW_LISTED,
+ REASON_ALARM_MANAGER_ALARM_CLOCK,
+ REASON_ALARM_MANAGER_WHILE_IDLE,
+ REASON_SERVICE_LAUNCH,
+ REASON_KEY_CHAIN,
+ REASON_PACKAGE_VERIFIER,
+ REASON_SYNC_MANAGER,
+ REASON_DOMAIN_VERIFICATION_V1,
+ REASON_DOMAIN_VERIFICATION_V2,
+ REASON_VPN,
+ REASON_NOTIFICATION_SERVICE,
+ REASON_PACKAGE_REPLACED,
+ REASON_LOCATION_PROVIDER,
+ REASON_MEDIA_BUTTON,
+ REASON_EVENT_SMS,
+ REASON_EVENT_MMS,
+ REASON_SHELL,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ReasonCode {}
+
+ /**
+ * @hide
+ */
+ public PowerExemptionManager(@NonNull Context context) {
+ mContext = context;
+ mService = context.getSystemService(DeviceIdleManager.class).getService();
+ }
+
+ /**
+ * Add the specified package to the permanent power save allow list.
+ */
+ @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+ public void addToPermanentAllowList(@NonNull String packageName) {
+ addToPermanentAllowList(Collections.singletonList(packageName));
+ }
+
+ /**
+ * Add the specified packages to the permanent power save allow list.
+ */
+ @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+ public void addToPermanentAllowList(@NonNull List<String> packageNames) {
+ try {
+ mService.addPowerSaveWhitelistApps(packageNames);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Get a list of app IDs of app that are allow-listed. This does not include temporarily
+ * allow-listed apps.
+ *
+ * @param includingIdle Set to true if the app should be allow-listed from device idle as well
+ * as other power save restrictions
+ * @hide
+ */
+ @NonNull
+ public int[] getAllowListedAppIds(boolean includingIdle) {
+ try {
+ if (includingIdle) {
+ return mService.getAppIdWhitelist();
+ } else {
+ return mService.getAppIdWhitelistExceptIdle();
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns true if the app is allow-listed from power save restrictions. This does not include
+ * temporarily allow-listed apps.
+ *
+ * @param includingIdle Set to true if the app should be allow-listed from device
+ * idle as well as other power save restrictions
+ * @hide
+ */
+ public boolean isAllowListed(@NonNull String packageName, boolean includingIdle) {
+ try {
+ if (includingIdle) {
+ return mService.isPowerSaveWhitelistApp(packageName);
+ } else {
+ return mService.isPowerSaveWhitelistExceptIdleApp(packageName);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Remove an app from the permanent power save allow list. Only apps that were added via
+ * {@link #addToPermanentAllowList(String)} or {@link #addToPermanentAllowList(List)} will be
+ * removed. Apps allow-listed by default by the system cannot be removed.
+ *
+ * @param packageName The app to remove from the allow list
+ */
+ @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+ public void removeFromAllowList(@NonNull String packageName) {
+ try {
+ mService.removePowerSaveWhitelistApp(packageName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Add an app to the temporary allow list for a short amount of time.
+ *
+ * @param packageName The package to add to the temp allow list
+ * @param durationMs How long to keep the app on the temp allow list for (in milliseconds)
+ * @param reasonCode one of {@link ReasonCode}, use {@link #REASON_UNKNOWN} if not sure.
+ * @param reason a optional human readable reason string, could be null or empty string.
+ */
+ @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
+ public void addToTemporaryAllowList(@NonNull String packageName, long durationMs,
+ @ReasonCode int reasonCode, @Nullable String reason) {
+ try {
+ mService.addPowerSaveTempWhitelistApp(packageName, durationMs, mContext.getUserId(),
+ reasonCode, reason);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Add an app to the temporary allow list for a short amount of time for a specific reason.
+ * The temporary allow list is kept separately from the permanent allow list and apps are
+ * automatically removed from the temporary allow list after a predetermined amount of time.
+ *
+ * @param packageName The package to add to the temp allow list
+ * @param event The reason to add the app to the temp allow list
+ * @param reasonCode one of {@link ReasonCode}, use {@link #REASON_UNKNOWN} if not sure.
+ * @param reason A human-readable reason explaining why the app is temp allow-listed. Only
+ * used for logging purposes. Could be null or empty string.
+ * @return The duration (in milliseconds) that the app is allow-listed for
+ */
+ @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
+ public long addToTemporaryAllowListForEvent(@NonNull String packageName,
+ @AllowListEvent int event, @ReasonCode int reasonCode, @Nullable String reason) {
+ try {
+ switch (event) {
+ case EVENT_MMS:
+ return mService.addPowerSaveTempWhitelistAppForMms(
+ packageName, mContext.getUserId(), reasonCode, reason);
+ case EVENT_SMS:
+ return mService.addPowerSaveTempWhitelistAppForSms(
+ packageName, mContext.getUserId(), reasonCode, reason);
+ case EVENT_UNSPECIFIED:
+ default:
+ return mService.whitelistAppTemporarily(
+ packageName, mContext.getUserId(), reasonCode, reason);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public static @ReasonCode int getReasonCodeFromProcState(int procState) {
+ if (procState <= PROCESS_STATE_PERSISTENT) {
+ return REASON_PROC_STATE_PERSISTENT;
+ } else if (procState <= PROCESS_STATE_PERSISTENT_UI) {
+ return REASON_PROC_STATE_PERSISTENT_UI;
+ } else if (procState <= PROCESS_STATE_TOP) {
+ return REASON_PROC_STATE_TOP;
+ } else if (procState <= PROCESS_STATE_BOUND_TOP) {
+ return REASON_PROC_STATE_BTOP;
+ } else if (procState <= PROCESS_STATE_FOREGROUND_SERVICE) {
+ return REASON_PROC_STATE_FGS;
+ } else if (procState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
+ return REASON_PROC_STATE_BFGS;
+ } else {
+ return REASON_DENIED;
+ }
+ }
+
+ /**
+ * Return string name of the integer reason code.
+ * @hide
+ * @param reasonCode
+ * @return string name of the reason code.
+ */
+ public static String reasonCodeToString(@ReasonCode int reasonCode) {
+ switch (reasonCode) {
+ case REASON_DENIED:
+ return "DENIED";
+ case REASON_UNKNOWN:
+ return "UNKNOWN";
+ case REASON_OTHER:
+ return "OTHER";
+ case REASON_PROC_STATE_PERSISTENT:
+ return "PROC_STATE_PERSISTENT";
+ case REASON_PROC_STATE_PERSISTENT_UI:
+ return "PROC_STATE_PERSISTENT_UI";
+ case REASON_PROC_STATE_TOP:
+ return "PROC_STATE_TOP";
+ case REASON_PROC_STATE_BTOP:
+ return "PROC_STATE_BTOP";
+ case REASON_PROC_STATE_FGS:
+ return "PROC_STATE_FGS";
+ case REASON_PROC_STATE_BFGS:
+ return "PROC_STATE_BFGS";
+ case REASON_UID_VISIBLE:
+ return "UID_VISIBLE";
+ case REASON_SYSTEM_UID:
+ return "SYSTEM_UID";
+ case REASON_ACTIVITY_STARTER:
+ return "ACTIVITY_STARTER";
+ case REASON_START_ACTIVITY_FLAG:
+ return "START_ACTIVITY_FLAG";
+ case REASON_FGS_BINDING:
+ return "FGS_BINDING";
+ case REASON_DEVICE_OWNER:
+ return "DEVICE_OWNER";
+ case REASON_PROFILE_OWNER:
+ return "PROFILE_OWNER";
+ case REASON_COMPANION_DEVICE_MANAGER:
+ return "COMPANION_DEVICE_MANAGER";
+ case REASON_BACKGROUND_ACTIVITY_PERMISSION:
+ return "BACKGROUND_ACTIVITY_PERMISSION";
+ case REASON_BACKGROUND_FGS_PERMISSION:
+ return "BACKGROUND_FGS_PERMISSION";
+ case REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION:
+ return "INSTR_BACKGROUND_ACTIVITY_PERMISSION";
+ case REASON_INSTR_BACKGROUND_FGS_PERMISSION:
+ return "INSTR_BACKGROUND_FGS_PERMISSION";
+ case REASON_SYSTEM_ALERT_WINDOW_PERMISSION:
+ return "SYSTEM_ALERT_WINDOW_PERMISSION";
+ case REASON_DEVICE_DEMO_MODE:
+ return "DEVICE_DEMO_MODE";
+ case REASON_EXEMPTED_PACKAGE:
+ return "EXEMPTED_PACKAGE";
+ case REASON_ALLOWLISTED_PACKAGE:
+ return "ALLOWLISTED_PACKAGE";
+ case REASON_APPOP:
+ return "APPOP";
+ case REASON_GEOFENCING:
+ return "GEOFENCING";
+ case REASON_PUSH_MESSAGING:
+ return "PUSH_MESSAGING";
+ case REASON_PUSH_MESSAGING_OVER_QUOTA:
+ return "PUSH_MESSAGING_OVER_QUOTA";
+ case REASON_ACTIVITY_RECOGNITION:
+ return "ACTIVITY_RECOGNITION";
+ case REASON_BOOT_COMPLETED:
+ return "BOOT_COMPLETED";
+ case REASON_PRE_BOOT_COMPLETED:
+ return "PRE_BOOT_COMPLETED";
+ case REASON_LOCKED_BOOT_COMPLETED:
+ return "LOCKED_BOOT_COMPLETED";
+ case REASON_SYSTEM_ALLOW_LISTED:
+ return "SYSTEM_ALLOW_LISTED";
+ case REASON_ALARM_MANAGER_ALARM_CLOCK:
+ return "ALARM_MANAGER_ALARM_CLOCK";
+ case REASON_ALARM_MANAGER_WHILE_IDLE:
+ return "ALARM_MANAGER_WHILE_IDLE";
+ case REASON_SERVICE_LAUNCH:
+ return "SERVICE_LAUNCH";
+ case REASON_KEY_CHAIN:
+ return "KEY_CHAIN";
+ case REASON_PACKAGE_VERIFIER:
+ return "PACKAGE_VERIFIER";
+ case REASON_SYNC_MANAGER:
+ return "SYNC_MANAGER";
+ case REASON_DOMAIN_VERIFICATION_V1:
+ return "DOMAIN_VERIFICATION_V1";
+ case REASON_DOMAIN_VERIFICATION_V2:
+ return "DOMAIN_VERIFICATION_V2";
+ case REASON_VPN:
+ return "VPN";
+ case REASON_NOTIFICATION_SERVICE:
+ return "NOTIFICATION_SERVICE";
+ case REASON_PACKAGE_REPLACED:
+ return "PACKAGE_REPLACED";
+ case REASON_LOCATION_PROVIDER:
+ return "LOCATION_PROVIDER";
+ case REASON_MEDIA_BUTTON:
+ return "MEDIA_BUTTON";
+ case REASON_EVENT_SMS:
+ return "EVENT_SMS";
+ case REASON_EVENT_MMS:
+ return "EVENT_MMS";
+ case REASON_SHELL:
+ return "SHELL";
+ default:
+ return "(unknown:" + reasonCode + ")";
+ }
+ }
+}
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 515cb74..82f2f69 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -147,10 +147,8 @@
/** The maximum number of concurrent jobs we run at one time. */
static final int MAX_JOB_CONTEXTS_COUNT = 16;
- /** Enforce a per-app limit on scheduled jobs? */
- private static final boolean ENFORCE_MAX_JOBS = true;
- /** The maximum number of jobs that we allow an unprivileged app to schedule */
- private static final int MAX_JOBS_PER_APP = 100;
+ /** The maximum number of jobs that we allow an app to schedule */
+ private static final int MAX_JOBS_PER_APP = 150;
/** The number of the most recently completed jobs to keep track of for debugging purposes. */
private static final int NUM_COMPLETED_JOB_HISTORY = 20;
@@ -1011,7 +1009,7 @@
if (DEBUG) Slog.d(TAG, "SCHEDULE: " + jobStatus.toShortString());
// Jobs on behalf of others don't apply to the per-app job cap
- if (ENFORCE_MAX_JOBS && packageName == null) {
+ if (packageName == null) {
if (mJobs.countJobsForUid(uId) > MAX_JOBS_PER_APP) {
Slog.w(TAG, "Too many jobs for uid " + uId);
throw new IllegalStateException("Apps may not schedule more than "
diff --git a/apex/media/framework/api/system-current.txt b/apex/media/framework/api/system-current.txt
index af2d2f7..6158e2e 100644
--- a/apex/media/framework/api/system-current.txt
+++ b/apex/media/framework/api/system-current.txt
@@ -47,12 +47,16 @@
public static final class MediaTranscodeManager.TranscodingSession {
method public void cancel();
+ method public int getErrorCode();
method @IntRange(from=0, to=100) public int getProgress();
method public int getResult();
method public int getSessionId();
method public int getStatus();
method public void setOnProgressUpdateListener(@NonNull java.util.concurrent.Executor, @Nullable android.media.MediaTranscodeManager.TranscodingSession.OnProgressUpdateListener);
method public void setOnProgressUpdateListener(int, @NonNull java.util.concurrent.Executor, @Nullable android.media.MediaTranscodeManager.TranscodingSession.OnProgressUpdateListener);
+ field public static final int ERROR_DROPPED_BY_SERVICE = 1; // 0x1
+ field public static final int ERROR_NONE = 0; // 0x0
+ field public static final int ERROR_SERVICE_DIED = 2; // 0x2
field public static final int RESULT_CANCELED = 4; // 0x4
field public static final int RESULT_ERROR = 3; // 0x3
field public static final int RESULT_NONE = 1; // 0x1
diff --git a/apex/media/framework/java/android/media/MediaTranscodeManager.java b/apex/media/framework/java/android/media/MediaTranscodeManager.java
index b29bed9..30d1896 100644
--- a/apex/media/framework/java/android/media/MediaTranscodeManager.java
+++ b/apex/media/framework/java/android/media/MediaTranscodeManager.java
@@ -217,7 +217,8 @@
// Updates the session status and result.
session.updateStatusAndResult(TranscodingSession.STATUS_FINISHED,
- TranscodingSession.RESULT_SUCCESS);
+ TranscodingSession.RESULT_SUCCESS,
+ TranscodingSession.ERROR_NONE);
// Notifies client the session is done.
if (session.mListener != null && session.mListenerExecutor != null) {
@@ -241,7 +242,7 @@
// Updates the session status and result.
session.updateStatusAndResult(TranscodingSession.STATUS_FINISHED,
- TranscodingSession.RESULT_ERROR);
+ TranscodingSession.RESULT_ERROR, errorCode);
// Notifies client the session failed.
if (session.mListener != null && session.mListenerExecutor != null) {
@@ -330,7 +331,8 @@
if (session.getStatus() == TranscodingSession.STATUS_RUNNING) {
session.updateStatusAndResult(TranscodingSession.STATUS_FINISHED,
- TranscodingSession.RESULT_ERROR);
+ TranscodingSession.RESULT_ERROR,
+ TranscodingSession.ERROR_SERVICE_DIED);
// Remove the session from pending sessions.
mPendingTranscodingSessions.remove(entry.getKey());
@@ -1239,6 +1241,33 @@
@Retention(RetentionPolicy.SOURCE)
public @interface Result {}
+
+ // The error code exposed here should be in sync with:
+ // frameworks/av/media/libmediatranscoding/aidl/android/media/TranscodingErrorCode.aidl
+ /** @hide */
+ @IntDef(prefix = { "TRANSCODING_SESSION_ERROR_" }, value = {
+ ERROR_NONE,
+ ERROR_DROPPED_BY_SERVICE,
+ ERROR_SERVICE_DIED})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TranscodingSessionErrorCode{}
+ /**
+ * Constant indicating that no error occurred.
+ */
+ public static final int ERROR_NONE = 0;
+
+ /**
+ * Constant indicating that the session is dropped by Transcoding service due to hitting
+ * the limit, e.g. too many back to back transcoding happen in a short time frame.
+ */
+ public static final int ERROR_DROPPED_BY_SERVICE = 1;
+
+ /**
+ * Constant indicating the backing transcoding service is died. Client should enqueue the
+ * the request again.
+ */
+ public static final int ERROR_SERVICE_DIED = 2;
+
/** Listener that gets notified when the progress changes. */
@FunctionalInterface
public interface OnProgressUpdateListener {
@@ -1272,6 +1301,8 @@
@GuardedBy("mLock")
private @Result int mResult = RESULT_NONE;
@GuardedBy("mLock")
+ private @TranscodingSessionErrorCode int mErrorCode = ERROR_NONE;
+ @GuardedBy("mLock")
private boolean mHasRetried = false;
// The original request that associated with this session.
private final TranscodingRequest mRequest;
@@ -1325,10 +1356,20 @@
}
private void updateStatusAndResult(@Status int sessionStatus,
- @Result int sessionResult) {
+ @Result int sessionResult, @TranscodingSessionErrorCode int errorCode) {
synchronized (mLock) {
mStatus = sessionStatus;
mResult = sessionResult;
+ mErrorCode = errorCode;
+ }
+ }
+
+ /**
+ * Retrieve the error code associated with the RESULT_ERROR.
+ */
+ public @TranscodingSessionErrorCode int getErrorCode() {
+ synchronized (mLock) {
+ return mErrorCode;
}
}
diff --git a/api/Android.bp b/api/Android.bp
index 1d4698e..1fdf177 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -347,3 +347,49 @@
out: ["combined-removed-dex.txt"],
cmd: "$(location gen_combined_removed_dex.sh) $(location metalava) $(genDir) $(in) > $(out)",
}
+
+genrule {
+ name: "services-system-server-current.txt",
+ srcs: [
+ ":service-permission{.system-server.api.txt}",
+ ":non-updatable-system-server-current.txt",
+ ],
+ out: ["system-server-current.txt"],
+ tools: ["metalava"],
+ cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)",
+ dists: [
+ {
+ targets: ["droidcore"],
+ dir: "api",
+ dest: "system-server-current.txt",
+ },
+ {
+ targets: ["sdk", "win_sdk"],
+ dir: "apistubs/android/system-server/api",
+ dest: "merge-android.txt",
+ },
+ ],
+}
+
+genrule {
+ name: "services-system-server-removed.txt",
+ srcs: [
+ ":service-permission{.system-server.removed-api.txt}",
+ ":non-updatable-system-server-removed.txt",
+ ],
+ out: ["system-server-removed.txt"],
+ tools: ["metalava"],
+ cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)",
+ dists: [
+ {
+ targets: ["droidcore"],
+ dir: "api",
+ dest: "system-server-removed.txt",
+ },
+ {
+ targets: ["sdk", "win_sdk"],
+ dir: "apistubs/android/system-server/api",
+ dest: "merge-removed.txt",
+ },
+ ],
+}
diff --git a/core/api/current.txt b/core/api/current.txt
index 2e0282a..bc25561 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -506,7 +506,7 @@
field public static final int dashGap = 16843175; // 0x10101a7
field public static final int dashWidth = 16843174; // 0x10101a6
field public static final int data = 16842798; // 0x101002e
- field public static final int dataExtractionRules = 16844350; // 0x101063e
+ field public static final int dataExtractionRules = 16844349; // 0x101063d
field public static final int datePickerDialogTheme = 16843948; // 0x10104ac
field public static final int datePickerMode = 16843955; // 0x10104b3
field public static final int datePickerStyle = 16843612; // 0x101035c
@@ -528,8 +528,8 @@
field public static final int detailSocialSummary = 16843428; // 0x10102a4
field public static final int detailsElementBackground = 16843598; // 0x101034e
field public static final int dial = 16843010; // 0x1010102
- field public static final int dialTint = 16844342; // 0x1010636
- field public static final int dialTintMode = 16844343; // 0x1010637
+ field public static final int dialTint = 16844341; // 0x1010635
+ field public static final int dialTintMode = 16844342; // 0x1010636
field public static final int dialogCornerRadius = 16844145; // 0x1010571
field public static final int dialogIcon = 16843252; // 0x10101f4
field public static final int dialogLayout = 16843255; // 0x10101f7
@@ -727,14 +727,14 @@
field public static final int groupIndicator = 16843019; // 0x101010b
field public static final int gwpAsanMode = 16844310; // 0x1010616
field public static final int hand_hour = 16843011; // 0x1010103
- field public static final int hand_hourTint = 16844344; // 0x1010638
- field public static final int hand_hourTintMode = 16844345; // 0x1010639
+ field public static final int hand_hourTint = 16844343; // 0x1010637
+ field public static final int hand_hourTintMode = 16844344; // 0x1010638
field public static final int hand_minute = 16843012; // 0x1010104
- field public static final int hand_minuteTint = 16844346; // 0x101063a
- field public static final int hand_minuteTintMode = 16844347; // 0x101063b
+ field public static final int hand_minuteTint = 16844345; // 0x1010639
+ field public static final int hand_minuteTintMode = 16844346; // 0x101063a
field public static final int hand_second = 16844323; // 0x1010623
- field public static final int hand_secondTint = 16844348; // 0x101063c
- field public static final int hand_secondTintMode = 16844349; // 0x101063d
+ field public static final int hand_secondTint = 16844347; // 0x101063b
+ field public static final int hand_secondTintMode = 16844348; // 0x101063c
field public static final int handle = 16843354; // 0x101025a
field public static final int handleProfiling = 16842786; // 0x1010022
field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e
@@ -818,7 +818,7 @@
field public static final int installLocation = 16843447; // 0x10102b7
field public static final int interactiveUiTimeout = 16844181; // 0x1010595
field public static final int interpolator = 16843073; // 0x1010141
- field public static final int isAccessibilityTool = 16844353; // 0x1010641
+ field public static final int isAccessibilityTool = 16844352; // 0x1010640
field public static final int isAlwaysSyncable = 16843571; // 0x1010333
field public static final int isAsciiCapable = 16843753; // 0x10103e9
field public static final int isAuxiliary = 16843647; // 0x101037f
@@ -970,8 +970,8 @@
field public static final int maxLines = 16843091; // 0x1010153
field public static final int maxLongVersionCode = 16844163; // 0x1010583
field public static final int maxRecents = 16843846; // 0x1010446
- field public static final int maxResizeHeight = 16844339; // 0x1010633
- field public static final int maxResizeWidth = 16844338; // 0x1010632
+ field public static final int maxResizeHeight = 16844338; // 0x1010632
+ field public static final int maxResizeWidth = 16844337; // 0x1010631
field public static final int maxRows = 16843059; // 0x1010133
field public static final int maxSdkVersion = 16843377; // 0x1010271
field public static final int maxWidth = 16843039; // 0x101011f
@@ -1074,7 +1074,7 @@
field public static final int panelTextAppearance = 16842850; // 0x1010062
field public static final int parentActivityName = 16843687; // 0x10103a7
field @Deprecated public static final int password = 16843100; // 0x101015c
- field public static final int passwordsActivity = 16844351; // 0x101063f
+ field public static final int passwordsActivity = 16844350; // 0x101063e
field public static final int path = 16842794; // 0x101002a
field public static final int pathAdvancedPattern = 16844320; // 0x1010620
field public static final int pathData = 16843781; // 0x1010405
@@ -1199,7 +1199,6 @@
field public static final int right = 16843183; // 0x10101af
field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
field public static final int ringtoneType = 16843257; // 0x10101f9
- field public static final int rippleStyle = 16844337; // 0x1010631
field public static final int rollbackDataPolicy = 16844311; // 0x1010617
field public static final int rotation = 16843558; // 0x1010326
field public static final int rotationAnimation = 16844090; // 0x101053a
@@ -1261,7 +1260,7 @@
field public static final int segmentedButtonStyle = 16843568; // 0x1010330
field public static final int selectAllOnFocus = 16843102; // 0x101015e
field public static final int selectable = 16843238; // 0x10101e6
- field public static final int selectableAsDefault = 16844352; // 0x1010640
+ field public static final int selectableAsDefault = 16844351; // 0x101063f
field public static final int selectableItemBackground = 16843534; // 0x101030e
field public static final int selectableItemBackgroundBorderless = 16843868; // 0x101045c
field @Deprecated public static final int selectedDateVerticalBar = 16843591; // 0x1010347
@@ -1408,8 +1407,8 @@
field public static final int tabWidgetStyle = 16842883; // 0x1010083
field public static final int tag = 16842961; // 0x10100d1
field public static final int targetActivity = 16843266; // 0x1010202
- field public static final int targetCellHeight = 16844341; // 0x1010635
- field public static final int targetCellWidth = 16844340; // 0x1010634
+ field public static final int targetCellHeight = 16844340; // 0x1010634
+ field public static final int targetCellWidth = 16844339; // 0x1010633
field public static final int targetClass = 16842799; // 0x101002f
field @Deprecated public static final int targetDescriptions = 16843680; // 0x10103a0
field public static final int targetId = 16843740; // 0x10103dc
@@ -3855,7 +3854,7 @@
method @Deprecated public void onTabUnselected(android.app.ActionBar.Tab, android.app.FragmentTransaction);
}
- public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+ @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
ctor public Activity();
method public void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
method public void closeContextMenu();
@@ -4771,9 +4770,9 @@
}
public class Dialog implements android.content.DialogInterface android.view.KeyEvent.Callback android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
- ctor public Dialog(@NonNull android.content.Context);
- ctor public Dialog(@NonNull android.content.Context, @StyleRes int);
- ctor protected Dialog(@NonNull android.content.Context, boolean, @Nullable android.content.DialogInterface.OnCancelListener);
+ ctor public Dialog(@NonNull @UiContext android.content.Context);
+ ctor public Dialog(@NonNull @UiContext android.content.Context, @StyleRes int);
+ ctor protected Dialog(@NonNull @UiContext android.content.Context, boolean, @Nullable android.content.DialogInterface.OnCancelListener);
method public void addContentView(@NonNull android.view.View, @Nullable android.view.ViewGroup.LayoutParams);
method public void cancel();
method public void closeOptionsMenu();
@@ -4787,7 +4786,7 @@
method public boolean dispatchTrackballEvent(@NonNull android.view.MotionEvent);
method public <T extends android.view.View> T findViewById(@IdRes int);
method @Nullable public android.app.ActionBar getActionBar();
- method @NonNull public final android.content.Context getContext();
+ method @NonNull @UiContext public final android.content.Context getContext();
method @Nullable public android.view.View getCurrentFocus();
method @NonNull public android.view.LayoutInflater getLayoutInflater();
method @Nullable public final android.app.Activity getOwnerActivity();
@@ -10346,10 +10345,10 @@
method @NonNull public android.content.Context createContext(@NonNull android.content.ContextParams);
method public abstract android.content.Context createContextForSplit(String) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.content.Context createDeviceProtectedStorageContext();
- method public abstract android.content.Context createDisplayContext(@NonNull android.view.Display);
+ method @DisplayContext public abstract android.content.Context createDisplayContext(@NonNull android.view.Display);
method public abstract android.content.Context createPackageContext(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method @NonNull public android.content.Context createWindowContext(int, @Nullable android.os.Bundle);
- method @NonNull public android.content.Context createWindowContext(@NonNull android.view.Display, int, @Nullable android.os.Bundle);
+ method @NonNull @UiContext public android.content.Context createWindowContext(int, @Nullable android.os.Bundle);
+ method @NonNull @UiContext public android.content.Context createWindowContext(@NonNull android.view.Display, int, @Nullable android.os.Bundle);
method public abstract String[] databaseList();
method public abstract boolean deleteDatabase(String);
method public abstract boolean deleteFile(String);
@@ -10514,7 +10513,7 @@
field public static final String JOB_SCHEDULER_SERVICE = "jobscheduler";
field public static final String KEYGUARD_SERVICE = "keyguard";
field public static final String LAUNCHER_APPS_SERVICE = "launcherapps";
- field public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
+ field @UiContext public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
field public static final String LOCATION_SERVICE = "location";
field public static final String MEDIA_COMMUNICATION_SERVICE = "media_communication";
field public static final String MEDIA_METRICS_SERVICE = "media_metrics";
@@ -10559,12 +10558,12 @@
field public static final String VIBRATOR_MANAGER_SERVICE = "vibrator_manager";
field public static final String VIBRATOR_SERVICE = "vibrator";
field public static final String VPN_MANAGEMENT_SERVICE = "vpn_management";
- field public static final String WALLPAPER_SERVICE = "wallpaper";
+ field @UiContext public static final String WALLPAPER_SERVICE = "wallpaper";
field public static final String WIFI_AWARE_SERVICE = "wifiaware";
field public static final String WIFI_P2P_SERVICE = "wifip2p";
field public static final String WIFI_RTT_RANGING_SERVICE = "wifirtt";
field public static final String WIFI_SERVICE = "wifi";
- field public static final String WINDOW_SERVICE = "window";
+ field @UiContext public static final String WINDOW_SERVICE = "window";
}
public final class ContextParams {
@@ -16687,13 +16686,9 @@
public class RippleDrawable extends android.graphics.drawable.LayerDrawable {
ctor public RippleDrawable(@NonNull android.content.res.ColorStateList, @Nullable android.graphics.drawable.Drawable, @Nullable android.graphics.drawable.Drawable);
method public int getRadius();
- method public int getRippleStyle();
method public void setColor(android.content.res.ColorStateList);
method public void setRadius(int);
- method public void setRippleStyle(int) throws java.lang.IllegalArgumentException;
field public static final int RADIUS_AUTO = -1; // 0xffffffff
- field public static final int STYLE_PATTERNED = 1; // 0x1
- field public static final int STYLE_SOLID = 0; // 0x0
}
public class RotateDrawable extends android.graphics.drawable.DrawableWrapper {
@@ -19058,7 +19053,7 @@
method public void startInternalChanges();
}
- public class InputMethodService extends android.inputmethodservice.AbstractInputMethodService {
+ @UiContext public class InputMethodService extends android.inputmethodservice.AbstractInputMethodService {
ctor public InputMethodService();
method @Deprecated public boolean enableHardwareAcceleration();
method public int getBackDisposition();
@@ -20569,6 +20564,7 @@
method @NonNull public android.media.AudioRecord.Builder setAudioPlaybackCaptureConfig(@NonNull android.media.AudioPlaybackCaptureConfiguration);
method public android.media.AudioRecord.Builder setAudioSource(int) throws java.lang.IllegalArgumentException;
method public android.media.AudioRecord.Builder setBufferSizeInBytes(int) throws java.lang.IllegalArgumentException;
+ method @NonNull public android.media.AudioRecord.Builder setContext(@NonNull android.content.Context);
method @NonNull public android.media.AudioRecord.Builder setPrivacySensitive(boolean);
}
@@ -22743,7 +22739,8 @@
}
public class MediaRecorder implements android.media.AudioRecordingMonitor android.media.AudioRouting android.media.MicrophoneDirection {
- ctor public MediaRecorder();
+ ctor @Deprecated public MediaRecorder();
+ ctor public MediaRecorder(@NonNull android.content.Context);
method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method protected void finalize();
method public java.util.List<android.media.MicrophoneInfo> getActiveMicrophones() throws java.io.IOException;
@@ -26555,236 +26552,236 @@
package android.net.rtp {
- public class AudioCodec {
- method public static android.net.rtp.AudioCodec getCodec(int, String, String);
- method public static android.net.rtp.AudioCodec[] getCodecs();
- field public static final android.net.rtp.AudioCodec AMR;
- field public static final android.net.rtp.AudioCodec GSM;
- field public static final android.net.rtp.AudioCodec GSM_EFR;
- field public static final android.net.rtp.AudioCodec PCMA;
- field public static final android.net.rtp.AudioCodec PCMU;
- field public final String fmtp;
- field public final String rtpmap;
- field public final int type;
+ @Deprecated public class AudioCodec {
+ method @Deprecated public static android.net.rtp.AudioCodec getCodec(int, String, String);
+ method @Deprecated public static android.net.rtp.AudioCodec[] getCodecs();
+ field @Deprecated public static final android.net.rtp.AudioCodec AMR;
+ field @Deprecated public static final android.net.rtp.AudioCodec GSM;
+ field @Deprecated public static final android.net.rtp.AudioCodec GSM_EFR;
+ field @Deprecated public static final android.net.rtp.AudioCodec PCMA;
+ field @Deprecated public static final android.net.rtp.AudioCodec PCMU;
+ field @Deprecated public final String fmtp;
+ field @Deprecated public final String rtpmap;
+ field @Deprecated public final int type;
}
- public class AudioGroup {
+ @Deprecated public class AudioGroup {
ctor @Deprecated public AudioGroup();
- ctor public AudioGroup(@NonNull android.content.Context);
- method public void clear();
- method public int getMode();
- method public android.net.rtp.AudioStream[] getStreams();
- method public void sendDtmf(int);
- method public void setMode(int);
- field public static final int MODE_ECHO_SUPPRESSION = 3; // 0x3
- field public static final int MODE_MUTED = 1; // 0x1
- field public static final int MODE_NORMAL = 2; // 0x2
- field public static final int MODE_ON_HOLD = 0; // 0x0
+ ctor @Deprecated public AudioGroup(@NonNull android.content.Context);
+ method @Deprecated public void clear();
+ method @Deprecated public int getMode();
+ method @Deprecated public android.net.rtp.AudioStream[] getStreams();
+ method @Deprecated public void sendDtmf(int);
+ method @Deprecated public void setMode(int);
+ field @Deprecated public static final int MODE_ECHO_SUPPRESSION = 3; // 0x3
+ field @Deprecated public static final int MODE_MUTED = 1; // 0x1
+ field @Deprecated public static final int MODE_NORMAL = 2; // 0x2
+ field @Deprecated public static final int MODE_ON_HOLD = 0; // 0x0
}
- public class AudioStream extends android.net.rtp.RtpStream {
- ctor public AudioStream(java.net.InetAddress) throws java.net.SocketException;
- method public android.net.rtp.AudioCodec getCodec();
- method public int getDtmfType();
- method public android.net.rtp.AudioGroup getGroup();
- method public final boolean isBusy();
- method public void join(android.net.rtp.AudioGroup);
- method public void setCodec(android.net.rtp.AudioCodec);
- method public void setDtmfType(int);
+ @Deprecated public class AudioStream extends android.net.rtp.RtpStream {
+ ctor @Deprecated public AudioStream(java.net.InetAddress) throws java.net.SocketException;
+ method @Deprecated public android.net.rtp.AudioCodec getCodec();
+ method @Deprecated public int getDtmfType();
+ method @Deprecated public android.net.rtp.AudioGroup getGroup();
+ method @Deprecated public final boolean isBusy();
+ method @Deprecated public void join(android.net.rtp.AudioGroup);
+ method @Deprecated public void setCodec(android.net.rtp.AudioCodec);
+ method @Deprecated public void setDtmfType(int);
}
- public class RtpStream {
- method public void associate(java.net.InetAddress, int);
- method public java.net.InetAddress getLocalAddress();
- method public int getLocalPort();
- method public int getMode();
- method public java.net.InetAddress getRemoteAddress();
- method public int getRemotePort();
- method public boolean isBusy();
- method public void release();
- method public void setMode(int);
- field public static final int MODE_NORMAL = 0; // 0x0
- field public static final int MODE_RECEIVE_ONLY = 2; // 0x2
- field public static final int MODE_SEND_ONLY = 1; // 0x1
+ @Deprecated public class RtpStream {
+ method @Deprecated public void associate(java.net.InetAddress, int);
+ method @Deprecated public java.net.InetAddress getLocalAddress();
+ method @Deprecated public int getLocalPort();
+ method @Deprecated public int getMode();
+ method @Deprecated public java.net.InetAddress getRemoteAddress();
+ method @Deprecated public int getRemotePort();
+ method @Deprecated public boolean isBusy();
+ method @Deprecated public void release();
+ method @Deprecated public void setMode(int);
+ field @Deprecated public static final int MODE_NORMAL = 0; // 0x0
+ field @Deprecated public static final int MODE_RECEIVE_ONLY = 2; // 0x2
+ field @Deprecated public static final int MODE_SEND_ONLY = 1; // 0x1
}
}
package android.net.sip {
- public class SipAudioCall {
- ctor public SipAudioCall(android.content.Context, android.net.sip.SipProfile);
- method public void answerCall(int) throws android.net.sip.SipException;
- method public void attachCall(android.net.sip.SipSession, String) throws android.net.sip.SipException;
- method public void close();
- method public void continueCall(int) throws android.net.sip.SipException;
- method public void endCall() throws android.net.sip.SipException;
- method public android.net.sip.SipProfile getLocalProfile();
- method public android.net.sip.SipProfile getPeerProfile();
- method public int getState();
- method public void holdCall(int) throws android.net.sip.SipException;
- method public boolean isInCall();
- method public boolean isMuted();
- method public boolean isOnHold();
- method public void makeCall(android.net.sip.SipProfile, android.net.sip.SipSession, int) throws android.net.sip.SipException;
- method public void sendDtmf(int);
- method public void sendDtmf(int, android.os.Message);
- method public void setListener(android.net.sip.SipAudioCall.Listener);
- method public void setListener(android.net.sip.SipAudioCall.Listener, boolean);
- method public void setSpeakerMode(boolean);
- method public void startAudio();
- method public void toggleMute();
+ @Deprecated public class SipAudioCall {
+ ctor @Deprecated public SipAudioCall(android.content.Context, android.net.sip.SipProfile);
+ method @Deprecated public void answerCall(int) throws android.net.sip.SipException;
+ method @Deprecated public void attachCall(android.net.sip.SipSession, String) throws android.net.sip.SipException;
+ method @Deprecated public void close();
+ method @Deprecated public void continueCall(int) throws android.net.sip.SipException;
+ method @Deprecated public void endCall() throws android.net.sip.SipException;
+ method @Deprecated public android.net.sip.SipProfile getLocalProfile();
+ method @Deprecated public android.net.sip.SipProfile getPeerProfile();
+ method @Deprecated public int getState();
+ method @Deprecated public void holdCall(int) throws android.net.sip.SipException;
+ method @Deprecated public boolean isInCall();
+ method @Deprecated public boolean isMuted();
+ method @Deprecated public boolean isOnHold();
+ method @Deprecated public void makeCall(android.net.sip.SipProfile, android.net.sip.SipSession, int) throws android.net.sip.SipException;
+ method @Deprecated public void sendDtmf(int);
+ method @Deprecated public void sendDtmf(int, android.os.Message);
+ method @Deprecated public void setListener(android.net.sip.SipAudioCall.Listener);
+ method @Deprecated public void setListener(android.net.sip.SipAudioCall.Listener, boolean);
+ method @Deprecated public void setSpeakerMode(boolean);
+ method @Deprecated public void startAudio();
+ method @Deprecated public void toggleMute();
}
- public static class SipAudioCall.Listener {
- ctor public SipAudioCall.Listener();
- method public void onCallBusy(android.net.sip.SipAudioCall);
- method public void onCallEnded(android.net.sip.SipAudioCall);
- method public void onCallEstablished(android.net.sip.SipAudioCall);
- method public void onCallHeld(android.net.sip.SipAudioCall);
- method public void onCalling(android.net.sip.SipAudioCall);
- method public void onChanged(android.net.sip.SipAudioCall);
- method public void onError(android.net.sip.SipAudioCall, int, String);
- method public void onReadyToCall(android.net.sip.SipAudioCall);
- method public void onRinging(android.net.sip.SipAudioCall, android.net.sip.SipProfile);
- method public void onRingingBack(android.net.sip.SipAudioCall);
+ @Deprecated public static class SipAudioCall.Listener {
+ ctor @Deprecated public SipAudioCall.Listener();
+ method @Deprecated public void onCallBusy(android.net.sip.SipAudioCall);
+ method @Deprecated public void onCallEnded(android.net.sip.SipAudioCall);
+ method @Deprecated public void onCallEstablished(android.net.sip.SipAudioCall);
+ method @Deprecated public void onCallHeld(android.net.sip.SipAudioCall);
+ method @Deprecated public void onCalling(android.net.sip.SipAudioCall);
+ method @Deprecated public void onChanged(android.net.sip.SipAudioCall);
+ method @Deprecated public void onError(android.net.sip.SipAudioCall, int, String);
+ method @Deprecated public void onReadyToCall(android.net.sip.SipAudioCall);
+ method @Deprecated public void onRinging(android.net.sip.SipAudioCall, android.net.sip.SipProfile);
+ method @Deprecated public void onRingingBack(android.net.sip.SipAudioCall);
}
- public class SipErrorCode {
- method public static String toString(int);
- field public static final int CLIENT_ERROR = -4; // 0xfffffffc
- field public static final int CROSS_DOMAIN_AUTHENTICATION = -11; // 0xfffffff5
- field public static final int DATA_CONNECTION_LOST = -10; // 0xfffffff6
- field public static final int INVALID_CREDENTIALS = -8; // 0xfffffff8
- field public static final int INVALID_REMOTE_URI = -6; // 0xfffffffa
- field public static final int IN_PROGRESS = -9; // 0xfffffff7
- field public static final int NO_ERROR = 0; // 0x0
- field public static final int PEER_NOT_REACHABLE = -7; // 0xfffffff9
- field public static final int SERVER_ERROR = -2; // 0xfffffffe
- field public static final int SERVER_UNREACHABLE = -12; // 0xfffffff4
- field public static final int SOCKET_ERROR = -1; // 0xffffffff
- field public static final int TIME_OUT = -5; // 0xfffffffb
- field public static final int TRANSACTION_TERMINTED = -3; // 0xfffffffd
+ @Deprecated public class SipErrorCode {
+ method @Deprecated public static String toString(int);
+ field @Deprecated public static final int CLIENT_ERROR = -4; // 0xfffffffc
+ field @Deprecated public static final int CROSS_DOMAIN_AUTHENTICATION = -11; // 0xfffffff5
+ field @Deprecated public static final int DATA_CONNECTION_LOST = -10; // 0xfffffff6
+ field @Deprecated public static final int INVALID_CREDENTIALS = -8; // 0xfffffff8
+ field @Deprecated public static final int INVALID_REMOTE_URI = -6; // 0xfffffffa
+ field @Deprecated public static final int IN_PROGRESS = -9; // 0xfffffff7
+ field @Deprecated public static final int NO_ERROR = 0; // 0x0
+ field @Deprecated public static final int PEER_NOT_REACHABLE = -7; // 0xfffffff9
+ field @Deprecated public static final int SERVER_ERROR = -2; // 0xfffffffe
+ field @Deprecated public static final int SERVER_UNREACHABLE = -12; // 0xfffffff4
+ field @Deprecated public static final int SOCKET_ERROR = -1; // 0xffffffff
+ field @Deprecated public static final int TIME_OUT = -5; // 0xfffffffb
+ field @Deprecated public static final int TRANSACTION_TERMINTED = -3; // 0xfffffffd
}
- public class SipException extends java.lang.Exception {
- ctor public SipException();
- ctor public SipException(String);
- ctor public SipException(String, Throwable);
+ @Deprecated public class SipException extends java.lang.Exception {
+ ctor @Deprecated public SipException();
+ ctor @Deprecated public SipException(String);
+ ctor @Deprecated public SipException(String, Throwable);
}
- public class SipManager {
- method public void close(String) throws android.net.sip.SipException;
- method public android.net.sip.SipSession createSipSession(android.net.sip.SipProfile, android.net.sip.SipSession.Listener) throws android.net.sip.SipException;
- method public static String getCallId(android.content.Intent);
- method public static String getOfferSessionDescription(android.content.Intent);
- method public android.net.sip.SipSession getSessionFor(android.content.Intent) throws android.net.sip.SipException;
- method public static boolean isApiSupported(android.content.Context);
- method public static boolean isIncomingCallIntent(android.content.Intent);
- method public boolean isOpened(String) throws android.net.sip.SipException;
- method public boolean isRegistered(String) throws android.net.sip.SipException;
- method public static boolean isSipWifiOnly(android.content.Context);
- method public static boolean isVoipSupported(android.content.Context);
- method public android.net.sip.SipAudioCall makeAudioCall(android.net.sip.SipProfile, android.net.sip.SipProfile, android.net.sip.SipAudioCall.Listener, int) throws android.net.sip.SipException;
- method public android.net.sip.SipAudioCall makeAudioCall(String, String, android.net.sip.SipAudioCall.Listener, int) throws android.net.sip.SipException;
- method public static android.net.sip.SipManager newInstance(android.content.Context);
- method public void open(android.net.sip.SipProfile) throws android.net.sip.SipException;
- method public void open(android.net.sip.SipProfile, android.app.PendingIntent, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
- method public void register(android.net.sip.SipProfile, int, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
- method public void setRegistrationListener(String, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
- method public android.net.sip.SipAudioCall takeAudioCall(android.content.Intent, android.net.sip.SipAudioCall.Listener) throws android.net.sip.SipException;
- method public void unregister(android.net.sip.SipProfile, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
- field public static final String EXTRA_CALL_ID = "android:sipCallID";
- field public static final String EXTRA_OFFER_SD = "android:sipOfferSD";
- field public static final int INCOMING_CALL_RESULT_CODE = 101; // 0x65
+ @Deprecated public class SipManager {
+ method @Deprecated public void close(String) throws android.net.sip.SipException;
+ method @Deprecated public android.net.sip.SipSession createSipSession(android.net.sip.SipProfile, android.net.sip.SipSession.Listener) throws android.net.sip.SipException;
+ method @Deprecated public static String getCallId(android.content.Intent);
+ method @Deprecated public static String getOfferSessionDescription(android.content.Intent);
+ method @Deprecated public android.net.sip.SipSession getSessionFor(android.content.Intent) throws android.net.sip.SipException;
+ method @Deprecated public static boolean isApiSupported(android.content.Context);
+ method @Deprecated public static boolean isIncomingCallIntent(android.content.Intent);
+ method @Deprecated public boolean isOpened(String) throws android.net.sip.SipException;
+ method @Deprecated public boolean isRegistered(String) throws android.net.sip.SipException;
+ method @Deprecated public static boolean isSipWifiOnly(android.content.Context);
+ method @Deprecated public static boolean isVoipSupported(android.content.Context);
+ method @Deprecated public android.net.sip.SipAudioCall makeAudioCall(android.net.sip.SipProfile, android.net.sip.SipProfile, android.net.sip.SipAudioCall.Listener, int) throws android.net.sip.SipException;
+ method @Deprecated public android.net.sip.SipAudioCall makeAudioCall(String, String, android.net.sip.SipAudioCall.Listener, int) throws android.net.sip.SipException;
+ method @Deprecated public static android.net.sip.SipManager newInstance(android.content.Context);
+ method @Deprecated public void open(android.net.sip.SipProfile) throws android.net.sip.SipException;
+ method @Deprecated public void open(android.net.sip.SipProfile, android.app.PendingIntent, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
+ method @Deprecated public void register(android.net.sip.SipProfile, int, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
+ method @Deprecated public void setRegistrationListener(String, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
+ method @Deprecated public android.net.sip.SipAudioCall takeAudioCall(android.content.Intent, android.net.sip.SipAudioCall.Listener) throws android.net.sip.SipException;
+ method @Deprecated public void unregister(android.net.sip.SipProfile, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
+ field @Deprecated public static final String EXTRA_CALL_ID = "android:sipCallID";
+ field @Deprecated public static final String EXTRA_OFFER_SD = "android:sipOfferSD";
+ field @Deprecated public static final int INCOMING_CALL_RESULT_CODE = 101; // 0x65
}
- public class SipProfile implements java.lang.Cloneable android.os.Parcelable java.io.Serializable {
- method public int describeContents();
- method public String getAuthUserName();
- method public boolean getAutoRegistration();
- method public String getDisplayName();
- method public String getPassword();
- method public int getPort();
- method public String getProfileName();
- method public String getProtocol();
- method public String getProxyAddress();
- method public boolean getSendKeepAlive();
- method public String getSipDomain();
- method public String getUriString();
- method public String getUserName();
- method public void setCallingUid(int);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.sip.SipProfile> CREATOR;
+ @Deprecated public class SipProfile implements java.lang.Cloneable android.os.Parcelable java.io.Serializable {
+ method @Deprecated public int describeContents();
+ method @Deprecated public String getAuthUserName();
+ method @Deprecated public boolean getAutoRegistration();
+ method @Deprecated public String getDisplayName();
+ method @Deprecated public String getPassword();
+ method @Deprecated public int getPort();
+ method @Deprecated public String getProfileName();
+ method @Deprecated public String getProtocol();
+ method @Deprecated public String getProxyAddress();
+ method @Deprecated public boolean getSendKeepAlive();
+ method @Deprecated public String getSipDomain();
+ method @Deprecated public String getUriString();
+ method @Deprecated public String getUserName();
+ method @Deprecated public void setCallingUid(int);
+ method @Deprecated public void writeToParcel(android.os.Parcel, int);
+ field @Deprecated public static final android.os.Parcelable.Creator<android.net.sip.SipProfile> CREATOR;
}
- public static class SipProfile.Builder {
- ctor public SipProfile.Builder(android.net.sip.SipProfile);
- ctor public SipProfile.Builder(String) throws java.text.ParseException;
- ctor public SipProfile.Builder(String, String) throws java.text.ParseException;
- method public android.net.sip.SipProfile build();
- method public android.net.sip.SipProfile.Builder setAuthUserName(String);
- method public android.net.sip.SipProfile.Builder setAutoRegistration(boolean);
- method public android.net.sip.SipProfile.Builder setDisplayName(String);
- method public android.net.sip.SipProfile.Builder setOutboundProxy(String);
- method public android.net.sip.SipProfile.Builder setPassword(String);
- method public android.net.sip.SipProfile.Builder setPort(int) throws java.lang.IllegalArgumentException;
- method public android.net.sip.SipProfile.Builder setProfileName(String);
- method public android.net.sip.SipProfile.Builder setProtocol(String) throws java.lang.IllegalArgumentException;
- method public android.net.sip.SipProfile.Builder setSendKeepAlive(boolean);
+ @Deprecated public static class SipProfile.Builder {
+ ctor @Deprecated public SipProfile.Builder(android.net.sip.SipProfile);
+ ctor @Deprecated public SipProfile.Builder(String) throws java.text.ParseException;
+ ctor @Deprecated public SipProfile.Builder(String, String) throws java.text.ParseException;
+ method @Deprecated public android.net.sip.SipProfile build();
+ method @Deprecated public android.net.sip.SipProfile.Builder setAuthUserName(String);
+ method @Deprecated public android.net.sip.SipProfile.Builder setAutoRegistration(boolean);
+ method @Deprecated public android.net.sip.SipProfile.Builder setDisplayName(String);
+ method @Deprecated public android.net.sip.SipProfile.Builder setOutboundProxy(String);
+ method @Deprecated public android.net.sip.SipProfile.Builder setPassword(String);
+ method @Deprecated public android.net.sip.SipProfile.Builder setPort(int) throws java.lang.IllegalArgumentException;
+ method @Deprecated public android.net.sip.SipProfile.Builder setProfileName(String);
+ method @Deprecated public android.net.sip.SipProfile.Builder setProtocol(String) throws java.lang.IllegalArgumentException;
+ method @Deprecated public android.net.sip.SipProfile.Builder setSendKeepAlive(boolean);
}
- public interface SipRegistrationListener {
- method public void onRegistering(String);
- method public void onRegistrationDone(String, long);
- method public void onRegistrationFailed(String, int, String);
+ @Deprecated public interface SipRegistrationListener {
+ method @Deprecated public void onRegistering(String);
+ method @Deprecated public void onRegistrationDone(String, long);
+ method @Deprecated public void onRegistrationFailed(String, int, String);
}
- public final class SipSession {
- method public void answerCall(String, int);
- method public void changeCall(String, int);
- method public void endCall();
- method public String getCallId();
- method public String getLocalIp();
- method public android.net.sip.SipProfile getLocalProfile();
- method public android.net.sip.SipProfile getPeerProfile();
- method public int getState();
- method public boolean isInCall();
- method public void makeCall(android.net.sip.SipProfile, String, int);
- method public void register(int);
- method public void setListener(android.net.sip.SipSession.Listener);
- method public void unregister();
+ @Deprecated public final class SipSession {
+ method @Deprecated public void answerCall(String, int);
+ method @Deprecated public void changeCall(String, int);
+ method @Deprecated public void endCall();
+ method @Deprecated public String getCallId();
+ method @Deprecated public String getLocalIp();
+ method @Deprecated public android.net.sip.SipProfile getLocalProfile();
+ method @Deprecated public android.net.sip.SipProfile getPeerProfile();
+ method @Deprecated public int getState();
+ method @Deprecated public boolean isInCall();
+ method @Deprecated public void makeCall(android.net.sip.SipProfile, String, int);
+ method @Deprecated public void register(int);
+ method @Deprecated public void setListener(android.net.sip.SipSession.Listener);
+ method @Deprecated public void unregister();
}
- public static class SipSession.Listener {
- ctor public SipSession.Listener();
- method public void onCallBusy(android.net.sip.SipSession);
- method public void onCallChangeFailed(android.net.sip.SipSession, int, String);
- method public void onCallEnded(android.net.sip.SipSession);
- method public void onCallEstablished(android.net.sip.SipSession, String);
- method public void onCalling(android.net.sip.SipSession);
- method public void onError(android.net.sip.SipSession, int, String);
- method public void onRegistering(android.net.sip.SipSession);
- method public void onRegistrationDone(android.net.sip.SipSession, int);
- method public void onRegistrationFailed(android.net.sip.SipSession, int, String);
- method public void onRegistrationTimeout(android.net.sip.SipSession);
- method public void onRinging(android.net.sip.SipSession, android.net.sip.SipProfile, String);
- method public void onRingingBack(android.net.sip.SipSession);
+ @Deprecated public static class SipSession.Listener {
+ ctor @Deprecated public SipSession.Listener();
+ method @Deprecated public void onCallBusy(android.net.sip.SipSession);
+ method @Deprecated public void onCallChangeFailed(android.net.sip.SipSession, int, String);
+ method @Deprecated public void onCallEnded(android.net.sip.SipSession);
+ method @Deprecated public void onCallEstablished(android.net.sip.SipSession, String);
+ method @Deprecated public void onCalling(android.net.sip.SipSession);
+ method @Deprecated public void onError(android.net.sip.SipSession, int, String);
+ method @Deprecated public void onRegistering(android.net.sip.SipSession);
+ method @Deprecated public void onRegistrationDone(android.net.sip.SipSession, int);
+ method @Deprecated public void onRegistrationFailed(android.net.sip.SipSession, int, String);
+ method @Deprecated public void onRegistrationTimeout(android.net.sip.SipSession);
+ method @Deprecated public void onRinging(android.net.sip.SipSession, android.net.sip.SipProfile, String);
+ method @Deprecated public void onRingingBack(android.net.sip.SipSession);
}
- public static class SipSession.State {
- method public static String toString(int);
- field public static final int DEREGISTERING = 2; // 0x2
- field public static final int INCOMING_CALL = 3; // 0x3
- field public static final int INCOMING_CALL_ANSWERING = 4; // 0x4
- field public static final int IN_CALL = 8; // 0x8
- field public static final int NOT_DEFINED = 101; // 0x65
- field public static final int OUTGOING_CALL = 5; // 0x5
- field public static final int OUTGOING_CALL_CANCELING = 7; // 0x7
- field public static final int OUTGOING_CALL_RING_BACK = 6; // 0x6
- field public static final int PINGING = 9; // 0x9
- field public static final int READY_TO_CALL = 0; // 0x0
- field public static final int REGISTERING = 1; // 0x1
+ @Deprecated public static class SipSession.State {
+ method @Deprecated public static String toString(int);
+ field @Deprecated public static final int DEREGISTERING = 2; // 0x2
+ field @Deprecated public static final int INCOMING_CALL = 3; // 0x3
+ field @Deprecated public static final int INCOMING_CALL_ANSWERING = 4; // 0x4
+ field @Deprecated public static final int IN_CALL = 8; // 0x8
+ field @Deprecated public static final int NOT_DEFINED = 101; // 0x65
+ field @Deprecated public static final int OUTGOING_CALL = 5; // 0x5
+ field @Deprecated public static final int OUTGOING_CALL_CANCELING = 7; // 0x7
+ field @Deprecated public static final int OUTGOING_CALL_RING_BACK = 6; // 0x6
+ field @Deprecated public static final int PINGING = 9; // 0x9
+ field @Deprecated public static final int READY_TO_CALL = 0; // 0x0
+ field @Deprecated public static final int REGISTERING = 1; // 0x1
}
}
@@ -35651,721 +35648,721 @@
package android.renderscript {
- public class Allocation extends android.renderscript.BaseObj {
- method public void copy1DRangeFrom(int, int, Object);
- method public void copy1DRangeFrom(int, int, int[]);
- method public void copy1DRangeFrom(int, int, short[]);
- method public void copy1DRangeFrom(int, int, byte[]);
- method public void copy1DRangeFrom(int, int, float[]);
- method public void copy1DRangeFrom(int, int, android.renderscript.Allocation, int);
- method public void copy1DRangeFromUnchecked(int, int, Object);
- method public void copy1DRangeFromUnchecked(int, int, int[]);
- method public void copy1DRangeFromUnchecked(int, int, short[]);
- method public void copy1DRangeFromUnchecked(int, int, byte[]);
- method public void copy1DRangeFromUnchecked(int, int, float[]);
- method public void copy1DRangeTo(int, int, Object);
- method public void copy1DRangeTo(int, int, int[]);
- method public void copy1DRangeTo(int, int, short[]);
- method public void copy1DRangeTo(int, int, byte[]);
- method public void copy1DRangeTo(int, int, float[]);
- method public void copy1DRangeToUnchecked(int, int, Object);
- method public void copy1DRangeToUnchecked(int, int, int[]);
- method public void copy1DRangeToUnchecked(int, int, short[]);
- method public void copy1DRangeToUnchecked(int, int, byte[]);
- method public void copy1DRangeToUnchecked(int, int, float[]);
- method public void copy2DRangeFrom(int, int, int, int, Object);
- method public void copy2DRangeFrom(int, int, int, int, byte[]);
- method public void copy2DRangeFrom(int, int, int, int, short[]);
- method public void copy2DRangeFrom(int, int, int, int, int[]);
- method public void copy2DRangeFrom(int, int, int, int, float[]);
- method public void copy2DRangeFrom(int, int, int, int, android.renderscript.Allocation, int, int);
- method public void copy2DRangeFrom(int, int, android.graphics.Bitmap);
- method public void copy2DRangeTo(int, int, int, int, Object);
- method public void copy2DRangeTo(int, int, int, int, byte[]);
- method public void copy2DRangeTo(int, int, int, int, short[]);
- method public void copy2DRangeTo(int, int, int, int, int[]);
- method public void copy2DRangeTo(int, int, int, int, float[]);
- method public void copy3DRangeFrom(int, int, int, int, int, int, Object);
- method public void copy3DRangeFrom(int, int, int, int, int, int, android.renderscript.Allocation, int, int, int);
- method public void copy3DRangeTo(int, int, int, int, int, int, Object);
- method public void copyFrom(android.renderscript.BaseObj[]);
- method public void copyFrom(Object);
- method public void copyFrom(int[]);
- method public void copyFrom(short[]);
- method public void copyFrom(byte[]);
- method public void copyFrom(float[]);
- method public void copyFrom(android.graphics.Bitmap);
- method public void copyFrom(android.renderscript.Allocation);
- method public void copyFromUnchecked(Object);
- method public void copyFromUnchecked(int[]);
- method public void copyFromUnchecked(short[]);
- method public void copyFromUnchecked(byte[]);
- method public void copyFromUnchecked(float[]);
- method public void copyTo(android.graphics.Bitmap);
- method public void copyTo(Object);
- method public void copyTo(byte[]);
- method public void copyTo(short[]);
- method public void copyTo(int[]);
- method public void copyTo(float[]);
- method public static android.renderscript.Allocation[] createAllocations(android.renderscript.RenderScript, android.renderscript.Type, int, int);
- method public static android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
- method public static android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
- method public static android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
- method public static android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap);
- method public static android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
- method public static android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
- method public static android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int, android.renderscript.Allocation.MipmapControl, int);
- method public static android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int);
- method public static android.renderscript.Allocation createFromString(android.renderscript.RenderScript, String, int);
- method public static android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int, int);
- method public static android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int);
- method public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, android.renderscript.Allocation.MipmapControl, int);
- method public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, int);
- method public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type);
- method public void generateMipmaps();
- method public java.nio.ByteBuffer getByteBuffer();
- method public int getBytesSize();
- method public android.renderscript.Element getElement();
- method public long getStride();
- method public android.view.Surface getSurface();
- method public long getTimeStamp();
- method public android.renderscript.Type getType();
- method public int getUsage();
- method public void ioReceive();
- method public void ioSend();
+ @Deprecated public class Allocation extends android.renderscript.BaseObj {
+ method @Deprecated public void copy1DRangeFrom(int, int, Object);
+ method @Deprecated public void copy1DRangeFrom(int, int, int[]);
+ method @Deprecated public void copy1DRangeFrom(int, int, short[]);
+ method @Deprecated public void copy1DRangeFrom(int, int, byte[]);
+ method @Deprecated public void copy1DRangeFrom(int, int, float[]);
+ method @Deprecated public void copy1DRangeFrom(int, int, android.renderscript.Allocation, int);
+ method @Deprecated public void copy1DRangeFromUnchecked(int, int, Object);
+ method @Deprecated public void copy1DRangeFromUnchecked(int, int, int[]);
+ method @Deprecated public void copy1DRangeFromUnchecked(int, int, short[]);
+ method @Deprecated public void copy1DRangeFromUnchecked(int, int, byte[]);
+ method @Deprecated public void copy1DRangeFromUnchecked(int, int, float[]);
+ method @Deprecated public void copy1DRangeTo(int, int, Object);
+ method @Deprecated public void copy1DRangeTo(int, int, int[]);
+ method @Deprecated public void copy1DRangeTo(int, int, short[]);
+ method @Deprecated public void copy1DRangeTo(int, int, byte[]);
+ method @Deprecated public void copy1DRangeTo(int, int, float[]);
+ method @Deprecated public void copy1DRangeToUnchecked(int, int, Object);
+ method @Deprecated public void copy1DRangeToUnchecked(int, int, int[]);
+ method @Deprecated public void copy1DRangeToUnchecked(int, int, short[]);
+ method @Deprecated public void copy1DRangeToUnchecked(int, int, byte[]);
+ method @Deprecated public void copy1DRangeToUnchecked(int, int, float[]);
+ method @Deprecated public void copy2DRangeFrom(int, int, int, int, Object);
+ method @Deprecated public void copy2DRangeFrom(int, int, int, int, byte[]);
+ method @Deprecated public void copy2DRangeFrom(int, int, int, int, short[]);
+ method @Deprecated public void copy2DRangeFrom(int, int, int, int, int[]);
+ method @Deprecated public void copy2DRangeFrom(int, int, int, int, float[]);
+ method @Deprecated public void copy2DRangeFrom(int, int, int, int, android.renderscript.Allocation, int, int);
+ method @Deprecated public void copy2DRangeFrom(int, int, android.graphics.Bitmap);
+ method @Deprecated public void copy2DRangeTo(int, int, int, int, Object);
+ method @Deprecated public void copy2DRangeTo(int, int, int, int, byte[]);
+ method @Deprecated public void copy2DRangeTo(int, int, int, int, short[]);
+ method @Deprecated public void copy2DRangeTo(int, int, int, int, int[]);
+ method @Deprecated public void copy2DRangeTo(int, int, int, int, float[]);
+ method @Deprecated public void copy3DRangeFrom(int, int, int, int, int, int, Object);
+ method @Deprecated public void copy3DRangeFrom(int, int, int, int, int, int, android.renderscript.Allocation, int, int, int);
+ method @Deprecated public void copy3DRangeTo(int, int, int, int, int, int, Object);
+ method @Deprecated public void copyFrom(android.renderscript.BaseObj[]);
+ method @Deprecated public void copyFrom(Object);
+ method @Deprecated public void copyFrom(int[]);
+ method @Deprecated public void copyFrom(short[]);
+ method @Deprecated public void copyFrom(byte[]);
+ method @Deprecated public void copyFrom(float[]);
+ method @Deprecated public void copyFrom(android.graphics.Bitmap);
+ method @Deprecated public void copyFrom(android.renderscript.Allocation);
+ method @Deprecated public void copyFromUnchecked(Object);
+ method @Deprecated public void copyFromUnchecked(int[]);
+ method @Deprecated public void copyFromUnchecked(short[]);
+ method @Deprecated public void copyFromUnchecked(byte[]);
+ method @Deprecated public void copyFromUnchecked(float[]);
+ method @Deprecated public void copyTo(android.graphics.Bitmap);
+ method @Deprecated public void copyTo(Object);
+ method @Deprecated public void copyTo(byte[]);
+ method @Deprecated public void copyTo(short[]);
+ method @Deprecated public void copyTo(int[]);
+ method @Deprecated public void copyTo(float[]);
+ method @Deprecated public static android.renderscript.Allocation[] createAllocations(android.renderscript.RenderScript, android.renderscript.Type, int, int);
+ method @Deprecated public static android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
+ method @Deprecated public static android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
+ method @Deprecated public static android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
+ method @Deprecated public static android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap);
+ method @Deprecated public static android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
+ method @Deprecated public static android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
+ method @Deprecated public static android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int, android.renderscript.Allocation.MipmapControl, int);
+ method @Deprecated public static android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int);
+ method @Deprecated public static android.renderscript.Allocation createFromString(android.renderscript.RenderScript, String, int);
+ method @Deprecated public static android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int, int);
+ method @Deprecated public static android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int);
+ method @Deprecated public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, android.renderscript.Allocation.MipmapControl, int);
+ method @Deprecated public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, int);
+ method @Deprecated public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type);
+ method @Deprecated public void generateMipmaps();
+ method @Deprecated public java.nio.ByteBuffer getByteBuffer();
+ method @Deprecated public int getBytesSize();
+ method @Deprecated public android.renderscript.Element getElement();
+ method @Deprecated public long getStride();
+ method @Deprecated public android.view.Surface getSurface();
+ method @Deprecated public long getTimeStamp();
+ method @Deprecated public android.renderscript.Type getType();
+ method @Deprecated public int getUsage();
+ method @Deprecated public void ioReceive();
+ method @Deprecated public void ioSend();
method @Deprecated public void resize(int);
- method public void setAutoPadding(boolean);
- method public void setFromFieldPacker(int, android.renderscript.FieldPacker);
- method public void setFromFieldPacker(int, int, android.renderscript.FieldPacker);
- method public void setFromFieldPacker(int, int, int, int, android.renderscript.FieldPacker);
- method public void setOnBufferAvailableListener(android.renderscript.Allocation.OnBufferAvailableListener);
- method public void setSurface(android.view.Surface);
- method public void syncAll(int);
- field public static final int USAGE_GRAPHICS_CONSTANTS = 8; // 0x8
- field public static final int USAGE_GRAPHICS_RENDER_TARGET = 16; // 0x10
- field public static final int USAGE_GRAPHICS_TEXTURE = 2; // 0x2
- field public static final int USAGE_GRAPHICS_VERTEX = 4; // 0x4
- field public static final int USAGE_IO_INPUT = 32; // 0x20
- field public static final int USAGE_IO_OUTPUT = 64; // 0x40
- field public static final int USAGE_SCRIPT = 1; // 0x1
- field public static final int USAGE_SHARED = 128; // 0x80
+ method @Deprecated public void setAutoPadding(boolean);
+ method @Deprecated public void setFromFieldPacker(int, android.renderscript.FieldPacker);
+ method @Deprecated public void setFromFieldPacker(int, int, android.renderscript.FieldPacker);
+ method @Deprecated public void setFromFieldPacker(int, int, int, int, android.renderscript.FieldPacker);
+ method @Deprecated public void setOnBufferAvailableListener(android.renderscript.Allocation.OnBufferAvailableListener);
+ method @Deprecated public void setSurface(android.view.Surface);
+ method @Deprecated public void syncAll(int);
+ field @Deprecated public static final int USAGE_GRAPHICS_CONSTANTS = 8; // 0x8
+ field @Deprecated public static final int USAGE_GRAPHICS_RENDER_TARGET = 16; // 0x10
+ field @Deprecated public static final int USAGE_GRAPHICS_TEXTURE = 2; // 0x2
+ field @Deprecated public static final int USAGE_GRAPHICS_VERTEX = 4; // 0x4
+ field @Deprecated public static final int USAGE_IO_INPUT = 32; // 0x20
+ field @Deprecated public static final int USAGE_IO_OUTPUT = 64; // 0x40
+ field @Deprecated public static final int USAGE_SCRIPT = 1; // 0x1
+ field @Deprecated public static final int USAGE_SHARED = 128; // 0x80
}
- public enum Allocation.MipmapControl {
- enum_constant public static final android.renderscript.Allocation.MipmapControl MIPMAP_FULL;
- enum_constant public static final android.renderscript.Allocation.MipmapControl MIPMAP_NONE;
- enum_constant public static final android.renderscript.Allocation.MipmapControl MIPMAP_ON_SYNC_TO_TEXTURE;
+ @Deprecated public enum Allocation.MipmapControl {
+ enum_constant @Deprecated public static final android.renderscript.Allocation.MipmapControl MIPMAP_FULL;
+ enum_constant @Deprecated public static final android.renderscript.Allocation.MipmapControl MIPMAP_NONE;
+ enum_constant @Deprecated public static final android.renderscript.Allocation.MipmapControl MIPMAP_ON_SYNC_TO_TEXTURE;
}
- public static interface Allocation.OnBufferAvailableListener {
- method public void onBufferAvailable(android.renderscript.Allocation);
+ @Deprecated public static interface Allocation.OnBufferAvailableListener {
+ method @Deprecated public void onBufferAvailable(android.renderscript.Allocation);
}
- public class AllocationAdapter extends android.renderscript.Allocation {
- method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
- method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
- method public static android.renderscript.AllocationAdapter createTyped(android.renderscript.RenderScript, android.renderscript.Allocation, android.renderscript.Type);
- method public void resize(int);
- method public void setFace(android.renderscript.Type.CubemapFace);
- method public void setLOD(int);
- method public void setX(int);
- method public void setY(int);
- method public void setZ(int);
+ @Deprecated public class AllocationAdapter extends android.renderscript.Allocation {
+ method @Deprecated public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
+ method @Deprecated public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
+ method @Deprecated public static android.renderscript.AllocationAdapter createTyped(android.renderscript.RenderScript, android.renderscript.Allocation, android.renderscript.Type);
+ method @Deprecated public void resize(int);
+ method @Deprecated public void setFace(android.renderscript.Type.CubemapFace);
+ method @Deprecated public void setLOD(int);
+ method @Deprecated public void setX(int);
+ method @Deprecated public void setY(int);
+ method @Deprecated public void setZ(int);
}
- public class BaseObj {
- method public void destroy();
- method public String getName();
- method public void setName(String);
+ @Deprecated public class BaseObj {
+ method @Deprecated public void destroy();
+ method @Deprecated public String getName();
+ method @Deprecated public void setName(String);
}
- public class Byte2 {
- ctor public Byte2();
- ctor public Byte2(byte, byte);
- field public byte x;
- field public byte y;
+ @Deprecated public class Byte2 {
+ ctor @Deprecated public Byte2();
+ ctor @Deprecated public Byte2(byte, byte);
+ field @Deprecated public byte x;
+ field @Deprecated public byte y;
}
- public class Byte3 {
- ctor public Byte3();
- ctor public Byte3(byte, byte, byte);
- field public byte x;
- field public byte y;
- field public byte z;
+ @Deprecated public class Byte3 {
+ ctor @Deprecated public Byte3();
+ ctor @Deprecated public Byte3(byte, byte, byte);
+ field @Deprecated public byte x;
+ field @Deprecated public byte y;
+ field @Deprecated public byte z;
}
- public class Byte4 {
- ctor public Byte4();
- ctor public Byte4(byte, byte, byte, byte);
- field public byte w;
- field public byte x;
- field public byte y;
- field public byte z;
+ @Deprecated public class Byte4 {
+ ctor @Deprecated public Byte4();
+ ctor @Deprecated public Byte4(byte, byte, byte, byte);
+ field @Deprecated public byte w;
+ field @Deprecated public byte x;
+ field @Deprecated public byte y;
+ field @Deprecated public byte z;
}
- public class Double2 {
- ctor public Double2();
- ctor public Double2(double, double);
- field public double x;
- field public double y;
+ @Deprecated public class Double2 {
+ ctor @Deprecated public Double2();
+ ctor @Deprecated public Double2(double, double);
+ field @Deprecated public double x;
+ field @Deprecated public double y;
}
- public class Double3 {
- ctor public Double3();
- ctor public Double3(double, double, double);
- field public double x;
- field public double y;
- field public double z;
+ @Deprecated public class Double3 {
+ ctor @Deprecated public Double3();
+ ctor @Deprecated public Double3(double, double, double);
+ field @Deprecated public double x;
+ field @Deprecated public double y;
+ field @Deprecated public double z;
}
- public class Double4 {
- ctor public Double4();
- ctor public Double4(double, double, double, double);
- field public double w;
- field public double x;
- field public double y;
- field public double z;
+ @Deprecated public class Double4 {
+ ctor @Deprecated public Double4();
+ ctor @Deprecated public Double4(double, double, double, double);
+ field @Deprecated public double w;
+ field @Deprecated public double x;
+ field @Deprecated public double y;
+ field @Deprecated public double z;
}
- public class Element extends android.renderscript.BaseObj {
- method public static android.renderscript.Element ALLOCATION(android.renderscript.RenderScript);
- method public static android.renderscript.Element A_8(android.renderscript.RenderScript);
- method public static android.renderscript.Element BOOLEAN(android.renderscript.RenderScript);
- method public static android.renderscript.Element ELEMENT(android.renderscript.RenderScript);
- method public static android.renderscript.Element F16(android.renderscript.RenderScript);
- method public static android.renderscript.Element F16_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element F16_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element F16_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element F32(android.renderscript.RenderScript);
- method public static android.renderscript.Element F32_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element F32_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element F32_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element F64(android.renderscript.RenderScript);
- method public static android.renderscript.Element F64_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element F64_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element F64_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element FONT(android.renderscript.RenderScript);
- method public static android.renderscript.Element I16(android.renderscript.RenderScript);
- method public static android.renderscript.Element I16_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element I16_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element I16_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element I32(android.renderscript.RenderScript);
- method public static android.renderscript.Element I32_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element I32_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element I32_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element I64(android.renderscript.RenderScript);
- method public static android.renderscript.Element I64_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element I64_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element I64_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element I8(android.renderscript.RenderScript);
- method public static android.renderscript.Element I8_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element I8_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element I8_4(android.renderscript.RenderScript);
+ @Deprecated public class Element extends android.renderscript.BaseObj {
+ method @Deprecated public static android.renderscript.Element ALLOCATION(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element A_8(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element BOOLEAN(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element ELEMENT(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F16(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F16_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F16_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F16_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F32(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F32_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F32_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F32_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F64(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F64_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F64_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F64_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element FONT(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I16(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I16_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I16_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I16_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I32(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I32_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I32_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I32_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I64(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I64_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I64_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I64_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I8(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I8_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I8_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I8_4(android.renderscript.RenderScript);
method @Deprecated public static android.renderscript.Element MATRIX4X4(android.renderscript.RenderScript);
- method public static android.renderscript.Element MATRIX_2X2(android.renderscript.RenderScript);
- method public static android.renderscript.Element MATRIX_3X3(android.renderscript.RenderScript);
- method public static android.renderscript.Element MATRIX_4X4(android.renderscript.RenderScript);
- method public static android.renderscript.Element MESH(android.renderscript.RenderScript);
- method public static android.renderscript.Element PROGRAM_FRAGMENT(android.renderscript.RenderScript);
- method public static android.renderscript.Element PROGRAM_RASTER(android.renderscript.RenderScript);
- method public static android.renderscript.Element PROGRAM_STORE(android.renderscript.RenderScript);
- method public static android.renderscript.Element PROGRAM_VERTEX(android.renderscript.RenderScript);
- method public static android.renderscript.Element RGBA_4444(android.renderscript.RenderScript);
- method public static android.renderscript.Element RGBA_5551(android.renderscript.RenderScript);
- method public static android.renderscript.Element RGBA_8888(android.renderscript.RenderScript);
- method public static android.renderscript.Element RGB_565(android.renderscript.RenderScript);
- method public static android.renderscript.Element RGB_888(android.renderscript.RenderScript);
- method public static android.renderscript.Element SAMPLER(android.renderscript.RenderScript);
- method public static android.renderscript.Element SCRIPT(android.renderscript.RenderScript);
- method public static android.renderscript.Element TYPE(android.renderscript.RenderScript);
- method public static android.renderscript.Element U16(android.renderscript.RenderScript);
- method public static android.renderscript.Element U16_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element U16_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element U16_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element U32(android.renderscript.RenderScript);
- method public static android.renderscript.Element U32_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element U32_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element U32_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element U64(android.renderscript.RenderScript);
- method public static android.renderscript.Element U64_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element U64_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element U64_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element U8(android.renderscript.RenderScript);
- method public static android.renderscript.Element U8_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element U8_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element U8_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element YUV(android.renderscript.RenderScript);
- method public static android.renderscript.Element createPixel(android.renderscript.RenderScript, android.renderscript.Element.DataType, android.renderscript.Element.DataKind);
- method public static android.renderscript.Element createVector(android.renderscript.RenderScript, android.renderscript.Element.DataType, int);
- method public int getBytesSize();
- method public android.renderscript.Element.DataKind getDataKind();
- method public android.renderscript.Element.DataType getDataType();
- method public android.renderscript.Element getSubElement(int);
- method public int getSubElementArraySize(int);
- method public int getSubElementCount();
- method public String getSubElementName(int);
- method public int getSubElementOffsetBytes(int);
- method public int getVectorSize();
- method public boolean isCompatible(android.renderscript.Element);
- method public boolean isComplex();
+ method @Deprecated public static android.renderscript.Element MATRIX_2X2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element MATRIX_3X3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element MATRIX_4X4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element MESH(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element PROGRAM_FRAGMENT(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element PROGRAM_RASTER(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element PROGRAM_STORE(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element PROGRAM_VERTEX(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element RGBA_4444(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element RGBA_5551(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element RGBA_8888(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element RGB_565(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element RGB_888(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element SAMPLER(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element SCRIPT(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element TYPE(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U16(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U16_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U16_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U16_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U32(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U32_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U32_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U32_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U64(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U64_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U64_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U64_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U8(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U8_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U8_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U8_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element YUV(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element createPixel(android.renderscript.RenderScript, android.renderscript.Element.DataType, android.renderscript.Element.DataKind);
+ method @Deprecated public static android.renderscript.Element createVector(android.renderscript.RenderScript, android.renderscript.Element.DataType, int);
+ method @Deprecated public int getBytesSize();
+ method @Deprecated public android.renderscript.Element.DataKind getDataKind();
+ method @Deprecated public android.renderscript.Element.DataType getDataType();
+ method @Deprecated public android.renderscript.Element getSubElement(int);
+ method @Deprecated public int getSubElementArraySize(int);
+ method @Deprecated public int getSubElementCount();
+ method @Deprecated public String getSubElementName(int);
+ method @Deprecated public int getSubElementOffsetBytes(int);
+ method @Deprecated public int getVectorSize();
+ method @Deprecated public boolean isCompatible(android.renderscript.Element);
+ method @Deprecated public boolean isComplex();
}
- public static class Element.Builder {
- ctor public Element.Builder(android.renderscript.RenderScript);
- method public android.renderscript.Element.Builder add(android.renderscript.Element, String, int);
- method public android.renderscript.Element.Builder add(android.renderscript.Element, String);
- method public android.renderscript.Element create();
+ @Deprecated public static class Element.Builder {
+ ctor @Deprecated public Element.Builder(android.renderscript.RenderScript);
+ method @Deprecated public android.renderscript.Element.Builder add(android.renderscript.Element, String, int);
+ method @Deprecated public android.renderscript.Element.Builder add(android.renderscript.Element, String);
+ method @Deprecated public android.renderscript.Element create();
}
- public enum Element.DataKind {
- enum_constant public static final android.renderscript.Element.DataKind PIXEL_A;
- enum_constant public static final android.renderscript.Element.DataKind PIXEL_DEPTH;
- enum_constant public static final android.renderscript.Element.DataKind PIXEL_L;
- enum_constant public static final android.renderscript.Element.DataKind PIXEL_LA;
- enum_constant public static final android.renderscript.Element.DataKind PIXEL_RGB;
- enum_constant public static final android.renderscript.Element.DataKind PIXEL_RGBA;
- enum_constant public static final android.renderscript.Element.DataKind PIXEL_YUV;
- enum_constant public static final android.renderscript.Element.DataKind USER;
+ @Deprecated public enum Element.DataKind {
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind PIXEL_A;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind PIXEL_DEPTH;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind PIXEL_L;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind PIXEL_LA;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind PIXEL_RGB;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind PIXEL_RGBA;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind PIXEL_YUV;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind USER;
}
- public enum Element.DataType {
- enum_constant public static final android.renderscript.Element.DataType BOOLEAN;
- enum_constant public static final android.renderscript.Element.DataType FLOAT_16;
- enum_constant public static final android.renderscript.Element.DataType FLOAT_32;
- enum_constant public static final android.renderscript.Element.DataType FLOAT_64;
- enum_constant public static final android.renderscript.Element.DataType MATRIX_2X2;
- enum_constant public static final android.renderscript.Element.DataType MATRIX_3X3;
- enum_constant public static final android.renderscript.Element.DataType MATRIX_4X4;
- enum_constant public static final android.renderscript.Element.DataType NONE;
- enum_constant public static final android.renderscript.Element.DataType RS_ALLOCATION;
- enum_constant public static final android.renderscript.Element.DataType RS_ELEMENT;
- enum_constant public static final android.renderscript.Element.DataType RS_FONT;
- enum_constant public static final android.renderscript.Element.DataType RS_MESH;
- enum_constant public static final android.renderscript.Element.DataType RS_PROGRAM_FRAGMENT;
- enum_constant public static final android.renderscript.Element.DataType RS_PROGRAM_RASTER;
- enum_constant public static final android.renderscript.Element.DataType RS_PROGRAM_STORE;
- enum_constant public static final android.renderscript.Element.DataType RS_PROGRAM_VERTEX;
- enum_constant public static final android.renderscript.Element.DataType RS_SAMPLER;
- enum_constant public static final android.renderscript.Element.DataType RS_SCRIPT;
- enum_constant public static final android.renderscript.Element.DataType RS_TYPE;
- enum_constant public static final android.renderscript.Element.DataType SIGNED_16;
- enum_constant public static final android.renderscript.Element.DataType SIGNED_32;
- enum_constant public static final android.renderscript.Element.DataType SIGNED_64;
- enum_constant public static final android.renderscript.Element.DataType SIGNED_8;
- enum_constant public static final android.renderscript.Element.DataType UNSIGNED_16;
- enum_constant public static final android.renderscript.Element.DataType UNSIGNED_32;
- enum_constant public static final android.renderscript.Element.DataType UNSIGNED_4_4_4_4;
- enum_constant public static final android.renderscript.Element.DataType UNSIGNED_5_5_5_1;
- enum_constant public static final android.renderscript.Element.DataType UNSIGNED_5_6_5;
- enum_constant public static final android.renderscript.Element.DataType UNSIGNED_64;
- enum_constant public static final android.renderscript.Element.DataType UNSIGNED_8;
+ @Deprecated public enum Element.DataType {
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType BOOLEAN;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType FLOAT_16;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType FLOAT_32;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType FLOAT_64;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType MATRIX_2X2;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType MATRIX_3X3;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType MATRIX_4X4;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType NONE;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_ALLOCATION;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_ELEMENT;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_FONT;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_MESH;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_PROGRAM_FRAGMENT;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_PROGRAM_RASTER;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_PROGRAM_STORE;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_PROGRAM_VERTEX;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_SAMPLER;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_SCRIPT;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_TYPE;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType SIGNED_16;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType SIGNED_32;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType SIGNED_64;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType SIGNED_8;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType UNSIGNED_16;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType UNSIGNED_32;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType UNSIGNED_4_4_4_4;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType UNSIGNED_5_5_5_1;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType UNSIGNED_5_6_5;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType UNSIGNED_64;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType UNSIGNED_8;
}
- public class FieldPacker {
- ctor public FieldPacker(int);
- ctor public FieldPacker(byte[]);
- method public void addBoolean(boolean);
- method public void addF32(float);
- method public void addF32(android.renderscript.Float2);
- method public void addF32(android.renderscript.Float3);
- method public void addF32(android.renderscript.Float4);
- method public void addF64(double);
- method public void addF64(android.renderscript.Double2);
- method public void addF64(android.renderscript.Double3);
- method public void addF64(android.renderscript.Double4);
- method public void addI16(short);
- method public void addI16(android.renderscript.Short2);
- method public void addI16(android.renderscript.Short3);
- method public void addI16(android.renderscript.Short4);
- method public void addI32(int);
- method public void addI32(android.renderscript.Int2);
- method public void addI32(android.renderscript.Int3);
- method public void addI32(android.renderscript.Int4);
- method public void addI64(long);
- method public void addI64(android.renderscript.Long2);
- method public void addI64(android.renderscript.Long3);
- method public void addI64(android.renderscript.Long4);
- method public void addI8(byte);
- method public void addI8(android.renderscript.Byte2);
- method public void addI8(android.renderscript.Byte3);
- method public void addI8(android.renderscript.Byte4);
- method public void addMatrix(android.renderscript.Matrix4f);
- method public void addMatrix(android.renderscript.Matrix3f);
- method public void addMatrix(android.renderscript.Matrix2f);
- method public void addObj(android.renderscript.BaseObj);
- method public void addU16(int);
- method public void addU16(android.renderscript.Int2);
- method public void addU16(android.renderscript.Int3);
- method public void addU16(android.renderscript.Int4);
- method public void addU32(long);
- method public void addU32(android.renderscript.Long2);
- method public void addU32(android.renderscript.Long3);
- method public void addU32(android.renderscript.Long4);
- method public void addU64(long);
- method public void addU64(android.renderscript.Long2);
- method public void addU64(android.renderscript.Long3);
- method public void addU64(android.renderscript.Long4);
- method public void addU8(short);
- method public void addU8(android.renderscript.Short2);
- method public void addU8(android.renderscript.Short3);
- method public void addU8(android.renderscript.Short4);
- method public void align(int);
- method public final byte[] getData();
- method public void reset();
- method public void reset(int);
- method public void skip(int);
- method public boolean subBoolean();
- method public android.renderscript.Byte2 subByte2();
- method public android.renderscript.Byte3 subByte3();
- method public android.renderscript.Byte4 subByte4();
- method public android.renderscript.Double2 subDouble2();
- method public android.renderscript.Double3 subDouble3();
- method public android.renderscript.Double4 subDouble4();
- method public float subF32();
- method public double subF64();
- method public android.renderscript.Float2 subFloat2();
- method public android.renderscript.Float3 subFloat3();
- method public android.renderscript.Float4 subFloat4();
- method public short subI16();
- method public int subI32();
- method public long subI64();
- method public byte subI8();
- method public android.renderscript.Int2 subInt2();
- method public android.renderscript.Int3 subInt3();
- method public android.renderscript.Int4 subInt4();
- method public android.renderscript.Long2 subLong2();
- method public android.renderscript.Long3 subLong3();
- method public android.renderscript.Long4 subLong4();
- method public android.renderscript.Matrix2f subMatrix2f();
- method public android.renderscript.Matrix3f subMatrix3f();
- method public android.renderscript.Matrix4f subMatrix4f();
- method public android.renderscript.Short2 subShort2();
- method public android.renderscript.Short3 subShort3();
- method public android.renderscript.Short4 subShort4();
- method public void subalign(int);
+ @Deprecated public class FieldPacker {
+ ctor @Deprecated public FieldPacker(int);
+ ctor @Deprecated public FieldPacker(byte[]);
+ method @Deprecated public void addBoolean(boolean);
+ method @Deprecated public void addF32(float);
+ method @Deprecated public void addF32(android.renderscript.Float2);
+ method @Deprecated public void addF32(android.renderscript.Float3);
+ method @Deprecated public void addF32(android.renderscript.Float4);
+ method @Deprecated public void addF64(double);
+ method @Deprecated public void addF64(android.renderscript.Double2);
+ method @Deprecated public void addF64(android.renderscript.Double3);
+ method @Deprecated public void addF64(android.renderscript.Double4);
+ method @Deprecated public void addI16(short);
+ method @Deprecated public void addI16(android.renderscript.Short2);
+ method @Deprecated public void addI16(android.renderscript.Short3);
+ method @Deprecated public void addI16(android.renderscript.Short4);
+ method @Deprecated public void addI32(int);
+ method @Deprecated public void addI32(android.renderscript.Int2);
+ method @Deprecated public void addI32(android.renderscript.Int3);
+ method @Deprecated public void addI32(android.renderscript.Int4);
+ method @Deprecated public void addI64(long);
+ method @Deprecated public void addI64(android.renderscript.Long2);
+ method @Deprecated public void addI64(android.renderscript.Long3);
+ method @Deprecated public void addI64(android.renderscript.Long4);
+ method @Deprecated public void addI8(byte);
+ method @Deprecated public void addI8(android.renderscript.Byte2);
+ method @Deprecated public void addI8(android.renderscript.Byte3);
+ method @Deprecated public void addI8(android.renderscript.Byte4);
+ method @Deprecated public void addMatrix(android.renderscript.Matrix4f);
+ method @Deprecated public void addMatrix(android.renderscript.Matrix3f);
+ method @Deprecated public void addMatrix(android.renderscript.Matrix2f);
+ method @Deprecated public void addObj(android.renderscript.BaseObj);
+ method @Deprecated public void addU16(int);
+ method @Deprecated public void addU16(android.renderscript.Int2);
+ method @Deprecated public void addU16(android.renderscript.Int3);
+ method @Deprecated public void addU16(android.renderscript.Int4);
+ method @Deprecated public void addU32(long);
+ method @Deprecated public void addU32(android.renderscript.Long2);
+ method @Deprecated public void addU32(android.renderscript.Long3);
+ method @Deprecated public void addU32(android.renderscript.Long4);
+ method @Deprecated public void addU64(long);
+ method @Deprecated public void addU64(android.renderscript.Long2);
+ method @Deprecated public void addU64(android.renderscript.Long3);
+ method @Deprecated public void addU64(android.renderscript.Long4);
+ method @Deprecated public void addU8(short);
+ method @Deprecated public void addU8(android.renderscript.Short2);
+ method @Deprecated public void addU8(android.renderscript.Short3);
+ method @Deprecated public void addU8(android.renderscript.Short4);
+ method @Deprecated public void align(int);
+ method @Deprecated public final byte[] getData();
+ method @Deprecated public void reset();
+ method @Deprecated public void reset(int);
+ method @Deprecated public void skip(int);
+ method @Deprecated public boolean subBoolean();
+ method @Deprecated public android.renderscript.Byte2 subByte2();
+ method @Deprecated public android.renderscript.Byte3 subByte3();
+ method @Deprecated public android.renderscript.Byte4 subByte4();
+ method @Deprecated public android.renderscript.Double2 subDouble2();
+ method @Deprecated public android.renderscript.Double3 subDouble3();
+ method @Deprecated public android.renderscript.Double4 subDouble4();
+ method @Deprecated public float subF32();
+ method @Deprecated public double subF64();
+ method @Deprecated public android.renderscript.Float2 subFloat2();
+ method @Deprecated public android.renderscript.Float3 subFloat3();
+ method @Deprecated public android.renderscript.Float4 subFloat4();
+ method @Deprecated public short subI16();
+ method @Deprecated public int subI32();
+ method @Deprecated public long subI64();
+ method @Deprecated public byte subI8();
+ method @Deprecated public android.renderscript.Int2 subInt2();
+ method @Deprecated public android.renderscript.Int3 subInt3();
+ method @Deprecated public android.renderscript.Int4 subInt4();
+ method @Deprecated public android.renderscript.Long2 subLong2();
+ method @Deprecated public android.renderscript.Long3 subLong3();
+ method @Deprecated public android.renderscript.Long4 subLong4();
+ method @Deprecated public android.renderscript.Matrix2f subMatrix2f();
+ method @Deprecated public android.renderscript.Matrix3f subMatrix3f();
+ method @Deprecated public android.renderscript.Matrix4f subMatrix4f();
+ method @Deprecated public android.renderscript.Short2 subShort2();
+ method @Deprecated public android.renderscript.Short3 subShort3();
+ method @Deprecated public android.renderscript.Short4 subShort4();
+ method @Deprecated public void subalign(int);
}
- public class Float2 {
- ctor public Float2();
- ctor public Float2(float, float);
- field public float x;
- field public float y;
+ @Deprecated public class Float2 {
+ ctor @Deprecated public Float2();
+ ctor @Deprecated public Float2(float, float);
+ field @Deprecated public float x;
+ field @Deprecated public float y;
}
- public class Float3 {
- ctor public Float3();
- ctor public Float3(float, float, float);
- field public float x;
- field public float y;
- field public float z;
+ @Deprecated public class Float3 {
+ ctor @Deprecated public Float3();
+ ctor @Deprecated public Float3(float, float, float);
+ field @Deprecated public float x;
+ field @Deprecated public float y;
+ field @Deprecated public float z;
}
- public class Float4 {
- ctor public Float4();
- ctor public Float4(float, float, float, float);
- field public float w;
- field public float x;
- field public float y;
- field public float z;
+ @Deprecated public class Float4 {
+ ctor @Deprecated public Float4();
+ ctor @Deprecated public Float4(float, float, float, float);
+ field @Deprecated public float w;
+ field @Deprecated public float x;
+ field @Deprecated public float y;
+ field @Deprecated public float z;
}
- public class Int2 {
- ctor public Int2();
- ctor public Int2(int, int);
- field public int x;
- field public int y;
+ @Deprecated public class Int2 {
+ ctor @Deprecated public Int2();
+ ctor @Deprecated public Int2(int, int);
+ field @Deprecated public int x;
+ field @Deprecated public int y;
}
- public class Int3 {
- ctor public Int3();
- ctor public Int3(int, int, int);
- field public int x;
- field public int y;
- field public int z;
+ @Deprecated public class Int3 {
+ ctor @Deprecated public Int3();
+ ctor @Deprecated public Int3(int, int, int);
+ field @Deprecated public int x;
+ field @Deprecated public int y;
+ field @Deprecated public int z;
}
- public class Int4 {
- ctor public Int4();
- ctor public Int4(int, int, int, int);
- field public int w;
- field public int x;
- field public int y;
- field public int z;
+ @Deprecated public class Int4 {
+ ctor @Deprecated public Int4();
+ ctor @Deprecated public Int4(int, int, int, int);
+ field @Deprecated public int w;
+ field @Deprecated public int x;
+ field @Deprecated public int y;
+ field @Deprecated public int z;
}
- public class Long2 {
- ctor public Long2();
- ctor public Long2(long, long);
- field public long x;
- field public long y;
+ @Deprecated public class Long2 {
+ ctor @Deprecated public Long2();
+ ctor @Deprecated public Long2(long, long);
+ field @Deprecated public long x;
+ field @Deprecated public long y;
}
- public class Long3 {
- ctor public Long3();
- ctor public Long3(long, long, long);
- field public long x;
- field public long y;
- field public long z;
+ @Deprecated public class Long3 {
+ ctor @Deprecated public Long3();
+ ctor @Deprecated public Long3(long, long, long);
+ field @Deprecated public long x;
+ field @Deprecated public long y;
+ field @Deprecated public long z;
}
- public class Long4 {
- ctor public Long4();
- ctor public Long4(long, long, long, long);
- field public long w;
- field public long x;
- field public long y;
- field public long z;
+ @Deprecated public class Long4 {
+ ctor @Deprecated public Long4();
+ ctor @Deprecated public Long4(long, long, long, long);
+ field @Deprecated public long w;
+ field @Deprecated public long x;
+ field @Deprecated public long y;
+ field @Deprecated public long z;
}
- public class Matrix2f {
- ctor public Matrix2f();
- ctor public Matrix2f(float[]);
- method public float get(int, int);
- method public float[] getArray();
- method public void load(android.renderscript.Matrix2f);
- method public void loadIdentity();
- method public void loadMultiply(android.renderscript.Matrix2f, android.renderscript.Matrix2f);
- method public void loadRotate(float);
- method public void loadScale(float, float);
- method public void multiply(android.renderscript.Matrix2f);
- method public void rotate(float);
- method public void scale(float, float);
- method public void set(int, int, float);
- method public void transpose();
+ @Deprecated public class Matrix2f {
+ ctor @Deprecated public Matrix2f();
+ ctor @Deprecated public Matrix2f(float[]);
+ method @Deprecated public float get(int, int);
+ method @Deprecated public float[] getArray();
+ method @Deprecated public void load(android.renderscript.Matrix2f);
+ method @Deprecated public void loadIdentity();
+ method @Deprecated public void loadMultiply(android.renderscript.Matrix2f, android.renderscript.Matrix2f);
+ method @Deprecated public void loadRotate(float);
+ method @Deprecated public void loadScale(float, float);
+ method @Deprecated public void multiply(android.renderscript.Matrix2f);
+ method @Deprecated public void rotate(float);
+ method @Deprecated public void scale(float, float);
+ method @Deprecated public void set(int, int, float);
+ method @Deprecated public void transpose();
}
- public class Matrix3f {
- ctor public Matrix3f();
- ctor public Matrix3f(float[]);
- method public float get(int, int);
- method public float[] getArray();
- method public void load(android.renderscript.Matrix3f);
- method public void loadIdentity();
- method public void loadMultiply(android.renderscript.Matrix3f, android.renderscript.Matrix3f);
- method public void loadRotate(float, float, float, float);
- method public void loadRotate(float);
- method public void loadScale(float, float);
- method public void loadScale(float, float, float);
- method public void loadTranslate(float, float);
- method public void multiply(android.renderscript.Matrix3f);
- method public void rotate(float, float, float, float);
- method public void rotate(float);
- method public void scale(float, float);
- method public void scale(float, float, float);
- method public void set(int, int, float);
- method public void translate(float, float);
- method public void transpose();
+ @Deprecated public class Matrix3f {
+ ctor @Deprecated public Matrix3f();
+ ctor @Deprecated public Matrix3f(float[]);
+ method @Deprecated public float get(int, int);
+ method @Deprecated public float[] getArray();
+ method @Deprecated public void load(android.renderscript.Matrix3f);
+ method @Deprecated public void loadIdentity();
+ method @Deprecated public void loadMultiply(android.renderscript.Matrix3f, android.renderscript.Matrix3f);
+ method @Deprecated public void loadRotate(float, float, float, float);
+ method @Deprecated public void loadRotate(float);
+ method @Deprecated public void loadScale(float, float);
+ method @Deprecated public void loadScale(float, float, float);
+ method @Deprecated public void loadTranslate(float, float);
+ method @Deprecated public void multiply(android.renderscript.Matrix3f);
+ method @Deprecated public void rotate(float, float, float, float);
+ method @Deprecated public void rotate(float);
+ method @Deprecated public void scale(float, float);
+ method @Deprecated public void scale(float, float, float);
+ method @Deprecated public void set(int, int, float);
+ method @Deprecated public void translate(float, float);
+ method @Deprecated public void transpose();
}
- public class Matrix4f {
- ctor public Matrix4f();
- ctor public Matrix4f(float[]);
- method public float get(int, int);
- method public float[] getArray();
- method public boolean inverse();
- method public boolean inverseTranspose();
- method public void load(android.renderscript.Matrix4f);
- method public void loadFrustum(float, float, float, float, float, float);
- method public void loadIdentity();
- method public void loadMultiply(android.renderscript.Matrix4f, android.renderscript.Matrix4f);
- method public void loadOrtho(float, float, float, float, float, float);
- method public void loadOrthoWindow(int, int);
- method public void loadPerspective(float, float, float, float);
- method public void loadProjectionNormalized(int, int);
- method public void loadRotate(float, float, float, float);
- method public void loadScale(float, float, float);
- method public void loadTranslate(float, float, float);
- method public void multiply(android.renderscript.Matrix4f);
- method public void rotate(float, float, float, float);
- method public void scale(float, float, float);
- method public void set(int, int, float);
- method public void translate(float, float, float);
- method public void transpose();
+ @Deprecated public class Matrix4f {
+ ctor @Deprecated public Matrix4f();
+ ctor @Deprecated public Matrix4f(float[]);
+ method @Deprecated public float get(int, int);
+ method @Deprecated public float[] getArray();
+ method @Deprecated public boolean inverse();
+ method @Deprecated public boolean inverseTranspose();
+ method @Deprecated public void load(android.renderscript.Matrix4f);
+ method @Deprecated public void loadFrustum(float, float, float, float, float, float);
+ method @Deprecated public void loadIdentity();
+ method @Deprecated public void loadMultiply(android.renderscript.Matrix4f, android.renderscript.Matrix4f);
+ method @Deprecated public void loadOrtho(float, float, float, float, float, float);
+ method @Deprecated public void loadOrthoWindow(int, int);
+ method @Deprecated public void loadPerspective(float, float, float, float);
+ method @Deprecated public void loadProjectionNormalized(int, int);
+ method @Deprecated public void loadRotate(float, float, float, float);
+ method @Deprecated public void loadScale(float, float, float);
+ method @Deprecated public void loadTranslate(float, float, float);
+ method @Deprecated public void multiply(android.renderscript.Matrix4f);
+ method @Deprecated public void rotate(float, float, float, float);
+ method @Deprecated public void scale(float, float, float);
+ method @Deprecated public void set(int, int, float);
+ method @Deprecated public void translate(float, float, float);
+ method @Deprecated public void transpose();
}
- public class RSDriverException extends android.renderscript.RSRuntimeException {
- ctor public RSDriverException(String);
+ @Deprecated public class RSDriverException extends android.renderscript.RSRuntimeException {
+ ctor @Deprecated public RSDriverException(String);
}
- public class RSIllegalArgumentException extends android.renderscript.RSRuntimeException {
- ctor public RSIllegalArgumentException(String);
+ @Deprecated public class RSIllegalArgumentException extends android.renderscript.RSRuntimeException {
+ ctor @Deprecated public RSIllegalArgumentException(String);
}
- public class RSInvalidStateException extends android.renderscript.RSRuntimeException {
- ctor public RSInvalidStateException(String);
+ @Deprecated public class RSInvalidStateException extends android.renderscript.RSRuntimeException {
+ ctor @Deprecated public RSInvalidStateException(String);
}
- public class RSRuntimeException extends java.lang.RuntimeException {
- ctor public RSRuntimeException(String);
+ @Deprecated public class RSRuntimeException extends java.lang.RuntimeException {
+ ctor @Deprecated public RSRuntimeException(String);
}
- public class RenderScript {
- method public void contextDump();
- method public static android.renderscript.RenderScript create(android.content.Context);
- method public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType);
- method public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType, int);
- method public static android.renderscript.RenderScript createMultiContext(android.content.Context, android.renderscript.RenderScript.ContextType, int, int);
- method public void destroy();
- method public void finish();
- method public final android.content.Context getApplicationContext();
- method public android.renderscript.RenderScript.RSErrorHandler getErrorHandler();
- method public android.renderscript.RenderScript.RSMessageHandler getMessageHandler();
- method public static long getMinorVersion();
- method public static void releaseAllContexts();
- method public void sendMessage(int, int[]);
- method public void setErrorHandler(android.renderscript.RenderScript.RSErrorHandler);
- method public void setMessageHandler(android.renderscript.RenderScript.RSMessageHandler);
- method public void setPriority(android.renderscript.RenderScript.Priority);
- field public static final int CREATE_FLAG_LOW_LATENCY = 2; // 0x2
- field public static final int CREATE_FLAG_LOW_POWER = 4; // 0x4
- field public static final int CREATE_FLAG_NONE = 0; // 0x0
+ @Deprecated public class RenderScript {
+ method @Deprecated public void contextDump();
+ method @Deprecated public static android.renderscript.RenderScript create(android.content.Context);
+ method @Deprecated public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType);
+ method @Deprecated public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType, int);
+ method @Deprecated public static android.renderscript.RenderScript createMultiContext(android.content.Context, android.renderscript.RenderScript.ContextType, int, int);
+ method @Deprecated public void destroy();
+ method @Deprecated public void finish();
+ method @Deprecated public final android.content.Context getApplicationContext();
+ method @Deprecated public android.renderscript.RenderScript.RSErrorHandler getErrorHandler();
+ method @Deprecated public android.renderscript.RenderScript.RSMessageHandler getMessageHandler();
+ method @Deprecated public static long getMinorVersion();
+ method @Deprecated public static void releaseAllContexts();
+ method @Deprecated public void sendMessage(int, int[]);
+ method @Deprecated public void setErrorHandler(android.renderscript.RenderScript.RSErrorHandler);
+ method @Deprecated public void setMessageHandler(android.renderscript.RenderScript.RSMessageHandler);
+ method @Deprecated public void setPriority(android.renderscript.RenderScript.Priority);
+ field @Deprecated public static final int CREATE_FLAG_LOW_LATENCY = 2; // 0x2
+ field @Deprecated public static final int CREATE_FLAG_LOW_POWER = 4; // 0x4
+ field @Deprecated public static final int CREATE_FLAG_NONE = 0; // 0x0
}
- public enum RenderScript.ContextType {
- enum_constant public static final android.renderscript.RenderScript.ContextType DEBUG;
- enum_constant public static final android.renderscript.RenderScript.ContextType NORMAL;
- enum_constant public static final android.renderscript.RenderScript.ContextType PROFILE;
+ @Deprecated public enum RenderScript.ContextType {
+ enum_constant @Deprecated public static final android.renderscript.RenderScript.ContextType DEBUG;
+ enum_constant @Deprecated public static final android.renderscript.RenderScript.ContextType NORMAL;
+ enum_constant @Deprecated public static final android.renderscript.RenderScript.ContextType PROFILE;
}
- public enum RenderScript.Priority {
- enum_constant public static final android.renderscript.RenderScript.Priority LOW;
- enum_constant public static final android.renderscript.RenderScript.Priority NORMAL;
+ @Deprecated public enum RenderScript.Priority {
+ enum_constant @Deprecated public static final android.renderscript.RenderScript.Priority LOW;
+ enum_constant @Deprecated public static final android.renderscript.RenderScript.Priority NORMAL;
}
- public static class RenderScript.RSErrorHandler implements java.lang.Runnable {
- ctor public RenderScript.RSErrorHandler();
- method public void run();
- field protected String mErrorMessage;
- field protected int mErrorNum;
+ @Deprecated public static class RenderScript.RSErrorHandler implements java.lang.Runnable {
+ ctor @Deprecated public RenderScript.RSErrorHandler();
+ method @Deprecated public void run();
+ field @Deprecated protected String mErrorMessage;
+ field @Deprecated protected int mErrorNum;
}
- public static class RenderScript.RSMessageHandler implements java.lang.Runnable {
- ctor public RenderScript.RSMessageHandler();
- method public void run();
- field protected int[] mData;
- field protected int mID;
- field protected int mLength;
+ @Deprecated public static class RenderScript.RSMessageHandler implements java.lang.Runnable {
+ ctor @Deprecated public RenderScript.RSMessageHandler();
+ method @Deprecated public void run();
+ field @Deprecated protected int[] mData;
+ field @Deprecated protected int mID;
+ field @Deprecated protected int mLength;
}
- public class Sampler extends android.renderscript.BaseObj {
- method public static android.renderscript.Sampler CLAMP_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler CLAMP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler CLAMP_NEAREST(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler MIRRORED_REPEAT_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler MIRRORED_REPEAT_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler MIRRORED_REPEAT_NEAREST(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler WRAP_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler WRAP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler WRAP_NEAREST(android.renderscript.RenderScript);
- method public float getAnisotropy();
- method public android.renderscript.Sampler.Value getMagnification();
- method public android.renderscript.Sampler.Value getMinification();
- method public android.renderscript.Sampler.Value getWrapS();
- method public android.renderscript.Sampler.Value getWrapT();
+ @Deprecated public class Sampler extends android.renderscript.BaseObj {
+ method @Deprecated public static android.renderscript.Sampler CLAMP_LINEAR(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler CLAMP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler CLAMP_NEAREST(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler MIRRORED_REPEAT_LINEAR(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler MIRRORED_REPEAT_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler MIRRORED_REPEAT_NEAREST(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler WRAP_LINEAR(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler WRAP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler WRAP_NEAREST(android.renderscript.RenderScript);
+ method @Deprecated public float getAnisotropy();
+ method @Deprecated public android.renderscript.Sampler.Value getMagnification();
+ method @Deprecated public android.renderscript.Sampler.Value getMinification();
+ method @Deprecated public android.renderscript.Sampler.Value getWrapS();
+ method @Deprecated public android.renderscript.Sampler.Value getWrapT();
}
- public static class Sampler.Builder {
- ctor public Sampler.Builder(android.renderscript.RenderScript);
- method public android.renderscript.Sampler create();
- method public void setAnisotropy(float);
- method public void setMagnification(android.renderscript.Sampler.Value);
- method public void setMinification(android.renderscript.Sampler.Value);
- method public void setWrapS(android.renderscript.Sampler.Value);
- method public void setWrapT(android.renderscript.Sampler.Value);
+ @Deprecated public static class Sampler.Builder {
+ ctor @Deprecated public Sampler.Builder(android.renderscript.RenderScript);
+ method @Deprecated public android.renderscript.Sampler create();
+ method @Deprecated public void setAnisotropy(float);
+ method @Deprecated public void setMagnification(android.renderscript.Sampler.Value);
+ method @Deprecated public void setMinification(android.renderscript.Sampler.Value);
+ method @Deprecated public void setWrapS(android.renderscript.Sampler.Value);
+ method @Deprecated public void setWrapT(android.renderscript.Sampler.Value);
}
- public enum Sampler.Value {
- enum_constant public static final android.renderscript.Sampler.Value CLAMP;
- enum_constant public static final android.renderscript.Sampler.Value LINEAR;
- enum_constant public static final android.renderscript.Sampler.Value LINEAR_MIP_LINEAR;
- enum_constant public static final android.renderscript.Sampler.Value LINEAR_MIP_NEAREST;
- enum_constant public static final android.renderscript.Sampler.Value MIRRORED_REPEAT;
- enum_constant public static final android.renderscript.Sampler.Value NEAREST;
- enum_constant public static final android.renderscript.Sampler.Value WRAP;
+ @Deprecated public enum Sampler.Value {
+ enum_constant @Deprecated public static final android.renderscript.Sampler.Value CLAMP;
+ enum_constant @Deprecated public static final android.renderscript.Sampler.Value LINEAR;
+ enum_constant @Deprecated public static final android.renderscript.Sampler.Value LINEAR_MIP_LINEAR;
+ enum_constant @Deprecated public static final android.renderscript.Sampler.Value LINEAR_MIP_NEAREST;
+ enum_constant @Deprecated public static final android.renderscript.Sampler.Value MIRRORED_REPEAT;
+ enum_constant @Deprecated public static final android.renderscript.Sampler.Value NEAREST;
+ enum_constant @Deprecated public static final android.renderscript.Sampler.Value WRAP;
}
- public class Script extends android.renderscript.BaseObj {
- method public void bindAllocation(android.renderscript.Allocation, int);
- method protected android.renderscript.Script.FieldID createFieldID(int, android.renderscript.Element);
- method protected android.renderscript.Script.InvokeID createInvokeID(int);
- method protected android.renderscript.Script.KernelID createKernelID(int, int, android.renderscript.Element, android.renderscript.Element);
- method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker);
- method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
- method protected void forEach(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.FieldPacker);
- method protected void forEach(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
- method public boolean getVarB(int);
- method public double getVarD(int);
- method public float getVarF(int);
- method public int getVarI(int);
- method public long getVarJ(int);
- method public void getVarV(int, android.renderscript.FieldPacker);
- method protected void invoke(int);
- method protected void invoke(int, android.renderscript.FieldPacker);
- method protected void reduce(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void setTimeZone(String);
- method public void setVar(int, float);
- method public void setVar(int, double);
- method public void setVar(int, int);
- method public void setVar(int, long);
- method public void setVar(int, boolean);
- method public void setVar(int, android.renderscript.BaseObj);
- method public void setVar(int, android.renderscript.FieldPacker);
- method public void setVar(int, android.renderscript.FieldPacker, android.renderscript.Element, int[]);
+ @Deprecated public class Script extends android.renderscript.BaseObj {
+ method @Deprecated public void bindAllocation(android.renderscript.Allocation, int);
+ method @Deprecated protected android.renderscript.Script.FieldID createFieldID(int, android.renderscript.Element);
+ method @Deprecated protected android.renderscript.Script.InvokeID createInvokeID(int);
+ method @Deprecated protected android.renderscript.Script.KernelID createKernelID(int, int, android.renderscript.Element, android.renderscript.Element);
+ method @Deprecated protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker);
+ method @Deprecated protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
+ method @Deprecated protected void forEach(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.FieldPacker);
+ method @Deprecated protected void forEach(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public boolean getVarB(int);
+ method @Deprecated public double getVarD(int);
+ method @Deprecated public float getVarF(int);
+ method @Deprecated public int getVarI(int);
+ method @Deprecated public long getVarJ(int);
+ method @Deprecated public void getVarV(int, android.renderscript.FieldPacker);
+ method @Deprecated protected void invoke(int);
+ method @Deprecated protected void invoke(int, android.renderscript.FieldPacker);
+ method @Deprecated protected void reduce(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void setTimeZone(String);
+ method @Deprecated public void setVar(int, float);
+ method @Deprecated public void setVar(int, double);
+ method @Deprecated public void setVar(int, int);
+ method @Deprecated public void setVar(int, long);
+ method @Deprecated public void setVar(int, boolean);
+ method @Deprecated public void setVar(int, android.renderscript.BaseObj);
+ method @Deprecated public void setVar(int, android.renderscript.FieldPacker);
+ method @Deprecated public void setVar(int, android.renderscript.FieldPacker, android.renderscript.Element, int[]);
}
- public static class Script.Builder {
+ @Deprecated public static class Script.Builder {
}
- public static class Script.FieldBase {
- ctor protected Script.FieldBase();
- method public android.renderscript.Allocation getAllocation();
- method public android.renderscript.Element getElement();
- method public android.renderscript.Type getType();
- method protected void init(android.renderscript.RenderScript, int);
- method protected void init(android.renderscript.RenderScript, int, int);
- method public void updateAllocation();
- field protected android.renderscript.Allocation mAllocation;
- field protected android.renderscript.Element mElement;
+ @Deprecated public static class Script.FieldBase {
+ ctor @Deprecated protected Script.FieldBase();
+ method @Deprecated public android.renderscript.Allocation getAllocation();
+ method @Deprecated public android.renderscript.Element getElement();
+ method @Deprecated public android.renderscript.Type getType();
+ method @Deprecated protected void init(android.renderscript.RenderScript, int);
+ method @Deprecated protected void init(android.renderscript.RenderScript, int, int);
+ method @Deprecated public void updateAllocation();
+ field @Deprecated protected android.renderscript.Allocation mAllocation;
+ field @Deprecated protected android.renderscript.Element mElement;
}
- public static final class Script.FieldID extends android.renderscript.BaseObj {
+ @Deprecated public static final class Script.FieldID extends android.renderscript.BaseObj {
}
- public static final class Script.InvokeID extends android.renderscript.BaseObj {
+ @Deprecated public static final class Script.InvokeID extends android.renderscript.BaseObj {
}
- public static final class Script.KernelID extends android.renderscript.BaseObj {
+ @Deprecated public static final class Script.KernelID extends android.renderscript.BaseObj {
}
- public static final class Script.LaunchOptions {
- ctor public Script.LaunchOptions();
- method public int getXEnd();
- method public int getXStart();
- method public int getYEnd();
- method public int getYStart();
- method public int getZEnd();
- method public int getZStart();
- method public android.renderscript.Script.LaunchOptions setX(int, int);
- method public android.renderscript.Script.LaunchOptions setY(int, int);
- method public android.renderscript.Script.LaunchOptions setZ(int, int);
+ @Deprecated public static final class Script.LaunchOptions {
+ ctor @Deprecated public Script.LaunchOptions();
+ method @Deprecated public int getXEnd();
+ method @Deprecated public int getXStart();
+ method @Deprecated public int getYEnd();
+ method @Deprecated public int getYStart();
+ method @Deprecated public int getZEnd();
+ method @Deprecated public int getZStart();
+ method @Deprecated public android.renderscript.Script.LaunchOptions setX(int, int);
+ method @Deprecated public android.renderscript.Script.LaunchOptions setY(int, int);
+ method @Deprecated public android.renderscript.Script.LaunchOptions setZ(int, int);
}
- public class ScriptC extends android.renderscript.Script {
- ctor protected ScriptC(int, android.renderscript.RenderScript);
- ctor protected ScriptC(long, android.renderscript.RenderScript);
- ctor protected ScriptC(android.renderscript.RenderScript, android.content.res.Resources, int);
- ctor protected ScriptC(android.renderscript.RenderScript, String, byte[], byte[]);
+ @Deprecated public class ScriptC extends android.renderscript.Script {
+ ctor @Deprecated protected ScriptC(int, android.renderscript.RenderScript);
+ ctor @Deprecated protected ScriptC(long, android.renderscript.RenderScript);
+ ctor @Deprecated protected ScriptC(android.renderscript.RenderScript, android.content.res.Resources, int);
+ ctor @Deprecated protected ScriptC(android.renderscript.RenderScript, String, byte[], byte[]);
}
- public final class ScriptGroup extends android.renderscript.BaseObj {
- method public Object[] execute(java.lang.Object...);
+ @Deprecated public final class ScriptGroup extends android.renderscript.BaseObj {
+ method @Deprecated public Object[] execute(java.lang.Object...);
method @Deprecated public void execute();
method @Deprecated public void setInput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
method @Deprecated public void setOutput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
}
- public static final class ScriptGroup.Binding {
- ctor public ScriptGroup.Binding(android.renderscript.Script.FieldID, Object);
+ @Deprecated public static final class ScriptGroup.Binding {
+ ctor @Deprecated public ScriptGroup.Binding(android.renderscript.Script.FieldID, Object);
}
@Deprecated public static final class ScriptGroup.Builder {
@@ -36376,336 +36373,336 @@
method @Deprecated public android.renderscript.ScriptGroup create();
}
- public static final class ScriptGroup.Builder2 {
- ctor public ScriptGroup.Builder2(android.renderscript.RenderScript);
- method public android.renderscript.ScriptGroup.Input addInput();
- method public android.renderscript.ScriptGroup.Closure addInvoke(android.renderscript.Script.InvokeID, java.lang.Object...);
- method public android.renderscript.ScriptGroup.Closure addKernel(android.renderscript.Script.KernelID, android.renderscript.Type, java.lang.Object...);
- method public android.renderscript.ScriptGroup create(String, android.renderscript.ScriptGroup.Future...);
+ @Deprecated public static final class ScriptGroup.Builder2 {
+ ctor @Deprecated public ScriptGroup.Builder2(android.renderscript.RenderScript);
+ method @Deprecated public android.renderscript.ScriptGroup.Input addInput();
+ method @Deprecated public android.renderscript.ScriptGroup.Closure addInvoke(android.renderscript.Script.InvokeID, java.lang.Object...);
+ method @Deprecated public android.renderscript.ScriptGroup.Closure addKernel(android.renderscript.Script.KernelID, android.renderscript.Type, java.lang.Object...);
+ method @Deprecated public android.renderscript.ScriptGroup create(String, android.renderscript.ScriptGroup.Future...);
}
- public static final class ScriptGroup.Closure extends android.renderscript.BaseObj {
- method public android.renderscript.ScriptGroup.Future getGlobal(android.renderscript.Script.FieldID);
- method public android.renderscript.ScriptGroup.Future getReturn();
+ @Deprecated public static final class ScriptGroup.Closure extends android.renderscript.BaseObj {
+ method @Deprecated public android.renderscript.ScriptGroup.Future getGlobal(android.renderscript.Script.FieldID);
+ method @Deprecated public android.renderscript.ScriptGroup.Future getReturn();
}
- public static final class ScriptGroup.Future {
+ @Deprecated public static final class ScriptGroup.Future {
}
- public static final class ScriptGroup.Input {
+ @Deprecated public static final class ScriptGroup.Input {
}
- public abstract class ScriptIntrinsic extends android.renderscript.Script {
+ @Deprecated public abstract class ScriptIntrinsic extends android.renderscript.Script {
}
- public final class ScriptIntrinsic3DLUT extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsic3DLUT create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.KernelID getKernelID();
- method public void setLUT(android.renderscript.Allocation);
+ @Deprecated public final class ScriptIntrinsic3DLUT extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsic3DLUT create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID();
+ method @Deprecated public void setLUT(android.renderscript.Allocation);
}
- public final class ScriptIntrinsicBLAS extends android.renderscript.ScriptIntrinsic {
- method public void BNNM(android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation, int, int);
- method public void CGBMV(int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
- method public void CGEMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
- method public void CGEMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
- method public void CGERC(android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void CGERU(android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void CHBMV(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
- method public void CHEMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
- method public void CHEMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
- method public void CHER(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void CHER2(int, android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void CHER2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
- method public void CHERK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
- method public void CHPMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
- method public void CHPR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void CHPR2(int, android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void CSYMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
- method public void CSYR2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
- method public void CSYRK(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
- method public void CTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void CTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void CTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void CTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void CTRMM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void CTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void CTRSM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void CTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void DGBMV(int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
- method public void DGEMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
- method public void DGEMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
- method public void DGER(double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void DSBMV(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
- method public void DSPMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
- method public void DSPR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void DSPR2(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void DSYMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
- method public void DSYMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
- method public void DSYR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void DSYR2(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void DSYR2K(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
- method public void DSYRK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
- method public void DTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void DTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void DTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void DTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void DTRMM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void DTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void DTRSM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void DTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void SGBMV(int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
- method public void SGEMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
- method public void SGEMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
- method public void SGER(float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void SSBMV(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
- method public void SSPMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
- method public void SSPR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void SSPR2(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void SSYMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
- method public void SSYMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
- method public void SSYR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void SSYR2(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void SSYR2K(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
- method public void SSYRK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
- method public void STBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void STBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void STPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void STPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void STRMM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void STRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void STRSM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void STRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void ZGBMV(int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
- method public void ZGEMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
- method public void ZGEMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
- method public void ZGERC(android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void ZGERU(android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void ZHBMV(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
- method public void ZHEMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
- method public void ZHEMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
- method public void ZHER(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void ZHER2(int, android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void ZHER2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
- method public void ZHERK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
- method public void ZHPMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
- method public void ZHPR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void ZHPR2(int, android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void ZSYMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
- method public void ZSYR2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
- method public void ZSYRK(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
- method public void ZTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void ZTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void ZTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void ZTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void ZTRMM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void ZTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void ZTRSM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void ZTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public static android.renderscript.ScriptIntrinsicBLAS create(android.renderscript.RenderScript);
- field public static final int CONJ_TRANSPOSE = 113; // 0x71
- field public static final int LEFT = 141; // 0x8d
- field public static final int LOWER = 122; // 0x7a
- field public static final int NON_UNIT = 131; // 0x83
- field public static final int NO_TRANSPOSE = 111; // 0x6f
- field public static final int RIGHT = 142; // 0x8e
- field public static final int TRANSPOSE = 112; // 0x70
- field public static final int UNIT = 132; // 0x84
- field public static final int UPPER = 121; // 0x79
+ @Deprecated public final class ScriptIntrinsicBLAS extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public void BNNM(android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation, int, int);
+ method @Deprecated public void CGBMV(int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+ method @Deprecated public void CGEMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+ method @Deprecated public void CGEMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+ method @Deprecated public void CGERC(android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void CGERU(android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void CHBMV(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+ method @Deprecated public void CHEMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+ method @Deprecated public void CHEMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+ method @Deprecated public void CHER(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void CHER2(int, android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void CHER2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+ method @Deprecated public void CHERK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
+ method @Deprecated public void CHPMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+ method @Deprecated public void CHPR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void CHPR2(int, android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void CSYMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+ method @Deprecated public void CSYR2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+ method @Deprecated public void CSYRK(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+ method @Deprecated public void CTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void CTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void CTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void CTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void CTRMM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void CTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void CTRSM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void CTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void DGBMV(int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+ method @Deprecated public void DGEMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+ method @Deprecated public void DGEMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+ method @Deprecated public void DGER(double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void DSBMV(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+ method @Deprecated public void DSPMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+ method @Deprecated public void DSPR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void DSPR2(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void DSYMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+ method @Deprecated public void DSYMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+ method @Deprecated public void DSYR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void DSYR2(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void DSYR2K(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+ method @Deprecated public void DSYRK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
+ method @Deprecated public void DTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void DTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void DTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void DTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void DTRMM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void DTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void DTRSM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void DTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void SGBMV(int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+ method @Deprecated public void SGEMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+ method @Deprecated public void SGEMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+ method @Deprecated public void SGER(float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void SSBMV(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+ method @Deprecated public void SSPMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+ method @Deprecated public void SSPR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void SSPR2(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void SSYMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+ method @Deprecated public void SSYMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+ method @Deprecated public void SSYR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void SSYR2(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void SSYR2K(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+ method @Deprecated public void SSYRK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
+ method @Deprecated public void STBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void STBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void STPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void STPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void STRMM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void STRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void STRSM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void STRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void ZGBMV(int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+ method @Deprecated public void ZGEMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+ method @Deprecated public void ZGEMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+ method @Deprecated public void ZGERC(android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void ZGERU(android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void ZHBMV(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+ method @Deprecated public void ZHEMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+ method @Deprecated public void ZHEMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+ method @Deprecated public void ZHER(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void ZHER2(int, android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void ZHER2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+ method @Deprecated public void ZHERK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
+ method @Deprecated public void ZHPMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+ method @Deprecated public void ZHPR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void ZHPR2(int, android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void ZSYMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+ method @Deprecated public void ZSYR2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+ method @Deprecated public void ZSYRK(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+ method @Deprecated public void ZTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void ZTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void ZTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void ZTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void ZTRMM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void ZTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void ZTRSM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void ZTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public static android.renderscript.ScriptIntrinsicBLAS create(android.renderscript.RenderScript);
+ field @Deprecated public static final int CONJ_TRANSPOSE = 113; // 0x71
+ field @Deprecated public static final int LEFT = 141; // 0x8d
+ field @Deprecated public static final int LOWER = 122; // 0x7a
+ field @Deprecated public static final int NON_UNIT = 131; // 0x83
+ field @Deprecated public static final int NO_TRANSPOSE = 111; // 0x6f
+ field @Deprecated public static final int RIGHT = 142; // 0x8e
+ field @Deprecated public static final int TRANSPOSE = 112; // 0x70
+ field @Deprecated public static final int UNIT = 132; // 0x84
+ field @Deprecated public static final int UPPER = 121; // 0x79
}
- public class ScriptIntrinsicBlend extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicBlend create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachClear(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachClear(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachDst(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachDst(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachDstAtop(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachDstAtop(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachDstIn(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachDstIn(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachDstOut(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachDstOut(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachDstOver(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachDstOver(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachMultiply(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachMultiply(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachSrc(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachSrc(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachSrcAtop(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachSrcAtop(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachSrcIn(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachSrcIn(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachSrcOut(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachSrcOut(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachSrcOver(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachSrcOver(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachSubtract(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachSubtract(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachXor(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachXor(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.KernelID getKernelIDAdd();
- method public android.renderscript.Script.KernelID getKernelIDClear();
- method public android.renderscript.Script.KernelID getKernelIDDst();
- method public android.renderscript.Script.KernelID getKernelIDDstAtop();
- method public android.renderscript.Script.KernelID getKernelIDDstIn();
- method public android.renderscript.Script.KernelID getKernelIDDstOut();
- method public android.renderscript.Script.KernelID getKernelIDDstOver();
- method public android.renderscript.Script.KernelID getKernelIDMultiply();
- method public android.renderscript.Script.KernelID getKernelIDSrc();
- method public android.renderscript.Script.KernelID getKernelIDSrcAtop();
- method public android.renderscript.Script.KernelID getKernelIDSrcIn();
- method public android.renderscript.Script.KernelID getKernelIDSrcOut();
- method public android.renderscript.Script.KernelID getKernelIDSrcOver();
- method public android.renderscript.Script.KernelID getKernelIDSubtract();
- method public android.renderscript.Script.KernelID getKernelIDXor();
+ @Deprecated public class ScriptIntrinsicBlend extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicBlend create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachClear(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachClear(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachDst(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachDst(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachDstAtop(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachDstAtop(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachDstIn(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachDstIn(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachDstOut(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachDstOut(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachDstOver(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachDstOver(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachMultiply(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachMultiply(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachSrc(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachSrc(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachSrcAtop(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachSrcAtop(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachSrcIn(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachSrcIn(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachSrcOut(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachSrcOut(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachSrcOver(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachSrcOver(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachSubtract(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachSubtract(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachXor(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachXor(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDAdd();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDClear();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDDst();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDDstAtop();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDDstIn();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDDstOut();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDDstOver();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDMultiply();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDSrc();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDSrcAtop();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDSrcIn();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDSrcOut();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDSrcOver();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDSubtract();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDXor();
}
- public final class ScriptIntrinsicBlur extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicBlur create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEach(android.renderscript.Allocation);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.FieldID getFieldID_Input();
- method public android.renderscript.Script.KernelID getKernelID();
- method public void setInput(android.renderscript.Allocation);
- method public void setRadius(float);
+ @Deprecated public final class ScriptIntrinsicBlur extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicBlur create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEach(android.renderscript.Allocation);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.FieldID getFieldID_Input();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID();
+ method @Deprecated public void setInput(android.renderscript.Allocation);
+ method @Deprecated public void setRadius(float);
}
- public final class ScriptIntrinsicColorMatrix extends android.renderscript.ScriptIntrinsic {
+ @Deprecated public final class ScriptIntrinsicColorMatrix extends android.renderscript.ScriptIntrinsic {
method @Deprecated public static android.renderscript.ScriptIntrinsicColorMatrix create(android.renderscript.RenderScript, android.renderscript.Element);
- method public static android.renderscript.ScriptIntrinsicColorMatrix create(android.renderscript.RenderScript);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.KernelID getKernelID();
- method public void setAdd(android.renderscript.Float4);
- method public void setAdd(float, float, float, float);
- method public void setColorMatrix(android.renderscript.Matrix4f);
- method public void setColorMatrix(android.renderscript.Matrix3f);
- method public void setGreyscale();
- method public void setRGBtoYUV();
- method public void setYUVtoRGB();
+ method @Deprecated public static android.renderscript.ScriptIntrinsicColorMatrix create(android.renderscript.RenderScript);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID();
+ method @Deprecated public void setAdd(android.renderscript.Float4);
+ method @Deprecated public void setAdd(float, float, float, float);
+ method @Deprecated public void setColorMatrix(android.renderscript.Matrix4f);
+ method @Deprecated public void setColorMatrix(android.renderscript.Matrix3f);
+ method @Deprecated public void setGreyscale();
+ method @Deprecated public void setRGBtoYUV();
+ method @Deprecated public void setYUVtoRGB();
}
- public final class ScriptIntrinsicConvolve3x3 extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicConvolve3x3 create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEach(android.renderscript.Allocation);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.FieldID getFieldID_Input();
- method public android.renderscript.Script.KernelID getKernelID();
- method public void setCoefficients(float[]);
- method public void setInput(android.renderscript.Allocation);
+ @Deprecated public final class ScriptIntrinsicConvolve3x3 extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicConvolve3x3 create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEach(android.renderscript.Allocation);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.FieldID getFieldID_Input();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID();
+ method @Deprecated public void setCoefficients(float[]);
+ method @Deprecated public void setInput(android.renderscript.Allocation);
}
- public final class ScriptIntrinsicConvolve5x5 extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicConvolve5x5 create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEach(android.renderscript.Allocation);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.FieldID getFieldID_Input();
- method public android.renderscript.Script.KernelID getKernelID();
- method public void setCoefficients(float[]);
- method public void setInput(android.renderscript.Allocation);
+ @Deprecated public final class ScriptIntrinsicConvolve5x5 extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicConvolve5x5 create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEach(android.renderscript.Allocation);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.FieldID getFieldID_Input();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID();
+ method @Deprecated public void setCoefficients(float[]);
+ method @Deprecated public void setInput(android.renderscript.Allocation);
}
- public final class ScriptIntrinsicHistogram extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicHistogram create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEach(android.renderscript.Allocation);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEach_Dot(android.renderscript.Allocation);
- method public void forEach_Dot(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.FieldID getFieldID_Input();
- method public android.renderscript.Script.KernelID getKernelID_Separate();
- method public void setDotCoefficients(float, float, float, float);
- method public void setOutput(android.renderscript.Allocation);
+ @Deprecated public final class ScriptIntrinsicHistogram extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicHistogram create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEach(android.renderscript.Allocation);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEach_Dot(android.renderscript.Allocation);
+ method @Deprecated public void forEach_Dot(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.FieldID getFieldID_Input();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID_Separate();
+ method @Deprecated public void setDotCoefficients(float, float, float, float);
+ method @Deprecated public void setOutput(android.renderscript.Allocation);
}
- public final class ScriptIntrinsicLUT extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicLUT create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.KernelID getKernelID();
- method public void setAlpha(int, int);
- method public void setBlue(int, int);
- method public void setGreen(int, int);
- method public void setRed(int, int);
+ @Deprecated public final class ScriptIntrinsicLUT extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicLUT create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID();
+ method @Deprecated public void setAlpha(int, int);
+ method @Deprecated public void setBlue(int, int);
+ method @Deprecated public void setGreen(int, int);
+ method @Deprecated public void setRed(int, int);
}
- public final class ScriptIntrinsicResize extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicResize create(android.renderscript.RenderScript);
- method public void forEach_bicubic(android.renderscript.Allocation);
- method public void forEach_bicubic(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.FieldID getFieldID_Input();
- method public android.renderscript.Script.KernelID getKernelID_bicubic();
- method public void setInput(android.renderscript.Allocation);
+ @Deprecated public final class ScriptIntrinsicResize extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicResize create(android.renderscript.RenderScript);
+ method @Deprecated public void forEach_bicubic(android.renderscript.Allocation);
+ method @Deprecated public void forEach_bicubic(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.FieldID getFieldID_Input();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID_bicubic();
+ method @Deprecated public void setInput(android.renderscript.Allocation);
}
- public final class ScriptIntrinsicYuvToRGB extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicYuvToRGB create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEach(android.renderscript.Allocation);
- method public android.renderscript.Script.FieldID getFieldID_Input();
- method public android.renderscript.Script.KernelID getKernelID();
- method public void setInput(android.renderscript.Allocation);
+ @Deprecated public final class ScriptIntrinsicYuvToRGB extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicYuvToRGB create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEach(android.renderscript.Allocation);
+ method @Deprecated public android.renderscript.Script.FieldID getFieldID_Input();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID();
+ method @Deprecated public void setInput(android.renderscript.Allocation);
}
- public class Short2 {
- ctor public Short2();
- ctor public Short2(short, short);
- field public short x;
- field public short y;
+ @Deprecated public class Short2 {
+ ctor @Deprecated public Short2();
+ ctor @Deprecated public Short2(short, short);
+ field @Deprecated public short x;
+ field @Deprecated public short y;
}
- public class Short3 {
- ctor public Short3();
- ctor public Short3(short, short, short);
- field public short x;
- field public short y;
- field public short z;
+ @Deprecated public class Short3 {
+ ctor @Deprecated public Short3();
+ ctor @Deprecated public Short3(short, short, short);
+ field @Deprecated public short x;
+ field @Deprecated public short y;
+ field @Deprecated public short z;
}
- public class Short4 {
- ctor public Short4();
- ctor public Short4(short, short, short, short);
- field public short w;
- field public short x;
- field public short y;
- field public short z;
+ @Deprecated public class Short4 {
+ ctor @Deprecated public Short4();
+ ctor @Deprecated public Short4(short, short, short, short);
+ field @Deprecated public short w;
+ field @Deprecated public short x;
+ field @Deprecated public short y;
+ field @Deprecated public short z;
}
- public class Type extends android.renderscript.BaseObj {
- method public static android.renderscript.Type createX(android.renderscript.RenderScript, android.renderscript.Element, int);
- method public static android.renderscript.Type createXY(android.renderscript.RenderScript, android.renderscript.Element, int, int);
- method public static android.renderscript.Type createXYZ(android.renderscript.RenderScript, android.renderscript.Element, int, int, int);
- method public int getCount();
- method public android.renderscript.Element getElement();
- method public int getX();
- method public int getY();
- method public int getYuv();
- method public int getZ();
- method public boolean hasFaces();
- method public boolean hasMipmaps();
+ @Deprecated public class Type extends android.renderscript.BaseObj {
+ method @Deprecated public static android.renderscript.Type createX(android.renderscript.RenderScript, android.renderscript.Element, int);
+ method @Deprecated public static android.renderscript.Type createXY(android.renderscript.RenderScript, android.renderscript.Element, int, int);
+ method @Deprecated public static android.renderscript.Type createXYZ(android.renderscript.RenderScript, android.renderscript.Element, int, int, int);
+ method @Deprecated public int getCount();
+ method @Deprecated public android.renderscript.Element getElement();
+ method @Deprecated public int getX();
+ method @Deprecated public int getY();
+ method @Deprecated public int getYuv();
+ method @Deprecated public int getZ();
+ method @Deprecated public boolean hasFaces();
+ method @Deprecated public boolean hasMipmaps();
}
- public static class Type.Builder {
- ctor public Type.Builder(android.renderscript.RenderScript, android.renderscript.Element);
- method public android.renderscript.Type create();
- method public android.renderscript.Type.Builder setFaces(boolean);
- method public android.renderscript.Type.Builder setMipmaps(boolean);
- method public android.renderscript.Type.Builder setX(int);
- method public android.renderscript.Type.Builder setY(int);
- method public android.renderscript.Type.Builder setYuvFormat(int);
- method public android.renderscript.Type.Builder setZ(int);
+ @Deprecated public static class Type.Builder {
+ ctor @Deprecated public Type.Builder(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public android.renderscript.Type create();
+ method @Deprecated public android.renderscript.Type.Builder setFaces(boolean);
+ method @Deprecated public android.renderscript.Type.Builder setMipmaps(boolean);
+ method @Deprecated public android.renderscript.Type.Builder setX(int);
+ method @Deprecated public android.renderscript.Type.Builder setY(int);
+ method @Deprecated public android.renderscript.Type.Builder setYuvFormat(int);
+ method @Deprecated public android.renderscript.Type.Builder setZ(int);
}
- public enum Type.CubemapFace {
- enum_constant public static final android.renderscript.Type.CubemapFace NEGATIVE_X;
- enum_constant public static final android.renderscript.Type.CubemapFace NEGATIVE_Y;
- enum_constant public static final android.renderscript.Type.CubemapFace NEGATIVE_Z;
- enum_constant public static final android.renderscript.Type.CubemapFace POSITIVE_X;
- enum_constant public static final android.renderscript.Type.CubemapFace POSITIVE_Y;
- enum_constant public static final android.renderscript.Type.CubemapFace POSITIVE_Z;
+ @Deprecated public enum Type.CubemapFace {
+ enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace NEGATIVE_X;
+ enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace NEGATIVE_Y;
+ enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace NEGATIVE_Z;
+ enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace POSITIVE_X;
+ enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace POSITIVE_Y;
+ enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace POSITIVE_Z;
enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace POSITVE_X;
enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace POSITVE_Y;
enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace POSITVE_Z;
@@ -39604,22 +39601,22 @@
method public final void conferenceRemoteConnections(android.telecom.RemoteConnection, android.telecom.RemoteConnection);
method public final void connectionServiceFocusReleased();
method @Nullable public final android.telecom.RemoteConference createRemoteIncomingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
- method public final android.telecom.RemoteConnection createRemoteIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+ method @Nullable public final android.telecom.RemoteConnection createRemoteIncomingConnection(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.ConnectionRequest);
method @Nullable public final android.telecom.RemoteConference createRemoteOutgoingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
- method public final android.telecom.RemoteConnection createRemoteOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+ method @Nullable public final android.telecom.RemoteConnection createRemoteOutgoingConnection(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.ConnectionRequest);
method public final java.util.Collection<android.telecom.Conference> getAllConferences();
method public final java.util.Collection<android.telecom.Connection> getAllConnections();
method public final android.os.IBinder onBind(android.content.Intent);
method public void onConference(android.telecom.Connection, android.telecom.Connection);
method public void onConnectionServiceFocusGained();
method public void onConnectionServiceFocusLost();
- method @Nullable public android.telecom.Conference onCreateIncomingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
+ method @Nullable public android.telecom.Conference onCreateIncomingConference(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.ConnectionRequest);
method public void onCreateIncomingConferenceFailed(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
method public android.telecom.Connection onCreateIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
method public void onCreateIncomingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
method public android.telecom.Connection onCreateIncomingHandoverConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
- method @Nullable public android.telecom.Conference onCreateOutgoingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
- method public void onCreateOutgoingConferenceFailed(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
+ method @Nullable public android.telecom.Conference onCreateOutgoingConference(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.ConnectionRequest);
+ method public void onCreateOutgoingConferenceFailed(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.ConnectionRequest);
method public android.telecom.Connection onCreateOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
method public void onCreateOutgoingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
method public android.telecom.Connection onCreateOutgoingHandoverConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
@@ -40536,6 +40533,9 @@
field public static final String KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool";
field public static final String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL = "sms_requires_destination_number_conversion_bool";
field public static final String KEY_SUPPORTS_CALL_COMPOSER_BOOL = "supports_call_composer_bool";
+ field public static final String KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_DTMF_BOOL = "supports_device_to_device_communication_using_dtmf_bool";
+ field public static final String KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL = "supports_device_to_device_communication_using_rtp_bool";
+ field public static final String KEY_SUPPORTS_SDP_NEGOTIATION_OF_D2D_RTP_HEADER_EXTENSIONS_BOOL = "supports_sdp_negotiation_of_d2d_rtp_header_extensions_bool";
field public static final String KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL = "support_3gpp_call_forwarding_while_roaming_bool";
field public static final String KEY_SUPPORT_ADD_CONFERENCE_PARTICIPANTS_BOOL = "support_add_conference_participants_bool";
field public static final String KEY_SUPPORT_ADHOC_CONFERENCE_CALLS_BOOL = "support_adhoc_conference_calls_bool";
@@ -42142,7 +42142,7 @@
}
public static interface TelephonyCallback.CallStateListener {
- method @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) public void onCallStateChanged(int, @Nullable String);
+ method public void onCallStateChanged(int);
}
public static interface TelephonyCallback.CarrierNetworkListener {
@@ -42912,7 +42912,7 @@
method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public int getVoWiFiModeSetting();
method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public boolean isAdvancedCallingSettingEnabled();
- method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public boolean isCrossSimCallingEnabledByUser() throws android.telephony.ims.ImsException;
+ method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public boolean isCrossSimCallingEnabled() throws android.telephony.ims.ImsException;
method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public boolean isTtyOverVolteEnabled();
method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public boolean isVoWiFiRoamingSettingEnabled();
method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public boolean isVoWiFiSettingEnabled();
@@ -46569,9 +46569,9 @@
public class GestureDetector {
ctor @Deprecated public GestureDetector(android.view.GestureDetector.OnGestureListener, android.os.Handler);
ctor @Deprecated public GestureDetector(android.view.GestureDetector.OnGestureListener);
- ctor public GestureDetector(android.content.Context, android.view.GestureDetector.OnGestureListener);
- ctor public GestureDetector(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler);
- ctor public GestureDetector(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler, boolean);
+ ctor public GestureDetector(@UiContext android.content.Context, android.view.GestureDetector.OnGestureListener);
+ ctor public GestureDetector(@UiContext android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler);
+ ctor public GestureDetector(@UiContext android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler, boolean);
method public boolean isLongpressEnabled();
method public boolean onGenericMotionEvent(android.view.MotionEvent);
method public boolean onTouchEvent(android.view.MotionEvent);
@@ -47260,7 +47260,7 @@
method public abstract android.view.LayoutInflater cloneInContext(android.content.Context);
method public final android.view.View createView(String, String, android.util.AttributeSet) throws java.lang.ClassNotFoundException, android.view.InflateException;
method @Nullable public final android.view.View createView(@NonNull android.content.Context, @NonNull String, @Nullable String, @Nullable android.util.AttributeSet) throws java.lang.ClassNotFoundException, android.view.InflateException;
- method public static android.view.LayoutInflater from(android.content.Context);
+ method public static android.view.LayoutInflater from(@UiContext android.content.Context);
method public android.content.Context getContext();
method public final android.view.LayoutInflater.Factory getFactory();
method public final android.view.LayoutInflater.Factory2 getFactory2();
@@ -48154,7 +48154,7 @@
method public final boolean getClipToOutline();
method @Nullable public final android.view.contentcapture.ContentCaptureSession getContentCaptureSession();
method public CharSequence getContentDescription();
- method public final android.content.Context getContext();
+ method @UiContext public final android.content.Context getContext();
method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo();
method public final boolean getDefaultFocusHighlightEnabled();
method public static int getDefaultSize(int, int);
@@ -48953,7 +48953,7 @@
public class ViewConfiguration {
ctor @Deprecated public ViewConfiguration();
- method public static android.view.ViewConfiguration get(android.content.Context);
+ method public static android.view.ViewConfiguration get(@UiContext android.content.Context);
method @Deprecated @FloatRange(from=1.0) public static float getAmbiguousGestureMultiplier();
method public static long getDefaultActionModeHideDuration();
method public static int getDoubleTapTimeout();
@@ -49511,7 +49511,7 @@
}
public abstract class Window {
- ctor public Window(android.content.Context);
+ ctor public Window(@UiContext android.content.Context);
method public abstract void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
method public void addFlags(int);
method public final void addOnFrameMetricsAvailableListener(@NonNull android.view.Window.OnFrameMetricsAvailableListener, android.os.Handler);
@@ -49526,7 +49526,7 @@
method public int getColorMode();
method public final android.view.Window getContainer();
method public android.transition.Scene getContentScene();
- method public final android.content.Context getContext();
+ method @UiContext public final android.content.Context getContext();
method @Nullable public abstract android.view.View getCurrentFocus();
method @NonNull public abstract android.view.View getDecorView();
method public static int getDefaultFeatures(android.content.Context);
@@ -51476,6 +51476,7 @@
method public int describeContents();
method public void dump(android.util.Printer, String);
method public android.content.ComponentName getComponent();
+ method public int getConfigChanges();
method public String getId();
method public int getIsDefaultResourceId();
method public String getPackageName();
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index c7d4058..057e16c 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -213,6 +213,13 @@
field @NonNull public final java.util.List<java.lang.String> underlyingIfaces;
}
+ public class VpnManager {
+ field @Deprecated public static final int TYPE_VPN_LEGACY = 3; // 0x3
+ field public static final int TYPE_VPN_NONE = -1; // 0xffffffff
+ field public static final int TYPE_VPN_PLATFORM = 2; // 0x2
+ field public static final int TYPE_VPN_SERVICE = 1; // 0x1
+ }
+
}
package android.os {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 5ca4d35..eddf5a4 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -147,6 +147,7 @@
field public static final String MANAGE_SENSOR_PRIVACY = "android.permission.MANAGE_SENSOR_PRIVACY";
field public static final String MANAGE_SMARTSPACE = "android.permission.MANAGE_SMARTSPACE";
field public static final String MANAGE_SOUND_TRIGGER = "android.permission.MANAGE_SOUND_TRIGGER";
+ field public static final String MANAGE_SPEECH_RECOGNITION = "android.permission.MANAGE_SPEECH_RECOGNITION";
field public static final String MANAGE_SUBSCRIPTION_PLANS = "android.permission.MANAGE_SUBSCRIPTION_PLANS";
field public static final String MANAGE_TEST_NETWORKS = "android.permission.MANAGE_TEST_NETWORKS";
field public static final String MANAGE_TIME_AND_ZONE_DETECTION = "android.permission.MANAGE_TIME_AND_ZONE_DETECTION";
@@ -359,6 +360,7 @@
field public static final int config_systemGallery = 17039399; // 0x1040027
field public static final int config_systemShell = 17039402; // 0x104002a
field public static final int config_systemSpeechRecognizer = 17039406; // 0x104002e
+ field public static final int config_systemTelevisionNotificationHandler = 17039409; // 0x1040031
field public static final int config_systemWellbeing = 17039408; // 0x1040030
field public static final int config_systemWifiCoexManager = 17039407; // 0x104002f
}
@@ -380,7 +382,7 @@
package android.app {
- public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+ @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
method public void convertFromTranslucent();
method public boolean convertToTranslucent(android.app.Activity.TranslucentConversionListener, android.app.ActivityOptions);
method @Deprecated public boolean isBackgroundVisibleBehind();
@@ -2172,6 +2174,7 @@
field public static final String OEM_LOCK_SERVICE = "oem_lock";
field public static final String PERMISSION_SERVICE = "permission";
field public static final String PERSISTENT_DATA_BLOCK_SERVICE = "persistent_data_block";
+ field public static final String POWER_EXEMPTION_SERVICE = "power_exemption";
field public static final String REBOOT_READINESS_SERVICE = "reboot_readiness";
field public static final String ROLLBACK_SERVICE = "rollback";
field public static final String SEARCH_UI_SERVICE = "search_ui";
@@ -2881,11 +2884,16 @@
}
public static final class FontFamilyUpdateRequest.FontFamily {
- ctor public FontFamilyUpdateRequest.FontFamily(@NonNull String, @NonNull java.util.List<android.graphics.fonts.FontFamilyUpdateRequest.Font>);
method @NonNull public java.util.List<android.graphics.fonts.FontFamilyUpdateRequest.Font> getFonts();
method @NonNull public String getName();
}
+ public static final class FontFamilyUpdateRequest.FontFamily.Builder {
+ ctor public FontFamilyUpdateRequest.FontFamily.Builder(@NonNull String, @NonNull java.util.List<android.graphics.fonts.FontFamilyUpdateRequest.Font>);
+ method @NonNull public android.graphics.fonts.FontFamilyUpdateRequest.FontFamily.Builder addFont(@NonNull android.graphics.fonts.FontFamilyUpdateRequest.Font);
+ method @NonNull public android.graphics.fonts.FontFamilyUpdateRequest.FontFamily build();
+ }
+
public final class FontFileUpdateRequest {
ctor public FontFileUpdateRequest(@NonNull android.os.ParcelFileDescriptor, @NonNull byte[]);
method @NonNull public android.os.ParcelFileDescriptor getParcelFileDescriptor();
@@ -3102,6 +3110,7 @@
method @NonNull public java.util.List<android.hardware.hdmi.HdmiDeviceInfo> getConnectedDevices();
method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getHdmiCecEnabled();
method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getHdmiCecVersion();
+ method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getHdmiCecVolumeControlEnabled();
method public int getPhysicalAddress();
method @Nullable public android.hardware.hdmi.HdmiPlaybackClient getPlaybackClient();
method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public String getPowerControlMode();
@@ -3109,6 +3118,8 @@
method @Nullable public android.hardware.hdmi.HdmiSwitchClient getSwitchClient();
method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getSystemAudioModeMuting();
method @Nullable public android.hardware.hdmi.HdmiTvClient getTvClient();
+ method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getTvSendStandbyOnSleep();
+ method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getTvWakeOnOneTouchPlay();
method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public java.util.List<java.lang.String> getUserCecSettings();
method public boolean isDeviceConnected(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
method public void powerOffDevice(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
@@ -3117,10 +3128,13 @@
method public void setActiveSource(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setHdmiCecEnabled(@NonNull int);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setHdmiCecVersion(@NonNull int);
+ method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setHdmiCecVolumeControlEnabled(int);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setPowerControlMode(@NonNull String);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setPowerStateChangeOnActiveSourceLost(@NonNull String);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setStandbyMode(boolean);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setSystemAudioModeMuting(@NonNull int);
+ method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setTvSendStandbyOnSleep(@NonNull int);
+ method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setTvWakeOnOneTouchPlay(@NonNull int);
field public static final String ACTION_OSD_MESSAGE = "android.hardware.hdmi.action.OSD_MESSAGE";
field public static final int AVR_VOLUME_MUTED = 101; // 0x65
field public static final String CEC_SETTING_NAME_HDMI_CEC_ENABLED = "hdmi_cec_enabled";
@@ -3128,6 +3142,9 @@
field public static final String CEC_SETTING_NAME_POWER_CONTROL_MODE = "send_standby_on_sleep";
field public static final String CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST = "power_state_change_on_active_source_lost";
field public static final String CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING = "system_audio_mode_muting";
+ field public static final String CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP = "tv_send_standby_on_sleep";
+ field public static final String CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY = "tv_wake_on_one_touch_play";
+ field public static final String CEC_SETTING_NAME_VOLUME_CONTROL_MODE = "volume_control_enabled";
field public static final int CLEAR_TIMER_STATUS_CEC_DISABLE = 162; // 0xa2
field public static final int CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION = 160; // 0xa0
field public static final int CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE = 161; // 0xa1
@@ -3223,6 +3240,12 @@
field public static final int TIMER_STATUS_PROGRAMMED_INFO_MIGHT_NOT_ENOUGH_SPACE = 11; // 0xb
field public static final int TIMER_STATUS_PROGRAMMED_INFO_NOT_ENOUGH_SPACE = 9; // 0x9
field public static final int TIMER_STATUS_PROGRAMMED_INFO_NO_MEDIA_INFO = 10; // 0xa
+ field public static final int TV_SEND_STANDBY_ON_SLEEP_DISABLED = 0; // 0x0
+ field public static final int TV_SEND_STANDBY_ON_SLEEP_ENABLED = 1; // 0x1
+ field public static final int TV_WAKE_ON_ONE_TOUCH_PLAY_DISABLED = 0; // 0x0
+ field public static final int TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED = 1; // 0x1
+ field public static final int VOLUME_CONTROL_DISABLED = 0; // 0x0
+ field public static final int VOLUME_CONTROL_ENABLED = 1; // 0x1
}
public static interface HdmiControlManager.CecSettingChangeListener {
@@ -7462,22 +7485,22 @@
package android.net.sip {
- public class SipAudioCall {
- method @Nullable public android.net.rtp.AudioGroup getAudioGroup();
- method public void setAudioGroup(@NonNull android.net.rtp.AudioGroup);
+ @Deprecated public class SipAudioCall {
+ method @Deprecated @Nullable public android.net.rtp.AudioGroup getAudioGroup();
+ method @Deprecated public void setAudioGroup(@NonNull android.net.rtp.AudioGroup);
}
- public class SipManager {
- method @NonNull public java.util.List<android.net.sip.SipProfile> getProfiles() throws android.net.sip.SipException;
- field public static final String ACTION_SIP_CALL_OPTION_CHANGED = "android.net.sip.action.SIP_CALL_OPTION_CHANGED";
- field public static final String ACTION_SIP_INCOMING_CALL = "android.net.sip.action.SIP_INCOMING_CALL";
- field public static final String ACTION_SIP_REMOVE_PROFILE = "android.net.sip.action.SIP_REMOVE_PROFILE";
- field public static final String ACTION_SIP_SERVICE_UP = "android.net.sip.action.SIP_SERVICE_UP";
- field public static final String ACTION_START_SIP = "android.net.sip.action.START_SIP";
+ @Deprecated public class SipManager {
+ method @Deprecated @NonNull public java.util.List<android.net.sip.SipProfile> getProfiles() throws android.net.sip.SipException;
+ field @Deprecated public static final String ACTION_SIP_CALL_OPTION_CHANGED = "android.net.sip.action.SIP_CALL_OPTION_CHANGED";
+ field @Deprecated public static final String ACTION_SIP_INCOMING_CALL = "android.net.sip.action.SIP_INCOMING_CALL";
+ field @Deprecated public static final String ACTION_SIP_REMOVE_PROFILE = "android.net.sip.action.SIP_REMOVE_PROFILE";
+ field @Deprecated public static final String ACTION_SIP_SERVICE_UP = "android.net.sip.action.SIP_SERVICE_UP";
+ field @Deprecated public static final String ACTION_START_SIP = "android.net.sip.action.START_SIP";
}
- public class SipProfile implements java.lang.Cloneable android.os.Parcelable java.io.Serializable {
- method public int getCallingUid();
+ @Deprecated public class SipProfile implements java.lang.Cloneable android.os.Parcelable java.io.Serializable {
+ method @Deprecated public int getCallingUid();
}
}
@@ -8152,6 +8175,25 @@
field @NonNull public static final android.os.Parcelable.Creator<android.os.ParcelableHolder> CREATOR;
}
+ public class PowerExemptionManager {
+ method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void addToPermanentAllowList(@NonNull String);
+ method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void addToPermanentAllowList(@NonNull java.util.List<java.lang.String>);
+ method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public void addToTemporaryAllowList(@NonNull String, long, int, @Nullable String);
+ method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public long addToTemporaryAllowListForEvent(@NonNull String, int, int, @Nullable String);
+ method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void removeFromAllowList(@NonNull String);
+ field public static final int EVENT_MMS = 2; // 0x2
+ field public static final int EVENT_SMS = 1; // 0x1
+ field public static final int EVENT_UNSPECIFIED = 0; // 0x0
+ 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_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
+ field public static final int REASON_UNKNOWN = 0; // 0x0
+ field public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED = 0; // 0x0
+ field public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED = 1; // 0x1
+ }
+
public final class PowerManager {
method @RequiresPermission(allOf={android.Manifest.permission.READ_DREAM_STATE, android.Manifest.permission.WRITE_DREAM_STATE}) public void dream(long);
method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public boolean forceSuspend();
@@ -9931,11 +9973,13 @@
package android.service.rotationresolver {
public final class RotationResolutionRequest implements android.os.Parcelable {
+ ctor public RotationResolutionRequest(@NonNull String, int, int, boolean, long);
method public int describeContents();
method public int getCurrentRotation();
method @NonNull public String getPackageName();
method public int getProposedRotation();
method public long getTimeoutMillis();
+ method public boolean shouldUseCamera();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.service.rotationresolver.RotationResolutionRequest> CREATOR;
}
@@ -10207,6 +10251,7 @@
ctor public HotwordDetectionService();
method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
method public void onDetectFromDspSource(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, long, @NonNull android.service.voice.HotwordDetectionService.DspHotwordDetectionCallback);
+ method public void onUpdateState(@Nullable android.os.Bundle, @Nullable android.os.SharedMemory);
field public static final String SERVICE_INTERFACE = "android.service.voice.HotwordDetectionService";
}
@@ -10217,10 +10262,8 @@
public class VoiceInteractionService extends android.app.Service {
method @NonNull public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(String, java.util.Locale, android.service.voice.AlwaysOnHotwordDetector.Callback);
+ method @NonNull public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(String, java.util.Locale, @Nullable android.os.Bundle, @Nullable android.os.SharedMemory, android.service.voice.AlwaysOnHotwordDetector.Callback);
method @NonNull @RequiresPermission("android.permission.MANAGE_VOICE_KEYPHRASES") public final android.media.voice.KeyphraseModelManager createKeyphraseModelManager();
- method public final int setHotwordDetectionConfig(@Nullable android.os.Bundle);
- field public static final int HOTWORD_CONFIG_FAILURE = 1; // 0x1
- field public static final int HOTWORD_CONFIG_SUCCESS = 0; // 0x0
}
}
@@ -11403,7 +11446,7 @@
field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_CALL_ATTRIBUTES_CHANGED = 27; // 0x1b
field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_CALL_DISCONNECT_CAUSE_CHANGED = 26; // 0x1a
field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_CALL_FORWARDING_INDICATOR_CHANGED = 4; // 0x4
- field @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) public static final int EVENT_CALL_STATE_CHANGED = 6; // 0x6
+ field public static final int EVENT_CALL_STATE_CHANGED = 6; // 0x6
field public static final int EVENT_CARRIER_NETWORK_CHANGED = 17; // 0x11
field @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static final int EVENT_CELL_INFO_CHANGED = 11; // 0xb
field @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static final int EVENT_CELL_LOCATION_CHANGED = 5; // 0x5
@@ -11415,6 +11458,7 @@
field public static final int EVENT_DISPLAY_INFO_CHANGED = 21; // 0x15
field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_EMERGENCY_NUMBER_LIST_CHANGED = 25; // 0x19
field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED = 28; // 0x1c
+ field @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) public static final int EVENT_LEGACY_CALL_STATE_CHANGED = 36; // 0x24
field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_MESSAGE_WAITING_INDICATOR_CHANGED = 3; // 0x3
field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_OEM_HOOK_RAW = 15; // 0xf
field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int EVENT_OUTGOING_EMERGENCY_CALL = 29; // 0x1d
@@ -11618,7 +11662,7 @@
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult setIccLockEnabled(boolean, @NonNull String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMobileDataPolicyEnabled(int, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
- method public int setNrDualConnectivityState(int);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setNrDualConnectivityState(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean);
@@ -12013,7 +12057,6 @@
}
public final class EpsBearerQosSessionAttributes implements android.os.Parcelable android.net.QosSessionAttributes {
- method @NonNull public static android.telephony.data.EpsBearerQosSessionAttributes create(@NonNull android.os.Parcel);
method public int describeContents();
method public long getGuaranteedDownlinkBitRate();
method public long getGuaranteedUplinkBitRate();
@@ -13796,6 +13839,7 @@
package android.uwb {
public final class AngleMeasurement implements android.os.Parcelable {
+ ctor public AngleMeasurement(double, double, double);
method public int describeContents();
method @FloatRange(from=0.0, to=1.0) public double getConfidenceLevel();
method @FloatRange(from=0.0, to=3.141592653589793) public double getErrorRadians();
@@ -13804,14 +13848,6 @@
field @NonNull public static final android.os.Parcelable.Creator<android.uwb.AngleMeasurement> CREATOR;
}
- public static final class AngleMeasurement.Builder {
- ctor public AngleMeasurement.Builder();
- method @NonNull public android.uwb.AngleMeasurement build();
- method @NonNull public android.uwb.AngleMeasurement.Builder setConfidenceLevel(double);
- method @NonNull public android.uwb.AngleMeasurement.Builder setErrorRadians(double);
- method @NonNull public android.uwb.AngleMeasurement.Builder setRadians(double);
- }
-
public final class AngleOfArrivalMeasurement implements android.os.Parcelable {
method public int describeContents();
method @Nullable public android.uwb.AngleMeasurement getAltitude();
@@ -13821,10 +13857,9 @@
}
public static final class AngleOfArrivalMeasurement.Builder {
- ctor public AngleOfArrivalMeasurement.Builder();
+ ctor public AngleOfArrivalMeasurement.Builder(@NonNull android.uwb.AngleMeasurement);
method @NonNull public android.uwb.AngleOfArrivalMeasurement build();
method @NonNull public android.uwb.AngleOfArrivalMeasurement.Builder setAltitude(@NonNull android.uwb.AngleMeasurement);
- method @NonNull public android.uwb.AngleOfArrivalMeasurement.Builder setAzimuth(@NonNull android.uwb.AngleMeasurement);
}
public final class DistanceMeasurement implements android.os.Parcelable {
@@ -13924,7 +13959,7 @@
public final class UwbManager {
method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public long elapsedRealtimeResolutionNanos();
method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public android.os.PersistableBundle getSpecificationInfo();
- method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public AutoCloseable openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback);
+ method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public android.os.CancellationSignal openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback);
method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void registerAdapterStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.uwb.UwbManager.AdapterStateCallback);
method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void unregisterAdapterStateCallback(@NonNull android.uwb.UwbManager.AdapterStateCallback);
}
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 7b5b198..8fa4659 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -87,7 +87,7 @@
package android.app {
- public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+ @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
method public void onMovedToDisplay(int, android.content.res.Configuration);
}
@@ -721,6 +721,8 @@
public class ActivityInfo extends android.content.pm.ComponentInfo implements android.os.Parcelable {
method public static boolean isTranslucentOrFloating(android.content.res.TypedArray);
+ field public static final long FORCE_NON_RESIZE_APP = 181136395L; // 0xacbec0bL
+ field public static final long FORCE_RESIZE_APP = 174042936L; // 0xa5faf38L
field public static final int RESIZE_MODE_RESIZEABLE = 2; // 0x2
}
@@ -938,6 +940,12 @@
method public void splitVertically(@NonNull android.graphics.Rect...);
}
+ 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 @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;
+ }
+
}
package android.graphics.drawable {
@@ -1176,7 +1184,7 @@
package android.inputmethodservice {
- public class InputMethodService extends android.inputmethodservice.AbstractInputMethodService {
+ @UiContext public class InputMethodService extends android.inputmethodservice.AbstractInputMethodService {
field public static final long FINISH_INPUT_NO_FALLBACK_CONNECTION = 156215187L; // 0x94fa793L
}
@@ -2123,6 +2131,14 @@
}
+package android.speech {
+
+ public class SpeechRecognizer {
+ method public void setTemporaryOnDeviceRecognizer(@Nullable android.content.ComponentName);
+ }
+
+}
+
package android.telecom {
public static class Call.Details {
@@ -2148,6 +2164,10 @@
method @NonNull public android.telecom.ConnectionRequest.Builder setVideoState(int);
}
+ public abstract class ConnectionService extends android.app.Service {
+ method public void onBindClient(@Nullable android.content.Intent);
+ }
+
}
package android.telephony {
@@ -2325,7 +2345,6 @@
field public static final String FFLAG_PREFIX = "sys.fflag.";
field public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
field public static final String PERSIST_PREFIX = "persist.sys.fflag.override.";
- field public static final String SCREENRECORD_LONG_PRESS = "settings_screenrecord_long_press";
field public static final String SETTINGS_WIFITRACKER2 = "settings_wifitracker2";
}
@@ -2700,6 +2719,10 @@
method @NonNull public static android.view.inputmethod.InlineSuggestionsResponse newInlineSuggestionsResponse(@NonNull java.util.List<android.view.inputmethod.InlineSuggestion>);
}
+ public final class InputMethodInfo implements android.os.Parcelable {
+ ctor public InputMethodInfo(@NonNull String, @NonNull String, @NonNull CharSequence, @NonNull String, int);
+ }
+
public final class InputMethodManager {
method public int getDisplayId();
method public boolean hasActiveInputConnection(@Nullable android.view.View);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 0b59586..8977ba7 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -5775,11 +5775,14 @@
// ResourcesImpl constructions.
final int diff = activity.mCurrentConfig.diffPublicOnly(newConfig);
- if (diff == 0 && !shouldUpdateWindowMetricsBounds(activity.mCurrentConfig, newConfig)
- && !movedToDifferentDisplay && mResourcesManager.isSameResourcesOverrideConfig(
- activityToken, amOverrideConfig)) {
- // Nothing significant, don't proceed with updating and reporting.
- return null;
+ if (diff == 0) {
+ if (!shouldUpdateWindowMetricsBounds(activity.mCurrentConfig, newConfig)
+ && !movedToDifferentDisplay
+ && mResourcesManager.isSameResourcesOverrideConfig(
+ activityToken, amOverrideConfig)) {
+ // Nothing significant, don't proceed with updating and reporting.
+ return null;
+ }
} else if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
// If this activity doesn't handle any of the config changes, then don't bother
// calling onConfigurationChanged. Otherwise, report to the activity for the
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index a6260d6..dba62b9 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -3228,6 +3228,12 @@
@Override
public void registerDexModule(@NonNull String dexModule,
@Nullable DexModuleRegisterCallback callback) {
+ // Create the callback delegate to be passed to package manager service.
+ DexModuleRegisterCallbackDelegate callbackDelegate = null;
+ if (callback != null) {
+ callbackDelegate = new DexModuleRegisterCallbackDelegate(callback);
+ }
+
// Check if this is a shared module by looking if the others can read it.
boolean isSharedModule = false;
try {
@@ -3236,18 +3242,13 @@
isSharedModule = true;
}
} catch (ErrnoException e) {
- callback.onDexModuleRegistered(dexModule, false,
- "Could not get stat the module file: " + e.getMessage());
+ if (callbackDelegate != null) {
+ callback.onDexModuleRegistered(dexModule, false,
+ "Could not get stat the module file: " + e.getMessage());
+ }
return;
}
- // Module path is ok.
- // Create the callback delegate to be passed to package manager service.
- DexModuleRegisterCallbackDelegate callbackDelegate = null;
- if (callback != null) {
- callbackDelegate = new DexModuleRegisterCallbackDelegate(callback);
- }
-
// Invoke the package manager service.
try {
mPM.registerDexModule(mContext.getPackageName(), dexModule,
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index be426aa..83d0246 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -1110,6 +1110,10 @@
mPackageName,
PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
UserHandle.myUserId());
+ if (pi == null) {
+ throw new IllegalStateException("Unable to get package info for "
+ + mPackageName + "; is package not installed?");
+ }
/*
* Two possible indications that this package could be
* sharing its virtual machine with other packages:
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index b00cfcb..2b45723 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1611,7 +1611,8 @@
/**
* {@code SemanticAction}: Mark the conversation associated with the notification as a
- * priority. Note that this is only for use by the notification assistant services.
+ * priority. Note that this is only for use by the notification assistant services. The
+ * type will be ignored for actions an app adds to its own notifications.
* @hide
*/
@SystemApi
@@ -1619,7 +1620,8 @@
/**
* {@code SemanticAction}: Mark content as a potential phishing attempt.
- * Note that this is only for use by the notification assistant services.
+ * Note that this is only for use by the notification assistant services. The type will
+ * be ignored for actions an app adds to its own notifications.
* @hide
*/
@SystemApi
@@ -5015,11 +5017,14 @@
}
if (p.text != null && p.text.length() != 0
&& (!showProgress || p.mAllowTextWithProgress)) {
- int textId = com.android.internal.R.id.text;
- contentView.setTextViewText(textId, processTextSpans(p.text));
- setTextViewColorSecondary(contentView, textId, p);
- contentView.setViewVisibility(textId, View.VISIBLE);
+ contentView.setViewVisibility(p.mTextViewId, View.VISIBLE);
+ contentView.setTextViewText(p.mTextViewId, processTextSpans(p.text));
+ setTextViewColorSecondary(contentView, p.mTextViewId, p);
hasSecondLine = true;
+ } else if (p.mTextViewId != R.id.text) {
+ // This alternate text view ID is not cleared by resetStandardTemplate
+ contentView.setViewVisibility(p.mTextViewId, View.GONE);
+ contentView.setTextViewText(p.mTextViewId, null);
}
setHeaderlessVerticalMargins(contentView, p, hasSecondLine);
@@ -5211,6 +5216,9 @@
// views in states with a header (big states)
result.mHeadingExtraMarginSet.applyToView(contentView, R.id.notification_header);
result.mTitleMarginSet.applyToView(contentView, R.id.title);
+ // If there is no title, the text (or big_text) needs to wrap around the image
+ result.mTitleMarginSet.applyToView(contentView, p.mTextViewId);
+ contentView.setInt(p.mTextViewId, "setNumIndentLines", p.hasTitle() ? 0 : 1);
}
}
@@ -5443,8 +5451,12 @@
return p.allowColorization && mN.isColorized();
}
- private boolean isCallActionColorCustomizable(StandardTemplateParams p) {
- return isColorized(p) && mContext.getResources().getBoolean(
+ private boolean isCallActionColorCustomizable() {
+ // NOTE: this doesn't need to check StandardTemplateParams.allowColorization because
+ // that is only used for disallowing colorization of headers for the minimized state,
+ // and neither of those conditions applies when showing actions.
+ // Not requiring StandardTemplateParams as an argument simplifies the creation process.
+ return mN.isColorized() && mContext.getResources().getBoolean(
R.bool.config_callNotificationActionColorsRequireColorized);
}
@@ -5510,13 +5522,13 @@
*/
private @NonNull List<Notification.Action> getNonContextualActions() {
if (mActions == null) return Collections.emptyList();
- List<Notification.Action> contextualActions = new ArrayList<>();
+ List<Notification.Action> standardActions = new ArrayList<>();
for (Notification.Action action : mActions) {
if (!action.isContextual()) {
- contextualActions.add(action);
+ standardActions.add(action);
}
}
- return contextualActions;
+ return standardActions;
}
private RemoteViews applyStandardTemplateWithActions(int layoutId,
@@ -5536,16 +5548,29 @@
// filter them out here.
List<Notification.Action> nonContextualActions = getNonContextualActions();
- int N = nonContextualActions.size();
- boolean emphazisedMode = mN.fullScreenIntent != null;
+ int numActions = Math.min(nonContextualActions.size(), MAX_ACTION_BUTTONS);
+ boolean emphazisedMode = mN.fullScreenIntent != null || p.mCallStyleActions;
+ if (p.mCallStyleActions) {
+ // Clear view padding to allow buttons to start on the left edge.
+ // This must be done before 'setEmphasizedMode' which sets top/bottom margins.
+ big.setViewPadding(R.id.actions, 0, 0, 0, 0);
+ // Add an optional indent that will make buttons start at the correct column when
+ // there is enough space to do so (and fall back to the left edge if not).
+ big.setInt(R.id.actions, "setCollapsibleIndentDimen",
+ R.dimen.call_notification_collapsible_indent);
+ }
big.setBoolean(R.id.actions, "setEmphasizedMode", emphazisedMode);
- if (N > 0 && !p.mHideActions) {
+ if (p.mCallStyleActions) {
+ // Use "wrap_content" (unlike normal emphasized mode) and allow prioritizing the
+ // required actions (Answer, Decline, and Hang Up).
+ big.setBoolean(R.id.actions, "setPrioritizedWrapMode", true);
+ }
+ if (numActions > 0 && !p.mHideActions) {
big.setViewVisibility(R.id.actions_container, View.VISIBLE);
big.setViewVisibility(R.id.actions, View.VISIBLE);
big.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target,
RemoteViews.MARGIN_BOTTOM, 0);
- if (N>MAX_ACTION_BUTTONS) N=MAX_ACTION_BUTTONS;
- for (int i=0; i<N; i++) {
+ for (int i = 0; i < numActions; i++) {
Action action = nonContextualActions.get(i);
boolean actionHasValidInput = hasValidRemoteInput(action);
@@ -5556,6 +5581,11 @@
// Clear the drawable
button.setInt(R.id.action0, "setBackgroundResource", 0);
}
+ if (p.mCallStyleActions && i > 0) {
+ // Clear start margin from non-first buttons to reduce the gap between them.
+ // (8dp remaining gap is from all buttons' standard 4dp inset).
+ button.setViewLayoutMarginDimen(R.id.action0, RemoteViews.MARGIN_START, 0);
+ }
big.addView(R.id.actions, button);
}
} else {
@@ -5773,11 +5803,11 @@
if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.S) {
return true;
}
- // If the big content view has no content, we can exempt the app from having to show it.
+ // Notifications with contentView and without a bigContentView, style, or actions would
+ // not have an expanded state before S, so showing the standard template expanded state
+ // usually looks wrong, so we keep it simple and don't show the expanded state.
boolean exempt = mN.contentView != null && mN.bigContentView == null
- && mStyle == null && mActions.size() == 0
- && mN.extras.getCharSequence(EXTRA_TITLE) == null
- && mN.extras.getCharSequence(EXTRA_TEXT) == null;
+ && mStyle == null && mActions.size() == 0;
return !exempt;
}
@@ -6017,7 +6047,7 @@
button.setColorStateList(R.id.action0, "setButtonBackground",
ColorStateList.valueOf(background));
button.setBoolean(R.id.action0, "setHasStroke", !hasColorOverride);
- if (p.mAllowActionIcons) {
+ if (p.mCallStyleActions) {
button.setImageViewIcon(R.id.action0, action.getIcon());
boolean priority = action.getExtras().getBoolean(CallStyle.KEY_ACTION_PRIORITY);
button.setBoolean(R.id.action0, "setWrapModePriority", priority);
@@ -7014,16 +7044,7 @@
p.title = mBigContentTitle;
}
- RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(layoutId, p,
- result);
-
- if (mBigContentTitle != null && mBigContentTitle.equals("")) {
- contentView.setViewVisibility(R.id.title, View.GONE);
- } else {
- contentView.setViewVisibility(R.id.title, View.VISIBLE);
- }
-
- return contentView;
+ return mBuilder.applyStandardTemplateWithActions(layoutId, p, result);
}
/**
@@ -7616,22 +7637,16 @@
public RemoteViews makeBigContentView() {
StandardTemplateParams p = mBuilder.mParams.reset()
.viewType(StandardTemplateParams.VIEW_TYPE_BIG)
- .fillTextsFrom(mBuilder).text(null);
- RemoteViews contentView = getStandardView(mBuilder.getBigTextLayoutResource(), p, null);
+ .textViewId(R.id.big_text)
+ .fillTextsFrom(mBuilder);
+ // Replace the text with the big text, but only if the big text is not empty.
CharSequence bigTextText = mBuilder.processLegacyText(mBigText);
- if (TextUtils.isEmpty(bigTextText)) {
- // In case the bigtext is null / empty fall back to the normal text to avoid a weird
- // experience
- bigTextText = mBuilder.processLegacyText(
- mBuilder.getAllExtras().getCharSequence(EXTRA_TEXT));
+ if (!TextUtils.isEmpty(bigTextText)) {
+ p.text(bigTextText);
}
- contentView.setTextViewText(R.id.big_text, mBuilder.processTextSpans(bigTextText));
- mBuilder.setTextViewColorSecondary(contentView, R.id.big_text, p);
- contentView.setViewVisibility(R.id.big_text,
- TextUtils.isEmpty(bigTextText) ? View.GONE : View.VISIBLE);
- return contentView;
+ return getStandardView(mBuilder.getBigTextLayoutResource(), p, null /* result */);
}
/**
@@ -9263,6 +9278,17 @@
return this;
}
+ /** @hide */
+ @Override
+ public Notification buildStyled(Notification wip) {
+ wip = super.buildStyled(wip);
+ // ensure that the actions in the builder and notification are corrected.
+ mBuilder.mActions = getActionsListWithSystemActions();
+ wip.actions = new Action[mBuilder.mActions.size()];
+ mBuilder.mActions.toArray(wip.actions);
+ return wip;
+ }
+
/**
* @hide
*/
@@ -9322,14 +9348,14 @@
}
@NonNull
- private Action makeNegativeAction(@NonNull StandardTemplateParams p) {
+ private Action makeNegativeAction() {
if (mDeclineIntent == null) {
- return makeAction(p, R.drawable.ic_call_decline,
+ return makeAction(R.drawable.ic_call_decline,
R.string.call_notification_hang_up_action,
mDeclineButtonColor, R.color.call_notification_decline_color,
mHangUpIntent);
} else {
- return makeAction(p, R.drawable.ic_call_decline,
+ return makeAction(R.drawable.ic_call_decline,
R.string.call_notification_decline_action,
mDeclineButtonColor, R.color.call_notification_decline_color,
mDeclineIntent);
@@ -9337,18 +9363,17 @@
}
@Nullable
- private Action makeAnswerAction(@NonNull StandardTemplateParams p) {
- return mAnswerIntent == null ? null : makeAction(p, R.drawable.ic_call_answer,
+ private Action makeAnswerAction() {
+ return mAnswerIntent == null ? null : makeAction(R.drawable.ic_call_answer,
R.string.call_notification_answer_action,
mAnswerButtonColor, R.color.call_notification_answer_color,
mAnswerIntent);
}
@NonNull
- private Action makeAction(@NonNull StandardTemplateParams p,
- @DrawableRes int icon, @StringRes int title,
+ private Action makeAction(@DrawableRes int icon, @StringRes int title,
@ColorInt Integer colorInt, @ColorRes int defaultColorRes, PendingIntent intent) {
- if (colorInt == null || !mBuilder.isCallActionColorCustomizable(p)) {
+ if (colorInt == null || !mBuilder.isCallActionColorCustomizable()) {
colorInt = mBuilder.mContext.getColor(defaultColorRes);
}
Action action = new Action.Builder(Icon.createWithResource("", icon),
@@ -9360,29 +9385,62 @@
return action;
}
- private ArrayList<Action> makeActionsList(@NonNull StandardTemplateParams p) {
- final Action negativeAction = makeNegativeAction(p);
- final Action answerAction = makeAnswerAction(p);
+ private boolean isActionAddedByCallStyle(Action action) {
+ // This is an internal extra added by the style to these actions. If an app were to add
+ // this extra to the action themselves, the action would be dropped. :shrug:
+ return action != null && action.getExtras().getBoolean(KEY_ACTION_PRIORITY);
+ }
- ArrayList<Action> actions = new ArrayList<>(MAX_ACTION_BUTTONS);
- final Action lastAction;
- if (answerAction == null) {
- // If there's no answer action, put the hang up / decline action at the end
- lastAction = negativeAction;
- } else {
- // Otherwise put the answer action at the end, and put the decline action at start.
- actions.add(negativeAction);
- lastAction = answerAction;
+ /**
+ * Gets the actions list for the call with the answer/decline/hangUp actions inserted in
+ * the correct place. This returns the correct result even if the system actions have
+ * already been added, and even if more actions were added since then.
+ * @hide
+ */
+ @NonNull
+ public ArrayList<Action> getActionsListWithSystemActions() {
+ // Define the system actions we expect to see
+ final Action negativeAction = makeNegativeAction();
+ final Action answerAction = makeAnswerAction();
+ // Sort the expected actions into the correct order:
+ // * If there's no answer action, put the hang up / decline action at the end
+ // * Otherwise put the answer action at the end, and put the decline action at start.
+ final Action firstAction = answerAction == null ? null : negativeAction;
+ final Action lastAction = answerAction == null ? negativeAction : answerAction;
+
+ // Start creating the result list.
+ int nonContextualActionSlotsRemaining = MAX_ACTION_BUTTONS;
+ ArrayList<Action> resultActions = new ArrayList<>(MAX_ACTION_BUTTONS);
+ if (firstAction != null) {
+ resultActions.add(firstAction);
+ --nonContextualActionSlotsRemaining;
}
- // For consistency with the standard actions bar, contextual actions are ignored.
- for (Action action : mBuilder.getNonContextualActions()) {
- if (actions.size() >= MAX_ACTION_BUTTONS - 1) {
- break;
+
+ // Copy actions into the new list, correcting system actions.
+ if (mBuilder.mActions != null) {
+ for (Notification.Action action : mBuilder.mActions) {
+ if (action.isContextual()) {
+ // Always include all contextual actions
+ resultActions.add(action);
+ } else if (isActionAddedByCallStyle(action)) {
+ // Drop any old versions of system actions
+ } else {
+ // Copy non-contextual actions; decrement the remaining action slots.
+ resultActions.add(action);
+ --nonContextualActionSlotsRemaining;
+ }
+ // If there's exactly one action slot left, fill it with the lastAction.
+ if (nonContextualActionSlotsRemaining == 1) {
+ resultActions.add(lastAction);
+ --nonContextualActionSlotsRemaining;
+ }
}
- actions.add(action);
}
- actions.add(lastAction);
- return actions;
+ // If there are any action slots left, the lastAction still needs to be added.
+ if (nonContextualActionSlotsRemaining >= 1) {
+ resultActions.add(lastAction);
+ }
+ return resultActions;
}
private RemoteViews makeCallLayout() {
@@ -9395,19 +9453,15 @@
// Bind standard template
StandardTemplateParams p = mBuilder.mParams.reset()
.viewType(StandardTemplateParams.VIEW_TYPE_BIG)
- .allowActionIcons(true)
+ .callStyleActions(true)
.allowTextWithProgress(true)
.hideLargeIcon(true)
.text(text)
.summaryText(mBuilder.processLegacyText(mVerificationText));
- RemoteViews contentView = mBuilder.applyStandardTemplate(
+ mBuilder.mActions = getActionsListWithSystemActions();
+ RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(
mBuilder.getCallLayoutResource(), p, null /* result */);
- // Bind actions.
- mBuilder.resetStandardTemplateWithActions(contentView);
- mBuilder.bindSnoozeAction(contentView, p);
- bindCallActions(contentView, p);
-
// Bind some extra conversation-specific header fields.
mBuilder.setTextViewColorPrimary(contentView, R.id.conversation_text, p);
mBuilder.setTextViewColorSecondary(contentView, R.id.app_name_divider, p);
@@ -9427,41 +9481,6 @@
return contentView;
}
- private void bindCallActions(RemoteViews view, StandardTemplateParams p) {
- view.setViewVisibility(R.id.actions_container, View.VISIBLE);
- view.setViewVisibility(R.id.actions, View.VISIBLE);
- view.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target,
- RemoteViews.MARGIN_BOTTOM, 0);
-
- // Clear view padding to allow buttons to start on the left edge.
- // This must be done before 'setEmphasizedMode' which sets top/bottom margins.
- view.setViewPadding(R.id.actions, 0, 0, 0, 0);
- // Add an optional indent that will make buttons start at the correct column when
- // there is enough space to do so (and fall back to the left edge if not).
- view.setInt(R.id.actions, "setCollapsibleIndentDimen",
- R.dimen.call_notification_collapsible_indent);
-
- // Emphasize so that buttons have borders or colored backgrounds
- boolean emphasizedMode = true;
- view.setBoolean(R.id.actions, "setEmphasizedMode", emphasizedMode);
- // Use "wrap_content" (unlike normal emphasized mode) and allow prioritizing the
- // required actions (Answer, Decline, and Hang Up).
- view.setBoolean(R.id.actions, "setPrioritizedWrapMode", true);
-
- // Create the buttons for the generated actions list.
- int i = 0;
- for (Action action : makeActionsList(p)) {
- final RemoteViews button = mBuilder.generateActionButton(action, emphasizedMode, p);
- if (i > 0) {
- // Clear start margin from non-first buttons to reduce the gap between buttons.
- // (8dp remaining gap is from all buttons' standard 4dp inset).
- button.setViewLayoutMarginDimen(R.id.action0, RemoteViews.MARGIN_START, 0);
- }
- view.addView(R.id.actions, button);
- ++i;
- }
- }
-
private void bindCallerVerification(RemoteViews contentView, StandardTemplateParams p) {
String iconContentDescription = null;
boolean showDivider = true;
@@ -12083,6 +12102,21 @@
if (viewId == R.id.notification_header) {
views.setFloat(R.id.notification_header,
"setTopLineExtraMarginEndDp", marginEndDp);
+ } else if (viewId == R.id.text || viewId == R.id.big_text) {
+ if (mValueIfGone != 0) {
+ throw new RuntimeException("Programming error: `text` and `big_text` use "
+ + "ImageFloatingTextView which can either show a margin or not; "
+ + "thus mValueIfGone must be 0, but it was " + mValueIfGone);
+ }
+ // Note that the caller must set "setNumIndentLines" to a positive int in order
+ // for this margin to do anything at all.
+ views.setFloat(viewId, "setImageEndMarginDp", mValueIfVisible);
+ views.setBoolean(viewId, "setHasImage", mRightIconVisible);
+ // Apply just the *extra* margin as the view layout margin; this will be
+ // unchanged depending on the visibility of the image, but it means that the
+ // extra margin applies to *every* line of text instead of just indented lines.
+ views.setViewLayoutMargin(viewId, RemoteViews.MARGIN_END,
+ extraMarginDp, TypedValue.COMPLEX_UNIT_DIP);
} else {
views.setViewLayoutMargin(viewId, RemoteViews.MARGIN_END,
marginEndDp, TypedValue.COMPLEX_UNIT_DIP);
@@ -12119,8 +12153,9 @@
boolean mHideProgress;
boolean mHideSnoozeButton;
boolean mPromotePicture;
- boolean mAllowActionIcons;
+ boolean mCallStyleActions;
boolean mAllowTextWithProgress;
+ int mTextViewId;
CharSequence title;
CharSequence text;
CharSequence headerTextSecondary;
@@ -12138,8 +12173,9 @@
mHideProgress = false;
mHideSnoozeButton = false;
mPromotePicture = false;
- mAllowActionIcons = false;
+ mCallStyleActions = false;
mAllowTextWithProgress = false;
+ mTextViewId = R.id.text;
title = null;
text = null;
summaryText = null;
@@ -12179,8 +12215,8 @@
return this;
}
- final StandardTemplateParams allowActionIcons(boolean allowActionIcons) {
- this.mAllowActionIcons = allowActionIcons;
+ final StandardTemplateParams callStyleActions(boolean callStyleActions) {
+ this.mCallStyleActions = callStyleActions;
return this;
}
@@ -12199,6 +12235,11 @@
return this;
}
+ public StandardTemplateParams textViewId(int textViewId) {
+ mTextViewId = textViewId;
+ return this;
+ }
+
final StandardTemplateParams title(CharSequence title) {
this.title = title;
return this;
diff --git a/core/java/android/app/WindowTokenClient.java b/core/java/android/app/WindowTokenClient.java
index 29792ac..2298e84 100644
--- a/core/java/android/app/WindowTokenClient.java
+++ b/core/java/android/app/WindowTokenClient.java
@@ -85,8 +85,10 @@
context.destroy();
mContextRef.clear();
}
- // If a secondary display is detached, release all views attached to this token.
- WindowManagerGlobal.getInstance().closeAll(this, mContextRef.getClass().getName(),
- "WindowContext");
+ ActivityThread.currentActivityThread().getHandler().post(() -> {
+ // If the tracked window token is detached, release all views attached to this token.
+ WindowManagerGlobal.getInstance().closeAll(WindowTokenClient.this,
+ "#onWindowTokenRemoved()", "WindowTokenClient");
+ });
}
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ccf41e5..30fb858 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -987,7 +987,8 @@
* The default for this extra is {@code false} - by default, the admin of a fully-managed
* device has the ability to grant sensors-related permissions.
*
- * <p>Use with {@link #ACTION_PROVISION_MANAGED_DEVICE} only.
+ * <p>Use only for device owner provisioning.
+ * @see #ACTION_GET_PROVISIONING_MODE
*/
public static final String EXTRA_PROVISIONING_PERMISSION_GRANT_OPT_OUT =
"android.app.extra.PROVISIONING_PERMISSION_GRANT_OPT_OUT";
@@ -11838,7 +11839,7 @@
/**
* @hide
- * Force update user setup completed status. This API has no effect on user build.
+ * Force update user setup completed status.
* @throws {@link SecurityException} if the caller has no
* {@code android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS} or the caller is
* not {@link UserHandle#SYSTEM_USER}
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index d79fac5..8fd0de7 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -849,6 +849,7 @@
public void setColorResources(@NonNull SparseIntArray colorMapping) {
mColorResources = RemoteViews.ColorResources.create(mContext, colorMapping);
mLayoutId = -1;
+ mViewMode = VIEW_MODE_NOINIT;
reapplyLastRemoteViews();
}
@@ -863,6 +864,7 @@
if (mColorResources != null) {
mColorResources = null;
mLayoutId = -1;
+ mViewMode = VIEW_MODE_NOINIT;
reapplyLastRemoteViews();
}
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index df5c58c..0509e3f 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4837,6 +4837,15 @@
public static final String POWER_WHITELIST_MANAGER = "power_whitelist";
/**
+ * System service name for the PowerExemptionManager.
+ *
+ * @see #getSystemService(String)
+ * @hide
+ */
+ @SystemApi
+ public static final String POWER_EXEMPTION_SERVICE = "power_exemption";
+
+ /**
* Use with {@link #getSystemService(String)} to retrieve a
* {@link android.app.admin.DevicePolicyManager} for working with global
* device policy management.
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 1660c9d..5a17753 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -892,22 +892,42 @@
*/
@ChangeId
@Disabled
- public static final long FORCE_RESIZE_APP = 174042936L; // number refers to buganizer id
+ @TestApi
+ public static final long FORCE_RESIZE_APP = 174042936L; // buganizer id
+
+ /**
+ * This change id forces the packages it is applied to to be non-resizable.
+ * @hide
+ */
+ @ChangeId
+ @Disabled
+ @TestApi
+ public static final long FORCE_NON_RESIZE_APP = 181136395L; // buganizer id
/**
* Return value for {@link #supportsSizeChanges()} indicating that this activity does not
- * support size changes.
+ * support size changes due to the android.supports_size_changes metadata flag either being
+ * unset or set to {@code false} on application or activity level.
+ *
* @hide
*/
- public static final int SIZE_CHANGES_UNSUPPORTED = 0;
+ public static final int SIZE_CHANGES_UNSUPPORTED_METADATA = 0;
+
+ /**
+ * Return value for {@link #supportsSizeChanges()} indicating that this activity has been
+ * overridden to not support size changes through the compat framework change id
+ * {@link #FORCE_NON_RESIZE_APP}.
+ * @hide
+ */
+ public static final int SIZE_CHANGES_UNSUPPORTED_OVERRIDE = 1;
/**
* Return value for {@link #supportsSizeChanges()} indicating that this activity supports size
- * changes due to the android.supports_size_changes metadata flag being set either on
- * application or on activity level.
+ * changes due to the android.supports_size_changes metadata flag being set to {@code true}
+ * either on application or activity level.
* @hide
*/
- public static final int SIZE_CHANGES_SUPPORTED_METADATA = 1;
+ public static final int SIZE_CHANGES_SUPPORTED_METADATA = 2;
/**
* Return value for {@link #supportsSizeChanges()} indicating that this activity has been
@@ -915,11 +935,12 @@
* {@link #FORCE_RESIZE_APP}.
* @hide
*/
- public static final int SIZE_CHANGES_SUPPORTED_OVERRIDE = 2;
+ public static final int SIZE_CHANGES_SUPPORTED_OVERRIDE = 3;
/** @hide */
@IntDef(prefix = { "SIZE_CHANGES_" }, value = {
- SIZE_CHANGES_UNSUPPORTED,
+ SIZE_CHANGES_UNSUPPORTED_METADATA,
+ SIZE_CHANGES_UNSUPPORTED_OVERRIDE,
SIZE_CHANGES_SUPPORTED_METADATA,
SIZE_CHANGES_SUPPORTED_OVERRIDE,
})
@@ -1213,6 +1234,12 @@
*/
@SizeChangesSupportMode
public int supportsSizeChanges() {
+ if (CompatChanges.isChangeEnabled(FORCE_NON_RESIZE_APP,
+ applicationInfo.packageName,
+ UserHandle.getUserHandleForUid(applicationInfo.uid))) {
+ return SIZE_CHANGES_UNSUPPORTED_OVERRIDE;
+ }
+
if (supportsSizeChanges) {
return SIZE_CHANGES_SUPPORTED_METADATA;
}
@@ -1223,7 +1250,7 @@
return SIZE_CHANGES_SUPPORTED_OVERRIDE;
}
- return SIZE_CHANGES_UNSUPPORTED;
+ return SIZE_CHANGES_UNSUPPORTED_METADATA;
}
/** @hide */
@@ -1269,8 +1296,10 @@
/** @hide */
public static String sizeChangesSupportModeToString(@SizeChangesSupportMode int mode) {
switch (mode) {
- case SIZE_CHANGES_UNSUPPORTED:
- return "SIZE_CHANGES_UNSUPPORTED";
+ case SIZE_CHANGES_UNSUPPORTED_METADATA:
+ return "SIZE_CHANGES_UNSUPPORTED_METADATA";
+ case SIZE_CHANGES_UNSUPPORTED_OVERRIDE:
+ return "SIZE_CHANGES_UNSUPPORTED_OVERRIDE";
case SIZE_CHANGES_SUPPORTED_METADATA:
return "SIZE_CHANGES_SUPPORTED_METADATA";
case SIZE_CHANGES_SUPPORTED_OVERRIDE:
diff --git a/core/java/android/content/pm/dex/DexMetadataHelper.java b/core/java/android/content/pm/dex/DexMetadataHelper.java
index 0d5b33c..8f9a0d7 100644
--- a/core/java/android/content/pm/dex/DexMetadataHelper.java
+++ b/core/java/android/content/pm/dex/DexMetadataHelper.java
@@ -29,6 +29,7 @@
import android.util.jar.StrictJarFile;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.security.VerityUtils;
import java.io.File;
import java.io.IOException;
@@ -76,7 +77,8 @@
* Returns whether fs-verity is required to install a dex metadata
*/
public static boolean isFsVerityRequired() {
- return SystemProperties.getBoolean(PROPERTY_DM_FSVERITY_REQUIRED, false);
+ return VerityUtils.isFsVeritySupported()
+ && SystemProperties.getBoolean(PROPERTY_DM_FSVERITY_REQUIRED, false);
}
/**
diff --git a/core/java/android/graphics/fonts/FontFamilyUpdateRequest.java b/core/java/android/graphics/fonts/FontFamilyUpdateRequest.java
index 25758e9..8c7695a 100644
--- a/core/java/android/graphics/fonts/FontFamilyUpdateRequest.java
+++ b/core/java/android/graphics/fonts/FontFamilyUpdateRequest.java
@@ -72,6 +72,45 @@
* A font family definition.
*/
public static final class FontFamily {
+
+ /**
+ * Builds a {@link FontFamily}.
+ */
+ public static final class Builder {
+ @NonNull private final String mName;
+ @NonNull private final List<Font> mFonts;
+
+ /**
+ * Constructs a {@link FontFamily.Builder}.
+ */
+ public Builder(@NonNull String name, @NonNull List<Font> fonts) {
+ Objects.requireNonNull(name);
+ Preconditions.checkStringNotEmpty(name);
+ Objects.requireNonNull(fonts);
+ Preconditions.checkCollectionElementsNotNull(fonts, "fonts");
+ Preconditions.checkCollectionNotEmpty(fonts, "fonts");
+ mName = name;
+ mFonts = new ArrayList<>(fonts);
+ }
+
+ /**
+ * Adds a {@link Font} to the builder.
+ *
+ * @return This builder object.
+ */
+ public @NonNull Builder addFont(@NonNull Font font) {
+ mFonts.add(font);
+ return this;
+ }
+
+ /**
+ * Builds a {@link FontFamily}.
+ */
+ public @NonNull FontFamily build() {
+ return new FontFamily(mName, mFonts);
+ }
+ }
+
@NonNull
private final String mName;
@NonNull
@@ -90,12 +129,7 @@
* @see android.graphics.Typeface#create(String, int)
* @see Font
*/
- public FontFamily(@NonNull String name, @NonNull List<Font> fonts) {
- Objects.requireNonNull(name);
- Preconditions.checkStringNotEmpty(name);
- Objects.requireNonNull(fonts);
- Preconditions.checkCollectionElementsNotNull(fonts, "fonts");
- Preconditions.checkCollectionNotEmpty(fonts, "fonts");
+ private FontFamily(@NonNull String name, @NonNull List<Font> fonts) {
mName = name;
mFonts = fonts;
}
diff --git a/core/java/android/hardware/SensorPrivacyManagerInternal.java b/core/java/android/hardware/SensorPrivacyManagerInternal.java
new file mode 100644
index 0000000..d12e9f8
--- /dev/null
+++ b/core/java/android/hardware/SensorPrivacyManagerInternal.java
@@ -0,0 +1,64 @@
+/*
+ * 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.hardware;
+
+/**
+ * SensorPrivacyManager calls for within the system server
+ * @hide
+ */
+public abstract class SensorPrivacyManagerInternal {
+
+ /**
+ * A class implementing this interface can register to receive a callback when state changes.
+ */
+ public interface OnSensorPrivacyChangedListener {
+ /**
+ * The callback invoked when the state changes.
+ */
+ void onSensorPrivacyChanged(boolean enabled);
+ }
+
+ /**
+ * A class implementing this interface can register to receive a callback when state changes for
+ * any user.
+ */
+ public interface OnUserSensorPrivacyChangedListener {
+ /**
+ * The callback invoked when the state changes.
+ */
+ void onSensorPrivacyChanged(int userId, boolean enabled);
+ }
+
+ /**
+ * Get the individual sensor privacy state for a given user.
+ */
+ public abstract boolean isSensorPrivacyEnabled(int userId, int sensor);
+
+ /**
+ * Registers a new listener to receive notification when the state of sensor privacy
+ * changes.
+ */
+ public abstract void addSensorPrivacyListener(int userId, int sensor,
+ OnSensorPrivacyChangedListener listener);
+
+ /**
+ * Registers a new listener to receive notification when the state of sensor privacy
+ * changes for any user.
+ */
+ public abstract void addSensorPrivacyListenerForAllUsers(int sensor,
+ OnUserSensorPrivacyChangedListener listener);
+}
diff --git a/core/java/android/hardware/display/AmbientDisplayConfiguration.java b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
index 7dc1eaa..93e5a0e 100644
--- a/core/java/android/hardware/display/AmbientDisplayConfiguration.java
+++ b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
@@ -52,7 +52,8 @@
|| wakeDisplayGestureEnabled(user)
|| pickupGestureEnabled(user)
|| tapGestureEnabled(user)
- || doubleTapGestureEnabled(user);
+ || doubleTapGestureEnabled(user)
+ || quickPickupSensorEnabled(user);
}
/** {@hide} */
@@ -100,6 +101,13 @@
}
/** {@hide} */
+ public boolean quickPickupSensorEnabled(int user) {
+ return boolSettingDefaultOff(Settings.Secure.DOZE_QUICK_PICKUP_GESTURE, user)
+ && !TextUtils.isEmpty(quickPickupSensorType())
+ && !alwaysOnEnabled(user);
+ }
+
+ /** {@hide} */
public boolean wakeScreenGestureAvailable() {
return mContext.getResources()
.getBoolean(R.bool.config_dozeWakeLockScreenSensorAvailable);
@@ -143,6 +151,11 @@
}
/** {@hide} */
+ public String quickPickupSensorType() {
+ return mContext.getResources().getString(R.string.config_quickPickupSensorType);
+ }
+
+ /** {@hide} */
public boolean pulseOnLongPressEnabled(int user) {
return pulseOnLongPressAvailable() && boolSettingDefaultOff(
Settings.Secure.DOZE_PULSE_ON_LONG_PRESS, user);
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index bbf421d..2c3e7f1 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -68,6 +68,9 @@
* {@link #EXTRA_WIFI_DISPLAY_STATUS} extra.
* </p><p>
* This broadcast is only sent to registered receivers and can only be sent by the system.
+ * </p><p>
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission is required to
+ * receive this broadcast.
* </p>
* @hide
*/
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 0256b7b..8dc8d5b 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -475,28 +475,11 @@
* @hide
*/
@RequiresPermission(MANAGE_BIOMETRIC)
- public void revokeChallenge() {
- final List<FaceSensorPropertiesInternal> faceSensorProperties =
- getSensorPropertiesInternal();
- if (faceSensorProperties.isEmpty()) {
- Slog.e(TAG, "No sensors during revokeChallenge");
- }
- revokeChallenge(faceSensorProperties.get(0).sensorId);
- }
-
- /**
- * Invalidates the current challenge.
- *
- * TODO(b/171335732): should take userId and challenge
- *
- * @hide
- */
- @RequiresPermission(MANAGE_BIOMETRIC)
- public void revokeChallenge(int sensorId) {
+ public void revokeChallenge(int sensorId, int userId, long challenge) {
if (mService != null) {
try {
- mService.revokeChallenge(mToken, sensorId, 0 /* userId */,
- mContext.getOpPackageName(), 0 /* challenge */);
+ mService.revokeChallenge(mToken, sensorId, userId,
+ mContext.getOpPackageName(), challenge);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index fc795d8..1c33b26 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -686,17 +686,6 @@
}
/**
- * Revokes the current challenge.
- * @hide
- */
- @RequiresPermission(MANAGE_FINGERPRINT)
- public void revokeChallenge(int userId) {
- // On HALs with only single in-flight challenge such as IBiometricsFingerprint@2.1,
- // this parameter is ignored.
- revokeChallenge(userId, 0L);
- }
-
- /**
* Revokes the specified challenge.
* @hide
*/
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index b90c728..ad71f15 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -461,6 +461,7 @@
* @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE
* @hide
*/
+ @SystemApi
public static final int VOLUME_CONTROL_ENABLED = 1;
/**
* HDMI CEC disabled.
@@ -468,6 +469,7 @@
* @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE
* @hide
*/
+ @SystemApi
public static final int VOLUME_CONTROL_DISABLED = 0;
/**
* @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE
@@ -486,12 +488,14 @@
*
* @hide
*/
+ @SystemApi
public static final int TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED = 1;
/**
* TV Wake on One Touch Play disabled.
*
* @hide
*/
+ @SystemApi
public static final int TV_WAKE_ON_ONE_TOUCH_PLAY_DISABLED = 0;
/**
* @hide
@@ -509,12 +513,14 @@
*
* @hide
*/
+ @SystemApi
public static final int TV_SEND_STANDBY_ON_SLEEP_ENABLED = 1;
/**
* Not sending <Standby> on sleep.
*
* @hide
*/
+ @SystemApi
public static final int TV_SEND_STANDBY_ON_SLEEP_DISABLED = 0;
/**
* @hide
@@ -759,6 +765,7 @@
* @hide
* @see android.hardware.hdmi.HdmiControlManager#setHdmiCecVolumeControlEnabled(int)
*/
+ @SystemApi
public static final String CEC_SETTING_NAME_VOLUME_CONTROL_MODE =
"volume_control_enabled";
/**
@@ -767,6 +774,7 @@
*
* @hide
*/
+ @SystemApi
public static final String CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY =
"tv_wake_on_one_touch_play";
/**
@@ -775,6 +783,7 @@
*
* @hide
*/
+ @SystemApi
public static final String CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP =
"tv_send_standby_on_sleep";
/**
@@ -1259,6 +1268,7 @@
* @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
public void setHdmiCecVolumeControlEnabled(
@VolumeControl int hdmiCecVolumeControlEnabled) {
@@ -1274,6 +1284,7 @@
* Returns whether volume changes via HDMI CEC are enabled.
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
@VolumeControl
public int getHdmiCecVolumeControlEnabled() {
@@ -2155,6 +2166,7 @@
*
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
public void setTvWakeOnOneTouchPlay(@NonNull @TvWakeOnOneTouchPlay int value) {
if (mService == null) {
@@ -2176,6 +2188,7 @@
*
* @hide
*/
+ @SystemApi
@NonNull
@TvWakeOnOneTouchPlay
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
@@ -2199,6 +2212,7 @@
*
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
public void setTvSendStandbyOnSleep(@NonNull @TvSendStandbyOnSleep int value) {
if (mService == null) {
@@ -2220,6 +2234,7 @@
*
* @hide
*/
+ @SystemApi
@NonNull
@TvSendStandbyOnSleep
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index a65f36b..eaa8bd4 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -60,7 +60,8 @@
private static final String TAG = "ContextHubManager";
/**
- * An extra of type int describing the client's authorization state.
+ * An extra containing an int from {@link AuthorizationState} describing the client's
+ * authorization state.
*/
public static final String EXTRA_CLIENT_AUTHORIZATION_STATE =
"android.hardware.location.extra.CLIENT_AUTHORIZATION_STATE";
@@ -115,11 +116,9 @@
/**
* Indicates the {@link ContextHubClient} will soon lose its authorization to communicate with a
- * nanoapp. The {@link ContextHubClient} must perform any cleanup with the nanoapp as soon as
- * possible.
- *
- * Note that the time between this state event and {@link AUTHORIZATION_DENIED} must be enough
- * for the {@link ContextHubClient} to send at least one message to the nanoapp.
+ * nanoapp. After receiving this state event, the {@link ContextHubClient} has one minute to
+ * perform any cleanup with the nanoapp such that the nanoapp is no longer performing work on
+ * behalf of the {@link ContextHubClient}.
*/
public static final int AUTHORIZATION_DENIED_GRACE_PERIOD = 1;
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index 5cfcd66..9198eb7 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -171,7 +171,7 @@
SomeArgs args = (SomeArgs) msg.obj;
try {
inputMethod.initializeInternal((IBinder) args.arg1, msg.arg1,
- (IInputMethodPrivilegedOperations) args.arg2);
+ (IInputMethodPrivilegedOperations) args.arg2, (int) args.arg3);
} finally {
args.recycle();
}
@@ -280,9 +280,10 @@
@BinderThread
@Override
public void initializeInternal(IBinder token, int displayId,
- IInputMethodPrivilegedOperations privOps) {
+ IInputMethodPrivilegedOperations privOps, int configChanges) {
mCaller.executeOrSendMessage(
- mCaller.obtainMessageIOO(DO_INITIALIZE_INTERNAL, displayId, token, privOps));
+ mCaller.obtainMessageIOOO(DO_INITIALIZE_INTERNAL, displayId, token, privOps,
+ configChanges));
}
@BinderThread
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 7e2be01..40a0fc4 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -70,6 +70,7 @@
import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -131,6 +132,7 @@
import android.window.WindowMetricsHelper;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.IInputContentUriToken;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
import com.android.internal.inputmethod.InputMethodPrivilegedOperations;
@@ -513,6 +515,8 @@
private boolean mIsAutomotive;
private Handler mHandler;
private boolean mImeSurfaceScheduledForRemoval;
+ private Configuration mLastKnownConfig;
+ private int mHandledConfigChanges;
/**
* An opaque {@link Binder} token of window requesting {@link InputMethodImpl#showSoftInput}
@@ -588,12 +592,13 @@
@MainThread
@Override
public final void initializeInternal(@NonNull IBinder token, int displayId,
- IInputMethodPrivilegedOperations privilegedOperations) {
+ IInputMethodPrivilegedOperations privilegedOperations, int configChanges) {
if (InputMethodPrivilegedOperationsRegistry.isRegistered(token)) {
Log.w(TAG, "The token has already registered, ignore this initialization.");
return;
}
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initializeInternal");
+ mHandledConfigChanges = configChanges;
mPrivOps.set(privilegedOperations);
InputMethodPrivilegedOperationsRegistry.put(token, mPrivOps);
updateInputMethodDisplay(displayId);
@@ -821,6 +826,9 @@
setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition);
}
final boolean isVisible = isInputViewShown();
+ if (isVisible && getResources() != null) {
+ mLastKnownConfig = new Configuration(getResources().getConfiguration());
+ }
final boolean visibilityChanged = isVisible != wasVisible;
if (resultReceiver != null) {
resultReceiver.send(visibilityChanged
@@ -1428,10 +1436,30 @@
* state: {@link #onStartInput} if input is active, and
* {@link #onCreateInputView} and {@link #onStartInputView} and related
* appropriate functions if the UI is displayed.
+ * <p>Starting with {@link Build.VERSION_CODES#S}, IMEs can opt into handling configuration
+ * changes themselves instead of being restarted with
+ * {@link android.R.styleable#InputMethod_configChanges}.
*/
@Override public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- resetStateForNewConfiguration();
+ if (shouldImeRestartForConfig(newConfig)) {
+ resetStateForNewConfiguration();
+ }
+ }
+
+ /**
+ * @return {@code true} if {@link InputMethodService} needs to restart to handle
+ * .{@link #onConfigurationChanged(Configuration)}
+ */
+ @VisibleForTesting
+ boolean shouldImeRestartForConfig(@NonNull Configuration newConfig) {
+ if (mLastKnownConfig == null) {
+ return true;
+ }
+ // If the new config is the same as the config this Service is already running with,
+ // then don't bother calling resetStateForNewConfiguration.
+ int unhandledDiff = (mLastKnownConfig.diffPublicOnly(newConfig) & ~mHandledConfigChanges);
+ return unhandledDiff != 0;
}
private void resetStateForNewConfiguration() {
@@ -3181,7 +3209,17 @@
requestHideSelf(InputMethodManager.HIDE_NOT_ALWAYS);
}
}
-
+
+ @VisibleForTesting
+ void setLastKnownConfig(@NonNull Configuration config) {
+ mLastKnownConfig = config;
+ }
+
+ @VisibleForTesting
+ void setHandledConfigChanges(int configChanges) {
+ mHandledConfigChanges = configChanges;
+ }
+
void startExtractingText(boolean inputChanged) {
final ExtractEditText eet = mExtractEditText;
if (eet != null && getCurrentInputStarted()
diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java
index f472ed4..77754d1 100644
--- a/core/java/android/net/VpnManager.java
+++ b/core/java/android/net/VpnManager.java
@@ -16,12 +16,15 @@
package android.net;
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.content.ComponentName;
@@ -56,18 +59,21 @@
*/
public class VpnManager {
/** Type representing a lack of VPN @hide */
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_NONE = -1;
/**
* A VPN created by an app using the {@link VpnService} API.
* @hide
*/
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_SERVICE = 1;
/**
* A VPN created using a {@link VpnManager} API such as {@link #startProvisionedVpnProfile}.
* @hide
*/
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_PLATFORM = 2;
/**
@@ -76,6 +82,7 @@
* @hide
*/
@Deprecated
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_LEGACY = 3;
/**
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index a46af97..b12dad0 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1247,9 +1247,9 @@
}
/**
- * Creates a directory with name {@code name} under an existing directory {@code baseDir}.
- * Returns a {@code File} object representing the directory on success, {@code null} on
- * failure.
+ * Creates a directory with name {@code name} under an existing directory {@code baseDir} if it
+ * doesn't exist already. Returns a {@code File} object representing the directory if it exists
+ * and {@code null} if not.
*
* @hide
*/
@@ -1259,13 +1259,23 @@
return createDir(dir) ? dir : null;
}
- /** @hide */
+ /**
+ * Ensure the given directory exists, creating it if needed. This method is threadsafe.
+ *
+ * @return false if the directory doesn't exist and couldn't be created
+ *
+ * @hide
+ */
public static boolean createDir(File dir) {
+ if (dir.mkdir()) {
+ return true;
+ }
+
if (dir.exists()) {
return dir.isDirectory();
}
- return dir.mkdir();
+ return false;
}
/**
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 786a7d0..a19728c 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -323,6 +323,13 @@
public static final int USER_ACTIVITY_EVENT_ATTENTION = 4;
/**
+ * User activity event type: {@link com.android.server.power.FaceDownDetector} taking action
+ * on behalf of user.
+ * @hide
+ */
+ public static final int USER_ACTIVITY_EVENT_FACE_DOWN = 5;
+
+ /**
* User activity flag: If already dimmed, extend the dim timeout
* but do not brighten. This flag is useful for keeping the screen on
* a little longer without causing a visible change such as when
diff --git a/core/java/android/os/incremental/IncrementalFileStorages.java b/core/java/android/os/incremental/IncrementalFileStorages.java
index 73520e0..2a42b98 100644
--- a/core/java/android/os/incremental/IncrementalFileStorages.java
+++ b/core/java/android/os/incremental/IncrementalFileStorages.java
@@ -51,6 +51,8 @@
public final class IncrementalFileStorages {
private static final String TAG = "IncrementalFileStorages";
+ private static final String SYSTEM_DATA_LOADER_PACKAGE = "android";
+
private @NonNull final IncrementalManager mIncrementalManager;
private @NonNull final File mStageDir;
private @Nullable IncrementalStorage mInheritedStorage;
@@ -116,7 +118,10 @@
mInheritedStorage = mIncrementalManager.openStorage(
inheritedDir.getAbsolutePath());
if (mInheritedStorage != null) {
- if (!mInheritedStorage.isFullyLoaded()) {
+ boolean systemDataLoader = SYSTEM_DATA_LOADER_PACKAGE.equals(
+ dataLoaderParams.getComponentName().getPackageName());
+ if (systemDataLoader && !mInheritedStorage.isFullyLoaded()) {
+ // System data loader does not support incomplete storages.
throw new IOException("Inherited storage has missing pages.");
}
diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java
index 396ba2d..82c4c71 100644
--- a/core/java/android/os/storage/StorageManagerInternal.java
+++ b/core/java/android/os/storage/StorageManagerInternal.java
@@ -52,6 +52,11 @@
}
/**
+ * Return true if fuse is mounted.
+ */
+ public abstract boolean isFuseMounted(int userId);
+
+ /**
* Create storage directories if it does not exist.
* Return true if the directories were setup correctly, otherwise false.
*/
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4dfbb6f..6865041 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8369,6 +8369,14 @@
public static final String DOZE_WAKE_DISPLAY_GESTURE = "doze_wake_display_gesture";
/**
+ * Gesture that wakes up the display on quick pickup, toggling between
+ * {@link Display.STATE_OFF} and {@link Display.STATE_DOZE}.
+ * @hide
+ */
+ @Readable
+ public static final String DOZE_QUICK_PICKUP_GESTURE = "doze_quick_pickup_gesture";
+
+ /**
* Whether the device should suppress the current doze configuration and disable dozing.
* @hide
*/
diff --git a/core/java/android/service/autofill/AutofillServiceInfo.java b/core/java/android/service/autofill/AutofillServiceInfo.java
index 4c8ee59..00c30b1 100644
--- a/core/java/android/service/autofill/AutofillServiceInfo.java
+++ b/core/java/android/service/autofill/AutofillServiceInfo.java
@@ -23,6 +23,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
@@ -38,6 +39,7 @@
import android.util.Xml;
import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.XmlUtils;
@@ -233,6 +235,39 @@
return compatibilityPackages;
}
+ /**
+ * Used by {@link TestDataBuilder}.
+ */
+ private AutofillServiceInfo(String passwordsActivity) {
+ mServiceInfo = new ServiceInfo();
+ mServiceInfo.applicationInfo = new ApplicationInfo();
+ mServiceInfo.packageName = "com.android.test";
+ mSettingsActivity = null;
+ mPasswordsActivity = passwordsActivity;
+ mCompatibilityPackages = null;
+ mInlineSuggestionsEnabled = false;
+ }
+
+ /**
+ * Builds test data for unit tests.
+ */
+ @VisibleForTesting
+ public static final class TestDataBuilder {
+ private String mPasswordsActivity;
+
+ public TestDataBuilder() {
+ }
+
+ public TestDataBuilder setPasswordsActivity(String passwordsActivity) {
+ mPasswordsActivity = passwordsActivity;
+ return this;
+ }
+
+ public AutofillServiceInfo build() {
+ return new AutofillServiceInfo(mPasswordsActivity);
+ }
+ }
+
@NonNull
public ServiceInfo getServiceInfo() {
return mServiceInfo;
diff --git a/core/java/android/service/rotationresolver/RotationResolutionRequest.java b/core/java/android/service/rotationresolver/RotationResolutionRequest.java
index 8e76e2f..8dec092 100644
--- a/core/java/android/service/rotationresolver/RotationResolutionRequest.java
+++ b/core/java/android/service/rotationresolver/RotationResolutionRequest.java
@@ -16,12 +16,15 @@
package android.service.rotationresolver;
+import android.annotation.DurationMillisLong;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.Surface;
+import com.android.internal.util.DataClass;
+
/**
* This class represents a request to an {@link RotationResolverService}. The request contains
* information from the system that can help RotationResolverService to determine the appropriate
@@ -33,68 +36,209 @@
* @hide
*/
@SystemApi
+@DataClass (
+ genParcelable = true,
+ genToString = true
+)
public final class RotationResolutionRequest implements Parcelable {
- private final @NonNull String mPackageName;
- private final int mProposedRotation;
- private final int mCurrentRotation;
- private final long mTimeoutMillis;
+ /** The Name of the package of the current fore-ground activity. */
+ @NonNull private final String mPackageName;
+
+ /** The current rotation of the screen. */
+ @Surface.Rotation private final int mCurrentRotation;
+
+ /** The proposed screen rotation in the system. */
+ @Surface.Rotation private final int mProposedRotation;
+
+ /** Whether should use camera signal to resolver rotation. */
+ private final boolean mShouldUseCamera;
+
+ /** The timeout of the request. */
+ @DurationMillisLong private final long mTimeoutMillis;
+
+
+
+
+ // Code below generated by codegen v1.0.22.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/rotationresolver/RotationResolutionRequest.java
+ //
+ // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+ // Settings > Editor > Code Style > Formatter Control
+ //@formatter:off
+
/**
- * @param proposedRotation The system proposed screen rotation.
- * @param currentRotation The current screen rotation of the phone.
- * @param packageName The current package name of the activity that is running in
- * foreground.
- * @param timeoutMillis The timeout in millisecond for the rotation request.
- * @hide
+ * Creates a new RotationResolutionRequest.
+ *
+ * @param packageName
+ * The Name of the package of the current fore-ground activity.
+ * @param currentRotation
+ * The current rotation of the screen.
+ * @param proposedRotation
+ * The proposed screen rotation in the system.
+ * @param shouldUseCamera
+ * Whether should use camera signal to resolver rotation.
+ * @param timeoutMillis
+ * The timeout of the request.
*/
- public RotationResolutionRequest(int proposedRotation, int currentRotation,
- @NonNull String packageName, long timeoutMillis) {
- mProposedRotation = proposedRotation;
- mCurrentRotation = currentRotation;
- mPackageName = packageName;
- mTimeoutMillis = timeoutMillis;
+ @DataClass.Generated.Member
+ public RotationResolutionRequest(
+ @NonNull String packageName,
+ @Surface.Rotation int currentRotation,
+ @Surface.Rotation int proposedRotation,
+ boolean shouldUseCamera,
+ @DurationMillisLong long timeoutMillis) {
+ this.mPackageName = packageName;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mPackageName);
+ this.mCurrentRotation = currentRotation;
+ com.android.internal.util.AnnotationValidations.validate(
+ Surface.Rotation.class, null, mCurrentRotation);
+ this.mProposedRotation = proposedRotation;
+ com.android.internal.util.AnnotationValidations.validate(
+ Surface.Rotation.class, null, mProposedRotation);
+ this.mShouldUseCamera = shouldUseCamera;
+ this.mTimeoutMillis = timeoutMillis;
+ com.android.internal.util.AnnotationValidations.validate(
+ DurationMillisLong.class, null, mTimeoutMillis);
+
+ // onConstructed(); // You can define this method to get a callback
}
- @Surface.Rotation public int getProposedRotation() {
- return mProposedRotation;
- }
-
- public int getCurrentRotation() {
- return mCurrentRotation;
- }
-
+ /**
+ * The Name of the package of the current fore-ground activity.
+ */
+ @DataClass.Generated.Member
public @NonNull String getPackageName() {
return mPackageName;
}
- public long getTimeoutMillis() {
+ /**
+ * The current rotation of the screen.
+ */
+ @DataClass.Generated.Member
+ public @Surface.Rotation int getCurrentRotation() {
+ return mCurrentRotation;
+ }
+
+ /**
+ * The proposed screen rotation in the system.
+ */
+ @DataClass.Generated.Member
+ public @Surface.Rotation int getProposedRotation() {
+ return mProposedRotation;
+ }
+
+ /**
+ * Whether should use camera signal to resolver rotation.
+ */
+ @DataClass.Generated.Member
+ public boolean shouldUseCamera() {
+ return mShouldUseCamera;
+ }
+
+ /**
+ * The timeout of the request.
+ */
+ @DataClass.Generated.Member
+ public @DurationMillisLong long getTimeoutMillis() {
return mTimeoutMillis;
}
@Override
- public int describeContents() {
- return 0;
+ @DataClass.Generated.Member
+ public String toString() {
+ // You can override field toString logic by defining methods like:
+ // String fieldNameToString() { ... }
+
+ return "RotationResolutionRequest { " +
+ "packageName = " + mPackageName + ", " +
+ "currentRotation = " + mCurrentRotation + ", " +
+ "proposedRotation = " + mProposedRotation + ", " +
+ "shouldUseCamera = " + mShouldUseCamera + ", " +
+ "timeoutMillis = " + mTimeoutMillis +
+ " }";
}
@Override
- public void writeToParcel(@NonNull Parcel parcel, int flags) {
- parcel.writeInt(mProposedRotation);
- parcel.writeInt(mCurrentRotation);
- parcel.writeString(mPackageName);
- parcel.writeLong(mTimeoutMillis);
+ @DataClass.Generated.Member
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ // You can override field parcelling by defining methods like:
+ // void parcelFieldName(Parcel dest, int flags) { ... }
+
+ byte flg = 0;
+ if (mShouldUseCamera) flg |= 0x8;
+ dest.writeByte(flg);
+ dest.writeString(mPackageName);
+ dest.writeInt(mCurrentRotation);
+ dest.writeInt(mProposedRotation);
+ dest.writeLong(mTimeoutMillis);
}
- public static final @NonNull Creator<RotationResolutionRequest> CREATOR =
- new Creator<RotationResolutionRequest>() {
- @Override
- public RotationResolutionRequest createFromParcel(Parcel source) {
- return new RotationResolutionRequest(source.readInt(), source.readInt(),
- source.readString(), source.readLong());
- }
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+ /** @hide */
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ @DataClass.Generated.Member
+ /* package-private */ RotationResolutionRequest(@NonNull Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ byte flg = in.readByte();
+ boolean shouldUseCamera = (flg & 0x8) != 0;
+ String packageName = in.readString();
+ int currentRotation = in.readInt();
+ int proposedRotation = in.readInt();
+ long timeoutMillis = in.readLong();
+
+ this.mPackageName = packageName;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mPackageName);
+ this.mCurrentRotation = currentRotation;
+ com.android.internal.util.AnnotationValidations.validate(
+ Surface.Rotation.class, null, mCurrentRotation);
+ this.mProposedRotation = proposedRotation;
+ com.android.internal.util.AnnotationValidations.validate(
+ Surface.Rotation.class, null, mProposedRotation);
+ this.mShouldUseCamera = shouldUseCamera;
+ this.mTimeoutMillis = timeoutMillis;
+ com.android.internal.util.AnnotationValidations.validate(
+ DurationMillisLong.class, null, mTimeoutMillis);
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public static final @NonNull Parcelable.Creator<RotationResolutionRequest> CREATOR
+ = new Parcelable.Creator<RotationResolutionRequest>() {
@Override
public RotationResolutionRequest[] newArray(int size) {
return new RotationResolutionRequest[size];
}
+
+ @Override
+ public RotationResolutionRequest createFromParcel(@NonNull Parcel in) {
+ return new RotationResolutionRequest(in);
+ }
};
+
+ @DataClass.Generated(
+ time = 1615402421314L,
+ codegenVersion = "1.0.22",
+ sourceFile = "frameworks/base/core/java/android/service/rotationresolver/RotationResolutionRequest.java",
+ inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.view.Surface.Rotation int mCurrentRotation\nprivate final @android.view.Surface.Rotation int mProposedRotation\nprivate final boolean mShouldUseCamera\nprivate final @android.annotation.DurationMillisLong long mTimeoutMillis\nclass RotationResolutionRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genToString=true)")
+ @Deprecated
+ private void __metadata() {}
+
+
+ //@formatter:on
+ // End of generated code
+
}
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index c1d9d58..def13db 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -41,10 +41,12 @@
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Build;
+import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
+import android.os.SharedMemory;
import android.util.Slog;
import com.android.internal.app.IHotwordRecognitionStatusCallback;
@@ -287,6 +289,7 @@
private final Handler mHandler;
private final IBinder mBinder = new Binder();
private final int mTargetSdkVersion;
+ private final boolean mSupportHotwordDetectionService;
private int mAvailability = STATE_NOT_READY;
@@ -488,11 +491,22 @@
* @param callback A non-null Callback for receiving the recognition events.
* @param modelManagementService A service that allows management of sound models.
* @param targetSdkVersion The target SDK version.
+ * @param supportHotwordDetectionService {@code true} if hotword detection service should be
+ * triggered, otherwise {@code false}.
+ * @param options Application configuration data provided by the
+ * {@link VoiceInteractionService}. The system strips out any remotable objects or other
+ * contents that can be used to communicate with other processes.
+ * @param sharedMemory The unrestricted data blob provided by the
+ * {@link VoiceInteractionService}. Use this to provide the hotword models data or other
+ * such data to the trusted process.
+ *
* @hide
*/
public AlwaysOnHotwordDetector(String text, Locale locale, Callback callback,
KeyphraseEnrollmentInfo keyphraseEnrollmentInfo,
- IVoiceInteractionManagerService modelManagementService, int targetSdkVersion) {
+ IVoiceInteractionManagerService modelManagementService, int targetSdkVersion,
+ boolean supportHotwordDetectionService, @Nullable Bundle options,
+ @Nullable SharedMemory sharedMemory) {
mText = text;
mLocale = locale;
mKeyphraseEnrollmentInfo = keyphraseEnrollmentInfo;
@@ -501,6 +515,10 @@
mInternalCallback = new SoundTriggerListener(mHandler);
mModelManagementService = modelManagementService;
mTargetSdkVersion = targetSdkVersion;
+ mSupportHotwordDetectionService = supportHotwordDetectionService;
+ if (mSupportHotwordDetectionService) {
+ setHotwordDetectionServiceConfig(options, sharedMemory);
+ }
try {
Identity identity = new Identity();
identity.packageName = ActivityThread.currentOpPackageName();
@@ -513,6 +531,38 @@
}
/**
+ * Set configuration and pass read-only data to hotword detection service.
+ *
+ * @param options Application configuration data provided by the
+ * {@link VoiceInteractionService}. The system strips out any remotable objects or other
+ * contents that can be used to communicate with other processes.
+ * @param sharedMemory The unrestricted data blob provided by the
+ * {@link VoiceInteractionService}. Use this to provide the hotword models data or other
+ * such data to the trusted process.
+ *
+ * @throws IllegalStateException if it doesn't support hotword detection service.
+ *
+ * @hide
+ */
+ public final void setHotwordDetectionServiceConfig(@Nullable Bundle options,
+ @Nullable SharedMemory sharedMemory) {
+ if (DBG) {
+ Slog.d(TAG, "setHotwordDetectionServiceConfig()");
+ }
+ if (!mSupportHotwordDetectionService) {
+ throw new IllegalStateException(
+ "setHotwordDetectionServiceConfig called, but it doesn't support hotword"
+ + " detection service");
+ }
+
+ try {
+ mModelManagementService.setHotwordDetectionServiceConfig(options, sharedMemory);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Gets the recognition modes supported by the associated keyphrase.
*
* @see #RECOGNITION_MODE_USER_IDENTIFICATION
@@ -839,6 +889,14 @@
synchronized (mLock) {
mAvailability = STATE_INVALID;
notifyStateChangedLocked();
+
+ if (mSupportHotwordDetectionService) {
+ try {
+ mModelManagementService.shutdownHotwordDetectionService();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
}
diff --git a/core/java/android/service/voice/HotwordDetectionService.java b/core/java/android/service/voice/HotwordDetectionService.java
index 7f1c5ff..fcef26f 100644
--- a/core/java/android/service/voice/HotwordDetectionService.java
+++ b/core/java/android/service/voice/HotwordDetectionService.java
@@ -27,13 +27,17 @@
import android.app.Service;
import android.content.Intent;
import android.media.AudioFormat;
+import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
+import android.os.SharedMemory;
import android.util.Log;
+import java.util.Locale;
+
/**
* Implemented by an application that wants to offer detection for hotword. The system will
* start the service after calling {@link VoiceInteractionService#setHotwordDetectionConfig}.
@@ -76,6 +80,17 @@
timeoutMillis,
new DspHotwordDetectionCallback(callback)));
}
+
+ @Override
+ public void setConfig(Bundle options, SharedMemory sharedMemory) throws RemoteException {
+ if (DBG) {
+ Log.d(TAG, "#setConfig");
+ }
+ mHandler.sendMessage(obtainMessage(HotwordDetectionService::onUpdateState,
+ HotwordDetectionService.this,
+ options,
+ sharedMemory));
+ }
};
@CallSuper
@@ -121,6 +136,25 @@
}
/**
+ * Called when the {@link VoiceInteractionService#createAlwaysOnHotwordDetector(String, Locale,
+ * Bundle, SharedMemory, AlwaysOnHotwordDetector.Callback)} or {@link AlwaysOnHotwordDetector#
+ * setHotwordDetectionServiceConfig(Bundle, SharedMemory)} requests an update of the hotword
+ * detection parameters.
+ *
+ * @param options Application configuration data provided by the
+ * {@link VoiceInteractionService}. The system strips out any remotable objects or other
+ * contents that can be used to communicate with other processes.
+ * @param sharedMemory The unrestricted data blob provided by the
+ * {@link VoiceInteractionService}. Use this to provide the hotword models data or other
+ * such data to the trusted process.
+ *
+ * @hide
+ */
+ @SystemApi
+ public void onUpdateState(@Nullable Bundle options, @Nullable SharedMemory sharedMemory) {
+ }
+
+ /**
* Callback for returning the detected result.
*
* @hide
diff --git a/core/java/android/service/voice/IHotwordDetectionService.aidl b/core/java/android/service/voice/IHotwordDetectionService.aidl
index cbe76e4..8f0874a 100644
--- a/core/java/android/service/voice/IHotwordDetectionService.aidl
+++ b/core/java/android/service/voice/IHotwordDetectionService.aidl
@@ -17,7 +17,9 @@
package android.service.voice;
import android.media.AudioFormat;
+import android.os.Bundle;
import android.os.ParcelFileDescriptor;
+import android.os.SharedMemory;
import android.service.voice.IDspHotwordDetectionCallback;
/**
@@ -31,4 +33,6 @@
in AudioFormat audioFormat,
long timeoutMillis,
in IDspHotwordDetectionCallback callback);
+
+ void setConfig(in Bundle options, in SharedMemory sharedMemory);
}
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 25f8090..048d9f5 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -17,7 +17,6 @@
package android.service.voice;
import android.Manifest;
-import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -36,6 +35,7 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SharedMemory;
import android.provider.Settings;
import android.util.ArraySet;
import android.util.Log;
@@ -47,8 +47,6 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -73,32 +71,6 @@
static final String TAG = VoiceInteractionService.class.getSimpleName();
/**
- * Indicates that the given configs have been set successfully after calling
- * {@link VoiceInteractionService#setHotwordDetectionConfig}.
- *
- * @hide
- */
- @SystemApi
- public static final int HOTWORD_CONFIG_SUCCESS = 0;
-
- /**
- * Indicates that the given configs have been set unsuccessfully after calling
- * {@link VoiceInteractionService#setHotwordDetectionConfig}.
- *
- * @hide
- */
- @SystemApi
- public static final int HOTWORD_CONFIG_FAILURE = 1;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, prefix = { "HOTWORD_CONFIG_" }, value = {
- HOTWORD_CONFIG_SUCCESS,
- HOTWORD_CONFIG_FAILURE,
- })
- public @interface HotwordConfigResult {}
-
- /**
* The {@link Intent} that must be declared as handled by the service.
* To be supported, the service must also require the
* {@link android.Manifest.permission#BIND_VOICE_INTERACTION} permission so
@@ -330,35 +302,6 @@
}
/**
- * Set hotword detection configuration.
- *
- * Note: Currently it will trigger hotword detection service after calling this function when
- * all conditions meet the requirements.
- *
- * @param options Config data.
- * @return {@link VoiceInteractionService#HOTWORD_CONFIG_SUCCESS} in case of success,
- * {@link VoiceInteractionService#HOTWORD_CONFIG_FAILURE} in case of failure.
- *
- * @throws IllegalStateException if the function is called before onReady() is called.
- *
- * @hide
- */
- @SystemApi
- @HotwordConfigResult
- public final int setHotwordDetectionConfig(
- @SuppressLint("NullableCollection") @Nullable Bundle options) {
- if (mSystemService == null) {
- throw new IllegalStateException("Not available until onReady() is called");
- }
-
- try {
- return mSystemService.setHotwordDetectionConfig(options);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
* Creates an {@link AlwaysOnHotwordDetector} for the given keyphrase and locale.
* This instance must be retained and used by the client.
* Calling this a second time invalidates the previously created hotword detector
@@ -374,9 +317,61 @@
@SystemApi
@NonNull
public final AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(
- @SuppressLint("MissingNullability") String keyphrase, // TODO: annotate nullability properly
+ @SuppressLint("MissingNullability") String keyphrase, // TODO: nullability properly
@SuppressLint({"MissingNullability", "UseIcu"}) Locale locale,
@SuppressLint("MissingNullability") AlwaysOnHotwordDetector.Callback callback) {
+ return createAlwaysOnHotwordDetectorInternal(keyphrase, locale,
+ /* supportHotwordDetectionService= */ false, /* options= */ null,
+ /* sharedMemory= */ null, callback);
+ }
+
+ /**
+ * Create an {@link AlwaysOnHotwordDetector} and trigger a {@link HotwordDetectionService}
+ * service, then it will also pass the read-only data to hotword detection service.
+ *
+ * Like {@see #createAlwaysOnHotwordDetector(String, Locale, AlwaysOnHotwordDetector.Callback)
+ * }. Before calling this function, you should set a valid hotword detection service with
+ * android:hotwordDetectionService in an android.voice_interaction metadata file and set
+ * android:isolatedProcess="true" in the AndroidManifest.xml of hotword detection service.
+ * Otherwise it will throw IllegalStateException. After calling this function, the system will
+ * also trigger a hotword detection service and pass the read-only data back to it.
+ *
+ * <p>Note: The system will trigger hotword detection service after calling this function when
+ * all conditions meet the requirements.
+ *
+ * @param keyphrase The keyphrase that's being used, for example "Hello Android".
+ * @param locale The locale for which the enrollment needs to be performed.
+ * @param options Application configuration data provided by the
+ * {@link VoiceInteractionService}. The system strips out any remotable objects or other
+ * contents that can be used to communicate with other processes.
+ * @param sharedMemory The unrestricted data blob provided by the
+ * {@link VoiceInteractionService}. Use this to provide the hotword models data or other
+ * such data to the trusted process.
+ * @param callback The callback to notify of detection events.
+ * @return An always-on hotword detector for the given keyphrase and locale.
+ *
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ public final AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(
+ @SuppressLint("MissingNullability") String keyphrase, // TODO: nullability properly
+ @SuppressLint({"MissingNullability", "UseIcu"}) Locale locale,
+ @Nullable Bundle options,
+ @Nullable SharedMemory sharedMemory,
+ @SuppressLint("MissingNullability") AlwaysOnHotwordDetector.Callback callback) {
+ return createAlwaysOnHotwordDetectorInternal(keyphrase, locale,
+ /* supportHotwordDetectionService= */ true, options,
+ sharedMemory, callback);
+ }
+
+ private AlwaysOnHotwordDetector createAlwaysOnHotwordDetectorInternal(
+ @SuppressLint("MissingNullability") String keyphrase, // TODO: nullability properly
+ @SuppressLint({"MissingNullability", "UseIcu"}) Locale locale,
+ boolean supportHotwordDetectionService,
+ @Nullable Bundle options,
+ @Nullable SharedMemory sharedMemory,
+ @SuppressLint("MissingNullability") AlwaysOnHotwordDetector.Callback callback) {
if (mSystemService == null) {
throw new IllegalStateException("Not available until onReady() is called");
}
@@ -385,7 +380,8 @@
safelyShutdownHotwordDetector();
mHotwordDetector = new AlwaysOnHotwordDetector(keyphrase, locale, callback,
mKeyphraseEnrollmentInfo, mSystemService,
- getApplicationContext().getApplicationInfo().targetSdkVersion);
+ getApplicationContext().getApplicationInfo().targetSdkVersion,
+ supportHotwordDetectionService, options, sharedMemory);
}
return mHotwordDetector;
}
@@ -432,7 +428,6 @@
}
private void safelyShutdownHotwordDetector() {
- // TODO (b/178171906): Need to check if the HotwordDetectionService should be unbound.
synchronized (mLock) {
if (mHotwordDetector == null) {
return;
diff --git a/core/java/android/speech/IRecognitionServiceManager.aidl b/core/java/android/speech/IRecognitionServiceManager.aidl
index 8e5292d..ad40226 100644
--- a/core/java/android/speech/IRecognitionServiceManager.aidl
+++ b/core/java/android/speech/IRecognitionServiceManager.aidl
@@ -31,4 +31,6 @@
in IBinder clientToken,
boolean onDevice,
in IRecognitionServiceManagerCallback callback);
+
+ void setTemporaryComponent(in ComponentName componentName);
}
diff --git a/core/java/android/speech/SpeechRecognizer.java b/core/java/android/speech/SpeechRecognizer.java
index 850f997..9b93a64 100644
--- a/core/java/android/speech/SpeechRecognizer.java
+++ b/core/java/android/speech/SpeechRecognizer.java
@@ -17,6 +17,8 @@
package android.speech;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -35,6 +37,8 @@
import android.util.Slog;
import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.LinkedBlockingQueue;
/**
* This class provides access to the speech recognition service. This service allows access to the
@@ -52,7 +56,7 @@
*/
public class SpeechRecognizer {
/** DEBUG value to enable verbose debug prints */
- private final static boolean DBG = false;
+ private static final boolean DBG = false;
/** Log messages identifier */
private static final String TAG = "SpeechRecognizer";
@@ -113,10 +117,11 @@
public static final int ERROR_SERVER_DISCONNECTED = 11;
/** action codes */
- private final static int MSG_START = 1;
- private final static int MSG_STOP = 2;
- private final static int MSG_CANCEL = 3;
- private final static int MSG_CHANGE_LISTENER = 4;
+ private static final int MSG_START = 1;
+ private static final int MSG_STOP = 2;
+ private static final int MSG_CANCEL = 3;
+ private static final int MSG_CHANGE_LISTENER = 4;
+ private static final int MSG_SET_TEMPORARY_ON_DEVICE_COMPONENT = 5;
/** The actual RecognitionService endpoint */
private IRecognitionService mService;
@@ -134,6 +139,7 @@
/** Handler that will execute the main tasks */
private Handler mHandler = new Handler(Looper.getMainLooper()) {
+
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
@@ -149,10 +155,19 @@
case MSG_CHANGE_LISTENER:
handleChangeListener((RecognitionListener) msg.obj);
break;
+ case MSG_SET_TEMPORARY_ON_DEVICE_COMPONENT:
+ handleSetTemporaryComponent((ComponentName) msg.obj);
+ break;
}
}
};
+ /**
+ * Temporary queue, saving the messages until the connection will be established, afterwards,
+ * only mHandler will receive the messages
+ */
+ private final Queue<Message> mPendingTasks = new LinkedBlockingQueue<>();
+
/** The Listener that will receive all the callbacks */
private final InternalListener mListener = new InternalListener();
@@ -287,11 +302,9 @@
if (mService == null) {
// First time connection: first establish a connection, then dispatch #startListening.
- connectToSystemService(
- () -> putMessage(Message.obtain(mHandler, MSG_START, recognizerIntent)));
- } else {
- putMessage(Message.obtain(mHandler, MSG_START, recognizerIntent));
+ connectToSystemService();
}
+ putMessage(Message.obtain(mHandler, MSG_START, recognizerIntent));
}
/**
@@ -336,6 +349,22 @@
putMessage(Message.obtain(mHandler, MSG_CANCEL));
}
+ /**
+ * Sets a temporary component to power on-device speech recognizer.
+ *
+ * <p>This is only expected to be called in tests, system would reject calls from client apps.
+ *
+ * @param componentName name of the component to set temporary replace speech recognizer. {@code
+ * null} value resets the recognizer to default.
+ *
+ * @hide
+ */
+ @TestApi
+ public void setTemporaryOnDeviceRecognizer(@Nullable ComponentName componentName) {
+ mHandler.sendMessage(
+ Message.obtain(mHandler, MSG_SET_TEMPORARY_ON_DEVICE_COMPONENT, componentName));
+ }
+
private static void checkIsCalledFromMainThread() {
if (Looper.myLooper() != Looper.getMainLooper()) {
throw new RuntimeException(
@@ -344,7 +373,11 @@
}
private void putMessage(Message msg) {
- mHandler.sendMessage(msg);
+ if (mService == null) {
+ mPendingTasks.offer(msg);
+ } else {
+ mHandler.sendMessage(msg);
+ }
}
/** sends the actual message to the service */
@@ -395,6 +428,22 @@
}
}
+ private void handleSetTemporaryComponent(ComponentName componentName) {
+ if (DBG) {
+ Log.d(TAG, "handleSetTemporaryComponent, componentName=" + componentName);
+ }
+
+ if (!maybeInitializeManagerService()) {
+ return;
+ }
+
+ try {
+ mManagerService.setTemporaryComponent(componentName);
+ } catch (final RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
private boolean checkOpenConnection() {
if (mService != null) {
return true;
@@ -422,16 +471,13 @@
}
mService = null;
+ mPendingTasks.clear();
mListener.mInternalListener = null;
}
/** Establishes a connection to system server proxy and initializes the session. */
- private void connectToSystemService(Runnable onSuccess) {
- mManagerService = IRecognitionServiceManager.Stub.asInterface(
- ServiceManager.getService(Context.SPEECH_RECOGNITION_SERVICE));
-
- if (mManagerService == null) {
- mListener.onError(ERROR_CLIENT);
+ private void connectToSystemService() {
+ if (!maybeInitializeManagerService()) {
return;
}
@@ -450,13 +496,19 @@
new IRecognitionServiceManagerCallback.Stub(){
@Override
public void onSuccess(IRecognitionService service) throws RemoteException {
+ if (DBG) {
+ Log.i(TAG, "Connected to speech recognition service");
+ }
mService = service;
- onSuccess.run();
+ while (!mPendingTasks.isEmpty()) {
+ mHandler.sendMessage(mPendingTasks.poll());
+ }
}
@Override
public void onError(int errorCode) throws RemoteException {
- Log.e(TAG, "Bind to system recognition service failed");
+ Log.e(TAG, "Bind to system recognition service failed with error "
+ + errorCode);
mListener.onError(errorCode);
}
});
@@ -465,6 +517,21 @@
}
}
+ private boolean maybeInitializeManagerService() {
+ if (mManagerService != null) {
+ return true;
+ }
+
+ mManagerService = IRecognitionServiceManager.Stub.asInterface(
+ ServiceManager.getService(Context.SPEECH_RECOGNITION_SERVICE));
+
+ if (mManagerService == null && mListener != null) {
+ mListener.onError(ERROR_CLIENT);
+ return false;
+ }
+ return true;
+ }
+
/**
* Returns the component name to be used for establishing a connection, based on the parameters
* used during initialization.
@@ -505,15 +572,15 @@
private static class InternalListener extends IRecognitionListener.Stub {
private RecognitionListener mInternalListener;
- private final static int MSG_BEGINNING_OF_SPEECH = 1;
- private final static int MSG_BUFFER_RECEIVED = 2;
- private final static int MSG_END_OF_SPEECH = 3;
- private final static int MSG_ERROR = 4;
- private final static int MSG_READY_FOR_SPEECH = 5;
- private final static int MSG_RESULTS = 6;
- private final static int MSG_PARTIAL_RESULTS = 7;
- private final static int MSG_RMS_CHANGED = 8;
- private final static int MSG_ON_EVENT = 9;
+ private static final int MSG_BEGINNING_OF_SPEECH = 1;
+ private static final int MSG_BUFFER_RECEIVED = 2;
+ private static final int MSG_END_OF_SPEECH = 3;
+ private static final int MSG_ERROR = 4;
+ private static final int MSG_READY_FOR_SPEECH = 5;
+ private static final int MSG_RESULTS = 6;
+ private static final int MSG_PARTIAL_RESULTS = 7;
+ private static final int MSG_RMS_CHANGED = 8;
+ private static final int MSG_ON_EVENT = 9;
private final Handler mInternalHandler = new Handler(Looper.getMainLooper()) {
@Override
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index e37921e..bbe887f 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -1326,7 +1326,7 @@
() -> mExecutor.execute(() -> psl.onCellLocationChanged(location)));
}
- public void onCallStateChanged(int state, String incomingNumber) {
+ public void onLegacyCallStateChanged(int state, String incomingNumber) {
PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
if (psl == null) return;
@@ -1334,6 +1334,10 @@
() -> mExecutor.execute(() -> psl.onCallStateChanged(state, incomingNumber)));
}
+ public void onCallStateChanged(int state) {
+ // Only used for the new TelephonyCallback class
+ }
+
public void onDataConnectionStateChanged(int state, int networkType) {
PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
if (psl == null) return;
diff --git a/core/java/android/telephony/TelephonyCallback.java b/core/java/android/telephony/TelephonyCallback.java
index a2584cae..2cadda2 100644
--- a/core/java/android/telephony/TelephonyCallback.java
+++ b/core/java/android/telephony/TelephonyCallback.java
@@ -20,11 +20,9 @@
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.compat.annotation.ChangeId;
-import android.compat.annotation.UnsupportedAppUsage;
import android.os.Binder;
import android.os.Build;
import android.telephony.emergency.EmergencyNumber;
@@ -170,12 +168,15 @@
/**
* Event for changes to the device call state.
- *
+ * <p>
+ * Handles callbacks to {@link CallStateListener#onCallStateChanged(int)}.
+ * <p>
+ * Note: This is different from the legacy {@link #EVENT_LEGACY_CALL_STATE_CHANGED} listener
+ * which can include the phone number of the caller. We purposely do not include the phone
+ * number as that information is not required for call state listeners going forward.
* @hide
- * @see CallStateListener#onCallStateChanged
*/
@SystemApi
- @RequiresPermission(android.Manifest.permission.READ_CALL_LOG)
public static final int EVENT_CALL_STATE_CHANGED = 6;
/**
@@ -556,6 +557,18 @@
public static final int EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED = 35;
/**
+ * Event for changes to the legacy call state changed listener implemented by
+ * {@link PhoneStateListener#onCallStateChanged(int, String)}. This listener variant is similar
+ * to the new {@link CallStateListener#onCallStateChanged(int)} with the important distinction
+ * that it CAN provide the phone number associated with a call.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_CALL_LOG)
+ public static final int EVENT_LEGACY_CALL_STATE_CHANGED = 36;
+
+ /**
* @hide
*/
@IntDef(prefix = {"EVENT_"}, value = {
@@ -593,7 +606,8 @@
EVENT_BARRING_INFO_CHANGED,
EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED,
EVENT_DATA_ENABLED_CHANGED,
- EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED
+ EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED,
+ EVENT_LEGACY_CALL_STATE_CHANGED
})
@Retention(RetentionPolicy.SOURCE)
public @interface TelephonyEvent {
@@ -723,17 +737,9 @@
* calling {@link TelephonyManager#getCallState()} from within this callback may return a
* different state than the callback reports.
*
- * @param state call state
- * @param phoneNumber call phone number. If application does not have
- * {@link android.Manifest.permission#READ_CALL_LOG} permission or
- * carrier
- * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an
- * empty string will be
- * passed as an argument.
+ * @param state the current call state
*/
- @RequiresPermission(android.Manifest.permission.READ_CALL_LOG)
- public void onCallStateChanged(@Annotation.CallState int state,
- @Nullable String phoneNumber);
+ public void onCallStateChanged(@Annotation.CallState int state);
}
/**
@@ -1426,13 +1432,17 @@
() -> mExecutor.execute(() -> listener.onCellLocationChanged(location)));
}
- public void onCallStateChanged(int state, String incomingNumber) {
+ public void onLegacyCallStateChanged(int state, String incomingNumber) {
+ // Not used for TelephonyCallback; part of the AIDL which is used by both the legacy
+ // PhoneStateListener and TelephonyCallback.
+ }
+
+ public void onCallStateChanged(int state) {
CallStateListener listener = (CallStateListener) mTelephonyCallbackWeakRef.get();
if (listener == null) return;
Binder.withCleanCallingIdentity(
- () -> mExecutor.execute(() -> listener.onCallStateChanged(state,
- incomingNumber)));
+ () -> mExecutor.execute(() -> listener.onCallStateChanged(state)));
}
public void onDataConnectionStateChanged(int state, int networkType) {
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 459c6e9..9cda4ae 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -861,6 +861,7 @@
eventList.add(TelephonyCallback.EVENT_CELL_LOCATION_CHANGED);
}
+ // Note: Legacy PhoneStateListeners use EVENT_LEGACY_CALL_STATE_CHANGED
if (telephonyCallback instanceof TelephonyCallback.CallStateListener) {
eventList.add(TelephonyCallback.EVENT_CALL_STATE_CHANGED);
}
@@ -1000,8 +1001,10 @@
eventList.add(TelephonyCallback.EVENT_CELL_LOCATION_CHANGED);
}
+ // Note: Legacy call state listeners can get the phone number which is not provided in the
+ // new version in TelephonyCallback.
if ((eventMask & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
- eventList.add(TelephonyCallback.EVENT_CALL_STATE_CHANGED);
+ eventList.add(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED);
}
if ((eventMask & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 4d321079..919c6e5 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -39,7 +39,6 @@
public static final String FFLAG_OVERRIDE_PREFIX = FFLAG_PREFIX + "override.";
public static final String PERSIST_PREFIX = "persist." + FFLAG_OVERRIDE_PREFIX;
public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
- public static final String SCREENRECORD_LONG_PRESS = "settings_screenrecord_long_press";
public static final String SETTINGS_WIFITRACKER2 = "settings_wifitracker2";
/** @hide */
public static final String SETTINGS_DO_NOT_RESTORE_PRESERVED =
@@ -59,7 +58,6 @@
DEFAULT_FLAGS.put("settings_audio_switcher", "true");
DEFAULT_FLAGS.put("settings_systemui_theme", "true");
DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
- DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
DEFAULT_FLAGS.put("settings_wifi_details_datausage_header", "false");
DEFAULT_FLAGS.put("settings_skip_direction_mutable", "true");
DEFAULT_FLAGS.put(SETTINGS_WIFITRACKER2, "true");
diff --git a/core/java/android/uwb/AngleMeasurement.java b/core/java/android/uwb/AngleMeasurement.java
index 9df213b..8c771ba 100644
--- a/core/java/android/uwb/AngleMeasurement.java
+++ b/core/java/android/uwb/AngleMeasurement.java
@@ -38,9 +38,30 @@
private final double mErrorRadians;
private final double mConfidenceLevel;
- private AngleMeasurement(double radians, double errorRadians, double confidenceLevel) {
+ /**
+ * Constructs a new {@link AngleMeasurement} object
+ *
+ * @param radians the angle in radians
+ * @param errorRadians the error of the angle measurement in radians
+ * @param confidenceLevel confidence level of the angle measurement
+ *
+ * @throws IllegalArgumentException if the radians, errorRadians, or confidenceLevel is out of
+ * allowed range
+ */
+ public AngleMeasurement(double radians, double errorRadians, double confidenceLevel) {
+ if (radians < -Math.PI || radians > Math.PI) {
+ throw new IllegalArgumentException("Invalid radians: " + radians);
+ }
mRadians = radians;
+
+ if (errorRadians < 0.0 || errorRadians > Math.PI) {
+ throw new IllegalArgumentException("Invalid error radians: " + errorRadians);
+ }
mErrorRadians = errorRadians;
+
+ if (confidenceLevel < 0.0 || confidenceLevel > 1.0) {
+ throw new IllegalArgumentException("Invalid confidence level: " + confidenceLevel);
+ }
mConfidenceLevel = confidenceLevel;
}
@@ -122,11 +143,7 @@
new Creator<AngleMeasurement>() {
@Override
public AngleMeasurement createFromParcel(Parcel in) {
- Builder builder = new Builder();
- builder.setRadians(in.readDouble());
- builder.setErrorRadians(in.readDouble());
- builder.setConfidenceLevel(in.readDouble());
- return builder.build();
+ return new AngleMeasurement(in.readDouble(), in.readDouble(), in.readDouble());
}
@Override
@@ -134,82 +151,4 @@
return new AngleMeasurement[size];
}
};
-
- /**
- * Builder class for {@link AngleMeasurement}.
- */
- public static final class Builder {
- private double mRadians = Double.NaN;
- private double mErrorRadians = Double.NaN;
- private double mConfidenceLevel = Double.NaN;
-
- /**
- * Set the angle in radians
- *
- * @param radians angle in radians
- * @throws IllegalArgumentException if angle exceeds allowed limits of [-Math.PI, +Math.PI]
- */
- @NonNull
- public Builder setRadians(double radians) {
- if (radians < -Math.PI || radians > Math.PI) {
- throw new IllegalArgumentException("Invalid radians: " + radians);
- }
- mRadians = radians;
- return this;
- }
-
- /**
- * Set the angle error in radians
- *
- * @param errorRadians error of the angle in radians
- * @throws IllegalArgumentException if the error exceeds the allowed limits of [0, +Math.PI]
- */
- @NonNull
- public Builder setErrorRadians(double errorRadians) {
- if (errorRadians < 0.0 || errorRadians > Math.PI) {
- throw new IllegalArgumentException(
- "Invalid error radians: " + errorRadians);
- }
- mErrorRadians = errorRadians;
- return this;
- }
-
- /**
- * Set the angle confidence level
- *
- * @param confidenceLevel level of confidence of the angle measurement
- * @throws IllegalArgumentException if the error exceeds the allowed limits of [0.0, 1.0]
- */
- @NonNull
- public Builder setConfidenceLevel(double confidenceLevel) {
- if (confidenceLevel < 0.0 || confidenceLevel > 1.0) {
- throw new IllegalArgumentException(
- "Invalid confidence level: " + confidenceLevel);
- }
- mConfidenceLevel = confidenceLevel;
- return this;
- }
-
- /**
- * Build the {@link AngleMeasurement} object
- *
- * @throws IllegalStateException if angle, error, or confidence values are missing
- */
- @NonNull
- public AngleMeasurement build() {
- if (Double.isNaN(mRadians)) {
- throw new IllegalStateException("Angle is not set");
- }
-
- if (Double.isNaN(mErrorRadians)) {
- throw new IllegalStateException("Angle error is not set");
- }
-
- if (Double.isNaN(mConfidenceLevel)) {
- throw new IllegalStateException("Angle confidence level is not set");
- }
-
- return new AngleMeasurement(mRadians, mErrorRadians, mConfidenceLevel);
- }
- }
}
diff --git a/core/java/android/uwb/AngleOfArrivalMeasurement.java b/core/java/android/uwb/AngleOfArrivalMeasurement.java
index 3d8626b..db04ad1 100644
--- a/core/java/android/uwb/AngleOfArrivalMeasurement.java
+++ b/core/java/android/uwb/AngleOfArrivalMeasurement.java
@@ -116,9 +116,8 @@
new Creator<AngleOfArrivalMeasurement>() {
@Override
public AngleOfArrivalMeasurement createFromParcel(Parcel in) {
- Builder builder = new Builder();
-
- builder.setAzimuth(in.readParcelable(AngleMeasurement.class.getClassLoader()));
+ Builder builder =
+ new Builder(in.readParcelable(AngleMeasurement.class.getClassLoader()));
builder.setAltitude(in.readParcelable(AngleMeasurement.class.getClassLoader()));
@@ -135,18 +134,16 @@
* Builder class for {@link AngleOfArrivalMeasurement}.
*/
public static final class Builder {
- private AngleMeasurement mAzimuthAngleMeasurement = null;
+ private final AngleMeasurement mAzimuthAngleMeasurement;
private AngleMeasurement mAltitudeAngleMeasurement = null;
/**
- * Set the azimuth angle
+ * Constructs an {@link AngleOfArrivalMeasurement} object
*
- * @param azimuthAngle azimuth angle
+ * @param azimuthAngle the azimuth angle of the measurement
*/
- @NonNull
- public Builder setAzimuth(@NonNull AngleMeasurement azimuthAngle) {
+ public Builder(@NonNull AngleMeasurement azimuthAngle) {
mAzimuthAngleMeasurement = azimuthAngle;
- return this;
}
/**
@@ -162,15 +159,9 @@
/**
* Build the {@link AngleOfArrivalMeasurement} object
- *
- * @throws IllegalStateException if the required azimuth angle is not provided
*/
@NonNull
public AngleOfArrivalMeasurement build() {
- if (mAzimuthAngleMeasurement == null) {
- throw new IllegalStateException("Azimuth angle measurement is not set");
- }
-
return new AngleOfArrivalMeasurement(mAzimuthAngleMeasurement,
mAltitudeAngleMeasurement);
}
diff --git a/core/java/android/uwb/IUwbAdapter.aidl b/core/java/android/uwb/IUwbAdapter.aidl
index 468a69c..4036892 100644
--- a/core/java/android/uwb/IUwbAdapter.aidl
+++ b/core/java/android/uwb/IUwbAdapter.aidl
@@ -62,9 +62,6 @@
/**
* Request to open a new ranging session
*
- * This function must return before calling any functions in
- * IUwbAdapterCallbacks.
- *
* This function does not start the ranging session, but all necessary
* components must be initialized and ready to start a new ranging
* session prior to calling IUwbAdapterCallback#onRangingOpened.
@@ -77,12 +74,16 @@
* RANGING_SESSION_OPEN_THRESHOLD_MS milliseconds of #openRanging being called
* if the ranging session fails to be opened.
*
+ * If the provided sessionHandle is already open for the calling client, then
+ * #onRangingOpenFailed must be called and the new session must not be opened.
+ *
+ * @param sessionHandle the session handle to open ranging for
* @param rangingCallbacks the callbacks used to deliver ranging information
* @param parameters the configuration to use for ranging
- * @return a SessionHandle used to identify this ranging request
*/
- SessionHandle openRanging(in IUwbRangingCallbacks rangingCallbacks,
- in PersistableBundle parameters);
+ void openRanging(in SessionHandle sessionHandle,
+ in IUwbRangingCallbacks rangingCallbacks,
+ in PersistableBundle parameters);
/**
* Request to start ranging
diff --git a/core/java/android/uwb/RangingManager.java b/core/java/android/uwb/RangingManager.java
index c0d8187..85f2c1c 100644
--- a/core/java/android/uwb/RangingManager.java
+++ b/core/java/android/uwb/RangingManager.java
@@ -17,6 +17,7 @@
package android.uwb;
import android.annotation.NonNull;
+import android.os.CancellationSignal;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.util.Log;
@@ -32,6 +33,7 @@
private final IUwbAdapter mAdapter;
private final Hashtable<SessionHandle, RangingSession> mRangingSessionTable = new Hashtable<>();
+ private int mNextSessionId = 1;
public RangingManager(IUwbAdapter adapter) {
mAdapter = adapter;
@@ -44,29 +46,26 @@
* @param executor {@link Executor} to run callbacks
* @param callbacks {@link RangingSession.Callback} to associate with the {@link RangingSession}
* that is being opened.
- * @return a new {@link RangingSession}
+ * @return a {@link CancellationSignal} that may be used to cancel the opening of the
+ * {@link RangingSession}.
*/
- public RangingSession openSession(@NonNull PersistableBundle params, @NonNull Executor executor,
+ public CancellationSignal openSession(@NonNull PersistableBundle params,
+ @NonNull Executor executor,
@NonNull RangingSession.Callback callbacks) {
- SessionHandle sessionHandle;
- try {
- sessionHandle = mAdapter.openRanging(this, params);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
synchronized (this) {
- if (hasSession(sessionHandle)) {
- Log.w(TAG, "Newly created session unexpectedly reuses an active SessionHandle");
- executor.execute(() -> callbacks.onClosed(
- RangingSession.Callback.REASON_GENERIC_ERROR,
- new PersistableBundle()));
- }
-
+ SessionHandle sessionHandle = new SessionHandle(mNextSessionId++);
RangingSession session =
new RangingSession(executor, callbacks, mAdapter, sessionHandle);
mRangingSessionTable.put(sessionHandle, session);
- return session;
+ try {
+ mAdapter.openRanging(sessionHandle, this, params);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ CancellationSignal cancellationSignal = new CancellationSignal();
+ cancellationSignal.setOnCancelListener(() -> session.close());
+ return cancellationSignal;
}
}
diff --git a/core/java/android/uwb/UwbManager.java b/core/java/android/uwb/UwbManager.java
index 63a6d05..844bbbe 100644
--- a/core/java/android/uwb/UwbManager.java
+++ b/core/java/android/uwb/UwbManager.java
@@ -25,6 +25,7 @@
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
+import android.os.CancellationSignal;
import android.os.IBinder;
import android.os.PersistableBundle;
import android.os.RemoteException;
@@ -228,14 +229,14 @@
* @param callbacks {@link RangingSession.Callback} to associate with the
* {@link RangingSession} that is being opened.
*
- * @return an {@link AutoCloseable} that is able to be used to close or cancel the opening of a
+ * @return an {@link CancellationSignal} that is able to be used to cancel the opening of a
* {@link RangingSession} that has been requested through {@link #openRangingSession}
* but has not yet been made available by
* {@link RangingSession.Callback#onOpened(RangingSession)}.
*/
@NonNull
@RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
- public AutoCloseable openRangingSession(@NonNull PersistableBundle parameters,
+ public CancellationSignal openRangingSession(@NonNull PersistableBundle parameters,
@NonNull @CallbackExecutor Executor executor,
@NonNull RangingSession.Callback callbacks) {
return mRangingManager.openSession(parameters, executor, callbacks);
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index d138b4b..d484f4d4 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -24,8 +24,11 @@
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.TestApi;
+import android.app.ActivityThread;
import android.app.KeyguardManager;
+import android.app.WindowConfiguration;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -44,11 +47,14 @@
import android.util.DisplayMetrics;
import android.util.Log;
+import com.android.internal.R;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Optional;
/**
* Provides information about the size and density of a logical display.
@@ -78,6 +84,7 @@
private static final String TAG = "Display";
private static final boolean DEBUG = false;
+ private final Object mLock = new Object();
private final DisplayManagerGlobal mGlobal;
private final int mDisplayId;
private final int mFlags;
@@ -112,6 +119,12 @@
private boolean mMayAdjustByFixedRotation;
/**
+ * Cache if the application is the recents component.
+ * TODO(b/179308296) Remove once Launcher addresses issue
+ */
+ private Optional<Boolean> mIsRecentsComponent = Optional.empty();
+
+ /**
* The default Display id, which is the id of the primary display assuming there is one.
*/
public static final int DEFAULT_DISPLAY = 0;
@@ -557,7 +570,7 @@
* @return True if the display is still valid.
*/
public boolean isValid() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mIsValid;
}
@@ -572,7 +585,7 @@
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public boolean getDisplayInfo(DisplayInfo outDisplayInfo) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
outDisplayInfo.copyFrom(mDisplayInfo);
return mIsValid;
@@ -589,7 +602,7 @@
* @hide
*/
public int getLayerStack() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.layerStack;
}
@@ -636,7 +649,7 @@
* @hide
*/
public DisplayAddress getAddress() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.address;
}
@@ -678,9 +691,9 @@
@UnsupportedAppUsage
public DisplayAdjustments getDisplayAdjustments() {
if (mResources != null) {
- final DisplayAdjustments currentAdjustements = mResources.getDisplayAdjustments();
- if (!mDisplayAdjustments.equals(currentAdjustements)) {
- mDisplayAdjustments = new DisplayAdjustments(currentAdjustements);
+ final DisplayAdjustments currentAdjustments = mResources.getDisplayAdjustments();
+ if (!mDisplayAdjustments.equals(currentAdjustments)) {
+ mDisplayAdjustments = new DisplayAdjustments(currentAdjustments);
}
}
@@ -696,7 +709,7 @@
* @return The display's name.
*/
public String getName() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.name;
}
@@ -709,7 +722,7 @@
* @hide
*/
public float getBrightnessDefault() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.brightnessDefault;
}
@@ -748,7 +761,7 @@
*/
@Deprecated
public void getSize(Point outSize) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
mDisplayInfo.getAppMetrics(mTempMetrics, getDisplayAdjustments());
outSize.x = mTempMetrics.widthPixels;
@@ -765,7 +778,7 @@
*/
@Deprecated
public void getRectSize(Rect outSize) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
mDisplayInfo.getAppMetrics(mTempMetrics, getDisplayAdjustments());
outSize.set(0, 0, mTempMetrics.widthPixels, mTempMetrics.heightPixels);
@@ -803,7 +816,7 @@
* for example, screen decorations like the status bar are being hidden.
*/
public void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
outSmallestSize.x = mDisplayInfo.smallestNominalAppWidth;
outSmallestSize.y = mDisplayInfo.smallestNominalAppHeight;
@@ -819,7 +832,7 @@
*/
@UnsupportedAppUsage
public int getMaximumSizeDimension() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return Math.max(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
}
@@ -830,7 +843,7 @@
*/
@Deprecated
public int getWidth() {
- synchronized (this) {
+ synchronized (mLock) {
updateCachedAppSizeIfNeededLocked();
return mCachedAppWidthCompat;
}
@@ -841,7 +854,7 @@
*/
@Deprecated
public int getHeight() {
- synchronized (this) {
+ synchronized (mLock) {
updateCachedAppSizeIfNeededLocked();
return mCachedAppHeightCompat;
}
@@ -866,7 +879,7 @@
*/
@Surface.Rotation
public int getRotation() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mMayAdjustByFixedRotation
? getDisplayAdjustments().getRotation(mDisplayInfo.rotation)
@@ -892,7 +905,7 @@
*/
@Nullable
public DisplayCutout getCutout() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mMayAdjustByFixedRotation
? getDisplayAdjustments().getDisplayCutout(mDisplayInfo.displayCutout)
@@ -910,7 +923,7 @@
@SuppressLint("VisiblySynchronized")
@Nullable
public RoundedCorner getRoundedCorner(@RoundedCorner.Position int position) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
RoundedCorners roundedCorners;
if (mMayAdjustByFixedRotation) {
@@ -942,7 +955,7 @@
* Gets the refresh rate of this display in frames per second.
*/
public float getRefreshRate() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.getRefreshRate();
}
@@ -958,7 +971,7 @@
*/
@Deprecated
public float[] getSupportedRefreshRates() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.getDefaultRefreshRates();
}
@@ -968,7 +981,7 @@
* Returns the active mode of the display.
*/
public Mode getMode() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.getMode();
}
@@ -978,7 +991,7 @@
* Gets the supported modes of this display.
*/
public Mode[] getSupportedModes() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
final Display.Mode[] modes = mDisplayInfo.supportedModes;
return Arrays.copyOf(modes, modes.length);
@@ -1004,7 +1017,7 @@
*/
@SuppressLint("VisiblySynchronized")
public boolean isMinimalPostProcessingSupported() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.minimalPostProcessingSupported;
}
@@ -1024,7 +1037,7 @@
* @hide
*/
public int getColorMode() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.colorMode;
}
@@ -1051,7 +1064,7 @@
* @see #isHdr()
*/
public HdrCapabilities getHdrCapabilities() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.hdrCapabilities;
}
@@ -1064,7 +1077,7 @@
* @see HdrCapabilities#getSupportedHdrTypes()
*/
public boolean isHdr() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.isHdr();
}
@@ -1077,7 +1090,7 @@
* {@link Configuration#isScreenWideColorGamut()}.
*/
public boolean isWideColorGamut() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.isWideColorGamut();
}
@@ -1092,7 +1105,7 @@
*/
@Nullable
public ColorSpace getPreferredWideGamutColorSpace() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
if (mDisplayInfo.isWideColorGamut()) {
return mGlobal.getPreferredWideGamutColorSpace();
@@ -1106,7 +1119,7 @@
* @hide
*/
public int[] getSupportedColorModes() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
int[] colorModes = mDisplayInfo.supportedColorModes;
return Arrays.copyOf(colorModes, colorModes.length);
@@ -1123,7 +1136,7 @@
@NonNull
@TestApi
public @ColorMode ColorSpace[] getSupportedWideColorGamut() {
- synchronized (this) {
+ synchronized (mLock) {
final ColorSpace[] defaultColorSpaces = new ColorSpace[0];
updateDisplayInfoLocked();
if (!isWideColorGamut()) {
@@ -1157,7 +1170,7 @@
* A/V synchronization.
*/
public long getAppVsyncOffsetNanos() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.appVsyncOffsetNanos;
}
@@ -1175,7 +1188,7 @@
* ({@link System#nanoTime}).
*/
public long getPresentationDeadlineNanos() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.presentationDeadlineNanos;
}
@@ -1190,7 +1203,10 @@
*/
@Nullable
public DeviceProductInfo getDeviceProductInfo() {
- return mDisplayInfo.deviceProductInfo;
+ synchronized (mLock) {
+ updateDisplayInfoLocked();
+ return mDisplayInfo.deviceProductInfo;
+ }
}
/**
@@ -1223,7 +1239,7 @@
*/
@Deprecated
public void getMetrics(DisplayMetrics outMetrics) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
mDisplayInfo.getAppMetrics(outMetrics, getDisplayAdjustments());
}
@@ -1276,8 +1292,20 @@
*/
@Deprecated
public void getRealSize(Point outSize) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
+ if (shouldReportMaxBounds()) {
+ final Rect bounds = mResources.getConfiguration()
+ .windowConfiguration.getMaxBounds();
+ outSize.x = bounds.width();
+ outSize.y = bounds.height();
+ if (DEBUG) {
+ Log.d(TAG, "getRealSize determined from max bounds: " + outSize);
+ }
+ // Skip adjusting by fixed rotation, since if it is necessary, the configuration
+ // should already reflect the expected rotation.
+ return;
+ }
outSize.x = mDisplayInfo.logicalWidth;
outSize.y = mDisplayInfo.logicalHeight;
if (mMayAdjustByFixedRotation) {
@@ -1334,8 +1362,19 @@
*/
@Deprecated
public void getRealMetrics(DisplayMetrics outMetrics) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
+ if (shouldReportMaxBounds()) {
+ mDisplayInfo.getMaxBoundsMetrics(outMetrics,
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO,
+ mResources.getConfiguration());
+ if (DEBUG) {
+ Log.d(TAG, "getRealMetrics determined from max bounds: " + outMetrics);
+ }
+ // Skip adjusting by fixed rotation, since if it is necessary, the configuration
+ // should already reflect the expected rotation.
+ return;
+ }
mDisplayInfo.getLogicalMetrics(outMetrics,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
if (mMayAdjustByFixedRotation) {
@@ -1345,6 +1384,53 @@
}
/**
+ * Determines if {@link WindowConfiguration#getMaxBounds()} should be reported as the
+ * display dimensions. The max bounds field may be smaller than the logical dimensions
+ * when apps need to be sandboxed.
+ *
+ * Depends upon {@link WindowConfiguration#getMaxBounds()} being set in
+ * {@link com.android.server.wm.ConfigurationContainer#providesMaxBounds()}. In most cases, this
+ * value reflects the size of the current DisplayArea.
+ * @return {@code true} when max bounds should be applied.
+ */
+ private boolean shouldReportMaxBounds() {
+ if (mResources == null) {
+ return false;
+ }
+ final Configuration config = mResources.getConfiguration();
+ // TODO(b/179308296) Temporarily exclude Launcher from being given max bounds, by checking
+ // if the caller is the recents component.
+ return config != null && !config.windowConfiguration.getMaxBounds().isEmpty()
+ && !isRecentsComponent();
+ }
+
+ /**
+ * Returns {@code true} when the calling package is the recents component.
+ * TODO(b/179308296) Remove once Launcher addresses issue
+ */
+ boolean isRecentsComponent() {
+ if (mIsRecentsComponent.isPresent()) {
+ return mIsRecentsComponent.get();
+ }
+ if (mResources == null) {
+ return false;
+ }
+ try {
+ String recentsComponent = mResources.getString(R.string.config_recentsComponentName);
+ if (recentsComponent == null) {
+ return false;
+ }
+ String recentsPackage = ComponentName.unflattenFromString(recentsComponent)
+ .getPackageName();
+ mIsRecentsComponent = Optional.of(recentsPackage != null
+ && recentsPackage.equals(ActivityThread.currentPackageName()));
+ return mIsRecentsComponent.get();
+ } catch (Resources.NotFoundException e) {
+ return false;
+ }
+ }
+
+ /**
* Gets the state of the display, such as whether it is on or off.
*
* @return The state of the display: one of {@link #STATE_OFF}, {@link #STATE_ON},
@@ -1352,7 +1438,7 @@
* {@link #STATE_UNKNOWN}.
*/
public int getState() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mIsValid ? mDisplayInfo.state : STATE_UNKNOWN;
}
@@ -1436,7 +1522,7 @@
// For debugging purposes
@Override
public String toString() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
final DisplayAdjustments adjustments = getDisplayAdjustments();
mDisplayInfo.getAppMetrics(mTempMetrics, adjustments);
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 655f423..a8aaeb7 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -24,6 +24,7 @@
import static android.view.DisplayInfoProto.NAME;
import android.annotation.Nullable;
+import android.app.WindowConfiguration;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
@@ -615,11 +616,29 @@
getMetricsWithSize(outMetrics, ci, configuration, appWidth, appHeight);
}
+ /**
+ * Populates {@code outMetrics} with details of the logical display. Bounds are limited
+ * by the logical size of the display.
+ *
+ * @param outMetrics the {@link DisplayMetrics} to be populated
+ * @param compatInfo the {@link CompatibilityInfo} to be applied
+ * @param configuration the {@link Configuration}
+ */
public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
Configuration configuration) {
getMetricsWithSize(outMetrics, compatInfo, configuration, logicalWidth, logicalHeight);
}
+ /**
+ * Similar to {@link #getLogicalMetrics}, but the limiting bounds are determined from
+ * {@link WindowConfiguration#getMaxBounds()}
+ */
+ public void getMaxBoundsMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
+ Configuration configuration) {
+ Rect bounds = configuration.windowConfiguration.getMaxBounds();
+ getMetricsWithSize(outMetrics, compatInfo, configuration, bounds.width(), bounds.height());
+ }
+
public int getNaturalWidth() {
return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
logicalWidth : logicalHeight;
diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java
index 79d8c14..5e0579d 100644
--- a/core/java/android/view/InputEventReceiver.java
+++ b/core/java/android/view/InputEventReceiver.java
@@ -159,6 +159,16 @@
}
/**
+ * Called when a drag event is received, from native code.
+ *
+ * @param isExiting if false, the window associated with this input channel has just received
+ * drag
+ * if true, the window associated with this input channel has just lost drag
+ */
+ public void onDragEvent(boolean isExiting, float x, float y) {
+ }
+
+ /**
* Called when a batched input event is pending.
*
* The batched input event will continue to accumulate additional movement
diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS
index cbb86de..31f6f6a 100644
--- a/core/java/android/view/OWNERS
+++ b/core/java/android/view/OWNERS
@@ -78,3 +78,8 @@
per-file ViewRootInsetsControllerHost.java = file:/services/core/java/com/android/server/wm/OWNERS
per-file Window*.java = file:/services/core/java/com/android/server/wm/OWNERS
per-file Window*.aidl = file:/services/core/java/com/android/server/wm/OWNERS
+
+# Scroll Capture
+per-file *ScrollCapture*.aidl = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
+per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
+per-file *CaptureHelper*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 9523bcd..ed840ce 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -70,7 +70,7 @@
* <p>Content capture provides real-time, continuous capture of application activity, display and
* events to an intelligence service that is provided by the Android system. The intelligence
* service then uses that info to mediate and speed user journey through different apps. For
- * example, when the user receives a restaurant address in a chat app and switchs to a map app
+ * example, when the user receives a restaurant address in a chat app and switches to a map app
* to search for that restaurant, the intelligence service could offer an autofill dialog to
* let the user automatically select its address.
*
diff --git a/core/java/android/view/inputmethod/InputMethod.java b/core/java/android/view/inputmethod/InputMethod.java
index de4554b..6ade5e6 100644
--- a/core/java/android/view/inputmethod/InputMethod.java
+++ b/core/java/android/view/inputmethod/InputMethod.java
@@ -105,7 +105,7 @@
*/
@MainThread
default void initializeInternal(IBinder token, int displayId,
- IInputMethodPrivilegedOperations privilegedOperations) {
+ IInputMethodPrivilegedOperations privilegedOperations, int configChanges) {
updateInputMethodDisplay(displayId);
attachToken(token);
}
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 5d876a6..25712f8 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -18,19 +18,23 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.graphics.drawable.Drawable;
+import android.inputmethodservice.InputMethodService;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
@@ -60,6 +64,7 @@
* @attr ref android.R.styleable#InputMethod_isDefault
* @attr ref android.R.styleable#InputMethod_supportsSwitchingToNextInputMethod
* @attr ref android.R.styleable#InputMethod_supportsInlineSuggestions
+ * @attr ref android.R.styleable#InputMethod_configChanges
*/
public final class InputMethodInfo implements Parcelable {
static final String TAG = "InputMethodInfo";
@@ -118,6 +123,12 @@
private final boolean mInlineSuggestionsEnabled;
/**
+ * The flag for configurations IME assumes the responsibility for handling in
+ * {@link InputMethodService#onConfigurationChanged(Configuration)}}.
+ */
+ private final int mHandledConfigChanges;
+
+ /**
* @param service the {@link ResolveInfo} corresponds in which the IME is implemented.
* @return a unique ID to be returned by {@link #getId()}. We have used
* {@link ComponentName#flattenToShortString()} for this purpose (and it is already
@@ -203,6 +214,8 @@
false);
inlineSuggestionsEnabled = sa.getBoolean(
com.android.internal.R.styleable.InputMethod_supportsInlineSuggestions, false);
+ mHandledConfigChanges = sa.getInt(
+ com.android.internal.R.styleable.InputMethod_configChanges, 0);
sa.recycle();
final int depth = parser.getDepth();
@@ -287,6 +300,7 @@
mIsVrOnly = source.readBoolean();
mService = ResolveInfo.CREATOR.createFromParcel(source);
mSubtypes = new InputMethodSubtypeArray(source);
+ mHandledConfigChanges = source.readInt();
mForceDefault = false;
}
@@ -298,7 +312,22 @@
this(buildFakeResolveInfo(packageName, className, label), false /* isAuxIme */,
settingsActivity, null /* subtypes */, 0 /* isDefaultResId */,
false /* forceDefault */, true /* supportsSwitchingToNextInputMethod */,
- false /* inlineSuggestionsEnabled */, false /* isVrOnly */);
+ false /* inlineSuggestionsEnabled */, false /* isVrOnly */,
+ 0 /* handledConfigChanges */);
+ }
+
+ /**
+ * Temporary API for creating a built-in input method for test.
+ * @hide
+ */
+ @TestApi
+ public InputMethodInfo(@NonNull String packageName, @NonNull String className,
+ @NonNull CharSequence label, @NonNull String settingsActivity,
+ int handledConfigChanges) {
+ this(buildFakeResolveInfo(packageName, className, label), false /* isAuxIme */,
+ settingsActivity, null /* subtypes */, 0 /* isDefaultResId */,
+ false /* forceDefault */, true /* supportsSwitchingToNextInputMethod */,
+ false /* inlineSuggestionsEnabled */, false /* isVrOnly */, handledConfigChanges);
}
/**
@@ -310,7 +339,7 @@
boolean forceDefault) {
this(ri, isAuxIme, settingsActivity, subtypes, isDefaultResId, forceDefault,
true /* supportsSwitchingToNextInputMethod */, false /* inlineSuggestionsEnabled */,
- false /* isVrOnly */);
+ false /* isVrOnly */, 0 /* handledconfigChanges */);
}
/**
@@ -321,7 +350,8 @@
List<InputMethodSubtype> subtypes, int isDefaultResId, boolean forceDefault,
boolean supportsSwitchingToNextInputMethod, boolean isVrOnly) {
this(ri, isAuxIme, settingsActivity, subtypes, isDefaultResId, forceDefault,
- supportsSwitchingToNextInputMethod, false /* inlineSuggestionsEnabled */, isVrOnly);
+ supportsSwitchingToNextInputMethod, false /* inlineSuggestionsEnabled */, isVrOnly,
+ 0 /* handledConfigChanges */);
}
/**
@@ -331,7 +361,7 @@
public InputMethodInfo(ResolveInfo ri, boolean isAuxIme, String settingsActivity,
List<InputMethodSubtype> subtypes, int isDefaultResId, boolean forceDefault,
boolean supportsSwitchingToNextInputMethod, boolean inlineSuggestionsEnabled,
- boolean isVrOnly) {
+ boolean isVrOnly, int handledConfigChanges) {
final ServiceInfo si = ri.serviceInfo;
mService = ri;
mId = new ComponentName(si.packageName, si.name).flattenToShortString();
@@ -343,6 +373,7 @@
mSupportsSwitchingToNextInputMethod = supportsSwitchingToNextInputMethod;
mInlineSuggestionsEnabled = inlineSuggestionsEnabled;
mIsVrOnly = isVrOnly;
+ mHandledConfigChanges = handledConfigChanges;
}
private static ResolveInfo buildFakeResolveInfo(String packageName, String className,
@@ -489,6 +520,17 @@
}
}
+ /**
+ * Returns the bit mask of kinds of configuration changes that this IME
+ * can handle itself (without being restarted by the system).
+ *
+ * @attr ref android.R.styleable#InputMethod_configChanges
+ */
+ @ActivityInfo.Config
+ public int getConfigChanges() {
+ return mHandledConfigChanges;
+ }
+
public void dump(Printer pw, String prefix) {
pw.println(prefix + "mId=" + mId
+ " mSettingsActivityName=" + mSettingsActivityName
@@ -579,6 +621,7 @@
dest.writeBoolean(mIsVrOnly);
mService.writeToParcel(dest, flags);
mSubtypes.writeToParcel(dest);
+ dest.writeInt(mHandledConfigChanges);
}
/**
diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java
index cf3358b..9f90b3b 100644
--- a/core/java/android/view/translation/UiTranslationController.java
+++ b/core/java/android/view/translation/UiTranslationController.java
@@ -25,6 +25,7 @@
import android.annotation.WorkerThread;
import android.app.Activity;
import android.content.Context;
+import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
@@ -54,6 +55,11 @@
*/
public class UiTranslationController {
+ // TODO(b/182433547): remove Build.IS_DEBUGGABLE before ship. Enable the logging in debug build
+ // to help the debug during the development phase
+ public static final boolean DEBUG = Log.isLoggable(UiTranslationManager.LOG_TAG, Log.DEBUG)
+ || Build.IS_DEBUGGABLE;
+
private static final String TAG = "UiTranslationController";
@NonNull
private final Activity mActivity;
@@ -93,6 +99,8 @@
if (!mActivity.isResumed()) {
return;
}
+ Log.i(TAG, "updateUiTranslationState state: " + stateToString(state)
+ + (DEBUG ? ", views: " + views : ""));
switch (state) {
case STATE_UI_TRANSLATION_STARTED:
final Pair<TranslationSpec, TranslationSpec> specs =
@@ -149,8 +157,69 @@
translator.dump(outerPrefix, pw);
pw.println();
}
+ synchronized (mLock) {
+ final int viewSize = mViews.size();
+ pw.print(outerPrefix); pw.print("number views: "); pw.println(viewSize);
+ for (int i = 0; i < viewSize; i++) {
+ pw.print(outerPrefix); pw.print("#"); pw.println(i);
+ final AutofillId autofillId = mViews.keyAt(i);
+ final View view = mViews.valueAt(i).get();
+ pw.print(pfx); pw.print("autofillId: "); pw.println(autofillId);
+ pw.print(pfx); pw.print("view:"); pw.println(view);
+ }
+ }
+ // TODO(b/182433547): we will remove debug rom condition before S release then we change
+ // change this back to "DEBUG"
+ if (Log.isLoggable(UiTranslationManager.LOG_TAG, Log.DEBUG)) {
+ dumpViewByTraversal(outerPrefix, pw);
+ }
}
+ private void dumpViewByTraversal(String outerPrefix, PrintWriter pw) {
+ final ArrayList<ViewRootImpl> roots =
+ WindowManagerGlobal.getInstance().getRootViews(mActivity.getActivityToken());
+ pw.print(outerPrefix); pw.println("Dump views:");
+ for (int rootNum = 0; rootNum < roots.size(); rootNum++) {
+ final View rootView = roots.get(rootNum).getView();
+ if (rootView instanceof ViewGroup) {
+ dumpChildren((ViewGroup) rootView, outerPrefix, pw);
+ } else {
+ dumpViewInfo(rootView, outerPrefix, pw);
+ }
+ }
+ }
+
+ private void dumpChildren(ViewGroup viewGroup, String outerPrefix, PrintWriter pw) {
+ final int childCount = viewGroup.getChildCount();
+ for (int i = 0; i < childCount; ++i) {
+ final View child = viewGroup.getChildAt(i);
+ if (child instanceof ViewGroup) {
+ pw.print(outerPrefix); pw.println("Children: ");
+ pw.print(outerPrefix); pw.print(outerPrefix); pw.println(child);
+ dumpChildren((ViewGroup) child, outerPrefix, pw);
+ } else {
+ pw.print(outerPrefix); pw.println("End Children: ");
+ pw.print(outerPrefix); pw.print(outerPrefix); pw.print(child);
+ dumpViewInfo(child, outerPrefix, pw);
+ }
+ }
+ }
+
+ private void dumpViewInfo(View view, String outerPrefix, PrintWriter pw) {
+ final AutofillId autofillId = view.getAutofillId();
+ pw.print(outerPrefix); pw.print("autofillId: "); pw.print(autofillId);
+ // TODO: print TranslationTransformation
+ boolean isContainsView = false;
+ synchronized (mLock) {
+ final WeakReference<View> viewRef = mViews.get(autofillId);
+ if (viewRef != null && viewRef.get() != null) {
+ isContainsView = true;
+ }
+ }
+ pw.print(outerPrefix); pw.print("isContainsView: "); pw.println(isContainsView);
+ }
+
+
/**
* The method is used by {@link Translator}, it will be called when the translation is done. The
* translation result can be get from here.
@@ -171,6 +240,9 @@
return;
}
final int resultCount = translatedResult.size();
+ if (DEBUG) {
+ Log.v(TAG, "onTranslationCompleted: receive " + resultCount + " responses.");
+ }
synchronized (mLock) {
for (int i = 0; i < resultCount; i++) {
final ViewTranslationResponse response = translatedResult.get(i);
@@ -180,7 +252,7 @@
}
final View view = mViews.get(autofillId).get();
if (view == null) {
- Log.w(TAG, "onTranslationCompleted: the Veiew for autofill id " + autofillId
+ Log.w(TAG, "onTranslationCompleted: the view for autofill id " + autofillId
+ " may be gone.");
continue;
}
@@ -208,6 +280,10 @@
@WorkerThread
private void sendTranslationRequest(Translator translator,
List<ViewTranslationRequest> requests) {
+ if (requests.size() == 0) {
+ Log.wtf(TAG, "No ViewTranslationRequest was collected.");
+ return;
+ }
final TranslationRequest request = new TranslationRequest.Builder()
.setViewTranslationRequests(requests)
.build();
@@ -233,7 +309,8 @@
requests.add(request);
}
if (currentCount == (foundViews.size() - 1)) {
- Log.v(TAG, "onUiTranslationStarted: send " + requests.size() + " request.");
+ Log.v(TAG, "onUiTranslationStarted: collect " + requests.size()
+ + " requests.");
mWorkerHandler.sendMessage(PooledLambda.obtainMessage(
UiTranslationController::sendTranslationRequest,
UiTranslationController.this, translator, requests));
@@ -287,6 +364,9 @@
for (int i = 0; i < viewCounts; i++) {
final View view = views.valueAt(i).get();
if (view == null) {
+ if (DEBUG) {
+ Log.d(TAG, "View was gone for autofillid = " + views.keyAt(i));
+ }
continue;
}
action.accept(view);
diff --git a/core/java/android/view/translation/UiTranslationManager.java b/core/java/android/view/translation/UiTranslationManager.java
index a3a6a2e..7c73e70 100644
--- a/core/java/android/view/translation/UiTranslationManager.java
+++ b/core/java/android/view/translation/UiTranslationManager.java
@@ -43,6 +43,14 @@
private static final String TAG = "UiTranslationManager";
/**
+ * The tag which uses for enabling debug log dump. To enable it, we can use command "adb shell
+ * setprop log.tag.UiTranslation DEBUG".
+ *
+ * @hide
+ */
+ public static final String LOG_TAG = "UiTranslation";
+
+ /**
* The state caller request to disable utranslation,, it is no longer need to ui translation.
*
* @hide
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index dc42ad5..45352e4 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -20,6 +20,9 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.compat.Compatibility;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.TypedArray;
@@ -58,6 +61,29 @@
* {@link #draw(Canvas)} method.</p>
*/
public class EdgeEffect {
+ /**
+ * This sets the default value for {@link #setType(int)} to {@link #TYPE_STRETCH} instead
+ * of {@link #TYPE_GLOW}. The type can still be overridden by the theme, view attribute,
+ * or by calling {@link #setType(int)}.
+ *
+ * @hide
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
+ public static final long USE_STRETCH_EDGE_EFFECT_BY_DEFAULT = 171228096L;
+
+ /**
+ * This sets the default value for {@link #setType(int)} to {@link #TYPE_STRETCH} instead
+ * of {@link #TYPE_GLOW} for views that instantiate with
+ * {@link #EdgeEffect(Context, AttributeSet)}, indicating use of S+ EdgeEffect support. The
+ * type can still be overridden by the theme, view attribute, or by calling
+ * {@link #setType(int)}.
+ *
+ * @hide
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
+ public static final long USE_STRETCH_EDGE_EFFECT_FOR_SUPPORTED = 178807038L;
/**
* The default blend mode used by {@link EdgeEffect}.
@@ -76,6 +102,28 @@
*/
public static final int TYPE_STRETCH = 1;
+ /**
+ * The velocity threshold before the spring animation is considered settled.
+ * The idea here is that velocity should be less than 1 pixel per frame (~16ms).
+ */
+ private static final double VELOCITY_THRESHOLD = 1.0 / 0.016;
+
+ /**
+ * The value threshold before the spring animation is considered close enough to
+ * the destination to be settled. This should be around 1 pixel.
+ */
+ private static final double VALUE_THRESHOLD = 1;
+
+ /**
+ * The natural frequency of the stretch spring.
+ */
+ private static final double NATURAL_FREQUENCY = 14.4222;
+
+ /**
+ * The damping ratio of the stretch spring.
+ */
+ private static final double DAMPING_RATIO = 0.875;
+
/** @hide */
@IntDef({TYPE_GLOW, TYPE_STRETCH})
@Retention(RetentionPolicy.SOURCE)
@@ -119,20 +167,19 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private float mGlowScaleY;
private float mDistance;
+ private float mVelocity; // only for stretch animations
private float mGlowAlphaStart;
private float mGlowAlphaFinish;
private float mGlowScaleYStart;
private float mGlowScaleYFinish;
- private float mDistanceStart;
- private float mDistanceFinish;
private long mStartTime;
private float mDuration;
private float mStretchIntensity = DEFAULT_MAX_STRETCH_INTENSITY;
private float mStretchDistance = -1f;
- private final Interpolator mInterpolator;
+ private final Interpolator mInterpolator = new DecelerateInterpolator();
private static final int STATE_IDLE = 0;
private static final int STATE_PULL = 1;
@@ -166,7 +213,7 @@
* @param context Context used to provide theming and resource information for the EdgeEffect
*/
public EdgeEffect(Context context) {
- this(context, null);
+ this(context, null, Compatibility.isChangeEnabled(USE_STRETCH_EDGE_EFFECT_BY_DEFAULT));
}
/**
@@ -175,18 +222,26 @@
* @param attrs The attributes of the XML tag that is inflating the view
*/
public EdgeEffect(@NonNull Context context, @Nullable AttributeSet attrs) {
- mPaint.setAntiAlias(true);
+ this(context, attrs,
+ Compatibility.isChangeEnabled(USE_STRETCH_EDGE_EFFECT_BY_DEFAULT)
+ || Compatibility.isChangeEnabled(USE_STRETCH_EDGE_EFFECT_FOR_SUPPORTED));
+ }
+
+ private EdgeEffect(@NonNull Context context, @Nullable AttributeSet attrs,
+ boolean defaultStretch) {
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.EdgeEffect);
final int themeColor = a.getColor(
com.android.internal.R.styleable.EdgeEffect_colorEdgeEffect, 0xff666666);
mEdgeEffectType = a.getInt(
- com.android.internal.R.styleable.EdgeEffect_edgeEffectType, TYPE_GLOW);
+ com.android.internal.R.styleable.EdgeEffect_edgeEffectType,
+ defaultStretch ? TYPE_STRETCH : TYPE_GLOW);
a.recycle();
+
+ mPaint.setAntiAlias(true);
mPaint.setColor((themeColor & 0xffffff) | 0x33000000);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setBlendMode(DEFAULT_BLEND_MODE);
- mInterpolator = new DecelerateInterpolator();
}
/**
@@ -239,6 +294,8 @@
*/
public void finish() {
mState = STATE_IDLE;
+ mDistance = 0;
+ mVelocity = 0;
}
/**
@@ -293,7 +350,8 @@
mDuration = PULL_TIME;
mPullDistance += deltaDistance;
- mDistanceStart = mDistanceFinish = mDistance = Math.max(0f, mPullDistance);
+ mDistance = Math.max(0f, mPullDistance);
+ mVelocity = 0;
final float absdd = Math.abs(deltaDistance);
mGlowAlpha = mGlowAlphaStart = Math.min(MAX_ALPHA,
@@ -387,11 +445,10 @@
mState = STATE_RECEDE;
mGlowAlphaStart = mGlowAlpha;
mGlowScaleYStart = mGlowScaleY;
- mDistanceStart = mDistance;
mGlowAlphaFinish = 0.f;
mGlowScaleYFinish = 0.f;
- mDistanceFinish = 0.f;
+ mVelocity = 0.f;
mStartTime = AnimationUtils.currentAnimationTimeMillis();
mDuration = RECEDE_TIME;
@@ -408,30 +465,36 @@
* @param velocity Velocity at impact in pixels per second.
*/
public void onAbsorb(int velocity) {
- mState = STATE_ABSORB;
- velocity = Math.min(Math.max(MIN_VELOCITY, Math.abs(velocity)), MAX_VELOCITY);
+ if (mEdgeEffectType == TYPE_STRETCH) {
+ mState = STATE_RECEDE;
+ mVelocity = velocity / mHeight;
+ mDistance = 0;
+ mStartTime = AnimationUtils.currentAnimationTimeMillis();
+ } else {
+ mState = STATE_ABSORB;
+ mVelocity = 0;
+ velocity = Math.min(Math.max(MIN_VELOCITY, Math.abs(velocity)), MAX_VELOCITY);
- mStartTime = AnimationUtils.currentAnimationTimeMillis();
- mDuration = 0.15f + (velocity * 0.02f);
+ mStartTime = AnimationUtils.currentAnimationTimeMillis();
+ mDuration = 0.15f + (velocity * 0.02f);
- // The glow depends more on the velocity, and therefore starts out
- // nearly invisible.
- mGlowAlphaStart = GLOW_ALPHA_START;
- mGlowScaleYStart = Math.max(mGlowScaleY, 0.f);
- mDistanceStart = mDistance;
+ // The glow depends more on the velocity, and therefore starts out
+ // nearly invisible.
+ mGlowAlphaStart = GLOW_ALPHA_START;
+ mGlowScaleYStart = Math.max(mGlowScaleY, 0.f);
- // Growth for the size of the glow should be quadratic to properly
- // respond
- // to a user's scrolling speed. The faster the scrolling speed, the more
- // intense the effect should be for both the size and the saturation.
- mGlowScaleYFinish = Math.min(0.025f + (velocity * (velocity / 100) * 0.00015f) / 2, 1.f);
- // Alpha should change for the glow as well as size.
- mGlowAlphaFinish = Math.max(
- mGlowAlphaStart, Math.min(velocity * VELOCITY_GLOW_FACTOR * .00001f, MAX_ALPHA));
- mTargetDisplacement = 0.5f;
-
- // Use glow values to estimate the absorption for stretch distance.
- mDistanceFinish = calculateDistanceFromGlowValues(mGlowScaleYFinish, mGlowAlphaFinish);
+ // Growth for the size of the glow should be quadratic to properly
+ // respond
+ // to a user's scrolling speed. The faster the scrolling speed, the more
+ // intense the effect should be for both the size and the saturation.
+ mGlowScaleYFinish = Math.min(0.025f + (velocity * (velocity / 100) * 0.00015f) / 2,
+ 1.f);
+ // Alpha should change for the glow as well as size.
+ mGlowAlphaFinish = Math.max(
+ mGlowAlphaStart,
+ Math.min(velocity * VELOCITY_GLOW_FACTOR * .00001f, MAX_ALPHA));
+ mTargetDisplacement = 0.5f;
+ }
}
/**
@@ -539,8 +602,8 @@
canvas.drawCircle(centerX, centerY, mRadius, mPaint);
canvas.restoreToCount(count);
} else if (canvas instanceof RecordingCanvas) {
- if (mState != STATE_PULL) {
- update();
+ if (mState == STATE_RECEDE) {
+ updateSpring();
}
RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
if (mTmpMatrix == null) {
@@ -597,7 +660,7 @@
}
boolean oneLastFrame = false;
- if (mState == STATE_RECEDE && mDistance == 0) {
+ if (mState == STATE_RECEDE && mDistance == 0 && mVelocity == 0) {
mState = STATE_IDLE;
oneLastFrame = true;
}
@@ -634,7 +697,7 @@
mGlowAlpha = mGlowAlphaStart + (mGlowAlphaFinish - mGlowAlphaStart) * interp;
mGlowScaleY = mGlowScaleYStart + (mGlowScaleYFinish - mGlowScaleYStart) * interp;
- mDistance = mDistanceStart + (mDistanceFinish - mDistanceStart) * interp;
+ mDistance = calculateDistanceFromGlowValues(mGlowScaleY, mGlowAlpha);
mDisplacement = (mDisplacement + mTargetDisplacement) / 2;
if (t >= 1.f - EPSILON) {
@@ -646,12 +709,10 @@
mGlowAlphaStart = mGlowAlpha;
mGlowScaleYStart = mGlowScaleY;
- mDistanceStart = mDistance;
// After absorb, the glow should fade to nothing.
mGlowAlphaFinish = 0.f;
mGlowScaleYFinish = 0.f;
- mDistanceFinish = 0.f;
break;
case STATE_PULL:
mState = STATE_PULL_DECAY;
@@ -660,12 +721,10 @@
mGlowAlphaStart = mGlowAlpha;
mGlowScaleYStart = mGlowScaleY;
- mDistanceStart = mDistance;
// After pull, the glow should fade to nothing.
mGlowAlphaFinish = 0.f;
mGlowScaleYFinish = 0.f;
- mDistanceFinish = 0.f;
break;
case STATE_PULL_DECAY:
mState = STATE_RECEDE;
@@ -677,6 +736,35 @@
}
}
+ private void updateSpring() {
+ final long time = AnimationUtils.currentAnimationTimeMillis();
+ final float deltaT = (time - mStartTime) / 1000f; // Convert from millis to seconds
+ if (deltaT < 0.001f) {
+ return; // Must have at least 1 ms difference
+ }
+ final double mDampedFreq = NATURAL_FREQUENCY * Math.sqrt(1 - DAMPING_RATIO * DAMPING_RATIO);
+
+ // We're always underdamped, so we can use only those equations:
+ double cosCoeff = mDistance;
+ double sinCoeff = (1 / mDampedFreq) * (DAMPING_RATIO * NATURAL_FREQUENCY
+ * mDistance + mVelocity);
+ double distance = Math.pow(Math.E, -DAMPING_RATIO * NATURAL_FREQUENCY * deltaT)
+ * (cosCoeff * Math.cos(mDampedFreq * deltaT)
+ + sinCoeff * Math.sin(mDampedFreq * deltaT));
+ double velocity = distance * (-NATURAL_FREQUENCY) * DAMPING_RATIO
+ + Math.pow(Math.E, -DAMPING_RATIO * NATURAL_FREQUENCY * deltaT)
+ * (-mDampedFreq * cosCoeff * Math.sin(mDampedFreq * deltaT)
+ + mDampedFreq * sinCoeff * Math.cos(mDampedFreq * deltaT));
+ mDistance = (float) distance;
+ mVelocity = (float) velocity;
+ mStartTime = time;
+ if (isAtEquilibrium()) {
+ mState = STATE_IDLE;
+ mDistance = 0;
+ mVelocity = 0;
+ }
+ }
+
/**
* @return The estimated pull distance as calculated from mGlowScaleY.
*/
@@ -692,4 +780,15 @@
}
return alpha / PULL_DISTANCE_ALPHA_GLOW_FACTOR;
}
+
+ /**
+ * @return true if the spring used for calculating the stretch animation is
+ * considered at rest or false if it is still animating.
+ */
+ private boolean isAtEquilibrium() {
+ double velocity = mVelocity * mHeight; // in pixels/second
+ double displacement = mDistance * mHeight; // in pixels
+ return Math.abs(velocity) < VELOCITY_THRESHOLD
+ && Math.abs(displacement) < VALUE_THRESHOLD;
+ }
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index fdc66fc..177a9f1 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -195,6 +195,7 @@
import android.view.textservice.SpellCheckerSubtype;
import android.view.textservice.TextServicesManager;
import android.view.translation.TranslationRequestValue;
+import android.view.translation.UiTranslationController;
import android.view.translation.ViewTranslationRequest;
import android.view.translation.ViewTranslationResponse;
import android.widget.RemoteViews.RemoteView;
@@ -9316,7 +9317,7 @@
}
for (int i = 0; i < n; i++) {
- max = Math.max(max, layout.getLineWidth(i));
+ max = Math.max(max, layout.getLineMax(i));
}
return (int) Math.ceil(max);
@@ -13835,6 +13836,10 @@
@Override
public ViewTranslationRequest onCreateTranslationRequest() {
if (mText == null || mText.length() == 0) {
+ // TODO(b/182433547): remove before S release
+ if (UiTranslationController.DEBUG) {
+ Log.w(LOG_TAG, "Cannot create translation request for the empty text.");
+ }
return null;
}
// Not translate password, editable text and not important for translation
@@ -13842,6 +13847,11 @@
// text selection apis, not support in S.
boolean isPassword = isAnyPasswordInputType() || hasPasswordTransformationMethod();
if (isTextEditable() || isPassword || isTextSelectable()) {
+ // TODO(b/182433547): remove before S release
+ if (UiTranslationController.DEBUG) {
+ Log.w(LOG_TAG, "Cannot create translation request. editable = " + isTextEditable()
+ + ", isPassword = " + isPassword + ", selectable = " + isTextSelectable());
+ }
return null;
}
// TODO(b/176488462): apply the view's important for translation property
@@ -13870,6 +13880,9 @@
// Restore to original text content.
if (mTranslationTransformation != null) {
setTransformationMethod(mTranslationTransformation.getOriginalTransformationMethod());
+ } else {
+ // TODO(b/182433547): remove before S release
+ Log.w(LOG_TAG, "onPauseUiTranslation(): no translated text.");
}
}
@@ -13889,7 +13902,8 @@
if (mTranslationTransformation != null) {
setTransformationMethod(mTranslationTransformation);
} else {
- Log.w(LOG_TAG, "onResumeTranslatedText(): no translated text.");
+ // TODO(b/182433547): remove before S release
+ Log.w(LOG_TAG, "onRestoreUiTranslation(): no translated text.");
}
}
@@ -13910,6 +13924,9 @@
if (mTranslationTransformation != null) {
setTransformationMethod(mTranslationTransformation.getOriginalTransformationMethod());
mTranslationTransformation = null;
+ } else {
+ // TODO(b/182433547): remove before S release
+ Log.w(LOG_TAG, "onFinishUiTranslation(): no translated text.");
}
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 6cfd498..d4d8536 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1119,7 +1119,7 @@
ClipboardManager clipboardManager = (ClipboardManager) getSystemService(
Context.CLIPBOARD_SERVICE);
- clipboardManager.setPrimaryClip(clipData);
+ clipboardManager.setPrimaryClipAsPackage(clipData, getReferrerPackageName());
Toast.makeText(getApplicationContext(), R.string.copied, Toast.LENGTH_SHORT).show();
// Log share completion via copy
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index ccb980e..592f7c7 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -21,6 +21,7 @@
import android.media.permission.Identity;
import android.os.Bundle;
import android.os.RemoteCallback;
+import android.os.SharedMemory;
import com.android.internal.app.IVoiceActionCheckCallback;
import com.android.internal.app.IVoiceInteractionSessionShowCallback;
@@ -225,14 +226,19 @@
IBinder client);
/**
- * Sets hotword detection configuration.
+ * Set configuration and pass read-only data to hotword detection service.
*
- * Note: Currently it will trigger hotword detection service after calling this function when
- * all conditions meet the requirements.
- *
- * @param options Config data.
- * @return {@link VoiceInteractionService#HOTWORD_CONFIG_SUCCESS} in case of success,
- * {@link VoiceInteractionService#HOTWORD_CONFIG_FAILURE} in case of failure.
+ * @param options Application configuration data provided by the
+ * {@link VoiceInteractionService}. The system strips out any remotable objects or other
+ * contents that can be used to communicate with other processes.
+ * @param sharedMemory The unrestricted data blob provided by the
+ * {@link VoiceInteractionService}. Use this to provide the hotword models data or other
+ * such data to the trusted process.
*/
- int setHotwordDetectionConfig(in Bundle options);
+ void setHotwordDetectionServiceConfig(in Bundle options, in SharedMemory sharedMemory);
+
+ /**
+ * Requests to shutdown hotword detection service.
+ */
+ void shutdownHotwordDetectionService();
}
diff --git a/core/java/com/android/internal/graphics/palette/Mean.java b/core/java/com/android/internal/graphics/palette/Mean.java
index 894f91b..bde0363 100644
--- a/core/java/com/android/internal/graphics/palette/Mean.java
+++ b/core/java/com/android/internal/graphics/palette/Mean.java
@@ -22,20 +22,19 @@
* Represents a centroid in Kmeans algorithms.
*/
public class Mean {
- private static final Random RANDOM = new Random(0);
-
public float[] center;
/**
* Constructor.
*
* @param upperBound maximum value of a dimension in the space Kmeans is optimizing in
+ * @param random used to generate a random center
*/
- Mean(int upperBound) {
+ Mean(int upperBound, Random random) {
center =
new float[]{
- RANDOM.nextInt(upperBound + 1), RANDOM.nextInt(upperBound + 1),
- RANDOM.nextInt(upperBound + 1)
+ random.nextInt(upperBound + 1), random.nextInt(upperBound + 1),
+ random.nextInt(upperBound + 1)
};
}
diff --git a/core/java/com/android/internal/graphics/palette/WSMeansQuantizer.java b/core/java/com/android/internal/graphics/palette/WSMeansQuantizer.java
index a87a34f..b4f216b 100644
--- a/core/java/com/android/internal/graphics/palette/WSMeansQuantizer.java
+++ b/core/java/com/android/internal/graphics/palette/WSMeansQuantizer.java
@@ -22,6 +22,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Random;
import java.util.Set;
@@ -57,13 +58,27 @@
}
if (maxColors > means.length) {
+ // Always initialize Random with the same seed. Ensures the results of quantization
+ // are consistent, even when random centroids are required.
+ Random random = new Random(0x42688);
int randomMeansToCreate = maxColors - means.length;
for (int i = 0; i < randomMeansToCreate; i++) {
- mMeans[means.length + i] = new Mean(100);
+ mMeans[means.length + i] = new Mean(100, random);
}
}
for (int pixel : pixels) {
+ // These are pixels from the bitmap that is being quantized.
+ // Depending on the bitmap & downscaling, it may have pixels that are less than opaque
+ // Ignore those pixels.
+ ///
+ // Note: they don't _have_ to be ignored, for example, we could instead turn them
+ // opaque. Traditionally, including outside Android, quantizers ignore transparent
+ // pixels, so that strategy was chosen.
+ int alpha = (pixel >> 24);
+ if (alpha < 255) {
+ continue;
+ }
Integer currentCount = mCountByColor.get(pixel);
if (currentCount == null) {
currentCount = 0;
@@ -105,8 +120,12 @@
/** Create random starting centroids for K-means. */
public static float[][] randomMeans(int maxColors, int upperBound) {
float[][] means = new float[maxColors][];
+
+ // Always initialize Random with the same seed. Ensures the results of quantization
+ // are consistent, even when random centroids are required.
+ Random random = new Random(0x42688);
for (int i = 0; i < maxColors; i++) {
- means[i] = new Mean(upperBound).center;
+ means[i] = new Mean(upperBound, random).center;
}
return means;
}
diff --git a/core/java/com/android/internal/graphics/palette/WuQuantizer.java b/core/java/com/android/internal/graphics/palette/WuQuantizer.java
index 66206bf..a2652ea 100644
--- a/core/java/com/android/internal/graphics/palette/WuQuantizer.java
+++ b/core/java/com/android/internal/graphics/palette/WuQuantizer.java
@@ -78,7 +78,12 @@
// All of the sample Wu implementations are reimplementations of a snippet of C code from
// the early 90s. They all cap the maximum # of colors at 256, and it is impossible to tell
// if this is a requirement, a consequence of QUANT_SIZE, or arbitrary.
- this.mMaxColors = Math.min(MAX_COLORS, maxColorCount);
+ //
+ // Also, the number of maximum colors should be capped at the number of pixels - otherwise,
+ // If extraction is run on a set of pixels whose count is less than max colors,
+ // then colors.length < max colors, and accesses to colors[index] throw an
+ // ArrayOutOfBoundsException.
+ this.mMaxColors = Math.min(Math.min(MAX_COLORS, maxColorCount), colors.length);
Box[] cube = new Box[mMaxColors];
int red, green, blue;
@@ -119,17 +124,13 @@
}
}
- // If extraction is run on a set of pixels whose count is less than the
- // number of max colors, then colors.length < max colors, and accesses
- // to colors[index] inside the for loop throw an ArrayOutOfBoundsException.
- int numColorsToCreate = (int) Math.min(mMaxColors, colors.length);
- for (k = 0; k < numColorsToCreate; ++k) {
+ for (k = 0; k < mMaxColors; ++k) {
weight = getVolume(cube[k], mWt);
if (weight > 0) {
red = (int) (getVolume(cube[k], mMr) / weight);
green = (int) (getVolume(cube[k], mMg) / weight);
blue = (int) (getVolume(cube[k], mMb) / weight);
- colors[k] = ((red & 0x0ff) << 16) | ((green & 0x0ff) << 8) | (blue & 0x0ff);
+ colors[k] = (255 << 24) | (red << 16) | (green << 8) | blue;
} else {
colors[k] = 0;
}
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java
index 5829047..7f0178e 100644
--- a/core/java/com/android/internal/jank/FrameTracker.java
+++ b/core/java/com/android/internal/jank/FrameTracker.java
@@ -206,9 +206,8 @@
* Cancel the trace session of the CUJ.
*/
public synchronized void cancel() {
- // The session is ongoing, end the trace session.
- // That means the cancel call is from external invocation, not from end().
- if (mBeginVsyncId != INVALID_ID && mEndVsyncId == INVALID_ID) {
+ // We don't need to end the trace section if it never begun.
+ if (mBeginVsyncId != INVALID_ID) {
Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId);
}
mCancelled = true;
diff --git a/core/java/com/android/internal/os/SelectedProcessCpuThreadReader.java b/core/java/com/android/internal/os/SelectedProcessCpuThreadReader.java
new file mode 100644
index 0000000..2ffff73
--- /dev/null
+++ b/core/java/com/android/internal/os/SelectedProcessCpuThreadReader.java
@@ -0,0 +1,57 @@
+/*
+ * 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.internal.os;
+
+import android.annotation.Nullable;
+import android.os.Process;
+
+/**
+ * Reads CPU usage statistics about a selected process identified by its cmdline.
+ *
+ * Handles finding the pid for the process and delegates CPU usage reading from the eBPF map to
+ * KernelSingleProcessCpuThreadReader. Exactly one long-lived instance of the process is expected.
+ * Otherwise, no statistics are returned.
+ *
+ * See also SystemServerCpuThreadReader.
+ */
+public final class SelectedProcessCpuThreadReader {
+ private final String[] mCmdline;
+
+ private int mPid;
+ private KernelSingleProcessCpuThreadReader mKernelCpuThreadReader;
+
+ public SelectedProcessCpuThreadReader(String cmdline) {
+ mCmdline = new String[] { cmdline };
+ }
+
+ /** Returns CPU times, per thread group, since tracking started. */
+ @Nullable
+ public KernelSingleProcessCpuThreadReader.ProcessCpuUsage readAbsolute() {
+ int[] pids = Process.getPidsForCommands(mCmdline);
+ if (pids == null || pids.length != 1) {
+ return null;
+ }
+ int pid = pids[0];
+ if (mPid == pid) {
+ return mKernelCpuThreadReader.getProcessCpuUsage();
+ }
+ mPid = pid;
+ mKernelCpuThreadReader = KernelSingleProcessCpuThreadReader.create(mPid);
+ mKernelCpuThreadReader.startTrackingThreadCpuTimes();
+ return null;
+ }
+}
diff --git a/core/java/com/android/internal/protolog/BaseProtoLogImpl.java b/core/java/com/android/internal/protolog/BaseProtoLogImpl.java
index bed85ae..83309fc 100644
--- a/core/java/com/android/internal/protolog/BaseProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/BaseProtoLogImpl.java
@@ -359,18 +359,6 @@
+ "\nLogging definitions loaded: " + mViewerConfig.knownViewerStringsNumber();
}
- /**
- * Writes the log buffer to a new file for the bugreport.
- *
- * This method is synchronized with {@code #startProtoLog(PrintWriter)} and
- * {@link #stopProtoLog(PrintWriter, boolean)}.
- */
- public void writeProtoLogToFile() {
- synchronized (mProtoLogEnabledLock) {
- writeProtoLogToFileLocked();
- }
- }
-
private void writeProtoLogToFileLocked() {
try {
long offset =
diff --git a/core/java/com/android/internal/security/OWNERS b/core/java/com/android/internal/security/OWNERS
new file mode 100644
index 0000000..41d1d66
--- /dev/null
+++ b/core/java/com/android/internal/security/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 36824
+
+per-file VerityUtils.java = victorhsieh@google.com
diff --git a/services/core/java/com/android/server/security/TEST_MAPPING b/core/java/com/android/internal/security/TEST_MAPPING
similarity index 100%
rename from services/core/java/com/android/server/security/TEST_MAPPING
rename to core/java/com/android/internal/security/TEST_MAPPING
diff --git a/services/core/java/com/android/server/security/VerityUtils.java b/core/java/com/android/internal/security/VerityUtils.java
similarity index 97%
rename from services/core/java/com/android/server/security/VerityUtils.java
rename to core/java/com/android/internal/security/VerityUtils.java
index 48a60387..ef703a9 100644
--- a/services/core/java/com/android/server/security/VerityUtils.java
+++ b/core/java/com/android/internal/security/VerityUtils.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.security;
+package com.android.internal.security;
import android.annotation.NonNull;
import android.os.Build;
@@ -42,7 +42,7 @@
import java.util.Arrays;
/** Provides fsverity related operations. */
-abstract public class VerityUtils {
+public abstract class VerityUtils {
private static final String TAG = "VerityUtils";
/**
@@ -156,8 +156,8 @@
return SetupResult.failed();
}
return SetupResult.ok(Os.dup(rfd), contentSize);
- } catch (IOException | SecurityException | DigestException | NoSuchAlgorithmException |
- SignatureNotFoundException | ErrnoException e) {
+ } catch (IOException | SecurityException | DigestException | NoSuchAlgorithmException
+ | SignatureNotFoundException | ErrnoException e) {
Slog.e(TAG, "Failed to set up apk verity: ", e);
return SetupResult.failed();
} finally {
@@ -243,14 +243,20 @@
private final FileDescriptor mFileDescriptor;
private final int mContentSize;
+ /** @deprecated */
+ @Deprecated
public static SetupResult ok(@NonNull FileDescriptor fileDescriptor, int contentSize) {
return new SetupResult(RESULT_OK, fileDescriptor, contentSize);
}
+ /** @deprecated */
+ @Deprecated
public static SetupResult skipped() {
return new SetupResult(RESULT_SKIPPED, null, -1);
}
+ /** @deprecated */
+ @Deprecated
public static SetupResult failed() {
return new SetupResult(RESULT_FAILED, null, -1);
}
diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
index ee94ef8..85114e5 100644
--- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -42,7 +42,8 @@
// Uses CellIdentity which is Parcelable here; will convert to CellLocation in client.
void onCellLocationChanged(in CellIdentity location);
- void onCallStateChanged(int state, String incomingNumber);
+ void onLegacyCallStateChanged(int state, String incomingNumber);
+ void onCallStateChanged(int state);
void onDataConnectionStateChanged(int state, int networkType);
void onDataActivity(int direction);
void onSignalStrengthsChanged(in SignalStrength signalStrength);
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index dc6880e..90c7282 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -175,7 +175,7 @@
mEnabled = properties.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED);
for (int action : ACTIONS_ALL) {
mTraceThresholdPerAction[action] =
- properties.getInt(getTraceTriggerNameForAction(action), -1);
+ properties.getInt(getNameOfAction(STATSD_ACTION[action]), -1);
}
}
}
diff --git a/core/java/com/android/internal/util/ScreenRecordHelper.java b/core/java/com/android/internal/util/ScreenRecordHelper.java
deleted file mode 100644
index ec7ed4e..0000000
--- a/core/java/com/android/internal/util/ScreenRecordHelper.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2018 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.internal.util;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-
-/**
- * Helper class to initiate a screen recording
- */
-public class ScreenRecordHelper {
- private final Context mContext;
-
- /**
- * Create a new ScreenRecordHelper for the given context
- * @param context
- */
- public ScreenRecordHelper(Context context) {
- mContext = context;
- }
-
- /**
- * Show dialog of screen recording options to user.
- */
- public void launchRecordPrompt() {
- final ComponentName launcherComponent = ComponentName.unflattenFromString(
- mContext.getResources().getString(
- com.android.internal.R.string.config_screenRecorderComponent));
- final Intent intent = new Intent();
- intent.setComponent(launcherComponent);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivity(intent);
- }
-}
diff --git a/core/java/com/android/internal/view/IInputMethod.aidl b/core/java/com/android/internal/view/IInputMethod.aidl
index c336373..8d82e33 100644
--- a/core/java/com/android/internal/view/IInputMethod.aidl
+++ b/core/java/com/android/internal/view/IInputMethod.aidl
@@ -35,7 +35,8 @@
* {@hide}
*/
oneway interface IInputMethod {
- void initializeInternal(IBinder token, int displayId, IInputMethodPrivilegedOperations privOps);
+ void initializeInternal(IBinder token, int displayId, IInputMethodPrivilegedOperations privOps,
+ int configChanges);
void onCreateInlineSuggestionsRequest(in InlineSuggestionsRequestInfo requestInfo,
in IInlineSuggestionsRequestCallback cb);
diff --git a/core/java/com/android/internal/view/OWNERS b/core/java/com/android/internal/view/OWNERS
index 851d1f3..eb2478f 100644
--- a/core/java/com/android/internal/view/OWNERS
+++ b/core/java/com/android/internal/view/OWNERS
@@ -18,3 +18,7 @@
per-file BaseIWIndow.java = file:/services/core/java/com/android/server/wm/OWNERS
per-file RotationPolicy.java = file:/services/core/java/com/android/server/wm/OWNERS
per-file WindowManagerPolicyThread.java = file:/services/core/java/com/android/server/wm/OWNERS
+
+# Scroll Capture
+per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
+per-file *CaptureHelper*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
diff --git a/core/java/com/android/internal/widget/ImageFloatingTextView.java b/core/java/com/android/internal/widget/ImageFloatingTextView.java
index e143498..2695b9c 100644
--- a/core/java/com/android/internal/widget/ImageFloatingTextView.java
+++ b/core/java/com/android/internal/widget/ImageFloatingTextView.java
@@ -36,8 +36,10 @@
@RemoteViews.RemoteView
public class ImageFloatingTextView extends TextView {
- /** Number of lines from the top to indent */
- private int mIndentLines;
+ /** Number of lines from the top to indent. */
+ private int mIndentLines = 0;
+ /** Whether or not there is an image to indent for. */
+ private boolean mHasImage = false;
/** Resolved layout direction */
private int mResolvedDirection = LAYOUT_DIRECTION_UNDEFINED;
@@ -96,7 +98,7 @@
// we set the endmargin on the requested number of lines.
int[] margins = null;
- if (mIndentLines > 0) {
+ if (mHasImage && mIndentLines > 0) {
margins = new int[mIndentLines + 1];
for (int i = 0; i < mIndentLines; i++) {
margins[i] = mImageEndMargin;
@@ -111,9 +113,24 @@
return builder.build();
}
+ /**
+ * @param imageEndMargin the end margin (in pixels) to indent the first few lines of the text
+ */
@RemotableViewMethod
public void setImageEndMargin(int imageEndMargin) {
- mImageEndMargin = imageEndMargin;
+ if (mImageEndMargin != imageEndMargin) {
+ mImageEndMargin = imageEndMargin;
+ invalidateTextIfIndenting();
+ }
+ }
+
+ /**
+ * @param imageEndMarginDp the end margin (in dp) to indent the first few lines of the text
+ */
+ @RemotableViewMethod
+ public void setImageEndMarginDp(float imageEndMarginDp) {
+ setImageEndMargin(
+ (int) (imageEndMarginDp * getResources().getDisplayMetrics().density));
}
@Override
@@ -121,7 +138,7 @@
int availableHeight = MeasureSpec.getSize(heightMeasureSpec) - mPaddingTop - mPaddingBottom;
if (getLayout() != null && getLayout().getHeight() != availableHeight) {
// We've been measured before and the new size is different than before, lets make sure
- // we reset the maximum lines, otherwise we may be cut short
+ // we reset the maximum lines, otherwise the last line of text may be partially cut off
mMaxLinesForHeight = -1;
nullLayouts();
}
@@ -130,7 +147,7 @@
if (layout.getHeight() > availableHeight) {
// With the existing layout, not all of our lines fit on the screen, let's find the
// first one that fits and ellipsize at that one.
- int maxLines = layout.getLineCount() - 1;
+ int maxLines = layout.getLineCount();
while (maxLines > 1 && layout.getLineBottom(maxLines - 1) > availableHeight) {
maxLines--;
}
@@ -152,31 +169,43 @@
if (layoutDirection != mResolvedDirection && isLayoutDirectionResolved()) {
mResolvedDirection = layoutDirection;
- if (mIndentLines > 0) {
- // Invalidate layout.
- nullLayouts();
- requestLayout();
- }
+ invalidateTextIfIndenting();
}
}
+ private void invalidateTextIfIndenting() {
+ if (mHasImage && mIndentLines > 0) {
+ // Invalidate layout.
+ nullLayouts();
+ requestLayout();
+ }
+ }
+
+ /**
+ * @param hasImage whether there is an image to wrap text around.
+ */
@RemotableViewMethod
public void setHasImage(boolean hasImage) {
- setNumIndentLines(hasImage ? 2 : 0);
+ setHasImageAndNumIndentLines(hasImage, mIndentLines);
}
/**
* @param lines the number of lines at the top that should be indented by indentEnd
- * @return whether a change was made
*/
- public boolean setNumIndentLines(int lines) {
- if (mIndentLines != lines) {
- mIndentLines = lines;
- // Invalidate layout.
+ @RemotableViewMethod
+ public void setNumIndentLines(int lines) {
+ setHasImageAndNumIndentLines(mHasImage, lines);
+ }
+
+ private void setHasImageAndNumIndentLines(boolean hasImage, int lines) {
+ int oldEffectiveLines = mHasImage ? mIndentLines : 0;
+ int newEffectiveLines = hasImage ? lines : 0;
+ mIndentLines = lines;
+ mHasImage = hasImage;
+ if (oldEffectiveLines != newEffectiveLines) {
+ // always invalidate layout.
nullLayouts();
requestLayout();
- return true;
}
- return false;
}
}
diff --git a/core/java/com/android/internal/widget/OWNERS b/core/java/com/android/internal/widget/OWNERS
index d284d51..8e68be0 100644
--- a/core/java/com/android/internal/widget/OWNERS
+++ b/core/java/com/android/internal/widget/OWNERS
@@ -1,4 +1,6 @@
per-file PointerLocationView.java = michaelwr@google.com, svv@google.com
+per-file RecyclerView.java = mount@google.com
+per-file ViewPager.java = mount@google.com
# LockSettings related
per-file *LockPattern* = file:/services/core/java/com/android/server/locksettings/OWNERS
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index d6d3387..a153fab 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -1,4 +1,3 @@
-
package {
default_applicable_licenses: ["frameworks_base_core_jni_license"],
}
@@ -69,10 +68,9 @@
"liblog",
"libminikin",
"libz",
- "libziparchive",
],
- static_libs: ["libnativehelper_lazy"],
+ static_libs: ["libnativehelper_lazy", "libziparchive_for_incfs", ],
export_include_dirs: [
".",
@@ -214,10 +212,12 @@
"com_android_internal_os_Zygote.cpp",
"com_android_internal_os_ZygoteCommandBuffer.cpp",
"com_android_internal_os_ZygoteInit.cpp",
+ "com_android_internal_security_VerityUtils.cpp",
"hwbinder/EphemeralStorage.cpp",
"fd_utils.cpp",
"android_hardware_input_InputWindowHandle.cpp",
"android_hardware_input_InputApplicationHandle.cpp",
+ "permission_utils.cpp",
],
static_libs: [
@@ -236,6 +236,7 @@
"audioflinger-aidl-cpp",
"av-types-aidl-cpp",
"android.hardware.camera.device@3.2",
+ "media_permission-aidl-cpp",
"libandroidicu",
"libbpf_android",
"libnetdbpf",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index ddd8613..3bc0ef4e 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -97,6 +97,7 @@
extern int register_android_media_MicrophoneInfo(JNIEnv *env);
extern int register_android_media_ToneGenerator(JNIEnv *env);
extern int register_android_media_midi(JNIEnv *env);
+extern int register_android_media_permission_Identity(JNIEnv* env);
namespace android {
@@ -200,6 +201,7 @@
extern int register_com_android_internal_os_Zygote(JNIEnv *env);
extern int register_com_android_internal_os_ZygoteCommandBuffer(JNIEnv *env);
extern int register_com_android_internal_os_ZygoteInit(JNIEnv *env);
+extern int register_com_android_internal_security_VerityUtils(JNIEnv* env);
extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
// Namespace for Android Runtime flags applied during boot time.
@@ -1534,6 +1536,7 @@
REG_JNI(register_com_android_internal_os_Zygote),
REG_JNI(register_com_android_internal_os_ZygoteCommandBuffer),
REG_JNI(register_com_android_internal_os_ZygoteInit),
+ REG_JNI(register_com_android_internal_security_VerityUtils),
REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
REG_JNI(register_android_hardware_Camera),
REG_JNI(register_android_hardware_camera2_CameraMetadata),
@@ -1562,6 +1565,7 @@
REG_JNI(register_android_media_RemoteDisplay),
REG_JNI(register_android_media_ToneGenerator),
REG_JNI(register_android_media_midi),
+ REG_JNI(register_android_media_permission_Identity),
REG_JNI(register_android_opengl_classes),
REG_JNI(register_android_server_NetworkManagementSocketTagger),
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 0e0f98e..7d3febb 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -22,6 +22,7 @@
#include <jni.h>
#include <nativehelper/JNIHelp.h>
#include "core_jni_helpers.h"
+#include "permission_utils.h"
#include <utils/Log.h>
#include <media/AudioRecord.h>
@@ -39,6 +40,9 @@
// ----------------------------------------------------------------------------
+using android::media::permission::convertIdentity;
+using android::media::permission::Identity;
+
using namespace android;
// ----------------------------------------------------------------------------
@@ -181,12 +185,11 @@
}
// ----------------------------------------------------------------------------
-static jint
-android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
- jobject jaa, jintArray jSampleRate, jint channelMask, jint channelIndexMask,
- jint audioFormat, jint buffSizeInBytes, jintArray jSession, jstring opPackageName,
- jlong nativeRecordInJavaObj)
-{
+static jint android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
+ jobject jaa, jintArray jSampleRate, jint channelMask,
+ jint channelIndexMask, jint audioFormat,
+ jint buffSizeInBytes, jintArray jSession,
+ jobject jIdentity, jlong nativeRecordInJavaObj) {
//ALOGV(">> Entering android_media_AudioRecord_setup");
//ALOGV("sampleRate=%d, audioFormat=%d, channel mask=%x, buffSizeInBytes=%d "
// "nativeRecordInJavaObj=0x%llX",
@@ -262,10 +265,8 @@
size_t frameSize = channelCount * bytesPerSample;
size_t frameCount = buffSizeInBytes / frameSize;
- ScopedUtfChars opPackageNameStr(env, opPackageName);
-
// create an uninitialized AudioRecord object
- lpRecorder = new AudioRecord(String16(opPackageNameStr.c_str()));
+ lpRecorder = new AudioRecord(convertIdentity(env, jIdentity));
// read the AudioAttributes values
auto paa = JNIAudioAttributeHelper::makeUnique();
@@ -373,8 +374,6 @@
return (jint) AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED;
}
-
-
// ----------------------------------------------------------------------------
static jint
android_media_AudioRecord_start(JNIEnv *env, jobject thiz, jint event, jint triggerSession)
@@ -893,9 +892,11 @@
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
static const JNINativeMethod gMethods[] = {
+ // name, signature, funcPtr
{"native_start", "(II)I", (void *)android_media_AudioRecord_start},
{"native_stop", "()V", (void *)android_media_AudioRecord_stop},
- {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;[IIIII[ILjava/lang/String;J)I",
+ {"native_setup",
+ "(Ljava/lang/Object;Ljava/lang/Object;[IIIII[ILandroid/media/permission/Identity;J)I",
(void *)android_media_AudioRecord_setup},
{"native_finalize", "()V", (void *)android_media_AudioRecord_finalize},
{"native_release", "()V", (void *)android_media_AudioRecord_release},
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 94bd28a..f102edc 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -2204,13 +2204,11 @@
return jStatus;
}
-static jint
-android_media_AudioSystem_getSurroundFormats(JNIEnv *env, jobject thiz,
- jobject jSurroundFormats, jboolean reported)
-{
+static jint android_media_AudioSystem_getSurroundFormats(JNIEnv *env, jobject thiz,
+ jobject jSurroundFormats) {
ALOGV("getSurroundFormats");
- if (jSurroundFormats == NULL) {
+ if (jSurroundFormats == nullptr) {
ALOGE("jSurroundFormats is NULL");
return (jint)AUDIO_JAVA_BAD_VALUE;
}
@@ -2221,10 +2219,10 @@
jint jStatus;
unsigned int numSurroundFormats = 0;
- audio_format_t *surroundFormats = NULL;
- bool *surroundFormatsEnabled = NULL;
- status_t status = AudioSystem::getSurroundFormats(
- &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
+ audio_format_t *surroundFormats = nullptr;
+ bool *surroundFormatsEnabled = nullptr;
+ status_t status = AudioSystem::getSurroundFormats(&numSurroundFormats, surroundFormats,
+ surroundFormatsEnabled);
if (status != NO_ERROR) {
ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
jStatus = nativeToJavaStatus(status);
@@ -2236,8 +2234,8 @@
}
surroundFormats = (audio_format_t *)calloc(numSurroundFormats, sizeof(audio_format_t));
surroundFormatsEnabled = (bool *)calloc(numSurroundFormats, sizeof(bool));
- status = AudioSystem::getSurroundFormats(
- &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
+ status = AudioSystem::getSurroundFormats(&numSurroundFormats, surroundFormats,
+ surroundFormatsEnabled);
jStatus = nativeToJavaStatus(status);
if (status != NO_ERROR) {
ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
@@ -2258,6 +2256,50 @@
return jStatus;
}
+static jint android_media_AudioSystem_getReportedSurroundFormats(JNIEnv *env, jobject thiz,
+ jobject jSurroundFormats) {
+ ALOGV("getReportedSurroundFormats");
+
+ if (jSurroundFormats == nullptr) {
+ ALOGE("jSurroundFormats is NULL");
+ return (jint)AUDIO_JAVA_BAD_VALUE;
+ }
+ if (!env->IsInstanceOf(jSurroundFormats, gArrayListClass)) {
+ ALOGE("jSurroundFormats not an arraylist");
+ return (jint)AUDIO_JAVA_BAD_VALUE;
+ }
+ jint jStatus;
+ unsigned int numSurroundFormats = 0;
+ audio_format_t *surroundFormats = nullptr;
+ status_t status = AudioSystem::getReportedSurroundFormats(&numSurroundFormats, surroundFormats);
+ if (status != NO_ERROR) {
+ ALOGE_IF(status != NO_ERROR, "AudioSystem::getReportedSurroundFormats error %d", status);
+ jStatus = nativeToJavaStatus(status);
+ goto exit;
+ }
+ if (numSurroundFormats == 0) {
+ jStatus = (jint)AUDIO_JAVA_SUCCESS;
+ goto exit;
+ }
+ surroundFormats = (audio_format_t *)calloc(numSurroundFormats, sizeof(audio_format_t));
+ status = AudioSystem::getReportedSurroundFormats(&numSurroundFormats, surroundFormats);
+ jStatus = nativeToJavaStatus(status);
+ if (status != NO_ERROR) {
+ ALOGE_IF(status != NO_ERROR, "AudioSystem::getReportedSurroundFormats error %d", status);
+ goto exit;
+ }
+ for (size_t i = 0; i < numSurroundFormats; i++) {
+ jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor,
+ audioFormatFromNative(surroundFormats[i]));
+ env->CallObjectMethod(jSurroundFormats, gArrayListMethods.add, surroundFormat);
+ env->DeleteLocalRef(surroundFormat);
+ }
+
+exit:
+ free(surroundFormats);
+ return jStatus;
+}
+
static jint
android_media_AudioSystem_setSurroundFormatEnabled(JNIEnv *env, jobject thiz,
jint audioFormat, jboolean enabled)
@@ -2619,8 +2661,10 @@
(void *)android_media_AudioSystem_getOffloadSupport},
{"getMicrophones", "(Ljava/util/ArrayList;)I",
(void *)android_media_AudioSystem_getMicrophones},
- {"getSurroundFormats", "(Ljava/util/Map;Z)I",
+ {"getSurroundFormats", "(Ljava/util/Map;)I",
(void *)android_media_AudioSystem_getSurroundFormats},
+ {"getReportedSurroundFormats", "(Ljava/util/ArrayList;)I",
+ (void *)android_media_AudioSystem_getReportedSurroundFormats},
{"setSurroundFormatEnabled", "(IZ)I",
(void *)android_media_AudioSystem_setSurroundFormatEnabled},
{"setAssistantUid", "(I)I", (void *)android_media_AudioSystem_setAssistantUid},
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index cae6db5..62767a6 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -48,6 +48,7 @@
using namespace android;
using ::android::media::VolumeShaper;
+using ::android::media::permission::Identity;
// ----------------------------------------------------------------------------
static const char* const kClassPathName = "android/media/AudioTrack";
@@ -328,7 +329,10 @@
// create the native AudioTrack object
ScopedUtfChars opPackageNameStr(env, opPackageName);
- lpTrack = new AudioTrack(opPackageNameStr.c_str());
+ // TODO b/182469354: make consistent with AudioRecord
+ Identity identity = Identity();
+ identity.packageName = std::string(opPackageNameStr.c_str());
+ lpTrack = new AudioTrack(identity);
// read the AudioAttributes values
auto paa = JNIAudioAttributeHelper::makeUnique();
@@ -390,8 +394,8 @@
sessionId, // audio session ID
offload ? AudioTrack::TRANSFER_SYNC_NOTIF_CALLBACK
: AudioTrack::TRANSFER_SYNC,
- (offload || encapsulationMode) ? &offloadInfo : NULL, -1,
- -1, // default uid, pid values
+ (offload || encapsulationMode) ? &offloadInfo : NULL,
+ Identity(), // default uid, pid values
paa.get());
break;
@@ -416,8 +420,8 @@
true, // thread can call Java
sessionId, // audio session ID
AudioTrack::TRANSFER_SHARED,
- NULL, // default offloadInfo
- -1, -1, // default uid, pid values
+ NULL, // default offloadInfo
+ Identity(), // default uid, pid values
paa.get());
break;
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index 5e142fd..ab6633f 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -57,6 +57,7 @@
jmethodID dispatchInputEvent;
jmethodID onFocusEvent;
jmethodID onPointerCaptureEvent;
+ jmethodID onDragEvent;
jmethodID onBatchedInputEventPending;
} gInputEventReceiverClassInfo;
@@ -400,6 +401,18 @@
finishInputEvent(seq, true /* handled */);
continue;
}
+ case AINPUT_EVENT_TYPE_DRAG: {
+ const DragEvent* dragEvent = static_cast<DragEvent*>(inputEvent);
+ if (kDebugDispatchCycle) {
+ ALOGD("channel '%s' ~ Received drag event: isExiting=%s",
+ getInputChannelName().c_str(), toString(dragEvent->isExiting()));
+ }
+ env->CallVoidMethod(receiverObj.get(), gInputEventReceiverClassInfo.onDragEvent,
+ jboolean(dragEvent->isExiting()), dragEvent->getX(),
+ dragEvent->getY());
+ finishInputEvent(seq, true /* handled */);
+ continue;
+ }
default:
assert(false); // InputConsumer should prevent this from ever happening
@@ -547,6 +560,8 @@
gInputEventReceiverClassInfo.onPointerCaptureEvent =
GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "onPointerCaptureEvent",
"(Z)V");
+ gInputEventReceiverClassInfo.onDragEvent =
+ GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "onDragEvent", "(ZFF)V");
gInputEventReceiverClassInfo.onBatchedInputEventPending =
GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "onBatchedInputEventPending",
"(I)V");
diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp
index 9746a07..96326f5 100644
--- a/core/jni/android_view_InputEventSender.cpp
+++ b/core/jni/android_view_InputEventSender.cpp
@@ -34,6 +34,8 @@
#include "core_jni_helpers.h"
+using android::base::Result;
+
namespace android {
// Log debug messages about the dispatch cycle.
@@ -197,16 +199,9 @@
ScopedLocalRef<jobject> senderObj(env, NULL);
bool skipCallbacks = false;
for (;;) {
- uint32_t publishedSeq;
- bool handled;
- std::function<void(uint32_t seq, bool handled, nsecs_t consumeTime)> callback =
- [&publishedSeq, &handled](uint32_t inSeq, bool inHandled,
- nsecs_t inConsumeTime) -> void {
- publishedSeq = inSeq;
- handled = inHandled;
- };
- status_t status = mInputPublisher.receiveFinishedSignal(callback);
- if (status) {
+ Result<InputPublisher::Finished> result = mInputPublisher.receiveFinishedSignal();
+ if (!result.ok()) {
+ const status_t status = result.error().code();
if (status == WOULD_BLOCK) {
return OK;
}
@@ -215,7 +210,7 @@
return status;
}
- auto it = mPublishedSeqMap.find(publishedSeq);
+ auto it = mPublishedSeqMap.find(result->seq);
if (it == mPublishedSeqMap.end()) {
continue;
}
@@ -225,9 +220,9 @@
if (kDebugDispatchCycle) {
ALOGD("channel '%s' ~ Received finished signal, seq=%u, handled=%s, "
- "pendingEvents=%zu.",
- getInputChannelName().c_str(), seq, handled ? "true" : "false",
- mPublishedSeqMap.size());
+ "pendingEvents=%zu.",
+ getInputChannelName().c_str(), seq, result->handled ? "true" : "false",
+ mPublishedSeqMap.size());
}
if (!skipCallbacks) {
@@ -241,8 +236,9 @@
}
env->CallVoidMethod(senderObj.get(),
- gInputEventSenderClassInfo.dispatchInputEventFinished,
- jint(seq), jboolean(handled));
+ gInputEventSenderClassInfo.dispatchInputEventFinished,
+ static_cast<jint>(result->seq),
+ static_cast<jboolean>(result->handled));
if (env->ExceptionCheck()) {
ALOGE("Exception dispatching finished signal.");
skipCallbacks = true;
diff --git a/core/jni/com_android_internal_os_KernelCpuBpfTracking.cpp b/core/jni/com_android_internal_os_KernelCpuBpfTracking.cpp
index 6b41b2e..d644e37 100644
--- a/core/jni/com_android_internal_os_KernelCpuBpfTracking.cpp
+++ b/core/jni/com_android_internal_os_KernelCpuBpfTracking.cpp
@@ -30,13 +30,13 @@
static jlongArray KernelCpuBpfTracking_getFreqsInternal(JNIEnv *env, jobject) {
auto freqs = android::bpf::getCpuFreqs();
- if (!freqs) return NULL;
+ if (!freqs) return nullptr;
std::vector<uint64_t> allFreqs;
for (const auto &vec : *freqs) std::copy(vec.begin(), vec.end(), std::back_inserter(allFreqs));
auto ar = env->NewLongArray(allFreqs.size());
- if (ar != NULL) {
+ if (ar != nullptr) {
env->SetLongArrayRegion(ar, 0, allFreqs.size(),
reinterpret_cast<const jlong *>(allFreqs.data()));
}
@@ -45,7 +45,7 @@
static jintArray KernelCpuBpfTracking_getFreqsClustersInternal(JNIEnv *env, jobject) {
auto freqs = android::bpf::getCpuFreqs();
- if (!freqs) return NULL;
+ if (!freqs) return nullptr;
std::vector<uint32_t> freqsClusters;
uint32_t clusters = freqs->size();
@@ -54,7 +54,7 @@
}
auto ar = env->NewIntArray(freqsClusters.size());
- if (ar != NULL) {
+ if (ar != nullptr) {
env->SetIntArrayRegion(ar, 0, freqsClusters.size(),
reinterpret_cast<const jint *>(freqsClusters.data()));
}
diff --git a/core/jni/com_android_internal_os_KernelCpuTotalBpfMapReader.cpp b/core/jni/com_android_internal_os_KernelCpuTotalBpfMapReader.cpp
index ad43014..472bd23 100644
--- a/core/jni/com_android_internal_os_KernelCpuTotalBpfMapReader.cpp
+++ b/core/jni/com_android_internal_os_KernelCpuTotalBpfMapReader.cpp
@@ -22,7 +22,7 @@
static jlongArray KernelCpuTotalBpfMapReader_readInternal(JNIEnv *env, jobject) {
auto freqTimes = android::bpf::getTotalCpuFreqTimes();
- if (!freqTimes) return JNI_FALSE;
+ if (!freqTimes) return nullptr;
std::vector<uint64_t> allTimes;
for (const auto &vec : *freqTimes) {
@@ -32,7 +32,7 @@
}
auto ar = env->NewLongArray(allTimes.size());
- if (ar != NULL) {
+ if (ar != nullptr) {
env->SetLongArrayRegion(ar, 0, allTimes.size(),
reinterpret_cast<const jlong *>(allTimes.data()));
}
diff --git a/core/jni/com_android_internal_os_KernelCpuUidBpfMapReader.cpp b/core/jni/com_android_internal_os_KernelCpuUidBpfMapReader.cpp
index 7900d30..098a4d8 100644
--- a/core/jni/com_android_internal_os_KernelCpuUidBpfMapReader.cpp
+++ b/core/jni/com_android_internal_os_KernelCpuUidBpfMapReader.cpp
@@ -37,7 +37,7 @@
jlongArray ar = (jlongArray)env->CallObjectMethod(sparseAr, gSparseArrayClassInfo.get, uid);
if (!ar) {
ar = env->NewLongArray(sz);
- if (ar == NULL) return ar;
+ if (ar == nullptr) return ar;
env->CallVoidMethod(sparseAr, gSparseArrayClassInfo.put, uid, ar);
}
return ar;
@@ -65,7 +65,7 @@
static uint64_t lastUpdate = 0;
uint64_t newLastUpdate = lastUpdate;
auto sparseAr = env->GetObjectField(thiz, gmData);
- if (sparseAr == NULL) return false;
+ if (sparseAr == nullptr) return false;
auto data = android::bpf::getUidsUpdatedCpuFreqTimes(&newLastUpdate);
if (!data.has_value()) return false;
@@ -75,7 +75,7 @@
for (const auto &subVec : times) s += subVec.size();
}
jlongArray ar = getUidArray(env, sparseAr, uid, s);
- if (ar == NULL) return false;
+ if (ar == nullptr) return false;
copy2DVecToArray(env, ar, times);
}
lastUpdate = newLastUpdate;
@@ -91,7 +91,7 @@
static uint64_t lastUpdate = 0;
uint64_t newLastUpdate = lastUpdate;
auto sparseAr = env->GetObjectField(thiz, gmData);
- if (sparseAr == NULL) return false;
+ if (sparseAr == nullptr) return false;
auto data = android::bpf::getUidsUpdatedConcurrentTimes(&newLastUpdate);
if (!data.has_value()) return false;
@@ -99,7 +99,7 @@
// TODO: revise calling code so we can divide by NSEC_PER_MSEC here instead
for (auto &time : times.active) time /= NSEC_PER_MSEC;
jlongArray ar = getUidArray(env, sparseAr, uid, times.active.size());
- if (ar == NULL) return false;
+ if (ar == nullptr) return false;
env->SetLongArrayRegion(ar, 0, times.active.size(),
reinterpret_cast<const jlong *>(times.active.data()));
}
@@ -111,7 +111,7 @@
jlong nCpus = get_nprocs_conf();
auto ar = env->NewLongArray(1);
- if (ar != NULL) env->SetLongArrayRegion(ar, 0, 1, &nCpus);
+ if (ar != nullptr) env->SetLongArrayRegion(ar, 0, 1, &nCpus);
return ar;
}
@@ -124,7 +124,7 @@
static uint64_t lastUpdate = 0;
uint64_t newLastUpdate = lastUpdate;
auto sparseAr = env->GetObjectField(thiz, gmData);
- if (sparseAr == NULL) return false;
+ if (sparseAr == nullptr) return false;
auto data = android::bpf::getUidsUpdatedConcurrentTimes(&newLastUpdate);
if (!data.has_value()) return false;
@@ -134,7 +134,7 @@
for (const auto &subVec : times.policy) s += subVec.size();
}
jlongArray ar = getUidArray(env, sparseAr, uid, s);
- if (ar == NULL) return false;
+ if (ar == nullptr) return false;
copy2DVecToArray(env, ar, times.policy);
}
lastUpdate = newLastUpdate;
@@ -143,12 +143,12 @@
static jlongArray KernelCpuUidClusterTimeBpfMapReader_getDataDimensions(JNIEnv *env, jobject) {
auto times = android::bpf::getUidConcurrentTimes(0);
- if (!times.has_value()) return NULL;
+ if (!times.has_value()) return nullptr;
std::vector<jlong> clusterCores;
for (const auto &vec : times->policy) clusterCores.push_back(vec.size());
auto ar = env->NewLongArray(clusterCores.size());
- if (ar != NULL) env->SetLongArrayRegion(ar, 0, clusterCores.size(), clusterCores.data());
+ if (ar != nullptr) env->SetLongArrayRegion(ar, 0, clusterCores.size(), clusterCores.data());
return ar;
}
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 836074f..cf96fe6 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -184,6 +184,17 @@
/** The numeric value for the normal priority a process should have. */
static constexpr int PROCESS_PRIORITY_DEFAULT = 0;
+/** Exponential back off parameters for storage dir check. */
+static constexpr unsigned int STORAGE_DIR_CHECK_RETRY_MULTIPLIER = 2;
+static constexpr unsigned int STORAGE_DIR_CHECK_INIT_INTERVAL_US = 50;
+static constexpr unsigned int STORAGE_DIR_CHECK_MAX_INTERVAL_US = 1000;
+/**
+ * Lower bound time we allow storage dir check to sleep.
+ * If it exceeds 2s, PROC_START_TIMEOUT_MSG will kill the starting app anyway,
+ * so it's fine to assume max retries is 5 mins.
+ */
+static constexpr int STORAGE_DIR_CHECK_TIMEOUT_US = 1000 * 60 * 5;
+
/**
* A helper class containing accounting information for USAPs.
*/
@@ -1458,6 +1469,31 @@
}
}
+static void WaitUntilDirReady(const std::string& target, fail_fn_t fail_fn) {
+ unsigned int sleepIntervalUs = STORAGE_DIR_CHECK_INIT_INTERVAL_US;
+
+ // This is just an approximate value as it doesn't need to be very accurate.
+ unsigned int sleepTotalUs = 0;
+
+ const char* dir_path = target.c_str();
+ while (sleepTotalUs < STORAGE_DIR_CHECK_TIMEOUT_US) {
+ if (access(dir_path, F_OK) == 0) {
+ return;
+ }
+ // Failed, so we add exponential backoff and retry
+ usleep(sleepIntervalUs);
+ sleepTotalUs += sleepIntervalUs;
+ sleepIntervalUs = std::min<unsigned int>(
+ sleepIntervalUs * STORAGE_DIR_CHECK_RETRY_MULTIPLIER,
+ STORAGE_DIR_CHECK_MAX_INTERVAL_US);
+ }
+ // Last chance and get the latest errno if it fails.
+ if (access(dir_path, F_OK) == 0) {
+ return;
+ }
+ fail_fn(CREATE_ERROR("Error dir is not ready %s: %s", dir_path, strerror(errno)));
+}
+
static void BindMountStorageToLowerFs(const userid_t user_id, const uid_t uid,
const char* dir_name, const char* package, fail_fn_t fail_fn) {
bool hasSdcardFs = IsSdcardfsUsed();
@@ -1468,6 +1504,10 @@
source = StringPrintf("/mnt/pass_through/%d/emulated/%d/%s/%s", user_id, user_id, dir_name,
package);
}
+
+ // Directory might be not ready, as prepareStorageDirs() is running asynchronously in ProcessList,
+ // so wait until dir is created.
+ WaitUntilDirReady(source, fail_fn);
std::string target = StringPrintf("/storage/emulated/%d/%s/%s", user_id, dir_name, package);
// As the parent is mounted as tmpfs, we need to create the target dir here.
diff --git a/services/core/jni/com_android_server_security_VerityUtils.cpp b/core/jni/com_android_internal_security_VerityUtils.cpp
similarity index 91%
rename from services/core/jni/com_android_server_security_VerityUtils.cpp
rename to core/jni/com_android_internal_security_VerityUtils.cpp
index dda44fb..411a392 100644
--- a/services/core/jni/com_android_server_security_VerityUtils.cpp
+++ b/core/jni/com_android_internal_security_VerityUtils.cpp
@@ -19,8 +19,8 @@
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedPrimitiveArray.h>
#include <nativehelper/ScopedUtfChars.h>
-#include "jni.h"
#include <utils/Log.h>
+#include "jni.h"
#include <errno.h>
#include <fcntl.h>
@@ -39,7 +39,7 @@
namespace {
-int enableFsverity(JNIEnv* env, jobject /* clazz */, jstring filePath, jbyteArray signature) {
+int enableFsverity(JNIEnv *env, jobject /* clazz */, jstring filePath, jbyteArray signature) {
ScopedUtfChars path(env, filePath);
if (path.c_str() == nullptr) {
return EINVAL;
@@ -124,11 +124,11 @@
{"measureFsverityNative", "(Ljava/lang/String;[B)I", (void *)measureFsverity},
};
-} // namespace
+} // namespace
-int register_android_server_security_VerityUtils(JNIEnv* env) {
- return jniRegisterNativeMethods(env,
- "com/android/server/security/VerityUtils", sMethods, NELEM(sMethods));
+int register_com_android_internal_security_VerityUtils(JNIEnv *env) {
+ return jniRegisterNativeMethods(env, "com/android/internal/security/VerityUtils", sMethods,
+ NELEM(sMethods));
}
-} // namespace android
+} // namespace android
diff --git a/core/jni/permission_utils.cpp b/core/jni/permission_utils.cpp
new file mode 100644
index 0000000..2b7ef99
--- /dev/null
+++ b/core/jni/permission_utils.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+#include "permission_utils.h"
+#include "core_jni_helpers.h"
+
+static struct {
+ jfieldID fieldUid; // Identity.uid
+ jfieldID fieldPid; // Identity.pid
+ jfieldID fieldPackageName; // Identity.packageName
+ jfieldID fieldAttributionTag; // Identity.attributionTag
+} javaIdentityFields;
+
+static const JNINativeMethod method_table[] = {
+ // no static methods, currently
+};
+
+int register_android_media_permission_Identity(JNIEnv* env) {
+ jclass identityClass = android::FindClassOrDie(env, "android/media/permission/Identity");
+ javaIdentityFields.fieldUid = android::GetFieldIDOrDie(env, identityClass, "uid", "I");
+ javaIdentityFields.fieldPid = android::GetFieldIDOrDie(env, identityClass, "pid", "I");
+ javaIdentityFields.fieldPackageName =
+ android::GetFieldIDOrDie(env, identityClass, "packageName", "Ljava/lang/String;");
+ javaIdentityFields.fieldAttributionTag =
+ android::GetFieldIDOrDie(env, identityClass, "attributionTag", "Ljava/lang/String;");
+
+ return android::RegisterMethodsOrDie(env, "android/media/permission/Identity", method_table,
+ NELEM(method_table));
+}
+
+namespace android::media::permission {
+
+Identity convertIdentity(JNIEnv* env, const jobject& jIdentity) {
+ Identity identity;
+
+ identity.uid = env->GetIntField(jIdentity, javaIdentityFields.fieldUid);
+ identity.pid = env->GetIntField(jIdentity, javaIdentityFields.fieldPid);
+
+ jstring packageNameStr = static_cast<jstring>(
+ env->GetObjectField(jIdentity, javaIdentityFields.fieldPackageName));
+ if (packageNameStr == nullptr) {
+ identity.packageName = std::nullopt;
+ } else {
+ identity.packageName = std::string(ScopedUtfChars(env, packageNameStr).c_str());
+ }
+
+ jstring attributionTagStr = static_cast<jstring>(
+ env->GetObjectField(jIdentity, javaIdentityFields.fieldAttributionTag));
+ if (attributionTagStr == nullptr) {
+ identity.attributionTag = std::nullopt;
+ } else {
+ identity.attributionTag = std::string(ScopedUtfChars(env, attributionTagStr).c_str());
+ }
+
+ return identity;
+}
+
+} // namespace android::media::permission
diff --git a/core/jni/permission_utils.h b/core/jni/permission_utils.h
new file mode 100644
index 0000000..d625bb6
--- /dev/null
+++ b/core/jni/permission_utils.h
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android/media/permission/Identity.h>
+#include <jni.h>
+
+namespace android::media::permission {
+
+Identity convertIdentity(JNIEnv* env, const jobject& jIdentity);
+}
+
+int register_android_media_permission_Identity(JNIEnv* env);
diff --git a/core/proto/android/app/OWNERS b/core/proto/android/app/OWNERS
index 296abd1..cc479e6 100644
--- a/core/proto/android/app/OWNERS
+++ b/core/proto/android/app/OWNERS
@@ -1 +1 @@
-per-file location_time_zone_manager.proto = nfuller@google.com, mingaleev@google.com
+per-file location_time_zone_manager.proto, time_zone_detector.proto = nfuller@google.com, mingaleev@google.com
diff --git a/core/proto/android/app/location_time_zone_manager.proto b/core/proto/android/app/location_time_zone_manager.proto
index f44d549..891e9fc 100644
--- a/core/proto/android/app/location_time_zone_manager.proto
+++ b/core/proto/android/app/location_time_zone_manager.proto
@@ -17,6 +17,7 @@
syntax = "proto2";
package android.app.time;
+import "frameworks/base/core/proto/android/app/time_zone_detector.proto";
import "frameworks/base/core/proto/android/privacy.proto";
option java_multiple_files = true;
@@ -31,15 +32,6 @@
repeated TimeZoneProviderStateProto secondary_provider_states = 3;
}
-// Represents a GeolocationTimeZoneSuggestion that can be / has been passed to the time zone
-// detector.
-message GeolocationTimeZoneSuggestionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- repeated string zone_ids = 1;
- repeated string debug_info = 2;
-}
-
// The state tracked for a LocationTimeZoneProvider.
message TimeZoneProviderStateProto {
option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/app/time_zone_detector.proto b/core/proto/android/app/time_zone_detector.proto
new file mode 100644
index 0000000..b33ca1d
--- /dev/null
+++ b/core/proto/android/app/time_zone_detector.proto
@@ -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.
+ */
+
+syntax = "proto2";
+package android.app.time;
+
+import "frameworks/base/core/proto/android/privacy.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "TimeZoneDetectorProto";
+
+// Represents a GeolocationTimeZoneSuggestion that can be / has been passed to the time zone
+// detector.
+message GeolocationTimeZoneSuggestionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ repeated string zone_ids = 1;
+ repeated string debug_info = 2;
+}
+
+/*
+ * An obfuscated and simplified time zone suggestion for metrics use.
+ *
+ * The suggestion's time zone IDs (which relate to location) are obfuscated by
+ * mapping them to an ordinal. When the ordinal is assigned consistently across
+ * several objects (i.e. so the same time zone ID is always mapped to the same
+ * ordinal), this allows comparisons between those objects. For example, we can
+ * answer "did these two suggestions agree?", "does the suggestion match the
+ * device's current time zone?", without leaking knowledge of location. Ordinals
+ * are also significantly more compact than full IANA TZDB IDs, albeit highly
+ * unstable and of limited use.
+ */
+message MetricsTimeZoneSuggestion {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ enum Type {
+ CERTAIN = 1;
+ UNCERTAIN = 2;
+ }
+ optional Type type = 1;
+
+ // The ordinals for time zone(s) in the suggestion. Always empty for
+ // UNCERTAIN, and can be empty for CERTAIN, for example when the device is in
+ // a disputed area / on an ocean.
+ repeated uint32 time_zone_ordinals = 2;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f7eb364..99ad6d1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -506,6 +506,8 @@
<protected-broadcast android:name="android.app.action.ACTION_PASSWORD_FAILED" />
<protected-broadcast android:name="android.app.action.ACTION_PASSWORD_SUCCEEDED" />
<protected-broadcast android:name="com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION" />
+ <protected-broadcast android:name="com.android.server.ACTION_PROFILE_OFF_DEADLINE" />
+ <protected-broadcast android:name="com.android.server.ACTION_TURN_PROFILE_ON_NOTIFICATION" />
<protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_ADDED" />
<protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_UNLOCKED" />
@@ -5257,15 +5259,20 @@
<permission android:name="android.permission.MANAGE_MUSIC_RECOGNITION"
android:protectionLevel="signature|privileged" />
+ <!-- @SystemApi Allows an application to manage speech recognition service.
+ @hide <p>Not for use by third-party applications.</p> -->
+ <permission android:name="android.permission.MANAGE_SPEECH_RECOGNITION"
+ android:protectionLevel="signature" />
+
<!-- @SystemApi Allows an application to manage the content suggestions service.
@hide <p>Not for use by third-party applications.</p> -->
<permission android:name="android.permission.MANAGE_CONTENT_SUGGESTIONS"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature" />
<!-- @SystemApi Allows an application to manage the app predictions service.
@hide <p>Not for use by third-party applications.</p> -->
<permission android:name="android.permission.MANAGE_APP_PREDICTIONS"
- android:protectionLevel="signature|appPredictor" />
+ android:protectionLevel="signature|appPredictor" />
<!-- @SystemApi Allows an application to manage the search ui service.
@hide <p>Not for use by third-party applications.</p> -->
diff --git a/core/res/res/layout/notification_template_text_multiline.xml b/core/res/res/layout/notification_template_text_multiline.xml
index d632ac9..ec493bc 100644
--- a/core/res/res/layout/notification_template_text_multiline.xml
+++ b/core/res/res/layout/notification_template_text_multiline.xml
@@ -22,7 +22,7 @@
android:layout_gravity="top"
android:layout_marginTop="@dimen/notification_text_margin_top"
android:minHeight="@dimen/notification_text_height"
- android:ellipsize="marquee"
+ android:ellipsize="end"
android:fadingEdge="horizontal"
android:gravity="top"
android:maxLines="2"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 648d2a1..7d7b731 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Laat die program toe om jou fotoversameling te wysig."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lees liggings in jou mediaversameling"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Laat die program toe om liggings in jou mediaversameling te lees."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Gebruik biometrie"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gebruik biometrie of skermslot"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifieer dat dit jy is"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gebruik jou biometrie om voort te gaan"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometriese hardeware is nie beskikbaar nie"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Stawing is gekanselleer"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nie herken nie"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Stawing is gekanselleer"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Geen PIN, patroon of wagwoord is gestel nie"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Kon nie staaf nie"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gebruik skermslot"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Voer jou toesteleiebewys in om voort te gaan."</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Gedeeltelike vingerafdruk is bespeur. Probeer asseblief weer."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kon nie vingerafdruk verwerk nie. Probeer asseblief weer."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Vingerafdruksensor is vuil. Maak dit skoon en probeer weer."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Hierdie toetstel het nie \'n vingerafdruksensor nie."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor is tydelik gedeaktiveer."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gebruik vingerafdruk"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gebruik vingerafdruk of skermslot"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gebruik jou vingerafdruk om voort te gaan"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Gesigslot word nie op hierdie toestel gesteun nie."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor is tydelik gedeaktiveer."</string>
<string name="face_name_template" msgid="3877037340223318119">"Gesig <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Gebruik gesigslot"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gebruik gesig- of skermslot"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Gebruik gesigslot om voort te gaan"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Gesig-ikoon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Nuus en tydskrifte"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kaarte en navigasie"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktiwiteit"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Toeganklikheid"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Toestelberging"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-ontfouting"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"uur"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index eb98c69..254ca9c 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"መተግበሪያው የፎቶ ስብስብዎን እንዲቀይረው ያስችለዋል።"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"አካባቢዎችን ከሚዲያ ስብስብዎ ማንበብ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"መተግበሪያው አካባቢዎችን ከሚዲያ ስብስብዎ እንዲያነብብ ያስችለዋል።"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ባዮሜትሪኮችን ይጠቀሙ"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ባዮሜትሪክስ ወይም ማያ ገጽ መቆለፊያን ይጠቀሙ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"እርስዎን መሆንዎን ያረጋግጡ"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ለመቀጠል ባዮሜትሪክዎን ይጠቀሙ"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ባዮሜትራዊ ሃርድዌር አይገኝም"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"ማረጋገጥ ተሰርዟል"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"አልታወቀም"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"ማረጋገጥ ተሰርዟል"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"ምንም ፒን፣ ሥርዓተ ጥለት ወይም የይለፍ ቃል አልተቀናበረም"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"ማረጋገጥ ላይ ስህተት"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"የማያ ገጽ መቆለፊን ይጠቀሙ"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"ለመቀጠል የመሣሪያዎን የመግቢያ ማስረጃ ያስገቡ"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"ከፊል የጣት አሻራ ተገኝቷል። እባክዎ እንደገና ይሞክሩ።"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ጣት አሻራን መስራት አልተቻለም። እባክዎ እንደገና ይሞክሩ።"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"የጣት አሻራ ዳሳሽ ቆሽሿል። እባክዎ ያጽዱት እና እንደገና ይሞክሩ።"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ይህ መሣሪያ የጣት አሻራ ዳሳሽ የለውም።"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ዳሳሽ ለጊዜው ተሰናክሏል።"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ጣት <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"የጣት አሻራ ይጠቀሙ"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"የጣት አሻራ ወይም የማያ ገጽ መቆለፊያ ይጠቀሙ"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ለመቀጠል የእርስዎን የጣት አሻራ ይጠቀሙ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"በመልክ መክፈት መስጫ በዚህ መሣሪያ ላይ አይደገፍም።"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"ዳሳሽ ለጊዜው ተሰናክሏል።"</string>
<string name="face_name_template" msgid="3877037340223318119">"ፊት <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"በመልክ መክፈትን ይጠቀሙ"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"የመልክ ወይም የማያ ገጽ መቆለፊያን ይጠቀሙ"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ለመቀጠል በመልክ መክፈትን ይጠቀሙ"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"የፊት አዶ"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"ዜና እና መጽሔቶች"</string>
<string name="app_category_maps" msgid="6395725487922533156">"ካርታዎች እና ዳሰሳ"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ውጤታማነት"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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">"የዩኤስቢ ማረሚያ"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ሰዓት"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index d6759b6..89ed573 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -562,23 +562,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"للسماح للتطبيق بتعديل مجموعة صورك."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"قراءة المواقع من مجموعة الوسائط التابعة لك"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"للسماح للتطبيق بقراءة المواقع من مجموعة الوسائط التابعة لك."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"استخدام المقاييس الحيوية"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"استخدام المقاييس الحيوية أو قفل الشاشة"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"إثبات هويتك"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"استخدام المقاييس الحيوية للمتابعة"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"معدّات المقاييس الحيوية غير متاحة."</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"تم إلغاء المصادقة."</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"لم يتم التعرف عليها."</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"تم إلغاء المصادقة."</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"لم يتم ضبط رقم تعريف شخصي أو نقش أو كلمة مرور."</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"خطأ في المصادقة"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"استخدام قفل الشاشة"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"إدخال بيانات اعتماد الجهاز للمتابعة"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"تم اكتشاف جزء من بصمة الإصبع فقط؛ يرجى إعادة المحاولة."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"تعذرت معالجة بصمة الإصبع. يُرجى إعادة المحاولة."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"زر استشعار بصمات الأصابع متّسخ. يُرجى تنظيفه وإعادة المحاولة."</string>
@@ -601,10 +596,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"لا يحتوي هذا الجهاز على مستشعِر بصمات إصبع."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"تم إيقاف جهاز الاستشعار مؤقتًا."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"الإصبع <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استخدام بصمة الإصبع"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استخدام بصمة الإصبع أو قفل الشاشة"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"يمكنك استخدام بصمة الإصبع للمتابعة."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -650,12 +643,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"\"فتح القفل بالوجه\" غير متوفر على هذا الجهاز."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"تم إيقاف جهاز الاستشعار مؤقتًا."</string>
<string name="face_name_template" msgid="3877037340223318119">"الوجه <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"استخدام ميزة \"فتح القفل بالوجه\""</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"استخدام ميزة \"فتح القفل بالوجه\" أو ميزة \"قفل الشاشة\""</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"استخدام ميزة \"فتح القفل بالوجه\" للمتابعة"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"رمز الوجه"</string>
@@ -2018,7 +2008,7 @@
<string name="notification_phishing_alert_content_description" msgid="494227305355958790">"تنبيه بشأن تصيّد احتيالي"</string>
<string name="notification_work_profile_content_description" msgid="5296477955677725799">"الملف الشخصي للعمل"</string>
<string name="notification_alerted_content_description" msgid="6139691253611265992">"تمّ تفعيل التنبيه"</string>
- <string name="notification_verified_content_description" msgid="6401483602782359391">"تم التحقّق"</string>
+ <string name="notification_verified_content_description" msgid="6401483602782359391">"تم التحقّق من المتّصل"</string>
<string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"توسيع"</string>
<string name="expand_button_content_description_expanded" msgid="7484217944948667489">"تصغير"</string>
<string name="expand_action_accessibility" msgid="1947657036871746627">"تبديل التوسيع"</string>
@@ -2094,8 +2084,7 @@
<string name="app_category_news" msgid="1172762719574964544">"الأخبار والمجلات"</string>
<string name="app_category_maps" msgid="6395725487922533156">"الخرائط والتنقل"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"الإنتاجية"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"ساعة"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 0a4c397..67d2ce0 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"এপক আপোনাৰ ফট’ সংগ্ৰহ সালসলনি কৰিবলৈ দিয়ে।"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"আপোনাৰ মিডিয়া সংগ্ৰহৰ অৱস্থান পঢ়িবলৈ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"এপক আপোনাৰ মিডিয়া সংগ্ৰহৰ অৱস্থান পঢ়িবলৈ দিয়ে।"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"বায়\'মেট্ৰিক ব্যৱহাৰ কৰক"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"বায়\'মেট্ৰিক অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"এইয়া আপুনিয়েই বুলি সত্যাপন কৰক"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"অব্যাহত ৰাখিবলৈ আপোনাৰ বায়\'মেট্ৰিক ব্যৱহাৰ কৰক"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"বায়োমেট্ৰিক হাৰ্ডৱেৰ উপলব্ধ নহয়"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"বিশ্বাসযোগ্যতাৰ প্ৰমাণীকৰণ বাতিল কৰা হৈছে"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"চিনাক্ত কৰিব পৰা নাই"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"বিশ্বাসযোগ্যতাৰ প্ৰমাণীকৰণ বাতিল কৰা হৈছে"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"কোনো পিন, আৰ্হি বা পাছৱৰ্ড ছেট কৰা নাই"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"আসোঁৱাহৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰি থকা হৈছে"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"স্ক্ৰীন ল\'ক ব্যৱহাৰ কৰক"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"অব্যাহত ৰাখিবলৈ আপোনাৰ ডিভাইচৰ ক্ৰেডেনশ্বিয়েল দিয়ক"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"ফিংগাৰপ্ৰিণ্ট আংশিকভাৱে চিনাক্ত কৰা হৈছে। অনুগ্ৰহ কৰি আকৌ চেষ্টা কৰক৷"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ফিগাৰপ্ৰিণ্টৰ প্ৰক্ৰিয়া সম্পাদন কৰিবপৰা নগ\'ল। অনুগ্ৰহ কৰি আকৌ চেষ্টা কৰক৷"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো লেতেৰা হৈ আছে। অনুগ্ৰহ কৰি পৰিষ্কাৰ কৰি আকৌ চেষ্টা কৰক।"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ছেন্সৰটো সাময়িকভাৱে অক্ষম হৈ আছে।"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> আঙুলি"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ফিংগাৰপ্ৰিণ্ট অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"অব্যাহত ৰাখিবলৈ আপোনাৰ ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"এই ডিভাইচটোত মুখাৱয়বৰদ্বাৰা আনলক কৰা সুবিধাটো নচলে।"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"ছেন্সৰটো সাময়িকভাৱে অক্ষম হৈ আছে।"</string>
<string name="face_name_template" msgid="3877037340223318119">"মুখমণ্ডল <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"মুখাৱয়বৰে আনলক কৰা ব্যৱহাৰ কৰক"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"মুখাৱয়বৰে আনলক কৰা অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"অব্যাহত ৰাখিবলৈ মুখাৱয়বৰে আনলক কৰা ব্যৱহাৰ কৰক"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"মুখমণ্ডলৰ আইকন"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"বাতৰি আৰু আলোচনী"</string>
<string name="app_category_maps" msgid="6395725487922533156">"মেপ আৰু দিক্-নিৰ্দেশনা"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"উৎপাদনশীলতা"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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">"ইউএছবি ডিবাগিং"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ঘণ্টা"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index afb5c39..76b5f1b 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Tətbiqin foto kolleksiyanıza düzəliş etməsinə icazə verir."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"media kolleksiyanızdan məkanları oxuyun"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Tətbiqin media kolleksiyanızdan məkanları oxumasına icazə verin."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometrik məlumatlardan istifadə edin"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrik məlumatlardan və ya ekran kilidindən istifadə edin"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Kimliyinizi doğrulayın"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Davam etmək üçün biometrik məlumatlarınızdan istifadə edin"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrik proqram əlçatan deyil"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Doğrulama ləğv edildi"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Tanınmır"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Doğrulama ləğv edildi"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Pin, nümunə və ya parol ayarlanmayıb"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Doğrulama zamanı xəta baş verdi"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekran kilidindən istifadə edin"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Davam etmək üçün cihazın giriş məlumatlarını daxil edin"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Barmaq izi yarımçıq müəyyən olundu. Lütfən, yenidən cəhd edin."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Barmaq izi tanınmadı. Lütfən, yenidən cəhd edin."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Barmaq izi sensoru çirklidir. Lütfən, təmizləyin və yenidən cəhd edin."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda barmaq izi sensoru yoxdur."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor müvəqqəti deaktivdir."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Barmaq <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmaq izindən istifadə edin"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmaq izi və ya ekran kilidindən istifadə edin"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Davam etmək üçün barmaq izinizi istifadə edin"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Üz kilidi bu cihazda dəstəklənmir."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor müvəqqəti deaktivdir."</string>
<string name="face_name_template" msgid="3877037340223318119">"Üz <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Üz ilə kiliddən çıxarmadan istifadə edin"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Üz və ya ekran kilidindən istifadə edin"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Davam etmək üçün üz ilə kiliddən çıxarmadan istifadə edin"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Üz işarəsi"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Xəbər və Jurnallar"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Xəritə və Naviqasiya"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Məhsuldarlıq"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Əlçatımlılıq"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Cihaz yaddaşı"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB sazlama"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"saat"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 0d23fa5..97781c7 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -553,23 +553,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Dozvoljava aplikaciji da menja kolekciju slika."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"čitanje lokacija iz medijske kolekcije"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Dozvoljava aplikaciji da čita lokacije iz medijske kolekcije."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Koristite biometriju"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Koristite biometriju ili zaključavanje ekrana"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrdite svoj identitet"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Koristite biometrijski podatak da biste nastavili"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrijski hardver nije dostupan"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Potvrda identiteta je otkazana"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nije prepoznato"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Potvrda identiteta je otkazana"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Niste podesili ni PIN, ni šablon, ni lozinku"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Greška pri potvrdi identiteta"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Koristite zaključavanje ekrana"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Unesite akreditiv za uređaj da biste nastavili"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Otkriven je delimični otisak prsta. Probajte ponovo."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nije uspela obrada otiska prsta. Probajte ponovo."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Senzor za otiske prstiju je prljav. Očistite ga i pokušajte ponovo."</string>
@@ -592,10 +587,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristite otisak prsta"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristite otisak prsta ili zaključavanje ekrana"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -641,12 +634,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Otključavanje licem nije podržano na ovom uređaju"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Senzor je privremeno onemogućen."</string>
<string name="face_name_template" msgid="3877037340223318119">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Koristite otključavanje licem"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Koristite zaključavanje licem ili zaključavanje ekrana"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Koristite otključavanje licem da biste nastavili"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona lica"</string>
@@ -1998,8 +1988,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Novosti i časopisi"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mape i navigacija"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivnost"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Pristupačnost"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Memorijski prostor uređaja"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Otklanjanje grešaka sa USB-a"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"sat"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 87b4ce7f..3267247 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Праграма зможа змяняць фотакалекцыю."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"паказваць месцазнаходжанне ў калекцыі мультымедыя"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Праграма зможа паказваць месцазнаходжанне ў калекцыі мультымедыя."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Выкарыстоўваць біяметрыю"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Выкарыстоўваць біяметрыю ці блакіроўку экрана"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Спраўдзіце, што гэта вы"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Каб працягнуць, скарыстайце свае біяметрычныя даныя"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Біяметрычнае абсталяванне недаступнае"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Аўтэнтыфікацыя скасавана"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Не распазнана"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Аўтэнтыфікацыя скасавана"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Не заданы PIN-код, узор разблакіроўкі або пароль"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Памылка аўтэнтыфікацыі"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ужываць блакіроўку экрана"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Каб працягнуць, увядзіце ўліковыя даныя вашай прылады"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Адсканіравана толькі частка адбітка пальца. Паспрабуйце яшчэ раз."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не атрымалася апрацаваць адбітак пальца. Паспрабуйце яшчэ раз."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Сканер адбіткаў пальцаў брудны. Ачысціце яго і паспрабуйце яшчэ раз."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На гэтай прыладзе няма сканера адбіткаў пальцаў."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчык часова выключаны."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Выкарыстоўваць адбітак пальца"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Выкарыстоўваць адбітак пальца ці блакіроўку экрана"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Каб працягнуць, выкарыстоўвайце свой адбітак пальца"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"На гэтай прыладзе распазнаванне твару не падтрымліваецца."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Датчык часова выключаны."</string>
<string name="face_name_template" msgid="3877037340223318119">"Твар <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Ужываць распазнаванне твару"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Выкарыстоўваць распазнаванне твару ці блакіроўку экрана"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Каб працягнуць, скарыстайце распазнаванне твару"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Значок твару"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Навіны і часопісы"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Карты і навігацыя"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Прадукцыйнасць"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"гадз"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 7e847e0..ac55c91 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Разрешава на приложението да променя колекцията ви от снимки."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"да чете местоположенията от мултимедийната ви колекция"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Разрешава на приложението да чете местоположенията от мултимедийната ви колекция."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Използване на биометр. данни"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Използване на биометрични данни или опцията за заключване на екрана"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Потвърдете, че сте вие"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Използвайте биометричните си данни, за да продължите"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометричният хардуер не е налице"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Удостоверяването бе анулирано"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Не е разпознато"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Удостоверяването бе анулирано"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Няма зададен ПИН код, фигура или парола"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Грешка при удостоверяването"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ползване на заключв. на екрана"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Въведете идентификационните данни на устройството, за да продължите"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Открит е частичен отпечатък. Моля, опитайте отново."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Отпечатъкът не бе обработен. Моля, опитайте отново."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Сензорът за отпечатъци е мръсен. Моля, почистете го и опитайте отново."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Това устройство няма сензор за отпечатъци."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорът е временно деактивиран."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Пръст <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Използване на отпечатък"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Използване на отпечатък или опцията за заключване на екрана"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Използвайте отпечатъка си, за да продължите"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Отключването с лице не се поддържа на това устройство."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Сензорът е временно деактивиран."</string>
<string name="face_name_template" msgid="3877037340223318119">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Използване на отключв. с лице"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Използване на отключването с лице или опцията за заключване на екрана"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Използвайте функцията за отключване с лице, за да продължите"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Икона на лице"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Новини и списания"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Карти и навигация"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Производителност"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"час"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 4d3d793..ff25441 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"অ্যাপকে আপনার ফটো সংগ্রহ পরিবর্তন করার অনুমতি দিন।"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ডিয়া সংগ্রহ থেকে লোকেশন দেখতে দিন"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"আপনার মিডিয়া সংগ্রহ থেকে লোকেশন দেখতে অ্যাপকে অনুমতি দিন।"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"বায়োমেট্রিক্স ব্যবহার করুন"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"বায়োমেট্রিক্স অথবা স্ক্রিন লক ব্যবহার করুন"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"আপনার পরিচয় যাচাই করুন"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"চালিয়ে যেতে আপনার বায়োমেট্রিক্স ব্যবহার করুন"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"বায়োমেট্রিক হার্ডওয়্যার পাওয়া যাবে না"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"যাচাইকরণ বাতিল হয়েছে"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"স্বীকৃত নয়"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"যাচাইকরণ বাতিল হয়েছে"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"পিন, প্যাটার্ন অথবা পাসওয়ার্ড সেট করা নেই"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"যাচাইকরণে সমস্যা হয়েছে"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"স্ক্রিন লক ব্যবহার করুন"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"চালিয়ে যেতে আপনার ডিভাইসের ক্রেডেনশিয়াল ব্যবহার করুন"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"আঙ্গুলের ছাপ আংশিক শনাক্ত করা হয়েছে৷ অনুগ্রহ করে আবার চেষ্টা করুন৷"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"আঙ্গুলের ছাপ প্রক্রিয়া করা যায়নি৷ অনুগ্রহ করে আবার চেষ্টা করুন৷"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"আঙ্গুলের ছাপ নেওয়ার সেন্সরটি অপরিস্কার৷ পরিষ্কার করে আবার চেষ্টা করুন৷"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইসে আঙ্গুলের ছাপ নেওয়ার সেন্সর নেই।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"সেন্সর অস্থায়ীভাবে বন্ধ করা আছে।"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"আঙ্গুল <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"আঙ্গুলের ছাপ ব্যবহার করুন"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"আঙ্গুলের ছাপ অথবা স্ক্রিন লক ব্যবহার করুন"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"চালিয়ে যেতে আঙ্গুলের ছাপ ব্যবহার করুন"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"এই ডিভাইসে মুখের সাহায্যে আনলক করার সুবিধাটি কাজ করে না।"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"সেন্সর অস্থায়ীভাবে বন্ধ করা আছে।"</string>
<string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> ফেস"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"মুখের সাহায্যে আনলক ব্যবহার করুন"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"মুখ অথবা স্ক্রিন লক ব্যবহার করুন"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"চালিয়ে যেতে মুখের সাহায্যে আনলক ব্যবহার করুন"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"ফেস আইকন"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"খবর ও পত্রিকাগুলি"</string>
<string name="app_category_maps" msgid="6395725487922533156">"ম্যাপ ও নেভিগেশান"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"উৎপাদনশীলতা"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"ঘণ্টা"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 2e24175..25129e4 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -553,23 +553,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Omogućava aplikaciji da mijenja vašu kolekciju fotografija."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"čitanje lokacija iz kolekcije medija"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Omogućava aplikaciji da čita lokacije iz vaše kolekcije medija."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Koristi biometriju"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Koristi biometriju ili zaključavanje ekrana"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrdite identitet"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Koristite biometriju da nastavite"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrijski hardver nije dostupan"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentifikacija je otkazana"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nije prepoznato"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentifikacija je otkazana"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nije postavljen PIN, uzorak niti lozinka"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Greška pri autentifikaciji"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Koristi zaključavanje ekrana"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Unesite akreditiv uređaja da nastavite"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Otkriven je djelimični otisak prsta. Pokušajte ponovo."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Obrada otiska prsta nije uspjela. Pokušajte ponovo."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Senzor za otisak prsta je prljav. Očistite ga i pokušajte ponovo."</string>
@@ -592,10 +587,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristi otisak prsta"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristi otisak prsta ili zaključavanje ekrana"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -641,12 +634,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Otključavanje licem nije podržano na ovom uređaju."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Senzor je privremeno onemogućen."</string>
<string name="face_name_template" msgid="3877037340223318119">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Koristi otključavanje licem"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Koristi otključavanje licem ili zaključavanje ekrana"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Koristite otključavanje licem da nastavite"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona lica"</string>
@@ -1998,8 +1988,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Vijesti i časopisi"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mape i navigacija"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivnost"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Pristupačnost"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Memorija uređaja"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Otklanjanje grešaka putem USB-a"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"sat"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 70caa2c..6f2af92 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permet que l\'aplicació modifiqui la teva col·lecció de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"llegir les ubicacions de les teves col·leccions multimèdia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permet que l\'aplicació llegeixi les ubicacions de les teves col·leccions multimèdia."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Utilitza la biometria"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Fes servir la biometria o el bloqueig de pantalla"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica que ets tu"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Utilitza la teva biometria per continuar"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Maquinari biomètric no disponible"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"S\'ha cancel·lat l\'autenticació"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"No s\'ha reconegut"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"S\'ha cancel·lat l\'autenticació"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No s\'ha definit cap PIN, patró o contrasenya"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error en l\'autenticació"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utilitza el bloqueig de pantalla"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Utilitza les credencials del teu dispositiu per continuar"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"S\'ha detectat una empremta digital parcial. Torna-ho a provar."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No s\'ha pogut processar l\'empremta digital. Torna-ho a provar."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"El sensor d\'empremtes dactilars està brut. Neteja\'l i torna-ho a provar."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aquest dispositiu no té sensor d\'empremtes dactilars."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor està desactivat temporalment."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dit <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilitza l\'empremta digital"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilitza l\'empremta digital o el bloqueig de pantalla"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Fes servir l\'empremta digital per continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"El desbloqueig facial no és compatible amb el dispositiu."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"El sensor està desactivat temporalment."</string>
<string name="face_name_template" msgid="3877037340223318119">"Cara <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Utilitza el desbloqueig facial"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Utilitza el desbloqueig facial o de pantalla"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Utilitza el desbloqueig facial per continuar"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Icona facial"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Notícies i revistes"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapes i navegació"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivitat"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibilitat"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Emmagatzematge del dispositiu"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Depuració per USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hora"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 0f73266..bd98662 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Umožňuje aplikaci upravit vaši sbírku fotek."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"čtení míst ze sbírky médií"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Umožňuje aplikaci číst místa z vaší sbírky médií."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Použít biometrii"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Použít biometrii nebo zámek obrazovky"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrďte, že jste to vy"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Pokračujte biometrickým ověřením"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrický hardware není k dispozici"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Ověření bylo zrušeno"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nerozpoznáno"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Ověření bylo zrušeno"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Není nastaven žádný PIN, gesto ani heslo"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Při ověřování došlo k chybě"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Použít zámek obrazovky"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Pokračujte zadáním identifikačních úřadů svého zařízení"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Byla zjištěna jen část otisku prstu. Zkuste to znovu."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Zpracování otisku prstu se nezdařilo. Zkuste to znovu."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Senzor otisků prstů je znečištěn. Vyčistěte jej a zkuste to znovu."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zařízení nemá snímač otisků prstů."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasně deaktivován."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použít otisk prstu"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Použít otisk prstu nebo zámek obrazovky"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Pokračujte přiložením prstu"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Odemknutí obličejem na tomto zařízení není podporováno."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Senzor je dočasně deaktivován."</string>
<string name="face_name_template" msgid="3877037340223318119">"Obličej <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Použít odemknutí obličejem"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Použít odemknutí obličejem nebo zámek obrazovky"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Pokračujte odemknutím obličejem"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona obličeje"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Zprávy a časopisy"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapy a navigace"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivita"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Přístupnost"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Úložiště zařízení"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Ladění přes USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hodina"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 13afaf2..70492e0 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -552,23 +552,18 @@
<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>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <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_dialog_default_title" msgid="55026799173208210">"Bekræft, at det er dig"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Brug dine biometriske data for at fortsætte"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrisk hardware er ikke tilgængelig"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Godkendelsen blev annulleret"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Ikke genkendt"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Godkendelsen blev annulleret"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Der er ikke angivet pinkode, mønster eller adgangskode"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Der opstod fejl i forbindelse med godkendelse"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Brug skærmlås"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Angiv dine loginoplysninger for enheden for at fortsætte"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Der blev registreret et delvist fingeraftryk. Prøv igen."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Fingeraftrykket kunne ikke behandles. Prøv igen."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingeraftrykslæseren er beskidt. Tør den af, og prøv igen."</string>
@@ -591,10 +586,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enhed har ingen fingeraftrykslæser."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidigt deaktiveret."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Fingeraftryk <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Brug fingeraftryk"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Brug fingeraftryk eller skærmlås"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Brug dit fingeraftryk for at fortsætte"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -640,12 +633,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Ansigtslås understøttes ikke på denne enhed."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensoren er midlertidigt deaktiveret."</string>
<string name="face_name_template" msgid="3877037340223318119">"Ansigt <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Brug ansigtslås"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Brug ansigts- eller skærmlås"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Brug ansigtslås for at fortsætte"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ansigt"</string>
@@ -1968,8 +1958,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Aviser og blade"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kort og navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivitet"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Hjælpefunktioner"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Lagerplads på enheden"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-fejlretning"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"time"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 512b3a5..6e458fa 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Ermöglicht der App, deine Fotosammlung zu ändern."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"Standorte aus meiner Mediensammlung abrufen"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Ermöglicht der App, Standorte aus deiner Mediensammlung abzurufen."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometrisches Verfahren nutzen"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrisches Verfahren oder Displaysperre verwenden"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Deine Identität bestätigen"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Mithilfe eines biometrischen Verfahrens fortfahren"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrische Hardware nicht verfügbar"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentifizierung abgebrochen"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nicht erkannt"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Authentifizierung abgebrochen"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Keine PIN, kein Muster und kein Passwort festgelegt"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Fehler bei der Authentifizierung"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Displaysperre verwenden"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Zum Fortfahren Anmeldedaten des Geräts eingeben"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Fingerabdruck nur teilweise erkannt. Bitte versuche es noch einmal."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Fingerabdruck konnte nicht verarbeitet werden. Bitte versuche es noch einmal."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingerabdrucksensor ist verschmutzt. Reinige ihn und versuche es noch einmal."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dieses Gerät hat keinen Fingerabdrucksensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Der Sensor ist vorübergehend deaktiviert."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Fingerabdruck verwenden"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Fingerabdruck oder Displaysperre verwenden"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Mithilfe deines Fingerabdrucks fortfahren"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Face Unlock wird auf diesem Gerät nicht unterstützt."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Der Sensor ist vorübergehend deaktiviert."</string>
<string name="face_name_template" msgid="3877037340223318119">"Gesicht <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Face Unlock verwenden"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Face Unlock oder Displaysperre verwenden"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Zum Fortfahren Face Unlock verwenden"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Gesichtssymbol"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Nachrichten & Zeitschriften"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Karten & Navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Effizienz"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Bedienungshilfen"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Gerätespeicher"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-Fehlerbehebung"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"Stunde"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index d9dc2c5..920f09e 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Επιτρέπει στην εφαρμογή να τροποποιήσει τη συλλογή φωτογραφιών σας."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ανάγνωση τοποθεσιών από τη συλλογή πολυμέσων σας"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Επιτρέπει στην εφαρμογή να διαβάσει τοποθεσίες από τη συλλογή πολυμέσων σας."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Χρήση βιομετρικών"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Χρήση βιομετρικών ή κλειδώματος οθόνης"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Επαλήθευση ταυτότητας"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Χρησιμοποιήστε βιομετρικά για να συνεχίσετε"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Δεν υπάρχει διαθέσιμος βιομετρικός εξοπλισμός"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Ο έλεγχος ταυτότητας ακυρώθηκε"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Δεν αναγνωρίστηκε"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Ο έλεγχος ταυτότητας ακυρώθηκε"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Δεν έχει οριστεί PIN, μοτίβο ή κωδικός πρόσβασης"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Σφάλμα κατά τον έλεγχο ταυτότητας"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Χρήση κλειδώματος οθόνης"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Εισαγάγετε το διαπιστευτήριο της συσκευής σας για να συνεχίσετε"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Εντοπίστηκε μόνο μέρος του δακτυλικού αποτυπώματος. Δοκιμάστε ξανά."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Δεν ήταν δυνατή η επεξεργασία του δακτυλικού αποτυπώματος. Δοκιμάστε ξανά."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Ο αισθητήρας δακτυλικού αποτυπώματος δεν είναι καθαρός. Καθαρίστε τον και δοκιμάστε ξανά."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Αυτή η συσκευή δεν διαθέτει αισθητήρα δακτυλικού αποτυπώματος."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Ο αισθητήρας απενεργοποιήθηκε προσωρινά."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Δάχτυλο <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Χρήση δακτυλικού αποτυπώματος"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Χρήση δακτυλικού αποτυπώματος ή κλειδώματος οθόνης"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Χρησιμοποιήστε το δακτυλικό αποτύπωμά σας για να συνεχίσετε"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Το Face Unlock δεν υποστηρίζεται σε αυτήν τη συσκευή."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Ο αισθητήρας απενεργοποιήθηκε προσωρινά."</string>
<string name="face_name_template" msgid="3877037340223318119">"Πρόσωπο <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Χρήση Face Unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Χρήση προσώπου ή κλειδώματος οθόνης"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Χρησιμοποιήστε το Face Unlock για να συνεχίσετε"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Εικ. προσ."</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Ειδήσεις και περιοδικά"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Χάρτες και πλοήγηση"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Παραγωγικότητα"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"ώρα"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 73e2ca0..43a7fb6 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Allows the app to modify your photo collection."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"read locations from your media collection"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Allows the app to read locations from your media collection."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Use biometrics"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify that it’s you"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use your biometric to continue"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometric hardware unavailable"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentication cancelled"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Not recognised"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Authentication cancelled"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No pin, pattern or password set"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Enter your device credential to continue"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Partial fingerprint detected. Please try again."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingerprint sensor is dirty. Please clean and try again."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Face unlock is not supported on this device."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor temporarily disabled."</string>
<string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use face unlock to continue"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Face icon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"News & Magazines"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps & Navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivity"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibility"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Device storage"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB debugging"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hour"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 67130e1..04390c7 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Allows the app to modify your photo collection."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"read locations from your media collection"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Allows the app to read locations from your media collection."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Use biometrics"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify that it’s you"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use your biometric to continue"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometric hardware unavailable"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentication cancelled"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Not recognised"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Authentication cancelled"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No pin, pattern or password set"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Enter your device credential to continue"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Partial fingerprint detected. Please try again."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingerprint sensor is dirty. Please clean and try again."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Face unlock is not supported on this device."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor temporarily disabled."</string>
<string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use face unlock to continue"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Face icon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"News & Magazines"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps & Navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivity"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibility"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Device storage"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB debugging"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hour"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 1d36494b..84224ed 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Allows the app to modify your photo collection."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"read locations from your media collection"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Allows the app to read locations from your media collection."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Use biometrics"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify that it’s you"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use your biometric to continue"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometric hardware unavailable"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentication cancelled"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Not recognised"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Authentication cancelled"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No pin, pattern or password set"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Enter your device credential to continue"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Partial fingerprint detected. Please try again."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingerprint sensor is dirty. Please clean and try again."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Face unlock is not supported on this device."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor temporarily disabled."</string>
<string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use face unlock to continue"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Face icon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"News & Magazines"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps & Navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivity"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibility"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Device storage"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB debugging"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hour"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 016c55c..d740e01 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Allows the app to modify your photo collection."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"read locations from your media collection"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Allows the app to read locations from your media collection."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Use biometrics"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify that it’s you"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use your biometric to continue"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometric hardware unavailable"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentication cancelled"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Not recognised"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Authentication cancelled"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No pin, pattern or password set"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Enter your device credential to continue"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Partial fingerprint detected. Please try again."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingerprint sensor is dirty. Please clean and try again."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Face unlock is not supported on this device."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor temporarily disabled."</string>
<string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use face unlock to continue"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Face icon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"News & Magazines"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps & Navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivity"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibility"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Device storage"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB debugging"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hour"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index bd7da80..6125c16 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que la app modifique tu colección de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"leer ubicaciones de tu colección de contenido multimedia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que la app lea las ubicaciones de tu colección de contenido multimedia."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Usar datos biométricos"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar datos biométricos o bloqueo de pantalla"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Comprueba que eres tú"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Usa tus datos biométricos para continuar"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"No hay hardware biométrico disponible"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Se canceló la autenticación"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"No se reconoció"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Se canceló la autenticación"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No se estableció ningún PIN, patrón ni contraseña"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error de autenticación"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueo de pantalla"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Ingresa las credenciales de tu dispositivo para continuar"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Se detectó parcialmente la huella dactilar. Vuelve a intentarlo."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No se pudo procesar la huella dactilar. Vuelve a intentarlo."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"El sensor de huellas dactilares está sucio. Limpia el sensor y vuelve a intentarlo."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas dactilares."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Se inhabilitó temporalmente el sensor."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella digital"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar bloqueo de huella dactilar o pantalla"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utiliza tu huella dactilar para continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"No se admite el desbloqueo facial en este dispositivo."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Se inhabilitó temporalmente el sensor."</string>
<string name="face_name_template" msgid="3877037340223318119">"Rostro <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Usar desbloqueo facial"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usar bloqueo facial o de pantalla"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Usa el desbloqueo facial para continuar"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ícono cara"</string>
@@ -1576,8 +1566,8 @@
<string name="expires_on" msgid="1623640879705103121">"Expira el:"</string>
<string name="serial_number" msgid="3479576915806623429">"Número de serie:"</string>
<string name="fingerprints" msgid="148690767172613723">"Huellas digitales:"</string>
- <string name="sha256_fingerprint" msgid="7103976380961964600">"Huella dactilar SHA-256"</string>
- <string name="sha1_fingerprint" msgid="2339915142825390774">"Huella dactilar SHA-1:"</string>
+ <string name="sha256_fingerprint" msgid="7103976380961964600">"Huella digital SHA-256"</string>
+ <string name="sha1_fingerprint" msgid="2339915142825390774">"Huella digital SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="3917045206812726099">"Ver todas"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="8880731437191978314">"Elige actividad"</string>
<string name="share_action_provider_share_with" msgid="1904096863622941880">"Compartir con"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Noticias y revistas"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapas y navegación"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productividad"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accesibilidad"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Almacenamiento del dispositivo"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Depuración por USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hora"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index d771977..0e163d2 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que la aplicación modifique tu colección de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"leer las ubicaciones de tu colección de contenido multimedia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que la aplicación lea las ubicaciones de tu colección de contenido multimedia."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Usar biometría"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar biometría o bloqueo de pantalla"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica que eres tú"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Usa tu biometría para continuar"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biométrico no disponible"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autenticación cancelada"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"No se reconoce"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autenticación cancelada"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No se ha definido el PIN, el patrón o la contraseña"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"No se ha podido autenticar"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueo de pantalla"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Introduce las credenciales del dispositivo para continuar"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Se ha detectado una huella digital parcial. Vuelve a intentarlo."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No se ha podido procesar la huella digital. Vuelve a intentarlo."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"El sensor de huellas digitales está sucio. Límpialo y vuelve a intentarlo."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas digitales."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor está inhabilitado en estos momentos."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella digital"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar huella digital o bloqueo de pantalla"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Usa tu huella digital para continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"El desbloqueo facial no está disponible en este dispositivo."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"El sensor está inhabilitado en estos momentos."</string>
<string name="face_name_template" msgid="3877037340223318119">"Cara <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Usar desbloqueo facial"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usar desbloqueo facial o bloqueo de pantalla"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Usa el desbloqueo facial para continuar"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Icono cara"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Noticias y revistas"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapas y navegación"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productividad"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accesibilidad"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Almacenamiento del dispositivo"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Depuración por USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hora"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index ec02fad..9f6df6e 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Võimaldab rakendusel muuta teie fotokogu."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"Lugeda teie meediakogus olevaid asukohti"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Võimaldab rakendusel lugeda teie meediakogus olevaid asukohti."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Biomeetria kasutamine"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biomeetria või ekraaniluku kasutamine"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Kinnitage oma isik"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Jätkamiseks kasutage biomeetriat"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biomeetriline riistvara ei ole saadaval"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentimine tühistati"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Ei tuvastatud"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentimine tühistati"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN-koodi, mustrit ega parooli pole määratud"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Viga autentimisel"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekraaniluku kasutamine"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Jätkamiseks sisestage seadme mandaat"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Tuvastati osaline sõrmejälg. Proovige uuesti."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Sõrmejälge ei õnnestunud töödelda. Proovige uuesti."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Sõrmejäljeandur on must. Puhastage see ja proovige uuesti."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Selles seadmes pole sõrmejäljeandurit."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Andur on ajutiselt keelatud."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Sõrmejälg <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sõrmejälje kasutamine"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Sõrmejälje või ekraaniluku kasutamine"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Jätkamiseks kasutage sõrmejälge"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Seade ei toeta Face Unlocki."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Andur on ajutiselt keelatud."</string>
<string name="face_name_template" msgid="3877037340223318119">"Nägu <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Face Unlocki kasutamine"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Face Unlocki või ekraaniluku kasutamine"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Jätkamiseks kasutage Face Unlocki"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Näoikoon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Uudised ja ajakirjad"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kaardid ja navigeerimine"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktiivsus"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Juurdepääsetavus"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Seadme salvestusruum"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB silumine"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"tund"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 8ee77a6..72d0833 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -313,8 +313,8 @@
<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">"Ariketa fisikoa"</string>
- <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ariketa fisikoak atzitu"</string>
+ <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Jarduera fisiko"</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>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Deien erregistroa"</string>
@@ -445,8 +445,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 ariketa fisikoa"</string>
- <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Aplikazioak ariketa fisikoa hauteman dezake."</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_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>
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Argazki-bilduma aldatzeko baimena ematen die aplikazioei."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"multimedia-edukien bildumako kokapena irakurri"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Multimedia-edukien bildumako kokapena irakurtzeko baimena ematen die aplikazioei."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Erabili sistema biometrikoak"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Erabili sistema biometrikoak edo pantailaren blokeoa"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Egiaztatu zeu zarela"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Aurrera egiteko, erabili sistema biometrikoak"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biometrikoa ez dago erabilgarri"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Utzi da autentifikazioa"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Ez da ezagutu"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Utzi egin da autentifikazioa"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Ez da ezarri PIN koderik, eredurik edo pasahitzik"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Errorea autentifikatzean"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Erabili pantailaren blokeoa"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Aurrera egiteko, idatzi gailuaren kredentzialak"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Hatz-marka ez da osorik hauteman. Saiatu berriro."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Ezin izan da prozesatu hatz-marka. Saiatu berriro."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Hatz-marken sentsorea zikina dago. Garbi ezazu, eta saiatu berriro."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Gailu honek ez du hatz-marken sentsorerik."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sentsorea aldi baterako desgaitu da."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> hatza"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Erabili hatz-marka"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Erabili hatz-marka edo pantailaren blokeoa"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Aurrera egiteko, erabili hatz-marka"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Gailu honek ez du onartzen aurpegiaren bidez desblokeatzea."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sentsorea aldi baterako desgaitu da."</string>
<string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> aurpegia"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Erabili aurpegiaren bidez desblokeatzeko eginbidea"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Erabili aurpegia edo pantailaren blokeoa"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Aurrera egiteko, erabili aurpegiaren bidez desblokeatzeko eginbidea"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Aurpegiaren ikonoa"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Albisteak eta aldizkariak"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapak eta nabigazioa"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktibitatea"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Erabilerraztasuna"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Gailuaren memoria"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB bidezko arazketa"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ordu"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 42b8c85..76d0c1e 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"به برنامه اجازه میدهد مجموعه عکستان را تغییر دهد."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"خواندن مکانها از مجموعه رسانه شما"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"به برنامه اجازه میدهد مکانها را از مجموعه رسانهتان بخواند."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"استفاده از زیستسنجشی"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"استفاده از زیستسنجشی یا قفل صفحه"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"تأیید کنید این شما هستید"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"برای ادامه، از زیستسنجشی استفاده کنید"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"سختافزار زیستسنجی دردسترس نیست"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"اصالتسنجی لغو شد"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"شناسایی نشد"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"اصالتسنجی لغو شد"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"پین، الگو یا گذرواژهای تنظیم نشده است"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"خطا هنگام اصالتسنجی"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"از قفل صفحه استفاده کنید"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"برای ادامه، اطلاعات کاربری دستگاهتان را وارد کنید"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"بخشی از اثر انگشت شناسایی شد. لطفاً دوباره امتحان کنید."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"اثرانگشت پردازش نشد. لطفاً دوباره امتحان کنید."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"حسگر اثر انگشت کثیف است. لطفاً آن را تمیز کنید و دوباره امتحان نمایید."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"این دستگاه حسگر اثر انگشت ندارد."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"حسگر بهطور موقت غیرفعال است."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"انگشت <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استفاده از اثر انگشت"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استفاده از اثر انگشت یا قفل صفحه"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"برای ادامه، از اثر انگشتتان استفاده کنید"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"«بازگشایی با چهره» در این دستگاه پشتیبانی نمیشود."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"حسگر بهطور موقت غیرفعال است."</string>
<string name="face_name_template" msgid="3877037340223318119">"چهره <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"استفاده از «بازگشایی با چهره»"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"استفاده از قفل صفحه یا چهره"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"برای ادامه، از «بازگشایی با چهره» استفاده کنید"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"نماد چهره"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"اخبار و مجله"</string>
<string name="app_category_maps" msgid="6395725487922533156">"نقشه و پیمایش"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"بهرهوری"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"ساعت"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index be0cd23..2e0d6cd 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Antaa sovelluksen muokata kuvakokoelmaasi."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lukea mediakokoelmasi sijainteja"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Antaa sovelluksen lukea mediakokoelmasi sijainteja."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Käytä biometriikkaa"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Käytä biometriikkaa tai näytön lukitusta"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Vahvista henkilöllisyytesi"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Jatka käyttämällä biometriikkaa"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrinen laitteisto ei käytettävissä"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Todennus peruutettu"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Ei tunnistettu"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Todennus peruutettu"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN-koodia, kuviota tai salasanaa ei ole asetettu"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Virhe todennuksessa"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Käytä näytön lukitusta"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Jatka lisäämällä laitteesi kirjautumistiedot"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Sormenjälki havaittiin vain osittain. Yritä uudelleen."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Sormenjäljen prosessointi epäonnistui. Yritä uudelleen."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Sormenjälkitunnistin on likainen. Puhdista tunnistin ja yritä uudelleen."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Laitteessa ei ole sormenjälkitunnistinta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tunnistin poistettu väliaikaisesti käytöstä."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Sormi <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Käytä sormenjälkeä"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Käytä sormenjälkeä tai näytön lukitusta"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Jatka sormenjäljen avulla"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Tämä laite ei tue Face Unlockia."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Tunnistin poistettu väliaikaisesti käytöstä."</string>
<string name="face_name_template" msgid="3877037340223318119">"Kasvot <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Käytä Face Unlockia"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Käytä Face Unlockia tai näytön lukitusta"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Jatka käyttämällä Face Unlockia"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Kasvokuvake"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Uutiset ja lehdet"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kartat ja navigointi"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Tuottavuus"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Esteettömyys"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Laitteen tallennustila"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-vianetsintä"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"tunnit"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 5c26e68..1ebc604 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Autorise l\'application à modifier votre collection de photos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lire les positions issues de votre collection multimédia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Autorise l\'application à lire les positions indiquées dans votre collection multimédia."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Utiliser les données biométriques"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utiliser les données biométriques ou le verrouillage de l\'écran"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirmez que c\'est vous"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Utilisez votre méthode d\'authentification biométrique pour continuer"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Matériel biométrique indisponible"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentification annulée"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Données biométriques non reconnues"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Authentification annulée"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Aucun NIP, schéma ou mot de passe défini"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Erreur d\'authentification"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utiliser le verrouillage de l\'écran"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Entrez votre authentifiant d\'appareil pour continuer"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Empreinte digitale partielle détectée. Veuillez réessayer."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Impossible de reconnaître l\'empreinte digitale. Veuillez réessayer."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Le capteur d\'empreintes digitales est sale. Veuillez le nettoyer et réessayer."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Cet appareil ne possède pas de capteur d\'empreintes digitales."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Le capteur a été désactivé temporairement."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utiliser l\'empreinte digitale ou le verrouillage de l\'écran"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilisez votre empreinte digitale pour continuer"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Cet appar. ne prend pas en charge le déverr. par reconn. faciale."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Le capteur a été désactivé temporairement."</string>
<string name="face_name_template" msgid="3877037340223318119">"Visage <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Utiliser le déverrouillage par reconnaissance faciale"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Utiliser la reconnaissance faciale ou le verrouillage de l\'écran"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Utilisez le déverrouillage par reconnaissance faciale pour continuer"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Icône visage"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Actualités et magazines"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Cartes et navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivité"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibilité"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Mémoire de l\'appareil"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Débogage USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"heures"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 3d8856d..ce36dbc 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Autorise l\'application à modifier votre bibliothèque photo."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"consulter des positions issues de votre bibliothèque multimédia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Autorise l\'application à consulter des positions issues de votre bibliothèque multimédia."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Utiliser la biométrie"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utiliser la biométrie ou le verrouillage de l\'écran"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirmez votre identité"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Utilisez la biométrie pour continuer"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Matériel biométrique indisponible"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentification annulée"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Non reconnu"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Authentification annulée"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Aucun code, schéma ni mot de passe n\'est défini"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Erreur d\'authentification"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utiliser verrouillage écran"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Saisissez l\'identifiant de l\'appareil pour continuer"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Empreinte digitale partiellement détectée. Veuillez réessayer."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Impossible de reconnaître l\'empreinte digitale. Veuillez réessayer."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Le lecteur d\'empreinte digitale est sale. Veuillez le nettoyer, puis réessayer."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aucun lecteur d\'empreinte digitale n\'est installé sur cet appareil."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Capteur temporairement désactivé."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utiliser votre empreinte digitale ou le verrouillage de l\'écran"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilisez votre empreinte digitale pour continuer"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Face Unlock n\'est pas compatible avec cet appareil."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Capteur temporairement désactivé."</string>
<string name="face_name_template" msgid="3877037340223318119">"Visage <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Utiliser Face Unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Utiliser Face Lock ou le verrouillage de l\'écran"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Utilisez Face Unlock pour continuer"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Icône visage"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Actualités et magazines"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Plans et navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivité"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibilité"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Mémoire de l\'appareil"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Débogage USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"heures"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 1c5ab13..9d95af8 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que a aplicación modifique a túa colección de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ler localizacións da túa colección multimedia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que a aplicación lea as localizacións da túa colección multimedia."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Utilizar desbloqueo biométrico"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utilizar desbloqueo biométrico ou credencial do dispositivo"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica que es ti"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Para continuar, utiliza o desbloqueo biométrico"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"O hardware biométrico non está dispoñible"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Cancelouse a autenticación"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Non se recoñeceu"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Cancelouse a autenticación"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Non se estableceu ningún PIN, padrón ou contrasinal"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Produciuse un erro ao realizar a autenticación"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar credencial do dispositivo"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Para continuar, mete a credencial do dispositivo"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Detectouse unha impresión dixital parcial. Téntao de novo."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Non se puido procesar a impresión dixital. Téntao de novo."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"O sensor de impresión dixital está sucio. Límpao e téntao de novo."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo non ten sensor de impresión dixital."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Desactivouse o sensor temporalmente."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilizar impresión dixital"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilizar impresión dixital ou credencial do dispositivo"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utiliza a túa impresión dixital para continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Este dispositivo non admite o desbloqueo facial."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Desactivouse o sensor temporalmente."</string>
<string name="face_name_template" msgid="3877037340223318119">"Cara <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Utilizar desbloqueo facial"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Utilizar desbloqueo facial ou credencial do dispositivo"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Para continuar, utiliza o desbloqueo facial"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Icona cara"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Noticias e revistas"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapas e navegación"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produtividade"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accesibilidade"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Almacenamento do dispositivo"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Depuración por USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hora"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index fd3a06b..334ba2d 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"એપને તમારો ફોટો સંગ્રહ સંશોધિત કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"આપના મીડિયા સંગ્રહમાંથી સ્થાનો વાંચવા"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"એપને તમારા મીડિયા સંગ્રહમાંથી સ્થાનો વાંચવાની મંજૂરી આપે છે."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"બાયોમેટ્રિક્સનો ઉપયોગ કરો"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"બાયોમેટ્રિક્સ અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"તે તમે જ છો એ ચકાસો"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"આગળ વધવા માટે બાયોમેટ્રિકનો ઉપયોગ કરો"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"બાયોમેટ્રિક હાર્ડવેર ઉપલબ્ધ નથી"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"પ્રમાણીકરણ રદ કર્યું"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"ઓળખાયેલ નથી"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"પ્રમાણીકરણ રદ કર્યું"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"કોઈ પિન, પૅટર્ન અથવા પાસવર્ડ સેટ કરેલો નથી"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"પ્રમાણિત કરવામાં ભૂલ આવી"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"ચાલુ રાખવા માટે તમારા ડિવાઇસની લૉગ ઇન વિગત દાખલ કરો"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"આંશિક ફિંગરપ્રિન્ટ મળી. કૃપા કરીને ફરી પ્રયાસ કરો."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ફિંગરપ્રિન્ટ પ્રક્રિયા કરી શકાઈ નથી. કૃપા કરીને ફરી પ્રયાસ કરો."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"ફિંગરપ્રિન્ટ સેન્સર ગંદું છે. કૃપા કરીને સાફ કરો અને ફરી પ્રયાસ કરો."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"આ ડિવાઇસમાં કોઈ ફિંગરપ્રિન્ટ સેન્સર નથી."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"સેન્સર હંગામી રૂપે બંધ કર્યું છે."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"આંગળી <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ફિંગરપ્રિન્ટ અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ચાલુ રાખવા માટે તમારી ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"આ ડિવાઇસ પર ફેસ અનલૉક કરવાની સુવિધા નથી."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"સેન્સર હંગામી રૂપે બંધ કર્યું છે."</string>
<string name="face_name_template" msgid="3877037340223318119">"ચહેરાનું <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"ફેસ અનલૉકનો ઉપયોગ કરો"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ફેસ લૉક અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"આગળ વધવા માટે ફેસ અનલૉકનો ઉપયોગ કરો"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"ચહેરા આઇકન"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"સમાચાર અને સામાયિકો"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps અને નેવિગેશન"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ઉત્પાદકતા"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"કલાક"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index be64e90..16e848f 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"इससे ऐप्लिकेशन को आपके फ़ोटो संग्रह में बदलाव करने की मंज़ूरी दी जाती है."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"अपने मीडिया संग्रह से जगह की जानकारी ऐक्सेस करने की अनुमति दें"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"इससे ऐप्लिकेशन को आपके मीडिया संग्रह से जगह की जानकारी ऐक्सेस करने की अनुमति दी जाती है."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"बायोमेट्रिक्स इस्तेमाल करें"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"बायोमेट्रिक्स या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"अपनी पहचान की पुष्टि करें"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"जारी रखने के लिए, बायोमेट्रिक्स इस्तेमाल करें"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"बायोमेट्रिक हार्डवेयर उपलब्ध नहीं है"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"प्रमाणीकरण रद्द किया गया"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"पहचान नहीं हो पाई"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"प्रमाणीकरण रद्द किया गया"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"पिन, पैटर्न या पासवर्ड सेट नहीं है"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"गड़बड़ी की पुष्टि की जा रही है"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"जारी रखने के लिए, अपने डिवाइस का क्रेडेंशियल डालें"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"अधूरा फ़िंगरप्रिंट प्रोसेस हो सका. कृपया फिर से कोशिश करें."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"फ़िंगरप्रिंट प्रोसेस नहीं हो सका. कृपया दोबारा कोशिश करें."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"फ़िंगरप्रिंट सेंसर गंदा है. कृपया साफ़ करें और फिर कोशिश करें."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"इस डिवाइस में फ़िंगरप्रिंट सेंसर नहीं है."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"फ़िंगरप्रिंट <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फ़िंगरप्रिंट इस्तेमाल करें"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फ़िंगरप्रिंट या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"जारी रखने के लिए फ़िंगरप्रिंट का इस्तेमाल करें"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"इस डिवाइस पर \'मालिक का चेहरा पहचानकर अनलॉक\' काम नहीं करती है."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string>
<string name="face_name_template" msgid="3877037340223318119">"चेहरा <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"\'फ़ेस अनलॉक\' इस्तेमाल करें"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"चेहरा पहचानने की सुविधा या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"जारी रखने के लिए, \'फ़ेस अनलॉक\' इस्तेमाल करें"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"चेहरे का आइकॉन"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"समाचार और पत्रिकाएं"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps और नेविगेशन ऐप्लिकेशन"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"उत्पादकता"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"घंटा"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 3a6ce21..15c36c9 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -553,23 +553,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Omogućuje aplikaciji izmjenu vaše zbirke fotografija."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"čitanje lokacija iz vaše medijske zbirke"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Omogućuje aplikaciji čitanje lokacija iz vaše medijske zbirke."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Upotreba biometrije"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Upotreba biometrijske autentifikacije ili zaključavanja zaslona"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrdite da ste to vi"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Upotrijebite svoju biometrijsku autentifikaciju da biste nastavili"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrijski hardver nije dostupan"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentifikacija otkazana"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nije prepoznato"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentifikacija otkazana"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nisu postavljeni PIN, uzorak ni zaporka"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Pogreška prilikom autentifikacije"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Upotreba zaključavanja zaslona"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Unesite vjerodajnicu uređaja da biste nastavili"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Otkriven je djelomični otisak prsta. Pokušajte ponovo."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Obrada otiska prsta nije uspjela. Pokušajte ponovo."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Senzor otiska prsta nije čist. Očistite ga i pokušajte ponovo."</string>
@@ -592,10 +587,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor otiska prsta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Upotreba otiska prsta"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Upotreba otiska prsta ili zaključavanja zaslona"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -641,12 +634,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Otključavanje licem nije podržano na ovom uređaju."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Senzor je privremeno onemogućen."</string>
<string name="face_name_template" msgid="3877037340223318119">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Upotreba otključavanja licem"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Upotreba lica ili zaključavanja zaslona"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Upotrijebite otključavanje licem da biste nastavili"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona lica"</string>
@@ -1998,8 +1988,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Vijesti i časopisi"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Karte i navigacija"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivnost"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Pristupačnost"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Pohrana na uređaju"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Otklanjanje pogrešaka putem USB-a"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"sat"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 3cd0aba..f28f1b6 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Engedélyezi az alkalmazásnak a fényképgyűjtemény módosítását."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"helyek olvasása a médiagyűjteményből"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Engedélyezi az alkalmazásnak a helyek médiagyűjteményből való olvasását."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometriai feloldás használata"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"A folytatás biometriai feloldással vagy képernyőzárral lehetséges"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Igazolja, hogy Ön az"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"A folytatás biometriai feloldással lehetséges"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrikus hardver nem áll rendelkezésre"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Hitelesítés megszakítva"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nem ismerhető fel"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Hitelesítés megszakítva"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nem állított be PIN-kódot, mintát vagy jelszót."</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Hiba történt a hitelesítés közben"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Képernyőzár használata"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"A folytatáshoz adja meg az eszköz hitelesítési adatait"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"A rendszer az ujjlenyomatnak csak egy részletét érzékelte. Próbálkozzon újra."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nem sikerült feldolgozni az ujjlenyomatot. Próbálkozzon újra."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Az ujjlenyomat-olvasó koszos. Tisztítsa meg, majd próbálkozzon újra."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ez az eszköz nem rendelkezik ujjlenyomat-érzékelővel."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Az érzékelő átmenetileg le van tiltva."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. ujj"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Ujjlenyomat használata"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"A folytatás ujjlenyomattal vagy képernyőzárral lehetséges"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"A folytatáshoz használja ujjlenyomatát"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Az eszköz nem támogatja az arcalapú feloldást"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Az érzékelő átmenetileg le van tiltva."</string>
<string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> arc"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Arcalapú feloldás használata"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"A folytatás arcalapú feloldással vagy képernyőzárral lehetséges"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"A folytatás arcalapú feloldással lehetséges"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Arcikon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Hírlapok és folyóiratok"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Térképek és navigáció"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Irodai alkalmazások"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Kisegítő alkalmazások"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Eszköztárhely"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-hibakeresés"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"óra"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 8d6e42e..959cb57 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Թույլ է տալիս հավելվածին փոփոխել ձեր լուսանկարների հավաքածուն:"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ճանաչել տեղադրության մասին տվյալները մեդիա բովանդակության հավաքածուից"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Թույլ է տալիս հավելվածին ճանաչել տեղադրության մասին տվյալները ձեր մեդիա բովանդակության հավաքածուից:"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Կենսաչափական համակարգեր"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Օգտագործել կենսաչափական համակարգեր կամ էկրանի կողպում"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Հաստատեք ձեր ինքնությունը"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Շարունակելու համար օգտագործեք կենսաչափական համակարգեր"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Կենսաչափական սարքը հասանելի չէ"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Նույնականացումը չեղարկվեց"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Չհաջողվեց ճանաչել"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Նույնականացումը չեղարկվեց"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Ավելացրեք PIN կոդ, նախշ կամ գաղտնաբառ։"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Չհաջողվեց նույնականացնել"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Էկրանի կողպում"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Շարունակելու համար մուտքագրեք սարքի նույնականացման տվյալները"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Մատնահետքն ամբողջությամբ չի սկանավորվել: Փորձեք նորից:"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Չհաջողվեց մշակել մատնահետքը: Նորից փորձեք:"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Մատնահետքերի սենսորն աղտոտված է: Մաքրեք այն և փորձեք նորից:"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Այս սարքը չունի մատնահետքերի սկաներ։"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Տվիչը ժամանակավորապես անջատված է:"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Մատնահետք <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Օգտագործել մատնահետք"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Օգտագործել մատնահետք կամ էկրանի կողպում"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Շարունակելու համար անհրաժեշտ է ձեր մատնահետքը"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Դեմքով ապակողպումն այս սարքում չի աջակցվում"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Տվիչը ժամանակավորապես անջատված է:"</string>
<string name="face_name_template" msgid="3877037340223318119">"Դեմք <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Օգտագործել դեմքով ապակողպում"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Օգտագործել դեմքով ապակողպում կամ էկրանի կողպում"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Շարունակելու համար օգտագործեք դեմքով ապակողպում"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Դեմքի պատկերակ"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Նորություններ և ամսագրեր"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Քարտեզներ և նավարկում"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Արդյունավետություն"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"ժամ"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 28d2ed8..9f69209 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Mengizinkan aplikasi untuk memodifikasi koleksi foto Anda."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"membaca lokasi dari koleksi media Anda"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Mengizinkan aplikasi untuk membaca lokasi dari koleksi media Anda."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Gunakan biometrik"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gunakan biometrik atau kunci layar"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifikasi bahwa ini memang Anda"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gunakan biometrik untuk melanjutkan"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biometrik tidak tersedia"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentikasi dibatalkan"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Tidak dikenali"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentikasi dibatalkan"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Tidak ada PIN, pola, atau sandi yang disetel"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error saat mengautentikasi"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gunakan kunci layar"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Masukkan kredensial perangkat untuk melanjutkan"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Sebagian sidik jari terdeteksi. Coba lagi."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Tidak dapat memproses sidik jari. Coba lagi."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Sensor sidik jari kotor. Bersihkan dan coba lagi."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Perangkat ini tidak memiliki sensor sidik jari."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor dinonaktifkan untuk sementara."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan sidik jari"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gunakan sidik jari atau kunci layar"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gunakan sidik jari untuk melanjutkan"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Face unlock tidak didukung di perangkat ini."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor dinonaktifkan untuk sementara."</string>
<string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> wajah"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Gunakan face unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gunakan face lock atau kunci layar"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Gunakan face unlock untuk melanjutkan"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikon wajah"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Berita & Majalah"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Peta & Navigasi"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivitas"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Aksesibilitas"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Penyimpanan perangkat"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Proses debug USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"jam"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index cd5b35a..0e11f03 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Leyfir forritinu að breyta myndasafninu þínu."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lesa staðsetningar úr efnissafninu þínu"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Leyfir forritinu að lesa staðsetningar úr efnissafninu þínu."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Nota lífkenni"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Nota lífkenni eða skjálás"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Staðfestu hver þú ert"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Notaðu lífkenni til að halda áfram"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Lífkennavélbúnaður ekki tiltækur"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Hætt við auðkenningu"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Þekktist ekki"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Hætt við auðkenningu"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Ekkert PIN-númer, mynstur eða aðgangsorð stillt"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Villa við auðkenningu"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Nota skjálás"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Færðu inn skilríki tækisins til að halda áfram"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Hluti fingrafars greindist. Reyndu aftur."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Ekki var hægt að vinna úr fingrafarinu. Reyndu aftur."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingrafaraskynjarinn er óhreinn. Hreinsaðu hann og reyndu aftur."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Þetta tæki er ekki með fingrafaralesara."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Slökkt tímabundið á skynjara."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Fingur <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Nota fingrafar"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Nota fingrafar eða skjálás"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Notaðu fingrafarið þitt til að halda áfram"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Andlitsopnun er ekki studd í þessu tæki."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Slökkt tímabundið á skynjara."</string>
<string name="face_name_template" msgid="3877037340223318119">"Andlit <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Nota andlitsopnun"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Nota andlit eða skjálás"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Notaðu andlitsopnun til að halda áfram"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Andlitstákn"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Fréttir og tímarit"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kort og leiðsögn"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Aðstoð"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Aðgengi"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Geymslurými tækis"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-villuleit"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"klst."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 83b4a68..b41996e 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Consente all\'app di modificare la tua raccolta di foto."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lettura delle posizioni dalla tua raccolta multimediale"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Consente all\'app di leggere le posizioni dalla tua raccolta multimediale."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Usa la biometria"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usa la biometria o il blocco schermo"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica la tua identità"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Usa la biometria per continuare"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biometrico non disponibile"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autenticazione annullata"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Non riconosciuto"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autenticazione annullata"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Non hai impostato PIN, sequenza o password"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Errore durante l\'autenticazione"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usa il blocco schermo"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Inserisci la credenziale del dispositivo per continuare"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Rilevata impronta parziale. Riprova."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Impossibile elaborare l\'impronta. Riprova."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Il sensore di impronte è sporco. Puliscilo e riprova."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Questo dispositivo non dispone di sensore di impronte."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensore temporaneamente disattivato."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usa l\'impronta"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usa l\'impronta o il blocco schermo"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilizza la tua impronta per continuare"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Sblocco con il volto non supportato su questo dispositivo."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensore temporaneamente disattivato."</string>
<string name="face_name_template" msgid="3877037340223318119">"Volto <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Usa Sblocco con il volto"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usa Sblocco con il volto o il blocco schermo"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Usa Sblocco con il volto per continuare"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Icona volto"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Notizie e riviste"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps e Navigatore"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produttività"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibilità"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Memoria dispositivo"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Debug USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ora"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index e3cb913..be05cc0 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"מאפשרת לאפליקציה לשנות את אוסף התמונות שלך."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"לקרוא מיקומים מאוסף המדיה שלך"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"מאפשרת לאפליקציה לקרוא מיקומים מאוסף המדיה שלך."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"שימוש במידע ביומטרי"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"שימוש במידע ביומטרי בנעילת מסך"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"אימות זהותך"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"יש להשתמש במידע ביומטרי כדי להמשיך"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"חומרה ביומטרית לא זמינה"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"האימות בוטל"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"לא זוהתה"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"האימות בוטל"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"עוד לא הוגדרו קוד גישה, קו ביטול נעילה או סיסמה"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"שגיאה באימות"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"שימוש בנעילת מסך"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"יש להזין את פרטי הכניסה של המכשיר כדי להמשיך"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"זוהתה טביעת אצבע חלקית. אפשר לנסות שוב."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"לא ניתן היה לעבד את טביעת האצבע. נסה שוב."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"החיישן של טביעות האצבעות מלוכלך. צריך לנקות אותו ולנסות שוב."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"במכשיר זה אין חיישן טביעות אצבע."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"החיישן מושבת באופן זמני."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"שימוש בטביעת אצבע"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"שימוש בטביעת אצבע או בנעילת מסך"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"יש להשתמש בטביעת האצבע כדי להמשיך"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"המכשיר הזה לא תומך בשחרור נעילה על ידי זיהוי פנים."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"החיישן מושבת באופן זמני."</string>
<string name="face_name_template" msgid="3877037340223318119">"פנים <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"שחרור נעילה על ידי זיהוי פנים"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"שימוש בזיהוי פנים או בנעילת מסך"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"יש להשתמש בשחרור נעילה על ידי זיהוי פנים כדי להמשיך"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"סמל הפנים"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"חדשות וכתבי עת"</string>
<string name="app_category_maps" msgid="6395725487922533156">"מפות וניווט"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"פרודוקטיביות"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"שעה"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 4b54bdb..e7c3438 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"写真コレクションの変更をアプリに許可します。"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"メディア コレクションの位置情報の読み取り"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"メディア コレクションの位置情報の読み取りをアプリに許可します。"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"生体認証の使用"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"生体認証または画面ロックの使用"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"本人確認"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"続行するには生体認証を使用してください"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"生体認証ハードウェアが利用できません"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"認証をキャンセルしました"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"認識されませんでした"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"認証をキャンセルしました"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN、パターン、パスワードが設定されていません"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"エラー認証"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"画面ロックの使用"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"続行するにはデバイスの認証情報を入力してください"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"指紋を一部しか検出できませんでした。もう一度お試しください。"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"指紋を処理できませんでした。もう一度お試しください。"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"指紋認証センサーに汚れがあります。汚れを落としてもう一度お試しください。"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"このデバイスには指紋認証センサーがありません。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"センサーが一時的に無効になっています。"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"指紋 <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"指紋の使用"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"指紋または画面ロックの使用"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"続行するには指紋認証を使用してください"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"このデバイスでは、顔認証はご利用いただけません。"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"センサーが一時的に無効になっています。"</string>
<string name="face_name_template" msgid="3877037340223318119">"顔 <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"顔認証の使用"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"顔認証または画面ロックの使用"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"続行するには顔認証を使用してください"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"顔アイコン"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"ニュース&雑誌"</string>
<string name="app_category_maps" msgid="6395725487922533156">"地図&ナビ"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"仕事効率化"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"時"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 7a03bb3..3fb6c69 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"აპი შეძლებს თქვენი ფოტოკოლექციის შეცვლას."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"მდებარეობების გაცნობა თქვენი მედიაკოლექციიდან"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"აპი შეძლებს მდებარეობების გაცნობას თქვენი მედიაკოლექციიდან."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"გამოიყენეთ ბიომეტრიული სისტემა"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"გამოიყენეთ ბიომეტრიული სისტემა ან ეკრანის დაბლოკვა"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"დაადასტურეთ ვინაობა"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"გასაგრძელებლად გამოიყენეთ თქვენი ბიომეტრიული მონაცემები"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ბიომეტრიული აპარატურა მიუწვდომელია"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"ავტორიზაცია გაუქმდა"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"არ არის ამოცნობილი"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"ავტორიზაცია გაუქმდა"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN-კოდი, ნიმუში ან პაროლი დაყენებული არ არის"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"შეცდომა ავთენტიკაციისას"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"გამოიყენეთ ეკრანის დაბლოკვა"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"გასაგრძელებლად შეიყვანეთ თქვენი მოწყობილობის ავტორიზაციის მონაცემი"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"აღმოჩენილია თითის ნაწილობრივი ანაბეჭდი. გთხოვთ, სცადოთ ხელახლა."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"თითის ანაბეჭდის დამუშავება ვერ მოხერხდა. გთხოვთ, ცადოთ ხელახლა."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"თითის ანაბეჭდის სენსორი დაბინძურებულია. გთხოვთ, გაასუფთაოთ და სცადოთ ხელახლა."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ამ მოწყობილობას არ აქვს თითის ანაბეჭდის სენსორი."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"სენსორი დროებით გათიშულია."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"გამოიყენეთ თითის ანაბეჭდი"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"გამოიყენეთ თითის ანაბეჭდი ან ეკრანის დაბლოკვა"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"გასაგრძელებლად გამოიყენეთ თქვენი თითის ანაბეჭდი"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"განბლოკვა სახით ამ მოწყობილობაზე მხარდაჭერილი არ არის."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"სენსორი დროებით გათიშულია."</string>
<string name="face_name_template" msgid="3877037340223318119">"სახე <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"გამოიყენეთ სახით განბლოკვა"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"გამოიყენეთ სახე ან ეკრანის დაბლოკვა"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"გასაგრძელებლად გამოიყენეთ სახით განბლოკვა"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"სახის ხატულა"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"ახალი ამბები და ჟურნალები"</string>
<string name="app_category_maps" msgid="6395725487922533156">"რუკები და ნავიგაცია"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"პროდუქტიულობა"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"საათი"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 1c00fe6..4404603 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Қолданбаға суреттер жинағын өзгертуге мүмкіндік береді."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"медиамазмұн жинағынан геодеректерді оқу"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Қолданбаға медиамазмұн жинағынан геодеректерді оқуға мүмкіндік береді."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Биометриканы пайдалану"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Биометриканы немесе экран құлпын пайдалану"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Бұл сіз екеніңізді растаңыз"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Жалғастыру үшін биометрикаңызды пайдаланыңыз."</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрикалық жабдық жоқ"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Аутентификациядан бас тартылды."</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Танылмады"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Аутентификациядан бас тартылды."</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Ешқандай PIN коды, өрнек немесе құпия сөз орнатылмаған."</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Аутентификациялауда қате шықты."</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Экран құлпын пайдалану"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Жалғастыру үшін құрылғының тіркелу деректерін енгізіңіз."</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Саусақ ізі толық анықталмады. Әрекетті қайталаңыз."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Саусақ ізін өңдеу мүмкін емес. Әрекетті қайталаңыз."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Сканер лас. Тазалап, әрекетті қайталаңыз."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бұл құрылғыда саусақ ізін оқу сканері жоқ."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик уақытша өшірулі."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> саусағы"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Саусақ ізін пайдалану"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Саусақ ізін немесе экран құлпын пайдалану"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Жалғастыру үшін саусақ ізін пайдаланыңыз."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Бұл құрылғыда Face Unlock функциясы істемейді."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Датчик уақытша өшірулі."</string>
<string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> беті"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Face Unlock функциясын пайдалану"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Face Lock функциясын немесе экран құлпын пайдалану"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Жалғастыру үшін Face Unlock функциясын пайдаланыңыз."</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Бет белгішесі"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Газеттер және журналдар"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Карта және навигация"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Өнімділік"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"сағат"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index a2512d2..fb11553 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"អនុញ្ញាតឱ្យកម្មវិធីកែប្រែបណ្ដុំរូបថតរបស់អ្នក។"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"អានទីតាំងពីបណ្ដុំមេឌៀរបស់អ្នក"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"អនុញ្ញាតឱ្យកម្មវិធីអានទីតាំងពីបណ្ដុំមេឌៀរបស់អ្នក។"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ប្រើជីវមាត្រ"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ប្រើជីវមាត្រ ឬការចាក់សោអេក្រង់"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ផ្ទៀងផ្ទាត់ថាជាអ្នក"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ប្រើជីវមាត្ររបស់អ្នក ដើម្បីបន្ត"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"មិនអាចប្រើឧបករណ៍ស្កេនស្នាមម្រាមដៃបានទេ"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"បានបោះបង់ការផ្ទៀងផ្ទាត់"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"មិនអាចសម្គាល់បានទេ"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"បានបោះបង់ការផ្ទៀងផ្ទាត់"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"គ្មានការកំណត់កូដ pin លំនាំ ឬពាក្យសម្ងាត់ទេ"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"មានបញ្ហាក្នុងការផ្ទៀងផ្ទាត់"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ប្រើការចាក់សោអេក្រង់"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"បញ្ចូលព័ត៌មានផ្ទៀងផ្ទាត់ឧបករណ៍របស់អ្នក ដើម្បីបន្ត"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"បានផ្តិតយកស្នាមម្រាមដៃមិនពេញលក្ខណៈ។ សូមព្យាយាមម្តងទៀត។"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"មិនអាចដំណើរការស្នាមម្រាមដៃបានទេ។ សូមព្យាយាមម្តងទៀត។"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"ឧបករណ៍ចាប់ស្នាមម្រាមដៃគឺប្រឡាក់។ សូមសម្អាត រួចព្យាយាមម្តងទៀត។"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ឧបករណ៍នេះមិនមានឧបករណ៍ចាប់ស្នាមម្រាមដៃទេ។"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"បានបិទឧបករណ៍ចាប់សញ្ញាជាបណ្តោះអាសន្ន។"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ម្រាមដៃ <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ប្រើស្នាមម្រាមដៃ"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ប្រើស្នាមម្រាមដៃ ឬការចាក់សោអេក្រង់"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ប្រើស្នាមម្រាមដៃរបស់អ្នក ដើម្បីបន្ត"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"មិនអាចប្រើការដោះសោតាមទម្រង់មុខនៅលើឧបករណ៍នេះបានទេ។"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"បានបិទឧបករណ៍ចាប់សញ្ញាជាបណ្តោះអាសន្ន។"</string>
<string name="face_name_template" msgid="3877037340223318119">"ផ្ទៃមុខទី <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"ប្រើការដោះសោតាមទម្រង់មុខ"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ប្រើមុខ ឬការចាក់សោអេក្រង់"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ប្រើការដោះសោតាមទម្រង់មុខ ដើម្បីបន្ត"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"រូបផ្ទៃមុខ"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"ព័ត៌មាន និងទស្សនាវដ្ដី"</string>
<string name="app_category_maps" msgid="6395725487922533156">"ផែនទី និងការរុករក"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ផលិតភាព"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"ម៉ោង"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index e9110c2..f484344d 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"ನಿಮ್ಮ ಫೋಟೋ ಸಂಗ್ರಹಣೆಯನ್ನು ಮಾರ್ಪಡಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ನಿಮ್ಮ ಮೀಡಿಯಾ ಸಂಗ್ರಹಣೆಯಿಂದ ಸ್ಥಳಗಳನ್ನು ಓದಿ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"ನಿಮ್ಮ ಮೀಡಿಯಾ ಸಂಗ್ರಹಣೆಯಿಂದ ಸ್ಥಳಗಳನ್ನು ಓದಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ಬಯೋಮೆಟ್ರಿಕ್ಸ್ ಬಳಸಿ"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ಬಯೋಮೆಟ್ರಿಕ್ಸ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ಇದು ನೀವೇ ಎಂದು ಪರಿಶೀಲಿಸಿ"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ಮುಂದುವರಿಸಲು ನಿಮ್ಮ ಬಯೋಮೆಟ್ರಿಕ್ ಬಳಸಿ"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ಬಯೋಮೆಟ್ರಿಕ್ ಹಾರ್ಡ್ವೇರ್ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"ಪ್ರಮಾಣೀಕರಣವನ್ನು ರದ್ದುಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"ಗುರುತಿಸಲಾಗಿಲ್ಲ"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"ಪ್ರಮಾಣೀಕರಣವನ್ನು ರದ್ದುಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"ಪಿನ್, ಪ್ಯಾಟರ್ನ್ ಅಥವಾ ಪಾಸ್ವರ್ಡ್ ಸೆಟ್ ಮಾಡಿಲ್ಲ"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"ದೃಢೀಕರಿಸುವಾಗ ದೋಷ ಎದುರಾಗಿದೆ"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬಳಸಿ"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"ಮುಂದುವರಿಸಲು ನಿಮ್ಮ ಸಾಧನದ ರುಜುವಾತನ್ನು ನಮೂದಿಸಿ"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"ಭಾಗಶಃ ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಪತ್ತೆಯಾಗಿದೆ. ದಯವಿಟ್ಟು ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಅನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ದಯವಿಟ್ಟು ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಕೊಳೆಯಾಗಿದೆ. ದಯವಿಟ್ಟು ಅದನ್ನು ಸ್ವಚ್ಛಗೊಳಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ಈ ಸಾಧನವು ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಹೊಂದಿಲ್ಲ."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ಸೆನ್ಸಾರ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ಫಿಂಗರ್ <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಬಳಸಿ"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬಳಸಿ"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ಮುಂದುವರಿಸಲು ನಿಮ್ಮ ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಬಳಸಿ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"ಈ ಸಾಧನದಲ್ಲಿ ಫೇಸ್ ಅನ್ಲಾಕ್ ವೈಶಿಷ್ಟ್ಯವು ಬೆಂಬಲಿತವಾಗಿಲ್ಲ."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"ಸೆನ್ಸಾರ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
<string name="face_name_template" msgid="3877037340223318119">"ಮುಖದ <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"ಫೇಸ್ ಅನ್ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ಫೇಸ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ಮುಂದುವರಿಸಲು ಫೇಸ್ ಅನ್ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"ಮುಖದ ಐಕಾನ್"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"ಸುದ್ದಿ ಮತ್ತು ನಿಯತಕಾಲಿಕೆಗಳು"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps ಮತ್ತು ನ್ಯಾವಿಗೇಶನ್"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ಉತ್ಪಾದಕತೆ"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"ಗಂಟೆ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 16e2efa..78cc1b5 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"앱에서 사진 컬렉션을 수정하도록 허용합니다."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"미디어 컬렉션에서 위치 읽기"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"앱에서 미디어 컬렉션의 위치를 읽도록 허용합니다."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"생체 인식 사용"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"생체 인식 또는 화면 잠금을 사용"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"본인 확인"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"생체 인식을 사용하여 계속하세요"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"생체 인식 하드웨어를 사용할 수 없음"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"인증이 취소되었습니다."</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"인식할 수 없음"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"인증이 취소되었습니다."</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN, 패턴, 비밀번호가 설정되지 않음"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"인증 오류"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"화면 잠금 사용"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"계속하려면 기기의 사용자 인증 정보를 입력하세요"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"지문이 일부만 인식되었습니다. 다시 시도해 주세요."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"지문을 인식할 수 없습니다. 다시 시도해 주세요."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"지문 센서를 깨끗이 닦고 다시 시도하세요."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"기기에 지문 센서가 없습니다."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"센서가 일시적으로 사용 중지되었습니다."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"손가락 <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"지문 사용"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"지문 또는 화면 잠금 사용"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"계속하려면 지문을 사용하세요."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"이 기기에서는 얼굴인식 잠금해제가 지원되지 않습니다."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"센서가 일시적으로 사용 중지되었습니다."</string>
<string name="face_name_template" msgid="3877037340223318119">"얼굴 <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"얼굴인식 잠금해제 사용"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"얼굴 또는 화면 잠금 사용"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"얼굴인식 잠금해제를 사용하여 계속하세요"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"얼굴 아이콘"</string>
@@ -1699,7 +1689,7 @@
<string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"기능 간에 전환하려면 세 손가락을 사용하여 위로 스와이프한 다음 잠시 기다립니다."</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_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>
<string name="owner_name" msgid="8713560351570795743">"소유자"</string>
<string name="error_message_title" msgid="4082495589294631966">"오류"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"뉴스/잡지"</string>
<string name="app_category_maps" msgid="6395725487922533156">"지도/내비게이션"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"생산성"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"시"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 2584225..5d8b898 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Колдонмого сүрөт жыйнагыңызды өзгөртүүгө мүмкүнчүлүк берет."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"медиа жыйнагыңыз сакталган жерлерди окуу"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Колдонмого медиа жыйнагыңыз сакталган жерлерди окууга мүмкүнчүлүк берет."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Биометрикалык жөндөөлөрдү колдонуу"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Биометрикалык жөндөөнү же экрандын кулпусун колдонуу"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Өзүңүздү ырастаңыз"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Улантуу үчүн биометрикалык жөндөөнү колдонуу"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрикалык аппарат жеткиликсиз"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Аныктыгын текшерүү жокко чыгарылды"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Таанылган жок"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Аныктыгын текшерүү жокко чыгарылды"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN код, графикалык ачкыч же сырсөз коюлган жок"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Аутентификация катасы"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Экран кулпусун колдонуу"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Улантуу үчүн түзмөгүңүздүн эсептик дайындарын киргизиңиз"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Манжа изи жарым-жартылай аныкталды. Кайталап көрүңүз."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Манжа изи иштелбей койду. Кайталап көрүңүз."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Манжа изинин сенсору кирдеп калган. Тазалап, кайталап көрүңүз."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бул түзмөктө манжа изинин сенсору жок."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сенсор убактылуу өчүрүлгөн."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-манжа"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Манжа изин колдонуу"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Манжа изин же экрандын кулпусун колдонуу"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Улантуу үчүн манжаңыздын изин колдонуңуз"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Жүзүнөн таануу функциясы бул түзмөктө иштебейт."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Сенсор убактылуу өчүрүлгөн."</string>
<string name="face_name_template" msgid="3877037340223318119">"Жүз <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Жүзүнөн таанып ачууну колдонуу"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Жүзүнөн таанып ачууну же экрандын кулпусун колдонуу"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Улантуу үчүн жүзүнөн таанып ачууну колдонуу"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Жүздүн сүрөтчөсү"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Жаңылыктар жана журналдар"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Карталар жана чабыттоо"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Өндүрүш категориясы"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"саат"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 7fb32e7..fcf47ed 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"ອະນຸຍາດໃຫ້ແອັບແກ້ໄຂຄໍເລັກຊັນຮູບຂອງທ່ານ."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ອ່ານສະຖານທີ່ຈາກຄໍເລັກຊັນມີເດຍຂອງທ່ານ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"ອະນຸຍາດໃຫ້ແອັບອ່ານສະຖານທີ່ຈາກຄໍເລັກຊັນມີເດຍຂອງທ່ານ."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ໃຊ້ລະບົບຊີວະມິຕິ"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ໃຊ້ລະບົບຊີວະມິຕິ ຫຼື ການລັອກໜ້າຈໍ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ຢັ້ງຢືນວ່າແມ່ນທ່ານ"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ໃຊ້ລະບົບຊີວະມິຕິຂອງທ່ານເພື່ອດຳເນີນການຕໍ່"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ຮາດແວຊີວະມິຕິບໍ່ສາມາດໃຊ້ໄດ້"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"ຍົກເລີກການຮັບຮອງຄວາມຖືກຕ້ອງແລ້ວ"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"ບໍ່ຮັບຮູ້"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"ຍົກເລີກການຮັບຮອງຄວາມຖືກຕ້ອງແລ້ວ"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"ບໍ່ໄດ້ຕັ້ງ PIN, ຮູບແບບປົດລັອກ ຫຼື ລະຫັດຜ່ານ"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"ເກີດຄວາມຜິດພາດໃນການພິສູດຢືນຢັນ"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ໃຊ້ການລັອກໜ້າຈໍ"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"ລະບຸຂໍ້ມູນການເຂົ້າສູ່ລະບົບອຸປະກອນຂອງທ່ານເພື່ອດຳເນີນການຕໍ່"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"ກວດພົບລາຍນີ້ວມືບາງສ່ວນແລ້ວ. ກະລຸນາລອງໃໝ່ອີກ."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ບໍ່ສາມາດດຳເນີນການລາຍນີ້ວມືໄດ້. ກະລຸນາລອງໃໝ່ອີກ."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"ເຊັນເຊີລາຍນີ້ວມືເປື້ອນ. ກະລຸນາທຳຄວາມສະອາດ ແລະລອງໃໝ່ອີກ."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ອຸປະກອນນີ້ບໍ່ມີເຊັນເຊີລາຍນິ້ວມື."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ປິດການເຮັດວຽກຂອງເຊັນເຊີໄວ້ຊົ່ວຄາວແລ້ວ."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ນີ້ວມື <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ໃຊ້ລາຍນິ້ວມື"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ໃຊ້ລາຍນິ້ວມື ຫຼື ການລັອກໜ້າຈໍ"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ໃຊ້ລາຍນີ້ວມືຂອງທ່ານເພື່ອສືບຕໍ່"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"ບໍ່ຮອງຮັບການປົດລັອກດ້ວຍໜ້າຢູ່ອຸປະກອນນີ້."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"ປິດການເຮັດວຽກຂອງເຊັນເຊີໄວ້ຊົ່ວຄາວແລ້ວ."</string>
<string name="face_name_template" msgid="3877037340223318119">"ໃບໜ້າ <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"ໃຊ້ການປົດລັອກດ້ວຍໜ້າ"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ໃຊ້ໃບໜ້າ ຫຼື ການລັອກໜ້າຈໍ"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ໃຊ້ການປົດລັອກດ້ວຍໜ້າເພື່ອດຳເນີນການຕໍ່"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"ໄອຄອນໃບໜ້າ"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"News & Magazines"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps & Navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ຜະລິດຕະພາບ"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"ຊົ່ວໂມງ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 820d7a0..4afef3b 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Programai leidžiama keisti nuotraukų kolekciją."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"skaityti vietoves iš medijos kolekcijos"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Programai leidžiama skaityti vietoves iš medijos kolekcijos."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Naudoti biometrinius duomenis"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Naudoti biometrinius duomenis arba ekrano užraktą"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Patvirtinkite, kad tai jūs"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Norėdami tęsti, naudokite biometrinius duomenis"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrinė aparatinė įranga nepasiekiama"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentifikavimas atšauktas"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Neatpažinta"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentifikavimas atšauktas"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nenustatytas PIN kodas, atrakinimo piešinys arba slaptažodis"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Autentifikuojant įvyko klaida"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Naudoti ekrano užraktą"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Jei norite tęsti, įveskite įrenginio prisijungimo duomenis"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Aptiktas dalinis piršto antspaudas. Bandykite dar kartą."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nepavyko apdoroti piršto antspaudo. Bandykite dar kartą."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Piršto antspaudo jutiklis purvinas. Nuvalykite ir bandykite dar kartą."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šiame įrenginyje nėra kontrolinio kodo jutiklio."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Jutiklis laikinai išjungtas."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> pirštas"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Naudoti kontrolinį kodą"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Naudoti kontrolinį kodą arba ekrano užraktą"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Naudokite kontrolinį kodą, kad galėtumėte tęsti"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Atrakinimas pagal veidą šiame įrenginyje nepalaikomas."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Jutiklis laikinai išjungtas."</string>
<string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> veidas"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Naudoti atrakinimą pagal veidą"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Naudoti atrakinimą pagal veidą arba ekrano užraktą"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Norėdami tęsti, naudokite atrakinimą pagal veidą"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Veido pkt."</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Naujienos ir žurnalai"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Žemėlapiai ir navigacija"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktyvumas"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Pritaikomumas"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Įrenginio saugykla"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB derinimas"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"valanda"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 91c38a4..8fbfb27 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -553,23 +553,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Ļauj lietotnei pārveidot jūsu fotoattēlu kolekciju."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"Lasīt atrašanās vietas no jūsu multivides kolekcijas"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Ļauj lietotnei lasīt atrašanās vietas no jūsu multivides kolekcijas."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometrijas izmantošana"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrijas vai ekrāna bloķēšanas izmantošana"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Apstipriniet, ka tas esat jūs"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Lai turpinātu, izmantojiet biometriju"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrisko datu aparatūra nav pieejama"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentifikācija ir atcelta"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Dati nav atpazīti"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentifikācija ir atcelta"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN, kombinācija vai parole nav iestatīta"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Autentifikācijas kļūda"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekrāna bloķēšanas metodes izmantošana"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Lai turpinātu, ievadiet savas ierīces akreditācijas datus"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Noteikts daļējs pirksta nospiedums. Lūdzu, mēģiniet vēlreiz."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nevarēja apstrādāt pirksta nospiedumu. Lūdzu, mēģiniet vēlreiz."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Pirkstu nospiedumu sensors ir netīrs. Lūdzu, notīriet to un mēģiniet vēlreiz."</string>
@@ -592,10 +587,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šajā ierīcē nav pirksta nospieduma sensora."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensors ir īslaicīgi atspējots."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. pirksts"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Pirksta nospieduma izmantošana"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Pirksta nospieduma vai ekrāna bloķēšanas metodes izmantošana"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Lai turpinātu, izmantojiet pirksta nospiedumu"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -641,12 +634,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Autorizācija pēc sejas šajā ierīcē netiek atbalstīta"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensors ir īslaicīgi atspējots."</string>
<string name="face_name_template" msgid="3877037340223318119">"Seja <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Autorizācija pēc sejas"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Autorizācijas pēc sejas vai ekrāna bloķēšanas metodes izmantošana"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Lai turpinātu, izmantojiet autorizāciju pēc sejas"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Sejas ikona"</string>
@@ -1998,8 +1988,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Ziņas un žurnāli"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kartes un navigācija"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivitāte"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Pieejamība"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Ierīces krātuve"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB atkļūdošana"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"stunda"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 88fb824..9d07234 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -20,7 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="byteShort" msgid="202579285008794431">"Б"</string>
+ <string name="byteShort" msgid="202579285008794431">"B"</string>
<string name="kilobyteShort" msgid="2214285521564195803">"KB"</string>
<string name="megabyteShort" msgid="6649361267635823443">"MB"</string>
<string name="gigabyteShort" msgid="7515809460261287991">"GB"</string>
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Дозволува апликацијата да ја менува вашата збирка на фотографии."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"да чита локации од вашата збирка на аудиовизуелни содржини"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Дозволува апликацијата да чита локации од вашата збирка на аудиовизуелни содржини."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Користи биометрика"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Користи биометрика или заклучен екран"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Потврдете дека сте вие"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Користете ја вашата биометрика за да продолжите"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрискиот хардвер е недостапен"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Проверката е откажана"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Непознат"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Проверката е откажана"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Не е поставен PIN, шема или лозинка"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Грешка при проверката"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Користи заклучување екран"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Внесете го акредитивот на уредот за да продолжите"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Откриен е делумен отпечаток. Обидете се повторно."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Отпечатокот не може да се обработи. Обидете се повторно."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Сензорот за отпечатоци е валкан. Исчистете го и обидете се повторно."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Уредов нема сензор за отпечатоци."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорот е привремено оневозможен."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користи отпечаток"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користи отпечаток или заклучување екран"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Користете го отпечатокот за да продолжите"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"„Отклучувањето со лик“ не е поддржано на уредов."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Сензорот е привремено оневозможен."</string>
<string name="face_name_template" msgid="3877037340223318119">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Користи отклучување со лик"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Користи лик или заклучување екран"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Користете отклучување со лик за да продолжите"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Икона"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Вести и списанија"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Карти и навигација"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Продуктивност"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"час"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index f82267d..8d91c51 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"നിങ്ങളുടെ ഫോട്ടോ ശേഖരം പരിഷ്ക്കരിക്കുന്നതിന് ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"നിങ്ങളുടെ മീഡിയ ശേഖരത്തിൽ നിന്നും ലൊക്കേഷനുകൾ റീഡ് ചെയ്യുക"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"നിങ്ങളുടെ മീഡിയ ശേഖരത്തിൽ നിന്നും ലൊക്കേഷനുകൾ റീഡ് ചെയ്യുന്നതിന് ആപ്പിനെ അനുവദിക്കുന്നു."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ബയോമെട്രിക്സ് ഉപയോഗിക്കുക"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ബയോമെട്രിക്സ് അല്ലെങ്കിൽ സ്ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ഇത് നിങ്ങളാണെന്ന് പരിശോധിച്ചുറപ്പിക്കുക"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"തുടരാൻ ബയോമെട്രിക് ഉപയോഗിക്കുക"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ബയോമെട്രിക് ഹാർഡ്വെയർ ലഭ്യമല്ല"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"പരിശോധിച്ചുറപ്പിക്കൽ റദ്ദാക്കി"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"തിരിച്ചറിഞ്ഞില്ല"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"പരിശോധിച്ചുറപ്പിക്കൽ റദ്ദാക്കി"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"പിന്നോ പാറ്റേണോ പാസ്വേഡോ സജ്ജീകരിച്ചിട്ടില്ല"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"പിശക് പരിശോധിച്ചുറപ്പിക്കുന്നു"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"സ്ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"തുടരാൻ നിങ്ങളുടെ ഉപകരണ ക്രെഡൻഷ്യലുകൾ നൽകുക"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"ഫിംഗർപ്രിന്റ് ഭാഗികമായി തിരിച്ചറിഞ്ഞു. വീണ്ടും ശ്രമിക്കുക."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ഫിംഗർപ്രിന്റ് പ്രോസസ് ചെയ്യാനായില്ല. വീണ്ടും ശ്രമിക്കുക."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"ഫിംഗർപ്രിന്റ് സെൻസറിൽ ചെളിയുണ്ട്. അത് വൃത്തിയാക്കി വീണ്ടും ശ്രമിക്കുക."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ഈ ഉപകരണത്തിൽ ഫിംഗർപ്രിന്റ് സെൻസറില്ല."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"സെൻസർ താൽക്കാലികമായി പ്രവർത്തനരഹിതമാക്കി."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"കൈവിരൽ <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ഫിംഗർപ്രിന്റ് അല്ലെങ്കിൽ സ്ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"തുടരുന്നതിന് നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് ഈ ഉപകരണം പിന്തുണയ്ക്കുന്നില്ല."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"സെൻസർ താൽക്കാലികമായി പ്രവർത്തനരഹിതമാക്കി."</string>
<string name="face_name_template" msgid="3877037340223318119">"മുഖം <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് ഉപയോഗിക്കുക"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"മുഖം അല്ലെങ്കിൽ സ്ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"തുടരാൻ മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് ഉപയോഗിക്കുക"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"മുഖത്തിന്റെ ഐക്കൺ"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"വാർത്തകളും മാസികകളും"</string>
<string name="app_category_maps" msgid="6395725487922533156">"മാപ്പുകളും നാവിഗേഷനും"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ഉല്പ്പാദനക്ഷമത"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"മണി."</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 203ad3d..faec2be 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Таны зургийн цуглуулгыг тохируулах зөвшөөрлийг аппад олгодог."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"медиа цуглуулгаасаа байршлыг унших"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Таны медиа цуглуулгаас байршлыг унших зөвшөөрлийг аппад олгодог."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Биометр ашиглах"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Биометр эсвэл дэлгэцийн түгжээ ашиглах"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Өөрийгөө мөн гэдгийг баталгаажуулаарай"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Үргэлжлүүлэхийн тулд биометрээ ашиглана уу"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрийн техник хангамж боломжгүй байна"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Нотолгоог цуцаллаа"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Таниагүй"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Нотолгоог цуцаллаа"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Тохируулсан пин, хээ эсвэл нууц үг алга"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Баталгаажуулахад алдаа гарлаа"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Дэлгэцийн түгжээг ашиглах"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Үргэлжлүүлэхийн тулд төхөөрөмжийнхөө мандат үнэмлэхийг оруулна уу"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Хурууны хээг дутуу уншуулсан байна. Дахин оролдоно уу."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Хурууны хээ боловсруулж чадахгүй байна. Дахин оролдоно уу."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Хурууны хээ мэдрэгч бохирдсон байна. Цэвэрлэсний дараа дахин оролдоно уу."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Энэ төхөөрөмжид хурууны хээ мэдрэгч алга."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Мэдрэгчийг түр хугацаанд идэвхгүй болгосон."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Хурууны хээ <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Хурууны хээ ашиглах"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Хурууны хээ эсвэл дэлгэцийн түгжээ ашиглах"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Үргэлжлүүлэхийн тулд хурууны хээгээ ашиглаарай"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Царайгаар тайлахыг энэ төхөөрөмж дээр дэмждэггүй."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Мэдрэгчийг түр хугацаанд идэвхгүй болгосон."</string>
<string name="face_name_template" msgid="3877037340223318119">"Царай <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Царайгаар тайлахыг ашиглах"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Царай эсвэл дэлгэцийн түгжээ ашиглах"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Үргэлжлүүлэхийн тулд царайгаар тайлахыг ашиглана уу"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Царайны дүрс тэмдэг"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Мэдээ & сэтгүүл"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Газрын зураг & зүг чиг"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Бүтээмж"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"Цаг"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index d8d43a6..3bf3063 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Membenarkan apl mengubah suai koleksi foto anda."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"baca lokasi daripada koleksi media anda"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Membenarkan apl membaca lokasi daripada koleksi media anda."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Gunakan biometrik"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gunakan biometrik atau kunci skrin"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Sahkan itu anda"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gunakan biometrik anda untuk meneruskan"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Perkakasan biometrik tidak tersedia"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Pengesahan dibatalkan"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Tidak dikenali"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Pengesahan dibatalkan"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Pin, corak atau kata laluan tidak ditetapkan"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Ralat semasa membuat pengesahan"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gunakan kunci skrin"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Masukkan bukti kelayakan peranti anda untuk meneruskan"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Cap jari separa dikesan. Sila cuba lagi."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Tidak dapat memproses cap jari. Sila cuba lagi."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Penderia cap jari kotor. Sila bersihkan dan cuba lagi."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Peranti ini tiada penderia cap jari."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Penderia dilumpuhkan sementara."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan cap jari"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gunakan cap jari atau kunci skrin"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gunakan cap jari anda untuk teruskan"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Wajah buka kunci tidak disokong pada peranti ini."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Penderia dilumpuhkan sementara."</string>
<string name="face_name_template" msgid="3877037340223318119">"Wajah <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Gunakan wajah buka kunci"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gunakan kunci wajah atau skrin"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Gunakan wajah buka kunci untuk meneruskan"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikon wajah"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Berita & Majalah"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Peta & Navigasi"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktiviti"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Kebolehaksesan"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Storan peranti"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Penyahpepijatan USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"jam"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 82008b0..f301483 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"အက်ပ်အား သင့်ဓာတ်ပုံစုစည်းမှုကို ပြုပြင်ခွင့်ပေးသည်။"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"သင့်မီဒီယာစုစည်းမှုမှ တည်နေရာများကို ဖတ်ခြင်း"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"အက်ပ်အား သင့်မီဒီယာစုစည်းမှုမှ တည်နေရာများကို ဖတ်ခွင့်ပေးသည်။"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ဇီဝမက်ထရစ်အချက်အလက်များ သုံးခြင်း"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ဇီဝမက်ထရစ်အချက်အလက်များ (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"သင်ဖြစ်ကြောင်း အတည်ပြုပါ"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ရှေ့ဆက်ရန် သင်၏ ဇီဝမက်ထရစ်အချက်အလက်ကို သုံးပါ"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ဇီဝအချက်အလက်သုံး ကွန်ပျူတာစက်ပစ္စည်း မရရှိနိုင်ပါ"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"အထောက်အထားစိစစ်ခြင်းကို ပယ်ဖျက်လိုက်သည်"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"မသိ"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"အထောက်အထားစိစစ်ခြင်းကို ပယ်ဖျက်လိုက်သည်"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"ပင်နံပါတ်၊ လော့ခ်ပုံစံ သို့မဟုတ် စကားဝှက် သတ်မှတ်မထားပါ"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"အထောက်အထားစိစစ်ရာတွင် အမှားအယွင်းရှိနေသည်"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"ရှေ့ဆက်ရန် သင့်စက်ပစ္စည်း၏ အထောက်အထားကို ထည့်သွင်းပါ"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"လက်ဗွေ တစ်ပိုင်းတစ်စ တွေ့ရှိသည်။ ကျေးဇူးပြု၍ ထပ်စမ်းကြည့်ပါ။"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"လက်ဗွေယူ၍ မရပါ။ ထပ်စမ်းကြည့်ပါ။"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"လက်ဗွေဖတ်ကိရိယာ ညစ်ပေနေသည်။ ကျေးဇူးပြု၍ သန့်ရှင်းလိုက်ပြီး ပြန်စမ်းကြည့်ပါ။"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ဤစက်တွင် လက်ဗွေအာရုံခံကိရိယာ မရှိပါ။"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"အာရုံခံကိရိယာကို ယာယီပိတ်ထားသည်။"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"လက်ချောင်း <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"လက်ဗွေ သုံးခြင်း"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"လက်ဗွေ (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ရှေ့ဆက်ရန် သင့်လက်ဗွေကို သုံးပါ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"ဤစက်ပစ္စည်းတွင် မျက်နှာမှတ် သော့ဖွင့်ခြင်းကို သုံး၍မရပါ။"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"အာရုံခံကိရိယာကို ယာယီပိတ်ထားသည်။"</string>
<string name="face_name_template" msgid="3877037340223318119">"မျက်နှာ <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"မျက်နှာမှတ်သော့ဖွင့်ခြင်းကို သုံးခြင်း"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"မျက်နှာမှတ်သော့ဖွင့်ခြင်း (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ရှေ့ဆက်ရန် မျက်နှာမှတ်သော့ဖွင့်ခြင်းကို သုံးပါ"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"မျက်နှာသင်္ကေတ"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"သတင်းနှင့် မဂ္ဂဇင်းများ"</string>
<string name="app_category_maps" msgid="6395725487922533156">"မြေပုံနှင့် ခရီးလမ်းညွှန်ချက်"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ထုတ်လုပ်နိုင်မှု"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"နာရီ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 1bafd60..07cf9c0 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Lar appen gjøre endringer i bildesamlingen din."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lese posisjoner fra mediesamlingen din"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Lar appen lese posisjoner fra mediesamlingen din."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Bruk biometri"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Bruk biometri eller skjermlås"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Bekreft at det er deg"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Bruk biometri for å fortsette"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrisk maskinvare er utilgjengelig"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentiseringen er avbrutt"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Ikke gjenkjent"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentiseringen er avbrutt"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN-kode, mønster eller passord er ikke angitt"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Feil under autentiseringen"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Bruk skjermlås"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Skriv inn enhetslegitimasjonen din for å fortsette"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Deler av fingeravtrykket er registrert. Prøv på nytt."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kunne ikke registrere fingeravtrykket. Prøv på nytt."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingeravtrykksensoren er skitten. Rengjør den og prøv på nytt."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enheten har ikke fingeravtrykkssensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidig slått av."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Bruk fingeravtrykk"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Bruk fingeravtrykk eller skjermlås"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Bruk fingeravtrykket ditt for å fortsette"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Ansiktslås støttes ikke på denne enheten"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensoren er midlertidig slått av."</string>
<string name="face_name_template" msgid="3877037340223318119">"Ansikt <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Bruk ansiktslås"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Bruk ansikts- eller skjermlås"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Bruk ansiktslås for å fortsette"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ansiktikon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Nyheter og tidsskrifter"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kart og navigering"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivitet"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Tilgjengelighet"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Lagring på enheten"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-feilsøking"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"time"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index a15a9a4..6295d44 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"यसले एपलाई तपाईंको तस्बिरको सङ्ग्रह परिमार्जन गर्न दिन्छ।"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"आफ्नो मिडियाको सङ्ग्रहका स्थानहरू पढ्नुहोस्"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"यसले एपलाई तपाईंको मिडिया सङ्ग्रहका स्थानहरू पढ्न दिन्छ।"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"बायोमेट्रिक्स प्रयोग गर्नुहोस्"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"बायोमेट्रिक्स वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"यो व्यक्ति तपाईं नै हो भन्ने प्रमाणित गर्नुहोस्"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"जारी राख्न आफ्नो बायोमेट्रिक प्रयोग गर्नुहोस्"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"बायोमेट्रिक हार्डवेयर उपलब्ध छैन"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"प्रमाणीकरण रद्द गरियो"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"पहिचान भएन"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"प्रमाणीकरण रद्द गरियो"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"कुनै पनि PIN, ढाँचा वा पासवर्ड सेट गरिएको छैन"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"प्रमाणित गर्ने क्रममा त्रुटि भयो"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"स्क्रिन लक प्रयोग गर्नुहोस्"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"जारी राख्न आफ्नो यन्त्रको PIN, प्याटर्न वा पासवर्ड हाल्नुहोस्"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"आंशिक फिंगरप्रिन्ट पत्ता लाग्यो। कृपया फेरि प्रयास गर्नुहोस्।"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"फिंगरप्रिन्ट प्रशोधन गर्न सकिएन। कृपया फेरि प्रयास गर्नुहोस्।"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"फिंगरप्रिन्ट सेन्सर फोहोर छ। कृपया सफा गरेर फेरि प्रयास गर्नुहोस्।"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"यो यन्त्रमा कुनै पनि फिंगरप्रिन्ट सेन्सर छैन।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"केही समयका लागि सेन्सर असक्षम पारियो।"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"औंला <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फिंगरप्रिन्ट वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"जारी राख्न आफ्नो फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"यस यन्त्रमा फेस अनलक सुविधा प्रयोग गर्न मिल्दैन।"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"केही समयका लागि सेन्सर असक्षम पारियो।"</string>
<string name="face_name_template" msgid="3877037340223318119">"अनुहार <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"फेस अनलक प्रयोग गर्नुहोस्"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"फेस अनलक वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"जारी राख्न फेस अनलक प्रयोग गर्नुहोस्"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"अनुहारको आइकन"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"समाचार तथा पत्रिकाहरू"</string>
<string name="app_category_maps" msgid="6395725487922533156">"नक्सा तथा नेभिगेसन"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"उत्पादकत्व"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"घन्टा"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 1f2680e..46880ea 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Hiermee sta je de app toe je fotocollectie aan te passen."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"locaties van je mediacollecties bekijken"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Hiermee sta je de app toe locaties van je mediacollectie te bekijken."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometrische gegevens gebruiken"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrische gegevens of schermvergrendeling gebruiken"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Je identiteit verifiëren"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gebruik je biometrische gegevens om door te gaan"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrische hardware niet beschikbaar"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Verificatie geannuleerd"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Niet herkend"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Verificatie geannuleerd"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Geen pincode, patroon of wachtwoord ingesteld"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Fout bij verificatie"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Schermvergrendeling gebruiken"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Geef de inloggegevens van je apparaat op om door te gaan"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Gedeeltelijke vingerafdruk gedetecteerd. Probeer het opnieuw."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kan vingerafdruk niet verwerken. Probeer het opnieuw."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"De vingerafdruksensor moet worden schoongemaakt. Probeer het daarna opnieuw."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dit apparaat heeft geen vingerafdruksensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor tijdelijk uitgeschakeld."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Vingerafdruk gebruiken"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Vingerafdruk of schermvergrendeling gebruiken"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gebruik je vingerafdruk om door te gaan."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Ontgrendelen via gezichtsherkenning wordt niet ondersteund op dit apparaat."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor tijdelijk uitgeschakeld."</string>
<string name="face_name_template" msgid="3877037340223318119">"Gezicht <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Ontgrendelen via gezichtsherkenning gebruiken"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gezicht of schermgrendeling gebruiken"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Gebruik ontgrendelen via gezichtsherkenning om door te gaan"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Gezichtspictogram"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Nieuws en tijdschriften"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps en navigatie"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productiviteit"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Toegankelijkheid"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Apparaatopslag"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-foutopsporing"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"uur"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index e3c3c09..7d65cde 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"ଆପଣଙ୍କ ଫଟୋ ସଂଗ୍ରହ ପରିବର୍ତ୍ତନ କରିବାକୁ ଆପ୍ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ଆପଣଙ୍କ ମିଡିଆ ସଂଗ୍ରହ ଠାରୁ ଲୋକେସନ୍ଗୁଡିକୁ ପଢନ୍ତୁ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"ଆପଣଙ୍କ ମିଡିଆ ସଂଗ୍ରହ ଠାରୁ ଅବସ୍ଥାନଗୁଡିକୁ ପଢିବାକୁ ଆପ୍ ଅନୁମତି ଦେଇଥାଏ।"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ବାୟୋମେଟ୍ରିକ୍ସ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ବାୟୋମେଟ୍ରିକ୍ସ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ଏହା ଆପଣ ବୋଲି ଯାଞ୍ଚ କରନ୍ତୁ"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ବାୟୋମେଟ୍ରିକ୍ସ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ବାୟୋମେଟ୍ରିକ୍ ହାର୍ଡୱେର୍ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"ପ୍ରାମାଣିକତାକୁ ବାତିଲ୍ କରାଯାଇଛି"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"ଚିହ୍ନଟ ହେଲାନାହିଁ"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"ପ୍ରାମାଣିକତାକୁ ବାତିଲ୍ କରାଯାଇଛି"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"କୌଣସି ପିନ୍, ପେଟେର୍ନ ବା ପାସ୍ୱର୍ଡ ସେଟ୍ ନାହିଁ"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"ପ୍ରାମାଣିକରଣ କରିବା ସମୟରେ ତ୍ରୁଟି"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ଡିଭାଇସର କ୍ରେଡେନ୍ସିଆଲ୍ ଲେଖନ୍ତୁ"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"ଆଂଶିକ ଟିପଚିହ୍ନ ଚିହ୍ନଟ ହେଲା। ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ଟିପଚିହ୍ନ ପ୍ରୋସେସ୍ କରାଯାଇପାରିଲା ନାହିଁ। ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"ଟିପଚିହ୍ନ ସେନ୍ସର୍ ମଇଳା ହୋଇଯାଇଛି। ଦୟାକରି ସଫା କରନ୍ତୁ ଓ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ଏହି ଡିଭାଇସ୍ରେ ଟିପଚିହ୍ନ ସେନ୍ସର୍ ନାହିଁ।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ସେନ୍ସରକୁ ଅସ୍ଥାୟୀ ଭାବେ ଅକ୍ଷମ କରାଯାଇଛି।"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ଆଙ୍ଗୁଠି <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ଟିପଚିହ୍ନ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"ଏହି ଡିଭାଇସ୍ରେ ଫେସ୍ ଅନ୍ଲକ୍ ସମର୍ଥିତ ନୁହେଁ।"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"ସେନ୍ସରକୁ ଅସ୍ଥାୟୀ ଭାବେ ଅକ୍ଷମ କରାଯାଇଛି।"</string>
<string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g>ଙ୍କ ଫେସ୍"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"ଫେସ୍ ଅନଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ଫେସ୍ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ଜାରି ରଖିବାକୁ ଫେସ୍ ଅନଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"ଫେସ୍ ଆଇକନ୍"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"ଖବର ଓ ମ୍ୟାଗାଜିନ୍"</string>
<string name="app_category_maps" msgid="6395725487922533156">"ମାନଚିତ୍ର ଓ ନେଭିଗେଶନ୍"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ଉତ୍ପାଦକତା"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"ଘଣ୍ଟା"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 01bf276..4b18320 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Zezwala aplikacji na modyfikowanie kolekcji zdjęć."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"odczytywanie lokalizacji z kolekcji multimediów"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Zezwala aplikacji na odczytywanie lokalizacji z kolekcji multimediów."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Używaj biometrii"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Używaj biometrii lub blokady ekranu"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potwierdź swoją tożsamość"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Użyj biometrii, by kontynuować"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Sprzęt biometryczny niedostępny"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Anulowano uwierzytelnianie"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nie rozpoznano"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Anulowano uwierzytelnianie"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nie ustawiono kodu PIN, wzoru ani hasła"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Podczas uwierzytelniania wystąpił błąd"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Używaj blokady ekranu"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Podaj dane logowania do urządzenia, aby kontynuować"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Odcisk palca został odczytany tylko częściowo. Spróbuj ponownie."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nie udało się przetworzyć odcisku palca. Spróbuj ponownie."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Czytnik linii papilarnych jest zabrudzony. Wyczyść go i spróbuj ponownie."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"To urządzenie nie jest wyposażone w czytnik linii papilarnych."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Czujnik jest tymczasowo wyłączony."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Odcisk palca <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Używaj odcisku palca"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Używaj odcisku palca lub blokady ekranu"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Użyj odcisku palca, by kontynuować"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"To urządzenie nie obsługuje rozpoznawania twarzy."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Czujnik jest tymczasowo wyłączony."</string>
<string name="face_name_template" msgid="3877037340223318119">"Twarz <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Używaj rozpoznawania twarzy"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Używaj rozpoznawania twarzy lub blokady ekranu"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Użyj rozpoznawania twarzy, aby kontynuować"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona twarzy"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Wiadomości i czasopisma"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapy i nawigacja"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktywność"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Ułatwienia dostępu"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Pamięć urządzenia"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Debugowanie USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"godz."</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index aa693582f..7d028f9 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que o app modifique sua coleção de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ler locais na sua coleção de mídias"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que o app leia os locais na sua coleção de mídias."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Usar biometria"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar biometria ou bloqueio de tela"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirme que é você"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use seus dados biométricos para continuar"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biométrico indisponível"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autenticação cancelada"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Não reconhecido"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autenticação cancelada"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nenhum PIN, padrão ou senha configurado"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Erro na autenticação"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueio de tela"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Insira as credenciais do dispositivo para continuar"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Impressão digital parcial detectada. Tente novamente."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"O sensor de impressão digital está sujo. Limpe-o e tente novamente."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar impressão digital ou bloqueio de tela"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use sua impressão digital para continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"O desbloqueio facial não é compatível com este dispositivo."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor desativado temporariamente."</string>
<string name="face_name_template" msgid="3877037340223318119">"Rosto <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Usar desbloqueio facial"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usar reconhecimento facial ou bloqueio de tela"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use o desbloqueio facial para continuar"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ícone facial"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Notícias e revistas"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapas e navegação"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produtividade"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Acessibilidade"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Armazenamento do dispositivo"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Depuração USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hora"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 232a1721..a01db5e 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que a app modifique a sua coleção de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ler as localizações a partir da sua coleção de multimédia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que a app leia as localizações a partir da sua coleção de multimédia."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Utilizar a biometria"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utilizar a biometria ou o bloqueio de ecrã"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirme a sua identidade"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Utilize a biometria para continuar."</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biométrico indisponível."</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autenticação cancelada"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Não reconhecido."</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autenticação cancelada"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nenhum PIN, padrão ou palavra-passe definidos."</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Erro ao autenticar."</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utilizar o bloqueio de ecrã"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Introduza a credencial do dispositivo para continuar."</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Impressão digital parcial detetada. Tente novamente."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"O sensor de impressões digitais está sujo. Limpe-o e tente novamente."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem sensor de impressões digitais."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporariamente desativado."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilizar a impressão digital"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilizar o bloqueio de ecrã ou a impressão digital"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilize a sua impressão digital para continuar."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Desbloqueio facial não suportado neste dispositivo."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor temporariamente desativado."</string>
<string name="face_name_template" msgid="3877037340223318119">"Rosto <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Utilizar o desbloqueio facial"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Utilizar o bloqueio através do rosto ou de ecrã"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Utilize o desbloqueio facial para continuar."</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ícone de rosto"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Notícias e revistas"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapas e navegação"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produtividade"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Acessibilidade"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Armazenamento do dispositivo"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Depuração USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hora"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index aa693582f..7d028f9 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que o app modifique sua coleção de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ler locais na sua coleção de mídias"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que o app leia os locais na sua coleção de mídias."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Usar biometria"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar biometria ou bloqueio de tela"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirme que é você"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use seus dados biométricos para continuar"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biométrico indisponível"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autenticação cancelada"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Não reconhecido"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autenticação cancelada"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nenhum PIN, padrão ou senha configurado"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Erro na autenticação"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueio de tela"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Insira as credenciais do dispositivo para continuar"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Impressão digital parcial detectada. Tente novamente."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"O sensor de impressão digital está sujo. Limpe-o e tente novamente."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar impressão digital ou bloqueio de tela"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use sua impressão digital para continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"O desbloqueio facial não é compatível com este dispositivo."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor desativado temporariamente."</string>
<string name="face_name_template" msgid="3877037340223318119">"Rosto <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Usar desbloqueio facial"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usar reconhecimento facial ou bloqueio de tela"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use o desbloqueio facial para continuar"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ícone facial"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Notícias e revistas"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapas e navegação"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produtividade"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Acessibilidade"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Armazenamento do dispositivo"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Depuração USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hora"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 01daa55..e8c5539 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -553,23 +553,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite aplicației să vă modifice colecția de fotografii."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"citiți locațiile din colecția media"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite aplicației să citească locațiile din colecția dvs. media."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Folosiți sistemele biometrice"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Folosiți sistemele biometrice sau blocarea ecranului"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirmați-vă identitatea"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Folosiți sistemele biometrice pentru a continua"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biometric indisponibil"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentificarea a fost anulată"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nu este recunoscut"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentificarea a fost anulată"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nu este setat niciun cod PIN, model sau parolă"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Eroare la autentificare"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Folosiți blocarea ecranului"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Introduceți datele de conectare ale dispozitivului pentru a continua"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"S-a detectat parțial amprenta. Încercați din nou."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Amprenta nu a putut fi procesată. Încercați din nou."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Senzorul pentru amprente este murdar. Curățați-l și încercați din nou."</string>
@@ -592,10 +587,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dispozitivul nu are senzor de amprentă."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzorul este dezactivat temporar."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Folosiți amprenta"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Folosiți amprenta sau blocarea ecranului"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Folosiți amprenta pentru a continua"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -641,12 +634,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Deblocarea facială nu este acceptată pe dispozitiv."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Senzorul este dezactivat temporar."</string>
<string name="face_name_template" msgid="3877037340223318119">"Chip <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Folosiți deblocarea facială"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Folosiți blocarea ecranului sau blocarea facială"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Folosiți deblocarea facială pentru a continua"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Pictograma chip"</string>
@@ -1998,8 +1988,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Știri și reviste"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Hărți și navigare"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivitate"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accesibilitate"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Stocare pe dispozitiv"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Remedierea erorilor prin USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"oră"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 1a513e4..48f96ef 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Приложение сможет вносить изменения в вашу фотоколлекцию."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"доступ к геоданным в медиаколлекции"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Приложение получит доступ к геоданным в вашей медиаколлекции."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Использовать биометрию"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Использовать биометрию или блокировку экрана"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Подтвердите, что это вы"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Чтобы продолжить, используйте биометрические данные"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрическое оборудование недоступно"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Аутентификация отменена"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Не распознано"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Аутентификация отменена"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Укажите PIN-код, пароль или графический ключ"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Ошибка аутентификации."</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Использовать блокировку экрана"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Чтобы продолжить, введите учетные данные устройства"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Отсканирована только часть отпечатка. Повторите попытку."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не удалось распознать отпечаток. Повторите попытку."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Очистите сканер и повторите попытку."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На этом устройстве нет сканера отпечатков пальцев."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сканер отпечатков пальцев временно отключен."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Отпечаток <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Использовать отпечаток пальца"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Использовать отпечаток пальца или блокировку экрана"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Чтобы продолжить, используйте цифровой отпечаток"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Это устройство не поддерживает функцию \"Фейсконтроль\"."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Датчик временно отключен."</string>
<string name="face_name_template" msgid="3877037340223318119">"Лицо <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Использовать фейсконтроль"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Использовать фейсконтроль или блокировку экрана"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Чтобы продолжить, используйте фейсконтроль"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Значок лица"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Новости и журналы"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Карты и навигация"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Работа"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"ч."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 011b042..f645fe1 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Umožňuje aplikácii upravovať zbierku fotiek."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"čítať polohy zo zbierky médií"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Umožňuje aplikácii čítať polohy zo zbierky médií."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Použiť biometrické údaje"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Použiť biometrické údaje alebo zámku obrazovky"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Overenie, že ste to vy"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Ak chcete pokračovať, použite biometrický údaj"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrický hardvér nie je k dispozícii"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Overenie bolo zrušené"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nerozpoznané"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Overenie bolo zrušené"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nie je nastavený PIN, vzor ani heslo"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Chyba overenia"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Použiť zámku obrazovky"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Ak chcete pokračovať, zadajte prihlasovacie údaje zariadenia"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Podarilo sa rozpoznať iba časť odtlačku prsta. Skúste to znova."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Odtlačok prsta sa nepodarilo spracovať. Skúste to znova."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Očistite senzor odtlačkov prstov a skúste to znova."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zariadenie nemá senzor odtlačkov prstov."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasne vypnutý."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst: <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použiť odtlačok prsta"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Použiť odtlačok prsta alebo zámku obrazovky"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Pokračujte nasnímaním odtlačku prsta"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Toto zariadenie nepodporuje odomknutie tvárou."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Senzor je dočasne vypnutý."</string>
<string name="face_name_template" msgid="3877037340223318119">"Tvár <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Použiť odomknutie tvárou"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Použiť tvár alebo zámku obrazovky"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Ak chcete pokračovať, použite odomknutie tvárou"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona tváre"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Noviny a časopisy"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapy a navigácia"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Kancelárske"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Dostupnosť"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Úložisko zariadenia"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Ladenie cez USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hodina"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 0a7f760..97de6a3 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Aplikaciji omogoča spreminjanje zbirke fotografij."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"branje lokacij v predstavnostni zbirki"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Aplikaciji omogoča branje lokacij v predstavnostni zbirki."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Uporaba biometrike"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Uporaba biometrike ali odklepanja s poverilnico"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Preverite, da ste res vi"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Za nadaljevanje uporabite biometrični podatek."</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Strojna oprema za biometrične podatke ni na voljo"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Preverjanje pristnosti je preklicano"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Ni prepoznano"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Preverjanje pristnosti je preklicano"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nastavljena ni nobena koda PIN, vzorec ali geslo"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Napaka pri preverjanju pristnosti"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Uporaba odklepanja s poverilnico"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Za nadaljevanje vnesite poverilnico za napravo."</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Zaznan delni prstni odtis. Poskusite znova."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Prstnega odtisa ni bilo mogoče obdelati. Poskusite znova."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Tipalo prstnih odtisov je umazano. Očistite ga in poskusite znova."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ta naprava nima tipala prstnih odtisov."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tipalo je začasno onemogočeno."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Uporaba prstnega odtisa"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Uporaba prstnega odtisa ali odklepanja s poverilnico"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Uporabite prstni odtis, če želite nadaljevati."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Ta naprava ne podpira odklepanja z obrazom."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Tipalo je začasno onemogočeno."</string>
<string name="face_name_template" msgid="3877037340223318119">"Obraz <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Uporaba odklepanja z obrazom"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Uporaba odklepanja z obrazom ali s poverilnico"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Za nadaljevanje uporabite odklepanje z obrazom."</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona obraza"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Novice in revije"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Zemljevidi in navigacija"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Storilnost"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Funkc. za ljudi s poseb. potreb."</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Shramba naprave"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Odpravljanje težav prek povezave USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ura"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index ddce26d..a78ff77 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Lejon aplikacionin të modifikojë koleksionin tënd të fotografive."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lexo vendndodhjet nga koleksioni yt i medias"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Lejon aplikacionin të lexojë vendndodhjet nga koleksioni yt i medias."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Përdor sistemet biometrike"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Përdor sistemet biometrike ose kyçjen e ekranit"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifiko që je ti"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Përdor sistemet e tua biometrike për të vazhduar"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Nuk ofrohet harduer biometrik"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Vërtetimi u anulua"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nuk njihet"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Vërtetimi u anulua"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nuk është vendosur kod PIN, motiv ose fjalëkalim"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Gabim gjatë vërtetimit"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Përdor kyçjen e ekranit"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Fut kredencialet e pajisjes për të vazhduar"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"U zbulua një gjurmë gishti e pjesshme. Provo përsëri."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Gjurma e gishtit nuk mund të përpunohej. Provo përsëri."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Sensori i gjurmës së gishtit nuk është i pastër. Pastroje dhe provo përsëri."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kjo pajisje nuk ka sensor të gjurmës së gishtit."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensori është çaktivizuar përkohësisht."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Përdor gjurmën e gishtit"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Përdor gjurmën e gishtit ose kyçjen e ekranit"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Përdor gjurmën e gishtit për të vazhduar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Shkyçja me fytyrë nuk mbështetet në këtë pajisje"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensori është çaktivizuar përkohësisht."</string>
<string name="face_name_template" msgid="3877037340223318119">"Fytyra <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Përdor shkyçjen me fytyrë"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Përdor kyçjen me fytyrë ose kyçjen e ekranit"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Përdor shkyçjen me fytyrë për të vazhduar"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona e fytyrës"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Lajme dhe revista"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Harta dhe navigim"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivitet"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Qasshmëria"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Hapësira ruajtëse e pajisjes"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Korrigjimi përmes USB-së"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"orë"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 11d5e7d..04bc35f 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -553,23 +553,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Дозвољава апликацији да мења колекцију слика."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"читање локација из медијске колекције"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Дозвољава апликацији да чита локације из медијске колекције."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Користите биометрију"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Користите биометрију или закључавање екрана"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Потврдите свој идентитет"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Користите биометријски податак да бисте наставили"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометријски хардвер није доступан"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Потврда идентитета је отказана"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Није препознато"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Потврда идентитета је отказана"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Нисте подесили ни PIN, ни шаблон, ни лозинку"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Грешка при потврди идентитета"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Користите закључавање екрана"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Унесите акредитив за уређај да бисте наставили"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Откривен је делимични отисак прста. Пробајте поново."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Није успела обрада отиска прста. Пробајте поново."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Сензор за отиске прстију је прљав. Очистите га и покушајте поново."</string>
@@ -592,10 +587,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Овај уређај нема сензор за отисак прста."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензор је привремено онемогућен."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користите отисак прста"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користите отисак прста или закључавање екрана"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Наставите помоћу отиска прста"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -641,12 +634,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Откључавање лицем није подржано на овом уређају"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Сензор је привремено онемогућен."</string>
<string name="face_name_template" msgid="3877037340223318119">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Користите откључавање лицем"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Користите закључавање лицем или закључавање екрана"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Користите откључавање лицем да бисте наставили"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Икона лица"</string>
@@ -1998,8 +1988,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Новости и часописи"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Мапе и навигација"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Продуктивност"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"сат"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 4f6ccff5..5ab243a 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Tillåter att appen gör ändringar i din fotosamling."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"läsa av platser i din mediesamling"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Tillåter att appen läser av platser i din mediesamling."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Använd biometri"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Använd biometrisk data eller skärmlåset"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifiera din identitet"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Fortsätt med hjälp av din biometriska data"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrisk maskinvara är inte tillgänglig"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentiseringen avbröts"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Identifierades inte"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentiseringen avbröts"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Pinkod, grafiskt lösenord eller lösenord har inte angetts"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Ett fel uppstod vid autentiseringen"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Använd skärmlåset"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Fortsätt genom att ange enhetens autentiseringsuppgifter"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Ofullständigt fingeravtryck. Försök igen."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Det gick inte att bearbeta fingeravtrycket. Försök igen."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingeravtryckssensorn är smutsig. Rengör den och försök igen."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Enheten har ingen fingeravtryckssensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensorn har tillfälligt inaktiverats."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Använd ditt fingeravtryck"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Använd ditt fingeravtryck eller skärmlåset"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Fortsätt med hjälp av ditt fingeravtryck"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Ansiktslås stöds inte på den här enheten."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensorn har tillfälligt inaktiverats."</string>
<string name="face_name_template" msgid="3877037340223318119">"Ansikte <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Använd ansiktslåset"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Använd ansiktslåset eller skärmlåset"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Fortsätt med hjälp av ansiktslåset"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ansikte"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Nyheter och tidskrifter"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kartor och navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivitet"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Tillgänglighet"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Enhetens lagringsutrymme"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-felsökning"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"timme"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 8dd721f..00477d1 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Inaruhusu programu kubadilisha mkusanyiko wa picha zako."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"kusoma maeneo kwenye mkusanyiko wa vipengee vyako"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Inaruhusu programu kusoma maeneo kwenye mkusanyiko wa vipengee vyako."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Tumia bayometriki"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Tumia bayometriki au mbinu ya kufunga skrini"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Thibitisha kuwa ni wewe"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Tumia bayometriki yako ili uendelee"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Maunzi ya bayometriki hayapatikani"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Imeghairi uthibitishaji"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Hayatambuliki"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Imeghairi uthibitishaji"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Hujaweka pin, mchoro au nenosiri"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Hitilafu imetokea wakati wa uthibitishaji"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Tumia mbinu ya kufunga skrini"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Weka kitambulisho cha kifaa chako ili uendelee."</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Kitambua alama kimetambua sehemu ya alama. Tafadhali jaribu tena."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Imeshindwa kuchakata alama ya kidole. Tafadhali jaribu tena."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Kitambua alama ya kidole ni kichafu. Tafadhali kisafishe na ujaribu tena."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kifaa hiki hakina kitambua alama ya kidole."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Kitambuzi kimezimwa kwa muda."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Kidole cha <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Tumia alama ya kidole"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Tumia alama ya kidole au mbinu ya kufunga skrini"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Tumia alama ya kidole chako ili uendelee"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Kufungua kwa uso hakutumiki kwenye kifaa hiki."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Kitambuzi kimezimwa kwa muda."</string>
<string name="face_name_template" msgid="3877037340223318119">"Uso wa <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Tumia kipengele cha kufungua kwa uso"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Tumia uso au mbinu ya kufunga skrini"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Tumia kipengele cha kufungua kwa uso ili uendelee"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Aikoni ya uso"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Habari na Magazeti"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Ramani na Maelekezo"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Uzalishaji"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Ufikivu"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Hifadhi ya kifaa"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Utatuzi wa USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"saa"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 3760c6d..6325c19 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"உங்களின் படத் தொகுப்பை மாற்ற ஆப்ஸை அனுமதிக்கும்."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"மீடியா தொகுப்பிலிருந்து இடங்களை அறிதல்"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"உங்களின் மீடியா தொகுப்பிலிருந்து இடங்களை அறிந்துகொள்ள ஆப்ஸை அனுமதிக்கும்."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"பயோமெட்ரிக்ஸைப் பயன்படுத்து"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"பயோமெட்ரிக்ஸையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"நீங்கள்தான் என உறுதிசெய்க"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"தொடர உங்கள் பயோமெட்ரிக்கைப் பயன்படுத்துங்கள்"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"பயோமெட்ரிக் வன்பொருள் இல்லை"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"அங்கீகரிப்பு ரத்தானது"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"அடையாளங்காணபடவில்லை"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"அங்கீகரிப்பு ரத்தானது"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"பின்னோ, பேட்டர்னோ, கடவுச்சொல்லோ அமைக்கப்படவில்லை"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"அங்கீகரிப்பதில் பிழை"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"திரைப் பூட்டைப் பயன்படுத்து"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"தொடர, சாதன அனுமதிச் சான்றை உள்ளிடுங்கள்"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"கைரேகையை ஓரளவுதான் கண்டறிய முடிந்தது. மீண்டும் முயலவும்."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"கைரேகையைச் செயலாக்க முடியவில்லை. மீண்டும் முயலவும்."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"கைரேகை சென்சாரில் தூசி உள்ளது. சுத்தம் செய்து, முயலவும்."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"இந்தச் சாதனத்தில் கைரேகை சென்சார் இல்லை."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"சென்சார் தற்காலிகமாக முடக்கப்பட்டுள்ளது."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"கைரேகையைப் பயன்படுத்து"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"கைரேகையையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"தொடர்வதற்கு கைரேகையைப் பயன்படுத்துங்கள்"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"இந்த சாதனத்தில் ’முகம் காட்டித் திறத்தல்’ ஆதரிக்கப்படவில்லை."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"சென்சார் தற்காலிகமாக முடக்கப்பட்டுள்ளது."</string>
<string name="face_name_template" msgid="3877037340223318119">"முகம் <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"முகம் காட்டித் திறத்தலை உபயோகி"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"முகத்தையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"தொடர, \'முகம் காட்டித் திறத்தல்\' அம்சத்தை உபயோகியுங்கள்"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"முக ஐகான்"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"செய்திகளும் பத்திரிகைகளும்"</string>
<string name="app_category_maps" msgid="6395725487922533156">"வரைபடங்களும் வழிசெலுத்தலும்"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"உற்பத்தித்திறன்"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"மணி"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 63ee3a0..c2a5d42 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"మీ ఫోటో సేకరణను సవరించడానికి యాప్ను అనుమతిస్తుంది."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"మీ మీడియా సేకరణ నుండి స్థానాలను చదవండి"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"మీ మీడియా సేకరణ నుండి స్థానాలను చదవడానికి యాప్ను అనుమతిస్తుంది."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"బయోమెట్రిక్స్ను ఉపయోగించండి"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"బయోమెట్రిక్స్ను లేదా స్క్రీన్ లాక్ను ఉపయోగించండి"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ఇది మీరేనని వెరిఫై చేసుకోండి"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"కొనసాగించడానికి, మీ బయోమెట్రిక్ను ఉపయోగించండి"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"బయోమెట్రిక్ హార్డ్వేర్ అందుబాటులో లేదు"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"ప్రమాణీకరణ రద్దు చేయబడింది"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"గుర్తించలేదు"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"ప్రమాణీకరణ రద్దు చేయబడింది"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"పిన్, ఆకృతి లేదా పాస్వర్డ్ సెట్ చేయబడలేదు"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"ప్రామాణీకరిస్తున్నప్పుడు ఎర్రర్ ఏర్పడింది"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"స్క్రీన్ లాక్ను ఉపయోగించండి"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"కొనసాగడానికి, మీ పరికర ఆధారాలను ఎంటర్ చేయండి"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"పాక్షిక వేలిముద్ర గుర్తించబడింది. దయచేసి మళ్లీ ప్రయత్నించండి."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"వేలిముద్రను ప్రాసెస్ చేయడం సాధ్యపడలేదు. దయచేసి మళ్లీ ప్రయత్నించండి."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"వేలిముద్ర సెన్సార్ మురికిగా ఉంది. దయచేసి శుభ్రపరిచి, మళ్లీ ప్రయత్నించండి."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ఈ పరికరంలో వేలిముద్ర సెన్సార్ ఎంపిక లేదు."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"సెన్సార్ తాత్కాలికంగా డిజేబుల్ చేయబడింది."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"వేలు <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"వేలిముద్రను ఉపయోగించండి"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"వేలిముద్ర లేదా స్క్రీన్ లాక్ను ఉపయోగించండి"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"కొనసాగించడానికి మీ వేలిముద్రను ఉపయోగించండి"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"ఈ పరికరంలో ముఖంతో అన్లాక్ను ఉపయోగించడానికి మద్దతు లేదు."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"సెన్సార్ తాత్కాలికంగా డిజేబుల్ చేయబడింది."</string>
<string name="face_name_template" msgid="3877037340223318119">"ముఖ <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"ఫేస్ అన్లాక్ను ఉపయోగించండి"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ముఖం లేదా స్క్రీన్ లాక్ను ఉపయోగించండి"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"కొనసాగించడానికి, మీ ఫేస్ అన్లాక్ను ఉపయోగించండి"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"ముఖ చిహ్నం"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"వార్తలు & వార్తాపత్రికలు"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps & నావిగేషన్"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ఉత్పాదకత"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"గంట"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 3c985b9..a5cfe40 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"อนุญาตให้แอปแก้ไขคอลเล็กชันรูปภาพของคุณ"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"อ่านตำแหน่งจากคอลเล็กชันสื่อของคุณ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"อนุญาตให้แอปอ่านตำแหน่งจากคอลเล็กชันสื่อของคุณ"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ใช้ข้อมูลไบโอเมตริก"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ใช้ข้อมูลไบโอเมตริกหรือการล็อกหน้าจอ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ยืนยันว่าเป็นตัวคุณ"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ใช้ข้อมูลไบโอเมตริกเพื่อดำเนินการต่อ"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ฮาร์ดแวร์ไบโอเมตริกไม่พร้อมใช้งาน"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"ยกเลิกการตรวจสอบสิทธิ์แล้ว"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"ไม่รู้จัก"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"ยกเลิกการตรวจสอบสิทธิ์แล้ว"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"ไม่ได้ตั้ง PIN, รูปแบบ หรือรหัสผ่าน"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"การตรวจสอบข้อผิดพลาด"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ใช้การล็อกหน้าจอ"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"ป้อนข้อมูลเข้าสู่ระบบอุปกรณ์เพื่อดำเนินการต่อ"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"ตรวจพบลายนิ้วมือเพียงบางส่วน โปรดลองอีกครั้ง"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ประมวลผลลายนิ้วมือไม่ได้ โปรดลองอีกครั้ง"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"เซ็นเซอร์ลายนิ้วมือไม่สะอาด โปรดทำความสะอาดและลองอีกครั้ง"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ลายนิ้วมือ"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ปิดใช้เซ็นเซอร์ชั่วคราวแล้ว"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"นิ้ว <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ใช้ลายนิ้วมือ"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ใช้ลายนิ้วมือหรือการล็อกหน้าจอ"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ใช้ลายนิ้วมือของคุณเพื่อดำเนินการต่อ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"อุปกรณ์นี้ไม่รองรับการปลดล็อกด้วยใบหน้า"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"ปิดใช้เซ็นเซอร์ชั่วคราวแล้ว"</string>
<string name="face_name_template" msgid="3877037340223318119">"ใบหน้า <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"ใช้การปลดล็อกด้วยใบหน้า"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ใช้การล็อกด้วยใบหน้าหรือการล็อกหน้าจอ"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ใช้การปลดล็อกด้วยใบหน้าเพื่อดำเนินการต่อ"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"ไอคอนใบหน้า"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"ข่าวสารและนิตยสาร"</string>
<string name="app_category_maps" msgid="6395725487922533156">"แผนที่และการนำทาง"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ประสิทธิภาพการทำงาน"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"ชั่วโมง"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 7402195..4829cef 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Pinapayagan ang app na baguhin ang iyong koleksyon ng larawan."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"basahin ang mga lokasyon mula sa iyong koleksyon ng media"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Pinapayagan ang app na basahin ang mga lokasyon mula sa iyong koleksyon ng media."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Gumamit ng biometrics"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gumamit ng biometrics o lock ng screen"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"I-verify na ikaw ito"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gamitin ang iyong biometric para magpatuloy"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Walang biometric hardware"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Nakansela ang pag-authenticate"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Hindi nakilala"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Nakansela ang pag-authenticate"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Walang itinakdang pin, pattern, o password"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Nagkaroon ng error sa pag-authenticate"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gumamit ng lock ng screen"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Ilagay ang kredensyal ng device para magpatuloy"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Hindi buo ang natukoy na fingerprint. Pakisubukan ulit."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Hindi maproseso ang fingerprint. Pakisubukan ulit."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Marumi ang sensor ng fingerprint. Pakilinis at subukang muli."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Walang sensor ng fingerprint ang device na ito."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Pansamantalang na-disable ang sensor."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Daliri <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gumamit ng fingerprint"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gumamit ng fingerprint o lock ng screen"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gamitin ang iyong fingerprint para magpatuloy"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Hindi sinusuportahan ang face unlock sa device na ito."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Pansamantalang na-disable ang sensor."</string>
<string name="face_name_template" msgid="3877037340223318119">"Mukha <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Gumamit ng face unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gumamit ng mukha o lock ng screen"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Gumamit ng face unlock para magpatuloy"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Face icon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Balita at Mga Magazine"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mga Mapa at Navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivity"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Pagiging Accessible"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Storage ng device"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Pag-debug ng USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"oras"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 147553f..186ffa7 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Uygulamanın fotoğraf koleksiyonunuzu değiştirmesine izin verir."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"medya koleksiyonunuzdaki konumları okuma"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Uygulamanın medya koleksiyonunuzdaki konumları okumasına izin verir."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Biyometri kullan"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biyometri veya ekran kilidi kullan"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Siz olduğunuzu doğrulayın"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Devam etmek için biyometri kullanın"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biyometrik donanım kullanılamıyor"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Kimlik doğrulama iptal edildi"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Tanınmadı"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Kimlik doğrulama iptal edildi"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN, desen veya şifre seti yok"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Kimlik doğrulama sırasında hata oluştu"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekran kilidi kullan"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Devam etmek için cihaz kimlik bilginizi girin"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Parmak izinin tümü algılanamadı. Lütfen tekrar deneyin."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Parmak izi işlenemedi. Lütfen tekrar deneyin."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Parmak izi sensörü kirli. Lütfen temizleyin ve tekrar deneyin."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda parmak izi sensörü yok."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensör geçici olarak devre dışı bırakıldı."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. parmak"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Parmak izi kullan"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Parmak izi veya ekran kilidi kullan"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Devam etmek için parmak izinizi kullanın"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Bu cihazda yüz tanıma kilidi desteklenmiyor"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensör geçici olarak devre dışı bırakıldı."</string>
<string name="face_name_template" msgid="3877037340223318119">"Yüz <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Yüz tanıma kilidi kullan"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Yüz tanıma veya ekran kilidi kullan"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Devam etmek için yüz tanıma kilidini kullanın"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Yüz simgesi"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Haberler ve Dergiler"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Haritalar ve Navigasyon"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Verimlilik"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Erişilebilirlik"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Cihazdaki depolama alanı"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB üzerinden hata ayıklama"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"saat"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 77e664a..7049a2e 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Додаток зможе змінювати вашу колекцію фотографій."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"розпізнавати геодані з колекції медіа-вмісту"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Додаток зможе розпізнавати геодані з вашої колекції медіа-вмісту."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Використовувати біометрію"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Використовувати біометрію або блокування екрана"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Підтвердьте, що це ви"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Щоб продовжити, скористайтеся біометрією"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Біометричне апаратне забезпечення недоступне"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Автентифікацію скасовано"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Не розпізнано"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Автентифікацію скасовано"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Не вказано PIN-код, ключ або пароль"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Помилка автентифікації"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Використовувати блокування екрана"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Щоб продовжити, введіть облікові дані пристрою"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Відбиток пальця розпізнано частково. Повторіть спробу."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не вдалось обробити відбиток пальця. Повторіть спробу."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Датчик відбитків пальців забруднився. Очистьте його та повторіть спробу."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На цьому пристрої немає сканера відбитків пальців."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик тимчасово вимкнено."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Відбиток пальця <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Використовувати відбиток пальця"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Використовувати відбиток пальця або блокування екрана"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Щоб продовжити, скористайтеся своїм відбитком пальця"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"На цьому пристрої не підтримується Фейсконтроль."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Датчик тимчасово вимкнено."</string>
<string name="face_name_template" msgid="3877037340223318119">"Обличчя <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Використовувати фейсконтроль"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Використовувати фейсконтроль або блокування екрана"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Щоб продовжити, скористайтеся фейсконтролем"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Значок обличчя"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Новини та журнали"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Карти й навігація"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Продуктивність"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"години"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 10f787b..615e2fa4 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"ایپ کو آپ کی تصویر کے مجموعے میں ترمیم کی اجازت دیتا ہے۔"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"اپنی میڈيا کے مجموعے سے مقامات پڑھیں"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"ایپ کو آپ کی میڈيا کے مجموعے سے مقامات پڑھنے کی اجازت دیتا ہے۔"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"بایو میٹرکس استعمال کریں"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"بایو میٹرکس یا اسکرین لاک استعمال کریں"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"توثیق کریں کہ یہ آپ ہیں"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"جاری رکھنے کیلئے اپنا بایو میٹرک استعمال کریں"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"بایومیٹرک ہارڈ ویئر دستیاب نہیں ہے"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"تصدیق کا عمل منسوخ ہو گیا"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"تسلیم شدہ نہیں ہے"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"تصدیق کا عمل منسوخ ہو گیا"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"کوئی پن، پیٹرن، یا پاس ورڈ سیٹ نہیں ہے"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"خرابی کی توثیق ہو رہی ہے"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"اسکرین لاک استعمال کریں"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"جاری رکھنے کیلئے اپنے آلے کی سند درج کریں"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"جزوی فنگر پرنٹ کی شناخت ہوئی۔ براہ کرم دوبارہ کوشش کریں۔"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"فنگر پرنٹ پر کارروائی نہیں کی جا سکی۔ براہ کرم دوبارہ کوشش کریں۔"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"فنگر پرنٹ سینسر گندا ہے۔ براہ کرم صاف کریں اور دوبارہ کوشش کریں۔"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"اس آلہ میں فنگر پرنٹ سینسر نہیں ہے۔"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"سینسر عارضی طور غیر فعال ہے۔"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"فنگر پرنٹ استعمال کریں"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"فنگر پرنٹ یا اسکرین لاک استعمال کریں"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"جاری رکھنے کیلئے اپنا فنگر پرنٹ استعمال کریں"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"اس آلہ پر چہرے کے ذریعے غیر مقفل کرنا تعاون یافتہ نہیں ہے۔"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"سینسر عارضی طور غیر فعال ہے۔"</string>
<string name="face_name_template" msgid="3877037340223318119">"چہرہ <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"چہرے کے ذریعے غیر مقفل کرنا استعمال کریں"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"چہرہ یا اسکرین لاک استعمال کریں"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"جاری رکھنے کیلئے چہرے کے ذریعے غیر مقفل کرنا استعمال کریں"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"چہرے کا آئیکن"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"خبریں اور میگزین"</string>
<string name="app_category_maps" msgid="6395725487922533156">"نقشے اور نیویگیشن"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"پروڈکٹیوٹی"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"گھنٹہ"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index f2c5589..0bcba06 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -553,7 +553,7 @@
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometrik tasdiqlash"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrika yoki ekran qulfi"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Oʻzingizni taniting"</string>
- <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Davob etish uchun biometrik tasdiqlang"</string>
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Davom etish uchun biometrik tasdiqlang"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrik sensor ishlamayapti"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentifikatsiya bekor qilindi"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Aniqlanmadi"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 4d7091c..11644d6 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Cho phép ứng dụng này sửa đổi bộ sưu tập ảnh của bạn."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"đọc vị trí từ bộ sưu tập phương tiện"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Cho phép ứng dụng này đọc vị trí từ bộ sưu tập phương tiện của bạn."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Dùng dữ liệu sinh trắc học"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Dùng dữ liệu sinh trắc học hoặc phương thức khóa màn hình"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Xác minh danh tính của bạn"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Dùng dữ liệu sinh trắc học của bạn để tiếp tục"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Không có phần cứng sinh trắc học"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Đã hủy xác thực"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Không nhận dạng được"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Đã hủy xác thực"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Chưa đặt mã PIN, hình mở khóa hoặc mật khẩu"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Lỗi khi xác thực"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Dùng phương thức khóa màn hình"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Nhập thông tin xác thực thiết bị của bạn để tiếp tục"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Đã phát hiện được một phần vân tay. Vui lòng thử lại."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Không thể xử lý vân tay. Vui lòng thử lại."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Cảm biến vân tay bị bẩn. Hãy làm sạch và thử lại."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Thiết bị này không có cảm biến vân tay."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Đã tạm thời tắt cảm biến."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Ngón tay <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Dùng vân tay"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Dùng vân tay hoặc phương thức khóa màn hình"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Sử dụng dấu vân tay của bạn để tiếp tục"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Thiết bị này không hỗ trợ tính năng mở khóa bằng khuôn mặt."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Đã tạm thời tắt cảm biến."</string>
<string name="face_name_template" msgid="3877037340223318119">"Khuôn mặt <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Dùng tính năng mở khóa bằng khuôn mặt"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Dùng khuôn mặt hoặc phương thức khóa màn hình"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Dùng tính năng mở khóa bằng khuôn mặt để tiếp tục"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Biểu tượng khuôn mặt"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Tin tức và tạp chí"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Bản đồ và dẫn đường"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Sản xuất"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Hỗ trợ tiếp cận"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Bộ nhớ của thiết bị"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Gỡ lỗi qua USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"giờ"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 1f8f176..ec455bc 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"允许该应用修改您的照片收藏。"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"从您的媒体收藏中读取位置信息"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"允许该应用从您的媒体收藏中读取位置信息。"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"使用生物识别"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"使用生物识别或屏幕锁定凭据"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"验证是您本人在操作"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"使用生物识别验证身份才能继续"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"生物识别硬件无法使用"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"身份验证已取消"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"无法识别"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"身份验证已取消"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"未设置任何 PIN 码、图案和密码"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"进行身份验证时出错"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用屏幕锁定凭据"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"输入您的设备凭据才能继续"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"仅检测到部分指纹,请重试。"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"无法处理指纹,请重试。"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"指纹传感器有脏污。请擦拭干净,然后重试。"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此设备没有指纹传感器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"传感器已暂时停用。"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指纹"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指纹或屏幕锁定凭据"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"使用指纹完成验证才能继续"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"此设备不支持人脸解锁。"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"传感器已暂时停用。"</string>
<string name="face_name_template" msgid="3877037340223318119">"面孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"使用人脸解锁"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"使用人脸解锁或屏幕锁定凭据"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"使用人脸解锁验证身份才能继续"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"面孔图标"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"新闻和杂志"</string>
<string name="app_category_maps" msgid="6395725487922533156">"地图和导航"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"办公"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"点"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index ebc02c50..16b9b0f 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"允許應用程式修改您的相片集。"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"讀取媒體集的位置"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"允許應用程式讀取媒體集的位置。"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"使用生物識別"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"使用生物識別或螢幕鎖定"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"驗證是你本人"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"如要繼續操作,請使用使用生物識別驗證身分"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"無法使用生物識別硬件"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"已取消驗證"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"未能識別"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"已取消驗證"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"未設定 PIN、圖案或密碼"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"驗證時發生錯誤"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用螢幕鎖定"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"如要繼續操作,請輸入裝置憑證"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"只偵測到部分指紋。請再試一次。"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"無法處理指紋。請再試一次。"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"指紋感應器不乾淨。請清潔後再試一次。"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此裝置沒有指紋感應器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋鎖定"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"請使用您的指紋繼續"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"此裝置不支援「臉孔解鎖」。"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"感應器已暫時停用。"</string>
<string name="face_name_template" msgid="3877037340223318119">"臉孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"使用臉孔解鎖"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"使用臉孔或螢幕鎖定"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"如要繼續操作,請使用臉孔解鎖驗證身分"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"臉孔圖示"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"新聞和雜誌"</string>
<string name="app_category_maps" msgid="6395725487922533156">"地圖和導航"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"生產力應用程式"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"時"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 10d05c1..90fe15d 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"允許應用程式修改你的相片收藏。"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"讀取你的媒體收藏的位置資訊"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"允許應用程式讀取你的媒體收藏的位置資訊。"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"使用生物特徵辨識功能"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"使用生物特徵辨識或螢幕鎖定功能"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"驗證你的身分"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"如要繼續操作,請使用生物特徵辨識功能驗證身分"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"無法使用生物特徵辨識硬體"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"已取消驗證"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"無法辨識"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"已取消驗證"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"未設定 PIN 碼、解鎖圖案或密碼"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"驗證時發生錯誤"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用螢幕鎖定功能"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"如要繼續操作,請輸入裝置憑證"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"僅偵測到部分指紋,請再試一次。"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"無法處理指紋,請再試一次。"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"指紋感應器有髒汙。請清潔感應器,然後再試一次。"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"這個裝置沒有指紋感應器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定功能"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"使用指紋完成驗證才能繼續操作"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"這個裝置不支援人臉解鎖功能。"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"感應器已暫時停用。"</string>
<string name="face_name_template" msgid="3877037340223318119">"臉孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"使用人臉解鎖功能"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"使用人臉解鎖或螢幕鎖定功能"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"如要繼續操作,請使用人臉解鎖功能驗證身分"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"臉孔圖示"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"新聞和雜誌"</string>
<string name="app_category_maps" msgid="6395725487922533156">"地圖和導航"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"工作效率"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <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="time_picker_hour_label" msgid="4208590187662336864">"點"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 976b97a2..1089f1e 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Ivumela uhlelo lwakho lokusebenza ukuthi lilungise iqoqo lakho lesithombe."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"funda izindawo kusukela kuqoqo lakho lemidiya"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Ivumela uhlelo lokusebenza ukuthi lifunde izindawo kusukela kuqoqo lakho lemidiya."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Sebenzisa i-biometrics"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Sebenzisa i-biometrics noma ukukhiya isikrini"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Qinisekisa ukuthi nguwe"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Sebenzisa i-biometric yakho ukuze uqhubeke"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"I-Biometric hardware ayitholakali"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Ukufakazela ubuqiniso kukhanseliwe"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Akwaziwa"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Ukufakazela ubuqiniso kukhanseliwe"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Ayikho iphinikhodi, iphethini, noma iphasiwedi esethiwe"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Iphutha lokufakazela ubuqiniso"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Sebenzisa isikhiya sesikrini"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Faka izifakazelo zedivayisi yakho ukuze uqhubeke"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Izigxivizo zeminwe ezincane zitholiwe. Sicela uzame futhi."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Ayikwazanga ukucubungula izigxivizo zeminwe. Sicela uzame futhi."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Inzwa yezigxivizo zeminwe ingcolile. Sicela uyihlanze uphinde uzame futhi."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Le divayisi ayinayo inzwa yezigxivizo zeminwe."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Inzwa ikhutshazwe okwesikhashana."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Umunwe ongu-<xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sebenzisa izigxivizo zeminwe"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Sebenzisa izigxivizo zeminwe noma ukukhiya isikrini"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Sebenzisa izigxivizo zakho zeminwe ukuze uqhubeke"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"I-face unlock ayisekelwe kule divayisi."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Inzwa ikhutshazwe okwesikhashana."</string>
<string name="face_name_template" msgid="3877037340223318119">"Ubuso be-<xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Sebenzisa i-face unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Sebenzisa i-face lock noma ukukhiya isikrini"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Sebenzisa i-face unlock ukuze uqhubeke"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Isithonjana sobuso"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Izindaba nomagazini"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Amamephu nokuzula"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Ukukhiqiza"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Ukufinyeleleka"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Isitoreji sedivayisi"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Ukulungisa iphutha le-USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ihora"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index e0a116b..7c446a9 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3564,6 +3564,16 @@
<attr name="__removed2" format="boolean" />
<!-- Specifies whether the IME supports showing inline suggestions. -->
<attr name="supportsInlineSuggestions" format="boolean" />
+ <!-- Specify one or more configuration changes that the IME will handle itself. If not
+ specified, the IME will be restarted if any of these configuration changes happen in
+ the system. Otherwise, the IME will remain running and its
+ {@link android.inputmethodservice.InputMethodService#onConfigurationChanged}
+ method is called with the new configuration.
+ <p>Note that all of these configuration changes can impact the
+ resource values seen by the application, so you will generally need
+ to re-retrieve all resources (including view layouts, drawables, etc)
+ to correctly handle any configuration change.-->
+ <attr name="configChanges" />
</declare-styleable>
<!-- This is the subtype of InputMethod. Subtype can describe locales (for example, en_US and
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 8bc3a52..a3d0ab5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -324,9 +324,6 @@
<item>"0,1"</item>
</string-array>
- <!-- The maximum duration (in milliseconds) we expect a network transition to take -->
- <integer name="config_networkTransitionTimeout">60000</integer>
-
<!-- Whether/how to notify the user on network switches. See LingerMonitor.java. -->
<integer translatable="false" name="config_networkNotifySwitchType">0</integer>
@@ -339,16 +336,6 @@
Settings.Global.NETWORK_AVOID_BAD_WIFI. This is the default value of that setting. -->
<integer translatable="false" name="config_networkAvoidBadWifi">1</integer>
- <!-- Configuration hook for the URL returned by ConnectivityManager#getCaptivePortalServerUrl.
- If empty, the returned value is controlled by Settings.Global.CAPTIVE_PORTAL_HTTP_URL,
- and if that value is empty, the framework will use a hard-coded default.
- This is *NOT* a URL that will always be used by the system network validation to detect
- captive portals: NetworkMonitor may use different strategies and will not necessarily use
- this URL. NetworkMonitor behaviour should be configured with NetworkStack resource overlays
- instead. -->
- <!--suppress CheckTagEmptyBody -->
- <string translatable="false" name="config_networkCaptivePortalServerUrl"></string>
-
<!-- If the hardware supports specially marking packets that caused a wakeup of the
main CPU, set this value to the mark used. -->
<integer name="config_networkWakeupPacketMark">0</integer>
@@ -456,14 +443,6 @@
apps requested it. -->
<bool name="config_vehicleInternalNetworkAlwaysRequested">false</bool>
- <!-- Configuration of network interfaces that support WakeOnLAN -->
- <string-array translatable="false" name="config_wakeonlan_supported_interfaces">
- <!--
- <item>wlan0</item>
- <item>eth0</item>
- -->
- </string-array>
-
<!-- This setting is deprecated, please use
com.android.networkstack.tethering.R.array.config_mobile_hotspot_provision_app instead. -->
<string-array translatable="false" name="config_mobile_hotspot_provision_app">
@@ -1961,6 +1940,8 @@
<string name="config_systemWifiCoexManager" translateable="false"></string>
<!-- The name of the package that will hold the wellbeing role. -->
<string name="config_systemWellbeing" translatable="false"></string>
+ <!-- The name of the package that will hold the television notification handler role -->
+ <string name="config_systemTelevisionNotificationHandler" translatable="false"></string>
<!-- The name of the package that will be allowed to change its components' label/icon. -->
<string name="config_overrideComponentUiPackage" translatable="false"></string>
@@ -2270,6 +2251,9 @@
<bool name="config_dozeWakeLockScreenSensorAvailable">false</bool>
<integer name="config_dozeWakeLockScreenDebounce">300</integer>
+ <!-- Type of the quick pickup sensor. Empty if quick pickup is not supported. -->
+ <string name="config_quickPickupSensorType" translatable="false"></string>
+
<!-- Control whether the always on display mode is available. This should only be enabled on
devices where the display has been tuned to be power efficient in DOZE and/or DOZE_SUSPEND
states. -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 10aa7b3..43dbd38 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -746,7 +746,7 @@
<dimen name="notification_right_icon_headerless_margin">20dp</dimen>
<!-- The top margin of the right icon in the "big" notification states -->
<!-- TODO(b/181048615): Move the large icon below the expander in big states -->
- <dimen name="notification_right_icon_big_margin_top">20dp</dimen>
+ <dimen name="notification_right_icon_big_margin_top">16dp</dimen>
<!-- The size of the left icon -->
<dimen name="notification_left_icon_size">@dimen/notification_icon_circle_size</dimen>
<!-- The left padding of the left icon -->
diff --git a/core/res/res/values/policy_exempt_apps.xml b/core/res/res/values/policy_exempt_apps.xml
new file mode 100644
index 0000000..1cead83
--- /dev/null
+++ b/core/res/res/values/policy_exempt_apps.xml
@@ -0,0 +1,24 @@
+<?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.
+ -->
+<resources>
+ <!--
+ A collection of apps that are critical for the device and hence will never be disabled by
+ device policies or APIs.
+ -->
+ <string-array translatable="false" name="policy_exempt_apps">
+ </string-array>
+</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 293018d..e0a728c 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3071,7 +3071,6 @@
<public name="windowSplashScreenAnimationDuration"/>
<public name="windowSplashScreenBrandingImage"/>
<public name="splashScreenTheme" />
- <public name="rippleStyle" />
<public name="maxResizeWidth" />
<public name="maxResizeHeight" />
<public name="targetCellWidth" />
@@ -3175,6 +3174,8 @@
<public name="config_systemWifiCoexManager" />
<!-- @hide @SystemApi -->
<public name="config_systemWellbeing" />
+ <!-- @hide @SystemApi -->
+ <public name="config_systemTelevisionNotificationHandler" />
</public-group>
<public-group type="id" first-id="0x01020055">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2ffa29b..4af561b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1532,6 +1532,8 @@
<string name="biometric_dialog_default_title">Verify it\u2019s you</string>
<!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with a biometric (e.g. fingerprint or face). [CHAR LIMIT=70] -->
<string name="biometric_dialog_default_subtitle">Use your biometric to continue</string>
+ <!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with a biometric (e.g. fingerprint or face) or their screen lock credential (i.e. PIN, pattern, or password). [CHAR LIMIT=90] -->
+ <string name="biometric_or_screen_lock_dialog_default_subtitle">Use your biometric or screen lock to continue</string>
<!-- Message shown when biometric hardware is not available [CHAR LIMIT=50] -->
<string name="biometric_error_hw_unavailable">Biometric hardware unavailable</string>
@@ -1604,6 +1606,8 @@
<string name="fingerprint_or_screen_lock_app_setting_name">Use fingerprint or screen lock</string>
<!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with their fingerprint. [CHAR LIMIT=70] -->
<string name="fingerprint_dialog_default_subtitle">Use your fingerprint to continue</string>
+ <!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with their fingerprint or screen lock credential (i.e. PIN, pattern, or password). [CHAR LIMIT=90] -->
+ <string name="fingerprint_or_screen_lock_dialog_default_subtitle">Use your fingerprint or screen lock to continue</string>
<!-- Array containing custom error messages from vendor. Vendor is expected to add and translate these strings -->
<string-array name="fingerprint_error_vendor">
@@ -1704,6 +1708,8 @@
<string name="face_or_screen_lock_app_setting_name">Use face or screen lock</string>
<!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with their face. [CHAR LIMIT=70] -->
<string name="face_dialog_default_subtitle">Use face unlock to continue</string>
+ <!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with their face or screen lock credential (i.e. PIN, pattern, or password). [CHAR LIMIT=90] -->
+ <string name="face_or_screen_lock_dialog_default_subtitle">Use your face or screen lock to continue</string>
<!-- Array containing custom error messages from vendor. Vendor is expected to add and translate these strings -->
<string-array name="face_error_vendor">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 07938fd..f194052 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -692,7 +692,6 @@
<java-symbol type="string" name="not_checked" />
<java-symbol type="array" name="config_ethernet_interfaces" />
<java-symbol type="bool" name="config_vehicleInternalNetworkAlwaysRequested" />
- <java-symbol type="array" name="config_wakeonlan_supported_interfaces" />
<java-symbol type="string" name="config_forceVoiceInteractionServicePackage" />
<java-symbol type="string" name="config_mms_user_agent" />
<java-symbol type="string" name="config_mms_user_agent_profile_url" />
@@ -1266,6 +1265,8 @@
<java-symbol type="array" name="vendor_disallowed_apps_managed_device" />
<java-symbol type="array" name="cross_profile_apps" />
<java-symbol type="array" name="vendor_cross_profile_apps" />
+ <java-symbol type="array" name="policy_exempt_apps" />
+ <java-symbol type="array" name="vendor_policy_exempt_apps" />
<java-symbol type="drawable" name="default_wallpaper" />
<java-symbol type="drawable" name="default_lock_wallpaper" />
@@ -1970,11 +1971,9 @@
<java-symbol type="integer" name="config_lowBatteryCloseWarningBump" />
<java-symbol type="integer" name="config_lowBatteryWarningLevel" />
<java-symbol type="integer" name="config_networkPolicyDefaultWarning" />
- <java-symbol type="integer" name="config_networkTransitionTimeout" />
<java-symbol type="integer" name="config_networkNotifySwitchType" />
<java-symbol type="array" name="config_networkNotifySwitches" />
<java-symbol type="integer" name="config_networkAvoidBadWifi" />
- <java-symbol type="string" name="config_networkCaptivePortalServerUrl" />
<java-symbol type="integer" name="config_networkWakeupPacketMark" />
<java-symbol type="integer" name="config_networkWakeupPacketMask" />
<java-symbol type="bool" name="config_apfDrop802_3Frames" />
@@ -2473,6 +2472,7 @@
<java-symbol type="string" name="biometric_or_screen_lock_app_setting_name" />
<java-symbol type="string" name="biometric_dialog_default_title" />
<java-symbol type="string" name="biometric_dialog_default_subtitle" />
+ <java-symbol type="string" name="biometric_or_screen_lock_dialog_default_subtitle" />
<java-symbol type="string" name="biometric_error_hw_unavailable" />
<java-symbol type="string" name="biometric_error_user_canceled" />
<java-symbol type="string" name="biometric_not_recognized" />
@@ -2504,6 +2504,7 @@
<java-symbol type="string" name="fingerprint_app_setting_name" />
<java-symbol type="string" name="fingerprint_or_screen_lock_app_setting_name" />
<java-symbol type="string" name="fingerprint_dialog_default_subtitle" />
+ <java-symbol type="string" name="fingerprint_or_screen_lock_dialog_default_subtitle" />
<java-symbol type="string" name="fingerprint_authenticated" />
<java-symbol type="string" name="fingerprint_error_no_fingerprints" />
<java-symbol type="string" name="fingerprint_error_hw_not_present" />
@@ -2553,6 +2554,7 @@
<java-symbol type="string" name="face_app_setting_name" />
<java-symbol type="string" name="face_or_screen_lock_app_setting_name" />
<java-symbol type="string" name="face_dialog_default_subtitle" />
+ <java-symbol type="string" name="face_or_screen_lock_dialog_default_subtitle" />
<java-symbol type="string" name="face_authenticated_no_confirmation_required" />
<java-symbol type="string" name="face_authenticated_confirmation_required" />
<java-symbol type="string" name="face_error_security_update_required" />
@@ -3592,6 +3594,7 @@
<java-symbol type="string" name="config_dozeUdfpsLongPressSensorType" />
<java-symbol type="bool" name="config_dozeWakeLockScreenSensorAvailable" />
<java-symbol type="integer" name="config_dozeWakeLockScreenDebounce" />
+ <java-symbol type="string" name="config_quickPickupSensorType" />
<java-symbol type="array" name="config_allowedGlobalInstantAppSettings" />
<java-symbol type="array" name="config_allowedSystemInstantAppSettings" />
diff --git a/core/res/res/values/vendor_policy_exempt_apps.xml b/core/res/res/values/vendor_policy_exempt_apps.xml
new file mode 100644
index 0000000..eb4c760
--- /dev/null
+++ b/core/res/res/values/vendor_policy_exempt_apps.xml
@@ -0,0 +1,24 @@
+<?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.
+ -->
+<resources>
+ <!--
+ A collection of apps that are critical for the device and hence will never be disabled by
+ device policies or APIs.
+ -->
+ <string-array translatable="false" name="vendor_policy_exempt_apps">
+ </string-array>
+</resources>
diff --git a/core/tests/coretests/src/android/app/appsearch/AppSearchSessionUnitTest.java b/core/tests/coretests/src/android/app/appsearch/AppSearchSessionUnitTest.java
new file mode 100644
index 0000000..fe31b90
--- /dev/null
+++ b/core/tests/coretests/src/android/app/appsearch/AppSearchSessionUnitTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.app.appsearch;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.expectThrows;
+
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+
+public class AppSearchSessionUnitTest {
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ private final AppSearchManager mAppSearch = mContext.getSystemService(AppSearchManager.class);
+ private final Executor mExecutor = mContext.getMainExecutor();
+ private AppSearchSession mSearchSession;
+
+ @Before
+ public void setUp() throws Exception {
+ // Remove all documents from any instances that may have been created in the tests.
+ Objects.requireNonNull(mAppSearch);
+ AppSearchManager.SearchContext searchContext = new AppSearchManager.SearchContext.Builder()
+ .setDatabaseName("testDb").build();
+ CompletableFuture<AppSearchResult<AppSearchSession>> future = new CompletableFuture<>();
+ mAppSearch.createSearchSession(searchContext, mExecutor, future::complete);
+ mSearchSession = future.get().getResultValue();
+
+ CompletableFuture<AppSearchResult<SetSchemaResponse>> schemaFuture =
+ new CompletableFuture<>();
+ mSearchSession.setSchema(
+ new SetSchemaRequest.Builder().setForceOverride(true).build(), mExecutor,
+ schemaFuture::complete);
+
+ schemaFuture.get().getResultValue();
+ }
+
+ @Test
+ public void testPutDocument_throwsNullException() throws Exception {
+ // Create a document
+ AppSearchEmail inEmail =
+ new AppSearchEmail.Builder("uri1")
+ .setFrom("from@example.com")
+ .setTo("to1@example.com", "to2@example.com")
+ .setSubject("testPut example")
+ .setBody("This is the body of the testPut email")
+ .build();
+
+ // clear the document bundle to make our service crash and throw an NullPointerException.
+ inEmail.getBundle().clear();
+ CompletableFuture<AppSearchBatchResult<String, Void>> putDocumentsFuture =
+ new CompletableFuture<>();
+
+ // Index the broken document.
+ mSearchSession.put(
+ new PutDocumentsRequest.Builder().addGenericDocuments(inEmail).build(),
+ mExecutor, new BatchResultCallback<String, Void>() {
+ @Override
+ public void onResult(AppSearchBatchResult<String, Void> result) {
+ putDocumentsFuture.complete(result);
+ }
+
+ @Override
+ public void onSystemError(Throwable throwable) {
+ putDocumentsFuture.completeExceptionally(throwable);
+ }
+ });
+
+ // Verify the NullPointException has been thrown.
+ ExecutionException executionException = expectThrows(ExecutionException.class,
+ putDocumentsFuture::get);
+ assertThat(executionException.getCause()).isInstanceOf(NullPointerException.class);
+ }
+}
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 57c0be5..5d75d9b 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -2923,7 +2923,7 @@
assertFalse("BaseCodePath should not be registered", callback.mSuccess);
}
- // Verify thatmodules which are not own by the calling package are not registered.
+ // Verify that modules which are not own by the calling package are not registered.
public void testRegisterDexModuleNotOwningModule() throws Exception {
TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
String moduleBelongingToOtherPackage = "/data/user/0/com.google.android.gms/module.apk";
@@ -2978,6 +2978,13 @@
assertFalse("DexModule registration should fail", callback.mSuccess);
}
+ // If the module does not exist on disk we should get a failure.
+ public void testRegisterDexModuleNotExistsNoCallback() throws Exception {
+ ApplicationInfo info = getContext().getApplicationInfo();
+ String nonExistentApk = Paths.get(info.dataDir, "non-existent.apk").toString();
+ getPm().registerDexModule(nonExistentApk, null);
+ }
+
// Copied from com.android.server.pm.InstructionSets because we don't have access to it here.
private static String[] getAppDexInstructionSets(ApplicationInfo info) {
if (info.primaryCpuAbi != null) {
diff --git a/core/tests/coretests/src/android/inputmethodservice/InputMethodServiceTest.java b/core/tests/coretests/src/android/inputmethodservice/InputMethodServiceTest.java
new file mode 100644
index 0000000..4863cfe
--- /dev/null
+++ b/core/tests/coretests/src/android/inputmethodservice/InputMethodServiceTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.inputmethodservice;
+
+import static android.content.res.Configuration.KEYBOARD_12KEY;
+import static android.content.res.Configuration.NAVIGATION_NONAV;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+
+import static junit.framework.Assert.assertFalse;
+
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.rule.ServiceTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.TimeoutException;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class InputMethodServiceTest {
+ private InputMethodService mService;
+ private Context mContext;
+ @Rule
+ public final ServiceTestRule serviceRule = new ServiceTestRule();
+
+ @Before
+ public void setUp() throws TimeoutException {
+ mContext = getInstrumentation().getContext();
+ mService = new InputMethodService();
+ }
+
+ @Test
+ public void testShouldImeRestartForConfig() throws Exception {
+ // Make sure we preserve Pre-S behavior i.e. Service restarts.
+ mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.R;
+ Configuration config = mContext.getResources().getConfiguration();
+ mService.setLastKnownConfig(config);
+ assertTrue("IME should restart for Pre-S",
+ mService.shouldImeRestartForConfig(config));
+
+ // IME shouldn't restart on targetSdk S+ (with no config changes).
+ mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.S;
+ assertFalse("IME shouldn't restart for S+",
+ mService.shouldImeRestartForConfig(config));
+
+ // Screen density changed but IME doesn't handle congfigChanges
+ config.densityDpi = 99;
+ assertTrue("IME should restart for unhandled configChanges",
+ mService.shouldImeRestartForConfig(config));
+
+ // opt-in IME to handle config changes.
+ mService.setHandledConfigChanges(ActivityInfo.CONFIG_DENSITY);
+ assertFalse("IME shouldn't restart for S+ since it handles configChanges",
+ mService.shouldImeRestartForConfig(config));
+ }
+}
diff --git a/core/tests/coretests/src/android/view/OWNERS b/core/tests/coretests/src/android/view/OWNERS
index 80165f0..fa1aa5e 100644
--- a/core/tests/coretests/src/android/view/OWNERS
+++ b/core/tests/coretests/src/android/view/OWNERS
@@ -9,3 +9,6 @@
per-file *Insets* = file:/services/core/java/com/android/server/wm/OWNERS
per-file *View* = file:/services/core/java/com/android/server/wm/OWNERS
per-file *Visibility* = file:/services/core/java/com/android/server/wm/OWNERS
+
+# Scroll Capture
+per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
diff --git a/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeTest.java b/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeTest.java
index 1e0e1235..f5fcb03 100644
--- a/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeTest.java
@@ -125,7 +125,7 @@
assertEquals("he", clonedSubtypeHe.getLocale());
}
- private static final InputMethodSubtype cloneViaParcel(final InputMethodSubtype original) {
+ private static InputMethodSubtype cloneViaParcel(final InputMethodSubtype original) {
Parcel parcel = null;
try {
parcel = Parcel.obtain();
@@ -157,4 +157,4 @@
.setIsAsciiCapable(true)
.build();
}
-}
\ No newline at end of file
+}
diff --git a/core/tests/coretests/src/android/view/inputmethod/SparseRectFArrayTest.java b/core/tests/coretests/src/android/view/inputmethod/SparseRectFArrayTest.java
index 453ad72..f264cc6 100644
--- a/core/tests/coretests/src/android/view/inputmethod/SparseRectFArrayTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/SparseRectFArrayTest.java
@@ -62,20 +62,20 @@
@Test
public void testBuilder() throws Exception {
- final RectF TEMP_RECT = new RectF(10.0f, 20.0f, 30.0f, 40.0f);
- final int TEMP_FLAGS = 0x1234;
+ final RectF testRect = new RectF(10.0f, 20.0f, 30.0f, 40.0f);
+ final int testFlags = 0x1234;
final SparseRectFArrayBuilder builder = new SparseRectFArrayBuilder();
- builder.append(100, TEMP_RECT.left, TEMP_RECT.top, TEMP_RECT.right, TEMP_RECT.bottom,
- TEMP_FLAGS);
+ builder.append(100, testRect.left, testRect.top, testRect.right, testRect.bottom,
+ testFlags);
assertNull(builder.build().get(-1));
assertNull(builder.build().get(0));
assertNull(builder.build().get(99));
assertEquals(0, builder.build().getFlags(99, 0 /* valueIfKeyNotFound */));
assertEquals(1, builder.build().getFlags(99, 1 /* valueIfKeyNotFound */));
- assertEquals(TEMP_RECT, builder.build().get(100));
- assertEquals(TEMP_FLAGS, builder.build().getFlags(100, 0 /* valueIfKeyNotFound */));
- assertEquals(TEMP_FLAGS, builder.build().getFlags(100, 1 /* valueIfKeyNotFound */));
+ assertEquals(testRect, builder.build().get(100));
+ assertEquals(testFlags, builder.build().getFlags(100, 0 /* valueIfKeyNotFound */));
+ assertEquals(testFlags, builder.build().getFlags(100, 1 /* valueIfKeyNotFound */));
assertNull(builder.build().get(101));
assertEquals(0, builder.build().getFlags(101, 0 /* valueIfKeyNotFound */));
assertEquals(1, builder.build().getFlags(101, 1 /* valueIfKeyNotFound */));
diff --git a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
index d50bb05..b89e8bc 100644
--- a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
@@ -232,7 +232,7 @@
assertThat(entry3.handlerClassName).isEqualTo(
"com.android.internal.os.LooperStatsTest$TestHandlerSecond");
assertThat(entry3.messageName).startsWith(
- "com.android.internal.os.LooperStatsTest-$$ExternalSyntheticLambda");
+ "com.android.internal.os.LooperStatsTest$$ExternalSyntheticLambda4");
assertThat(entry3.messageCount).isEqualTo(1);
assertThat(entry3.recordedMessageCount).isEqualTo(1);
assertThat(entry3.exceptionCount).isEqualTo(0);
diff --git a/core/tests/coretests/src/com/android/internal/view/OWNERS b/core/tests/coretests/src/com/android/internal/view/OWNERS
new file mode 100644
index 0000000..1dad10d
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/view/OWNERS
@@ -0,0 +1,3 @@
+# Scroll Capture
+per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
+per-file *CaptureHelper*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
diff --git a/core/tests/mockingcoretests/src/android/view/DisplayTests.java b/core/tests/mockingcoretests/src/android/view/DisplayTests.java
new file mode 100644
index 0000000..678f21f
--- /dev/null
+++ b/core/tests/mockingcoretests/src/android/view/DisplayTests.java
@@ -0,0 +1,531 @@
+/*
+ * 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.view;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_90;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.hardware.display.DisplayManagerGlobal;
+import android.platform.test.annotations.Presubmit;
+import android.util.DisplayMetrics;
+import android.view.DisplayAdjustments.FixedRotationAdjustments;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.quality.Strictness;
+
+import java.util.function.Consumer;
+
+/**
+ * Tests for {@link Display}.
+ *
+ * <p>Build/Install/Run:
+ *
+ * atest FrameworksMockingCoreTests:android.view.DisplayTests
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class DisplayTests {
+
+ private static final int APP_WIDTH = 272;
+ private static final int APP_HEIGHT = 700;
+ // Tablet size device, ROTATION_0 corresponds to portrait.
+ private static final int LOGICAL_WIDTH = 700;
+ private static final int LOGICAL_HEIGHT = 1800;
+
+ // Bounds of the app when the device is in portrait mode.
+ private static Rect sAppBoundsPortrait = buildAppBounds(LOGICAL_WIDTH, LOGICAL_HEIGHT);
+ private static Rect sAppBoundsLandscape = buildAppBounds(LOGICAL_HEIGHT, LOGICAL_WIDTH);
+
+ private StaticMockitoSession mMockitoSession;
+
+ private DisplayManagerGlobal mDisplayManagerGlobal;
+ private Context mApplicationContext;
+ private DisplayInfo mDisplayInfo = new DisplayInfo();
+
+ @Before
+ public void setupTests() {
+ mMockitoSession = mockitoSession()
+ .mockStatic(DisplayManagerGlobal.class)
+ .strictness(Strictness.LENIENT)
+ .startMocking();
+
+ // Ensure no adjustments are set before each test.
+ mApplicationContext = ApplicationProvider.getApplicationContext();
+ DisplayAdjustments displayAdjustments =
+ mApplicationContext.getResources().getDisplayAdjustments();
+ displayAdjustments.setFixedRotationAdjustments(null);
+ mApplicationContext.getResources().overrideDisplayAdjustments(null);
+ mApplicationContext.getResources().getConfiguration().windowConfiguration.setAppBounds(
+ null);
+ mApplicationContext.getResources().getConfiguration().windowConfiguration.setMaxBounds(
+ null);
+ mDisplayInfo.rotation = ROTATION_0;
+
+ mDisplayManagerGlobal = mock(DisplayManagerGlobal.class);
+ doReturn(mDisplayInfo).when(mDisplayManagerGlobal).getDisplayInfo(anyInt());
+ }
+
+ @After
+ public void teardownTests() {
+ if (mMockitoSession != null) {
+ mMockitoSession.finishMocking();
+ }
+ Mockito.framework().clearInlineMocks();
+ }
+
+ @Test
+ public void testConstructor_defaultDisplayAdjustments_matchesDisplayInfo() {
+ setDisplayInfoPortrait(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+ assertThat(display.getDisplayAdjustments()).isEqualTo(
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+ DisplayInfo actualDisplayInfo = new DisplayInfo();
+ display.getDisplayInfo(actualDisplayInfo);
+ verifyDisplayInfo(actualDisplayInfo, mDisplayInfo);
+ }
+
+ @Test
+ public void testConstructor_defaultResources_matchesDisplayInfo() {
+ setDisplayInfoPortrait(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ assertThat(display.getDisplayAdjustments()).isEqualTo(
+ mApplicationContext.getResources().getDisplayAdjustments());
+ DisplayInfo actualDisplayInfo = new DisplayInfo();
+ display.getDisplayInfo(actualDisplayInfo);
+ verifyDisplayInfo(actualDisplayInfo, mDisplayInfo);
+ }
+
+ @Test
+ public void testGetRotation_defaultDisplayAdjustments_rotationNotAdjusted() {
+ setDisplayInfoPortrait(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+ assertThat(display.getRotation()).isEqualTo(ROTATION_0);
+ }
+
+ @Test
+ public void testGetRotation_displayAdjustmentsWithoutOverride_rotationNotAdjusted() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated, but no override is set.
+ DisplayAdjustments displayAdjustments = DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
+ final FixedRotationAdjustments fixedRotationAdjustments =
+ new FixedRotationAdjustments(ROTATION_90, APP_WIDTH, APP_HEIGHT,
+ DisplayCutout.NO_CUTOUT);
+ displayAdjustments.setFixedRotationAdjustments(fixedRotationAdjustments);
+ // GIVEN display is constructed with display adjustments.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ displayAdjustments);
+ // THEN rotation is not adjusted since no override was set.
+ assertThat(display.getRotation()).isEqualTo(ROTATION_0);
+ }
+
+ @Test
+ public void testGetRotation_resourcesWithoutOverride_rotationNotAdjusted() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated, but no override is set.
+ setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN rotation is not adjusted since no override is set.
+ assertThat(display.getRotation()).isEqualTo(ROTATION_0);
+ }
+
+ @Test
+ public void testGetRotation_resourcesWithOverrideDisplayAdjustments_rotationAdjusted() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated, and an override is set.
+ setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN rotation is adjusted since an override is set.
+ assertThat(display.getRotation()).isEqualTo(ROTATION_90);
+ }
+
+ @Test
+ public void testGetRealSize_defaultResourcesPortrait_matchesLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches display orientation.
+ verifyRealSizeIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealSize_defaultResourcesLandscape_matchesRotatedLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches display orientation.
+ verifyRealSizeIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealSize_defaultDisplayAdjustmentsPortrait_matchesLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+ // THEN real size matches display orientation.
+ verifyRealSizeIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealSize_defaultDisplayAdjustmentsLandscape_matchesLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+ // THEN real size matches display orientation.
+ verifyRealSizeIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealSize_resourcesPortraitWithFixedRotation_notRotatedLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated.
+ setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches display orientation.
+ verifyRealSizeIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealSize_resourcesWithLandscapeFixedRotation_notRotatedLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated.
+ setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches display orientation.
+ verifyRealSizeIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealSize_resourcesWithPortraitOverrideRotation_rotatedLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated, and an override is set.
+ setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches app orientation.
+ verifyRealSizeIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealSize_resourcesWithLandscapeOverrideRotation_rotatedLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated, and an override is set.
+ setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches app orientation.
+ verifyRealSizeIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealSize_resourcesPortraitSandboxed_matchesSandboxBounds() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN app is letterboxed.
+ setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
+ sAppBoundsPortrait);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches app bounds.
+ verifyRealSizeMatchesApp(display, sAppBoundsPortrait);
+ }
+
+ @Test
+ public void testGetRealSize_resourcesLandscapeSandboxed_matchesSandboxBounds() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ // GIVEN app is letterboxed.
+ setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
+ sAppBoundsLandscape);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches app bounds.
+ verifyRealSizeMatchesApp(display, sAppBoundsLandscape);
+ }
+
+ @Test
+ public void testGetRealMetrics_defaultResourcesPortrait_matchesLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches display orientation.
+ verifyRealMetricsIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_defaultResourcesLandscape_matchesRotatedLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches display orientation.
+ verifyRealMetricsIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_defaultDisplayAdjustmentsPortrait_matchesLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+ // THEN real metrics matches display orientation.
+ verifyRealMetricsIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_defaultDisplayAdjustmentsLandscape_matchesLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+ // THEN real metrics matches display orientation.
+ verifyRealMetricsIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_resourcesPortraitWithFixedRotation_notRotatedLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated.
+ setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches display orientation.
+ verifyRealMetricsIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_resourcesWithLandscapeFixedRotation_notRotatedLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated.
+ setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches display orientation.
+ verifyRealMetricsIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_resourcesWithPortraitOverrideRotation_rotatedLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated with an override.
+ setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches app orientation.
+ verifyRealMetricsIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_resourcesWithLandscapeOverrideRotation_rotatedLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated.
+ setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches app orientation.
+ verifyRealMetricsIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_resourcesPortraitSandboxed_matchesSandboxBounds() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN app is letterboxed.
+ setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
+ sAppBoundsPortrait);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches app bounds.
+ verifyRealMetricsMatchesApp(display, sAppBoundsPortrait);
+ }
+
+ @Test
+ public void testGetRealMetrics_resourcesLandscapeSandboxed_matchesSandboxBounds() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ // GIVEN app is letterboxed.
+ setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
+ sAppBoundsLandscape);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches app bounds.
+ verifyRealMetricsMatchesApp(display, sAppBoundsLandscape);
+ }
+
+ // Given rotated display dimensions, calculate the letterboxed app bounds.
+ private static Rect buildAppBounds(int displayWidth, int displayHeight) {
+ final int midWidth = displayWidth / 2;
+ final int left = midWidth - (APP_WIDTH / 2);
+ final int right = midWidth + (APP_WIDTH / 2);
+ final int midHeight = displayHeight / 2;
+ // Coordinate system starts at top left.
+ final int top = midHeight - (APP_HEIGHT / 2);
+ final int bottom = midHeight + (APP_HEIGHT / 2);
+ return new Rect(left, top, right, bottom);
+ }
+
+ private static void setDisplayInfoLandscape(DisplayInfo displayInfo) {
+ displayInfo.rotation = ROTATION_90;
+ // Flip width & height assignment since the device is rotated.
+ displayInfo.logicalWidth = LOGICAL_HEIGHT;
+ displayInfo.logicalHeight = LOGICAL_WIDTH;
+ }
+
+ private static void setDisplayInfoPortrait(DisplayInfo displayInfo) {
+ displayInfo.rotation = ROTATION_0;
+ displayInfo.logicalWidth = LOGICAL_WIDTH;
+ displayInfo.logicalHeight = LOGICAL_HEIGHT;
+ }
+
+ /**
+ * Set max bounds to be sandboxed to the app bounds, indicating the app is in
+ * size compat mode or letterbox.
+ */
+ private static void setMaxBoundsSandboxedToMatchAppBounds(Resources resources, Rect appBounds) {
+ resources.getConfiguration().windowConfiguration.setMaxBounds(appBounds);
+ }
+
+ /**
+ * Do not compare entire display info, since it is updated to match display the test is run on.
+ */
+ private static void verifyDisplayInfo(DisplayInfo actual, DisplayInfo expected) {
+ assertThat(actual.displayId).isEqualTo(expected.displayId);
+ assertThat(actual.rotation).isEqualTo(expected.rotation);
+ assertThat(actual.logicalWidth).isEqualTo(LOGICAL_WIDTH);
+ assertThat(actual.logicalHeight).isEqualTo(LOGICAL_HEIGHT);
+ }
+
+ private static void verifyRealSizeIsLandscape(Display display) {
+ Point size = new Point();
+ display.getRealSize(size);
+ // Flip the width and height check since the device is rotated.
+ assertThat(size).isEqualTo(new Point(LOGICAL_HEIGHT, LOGICAL_WIDTH));
+ }
+
+ private static void verifyRealMetricsIsLandscape(Display display) {
+ DisplayMetrics metrics = new DisplayMetrics();
+ display.getRealMetrics(metrics);
+ // Flip the width and height check since the device is rotated.
+ assertThat(metrics.widthPixels).isEqualTo(LOGICAL_HEIGHT);
+ assertThat(metrics.heightPixels).isEqualTo(LOGICAL_WIDTH);
+ }
+
+ private static void verifyRealSizeIsPortrait(Display display) {
+ Point size = new Point();
+ display.getRealSize(size);
+ assertThat(size).isEqualTo(new Point(LOGICAL_WIDTH, LOGICAL_HEIGHT));
+ }
+
+ private static void verifyRealMetricsIsPortrait(Display display) {
+ DisplayMetrics metrics = new DisplayMetrics();
+ display.getRealMetrics(metrics);
+ assertThat(metrics.widthPixels).isEqualTo(LOGICAL_WIDTH);
+ assertThat(metrics.heightPixels).isEqualTo(LOGICAL_HEIGHT);
+ }
+
+ private static void verifyRealSizeMatchesApp(Display display, Rect appBounds) {
+ Point size = new Point();
+ display.getRealSize(size);
+ assertThat(size).isEqualTo(new Point(appBounds.width(), appBounds.height()));
+ }
+
+ private static void verifyRealMetricsMatchesApp(Display display, Rect appBounds) {
+ DisplayMetrics metrics = new DisplayMetrics();
+ display.getRealMetrics(metrics);
+ assertThat(metrics.widthPixels).isEqualTo(appBounds.width());
+ assertThat(metrics.heightPixels).isEqualTo(appBounds.height());
+ }
+
+ private static FixedRotationAdjustments setOverrideFixedRotationAdjustments(
+ Resources resources, @Surface.Rotation int rotation) {
+ FixedRotationAdjustments fixedRotationAdjustments =
+ setFixedRotationAdjustments(resources, rotation);
+ resources.overrideDisplayAdjustments(
+ buildOverrideRotationAdjustments(fixedRotationAdjustments));
+ return fixedRotationAdjustments;
+ }
+
+ private static FixedRotationAdjustments setFixedRotationAdjustments(Resources resources,
+ @Surface.Rotation int rotation) {
+ final FixedRotationAdjustments fixedRotationAdjustments =
+ new FixedRotationAdjustments(rotation, APP_WIDTH, APP_HEIGHT,
+ DisplayCutout.NO_CUTOUT);
+ resources.getDisplayAdjustments().setFixedRotationAdjustments(fixedRotationAdjustments);
+ return fixedRotationAdjustments;
+ }
+
+ private static Consumer<DisplayAdjustments> buildOverrideRotationAdjustments(
+ FixedRotationAdjustments fixedRotationAdjustments) {
+ return consumedDisplayAdjustments
+ -> consumedDisplayAdjustments.setFixedRotationAdjustments(fixedRotationAdjustments);
+ }
+}
diff --git a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
index c01bb75..e41805d 100644
--- a/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
+++ b/core/tests/uwbtests/src/android/uwb/RangingManagerTest.java
@@ -22,7 +22,6 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.os.PersistableBundle;
import android.os.RemoteException;
@@ -32,6 +31,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import java.util.concurrent.Executor;
@@ -42,51 +42,23 @@
@RunWith(AndroidJUnit4.class)
public class RangingManagerTest {
- private static final IUwbAdapter ADAPTER = mock(IUwbAdapter.class);
private static final Executor EXECUTOR = UwbTestUtils.getExecutor();
private static final PersistableBundle PARAMS = new PersistableBundle();
private static final @RangingChangeReason int REASON = RangingChangeReason.UNKNOWN;
@Test
public void testOpenSession_OpenRangingInvoked() throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
+ RangingManager rangingManager = new RangingManager(adapter);
RangingSession.Callback callback = mock(RangingSession.Callback.class);
rangingManager.openSession(PARAMS, EXECUTOR, callback);
- verify(ADAPTER, times(1)).openRanging(eq(rangingManager), eq(PARAMS));
- }
-
- @Test
- public void testOpenSession_ErrorIfSameSessionHandleReturned() throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- SessionHandle handle = new SessionHandle(1);
- when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
-
- rangingManager.openSession(PARAMS, EXECUTOR, callback);
-
- // Calling openSession will cause the same session handle to be returned. The onClosed
- // callback should be invoked
- RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
- rangingManager.openSession(PARAMS, EXECUTOR, callback2);
- verify(callback, times(0)).onClosed(anyInt(), any());
- verify(callback2, times(1)).onClosed(anyInt(), any());
- }
-
- @Test
- public void testOnRangingOpened_ValidSessionHandle() throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- SessionHandle handle = new SessionHandle(1);
- when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
-
- rangingManager.openSession(PARAMS, EXECUTOR, callback);
- rangingManager.onRangingOpened(handle);
- verify(callback, times(1)).onOpened(any());
+ verify(adapter, times(1)).openRanging(any(), eq(rangingManager), eq(PARAMS));
}
@Test
public void testOnRangingOpened_InvalidSessionHandle() throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
+ RangingManager rangingManager = new RangingManager(adapter);
RangingSession.Callback callback = mock(RangingSession.Callback.class);
rangingManager.onRangingOpened(new SessionHandle(2));
@@ -95,18 +67,20 @@
@Test
public void testOnRangingOpened_MultipleSessionsRegistered() throws RemoteException {
- SessionHandle sessionHandle1 = new SessionHandle(1);
- SessionHandle sessionHandle2 = new SessionHandle(2);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
+ ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+ ArgumentCaptor.forClass(SessionHandle.class);
- when(ADAPTER.openRanging(any(), any()))
- .thenReturn(sessionHandle1)
- .thenReturn(sessionHandle2);
-
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ RangingManager rangingManager = new RangingManager(adapter);
rangingManager.openSession(PARAMS, EXECUTOR, callback1);
+ verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
+
rangingManager.openSession(PARAMS, EXECUTOR, callback2);
+ verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
rangingManager.onRangingOpened(sessionHandle1);
verify(callback1, times(1)).onOpened(any());
@@ -119,12 +93,17 @@
@Test
public void testCorrectCallbackInvoked() throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
+ RangingManager rangingManager = new RangingManager(adapter);
RangingSession.Callback callback = mock(RangingSession.Callback.class);
- SessionHandle handle = new SessionHandle(1);
- when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
+
+ ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+ ArgumentCaptor.forClass(SessionHandle.class);
rangingManager.openSession(PARAMS, EXECUTOR, callback);
+ verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle handle = sessionHandleCaptor.getValue();
+
rangingManager.onRangingOpened(handle);
verify(callback, times(1)).onOpened(any());
@@ -156,20 +135,23 @@
@Test
public void testOnRangingClosed_MultipleSessionsRegistered() throws RemoteException {
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
// Verify that if multiple sessions are registered, only the session that is
// requested to close receives the associated callbacks
- SessionHandle sessionHandle1 = new SessionHandle(1);
- SessionHandle sessionHandle2 = new SessionHandle(2);
RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
- when(ADAPTER.openRanging(any(), any()))
- .thenReturn(sessionHandle1)
- .thenReturn(sessionHandle2);
+ RangingManager rangingManager = new RangingManager(adapter);
+ ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+ ArgumentCaptor.forClass(SessionHandle.class);
- RangingManager rangingManager = new RangingManager(ADAPTER);
rangingManager.openSession(PARAMS, EXECUTOR, callback1);
+ verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
+
rangingManager.openSession(PARAMS, EXECUTOR, callback2);
+ verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
rangingManager.onRangingClosed(sessionHandle1, REASON, PARAMS);
verify(callback1, times(1)).onClosed(anyInt(), any());
@@ -182,19 +164,22 @@
@Test
public void testOnRangingReport_MultipleSessionsRegistered() throws RemoteException {
- SessionHandle sessionHandle1 = new SessionHandle(1);
- SessionHandle sessionHandle2 = new SessionHandle(2);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
RangingSession.Callback callback1 = mock(RangingSession.Callback.class);
RangingSession.Callback callback2 = mock(RangingSession.Callback.class);
- when(ADAPTER.openRanging(any(), any()))
- .thenReturn(sessionHandle1)
- .thenReturn(sessionHandle2);
+ ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+ ArgumentCaptor.forClass(SessionHandle.class);
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ RangingManager rangingManager = new RangingManager(adapter);
rangingManager.openSession(PARAMS, EXECUTOR, callback1);
+ verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle1 = sessionHandleCaptor.getValue();
+
rangingManager.onRangingStarted(sessionHandle1, PARAMS);
rangingManager.openSession(PARAMS, EXECUTOR, callback2);
+ verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle sessionHandle2 = sessionHandleCaptor.getValue();
rangingManager.onRangingStarted(sessionHandle2, PARAMS);
rangingManager.onRangingResult(sessionHandle1, UwbTestUtils.getRangingReports(1));
@@ -232,17 +217,24 @@
private void runReason(@RangingChangeReason int reasonIn,
@RangingSession.Callback.Reason int reasonOut) throws RemoteException {
- RangingManager rangingManager = new RangingManager(ADAPTER);
+ IUwbAdapter adapter = mock(IUwbAdapter.class);
+ RangingManager rangingManager = new RangingManager(adapter);
RangingSession.Callback callback = mock(RangingSession.Callback.class);
- SessionHandle handle = new SessionHandle(1);
- when(ADAPTER.openRanging(any(), any())).thenReturn(handle);
+
+ ArgumentCaptor<SessionHandle> sessionHandleCaptor =
+ ArgumentCaptor.forClass(SessionHandle.class);
+
rangingManager.openSession(PARAMS, EXECUTOR, callback);
+ verify(adapter, times(1)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ SessionHandle handle = sessionHandleCaptor.getValue();
rangingManager.onRangingOpenFailed(handle, reasonIn, PARAMS);
verify(callback, times(1)).onOpenFailed(eq(reasonOut), eq(PARAMS));
// Open a new session
rangingManager.openSession(PARAMS, EXECUTOR, callback);
+ verify(adapter, times(2)).openRanging(sessionHandleCaptor.capture(), any(), any());
+ handle = sessionHandleCaptor.getValue();
rangingManager.onRangingOpened(handle);
rangingManager.onRangingStartFailed(handle, reasonIn, PARAMS);
diff --git a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
index 8e7f7c56..75c6924 100644
--- a/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
+++ b/core/tests/uwbtests/src/android/uwb/UwbTestUtils.java
@@ -16,34 +16,23 @@
package android.uwb;
-import android.content.Context;
-import android.content.pm.PackageManager;
import android.os.SystemClock;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.Executor;
public class UwbTestUtils {
private UwbTestUtils() {}
- public static boolean isUwbSupported(Context context) {
- PackageManager packageManager = context.getPackageManager();
- return packageManager.hasSystemFeature(PackageManager.FEATURE_UWB);
- }
-
public static AngleMeasurement getAngleMeasurement() {
- return new AngleMeasurement.Builder()
- .setRadians(getDoubleInRange(-Math.PI, Math.PI))
- .setErrorRadians(getDoubleInRange(0, Math.PI))
- .setConfidenceLevel(getDoubleInRange(0, 1))
- .build();
+ return new AngleMeasurement(
+ getDoubleInRange(-Math.PI, Math.PI),
+ getDoubleInRange(0, Math.PI),
+ getDoubleInRange(0, 1));
}
public static AngleOfArrivalMeasurement getAngleOfArrivalMeasurement() {
- return new AngleOfArrivalMeasurement.Builder()
+ return new AngleOfArrivalMeasurement.Builder(getAngleMeasurement())
.setAltitude(getAngleMeasurement())
- .setAzimuth(getAngleMeasurement())
.build();
}
@@ -69,14 +58,6 @@
.build();
}
- public static List<RangingMeasurement> getRangingMeasurements(int num) {
- List<RangingMeasurement> result = new ArrayList<>();
- for (int i = 0; i < num; i++) {
- result.add(getRangingMeasurement());
- }
- return result;
- }
-
public static RangingReport getRangingReports(int numMeasurements) {
RangingReport.Builder builder = new RangingReport.Builder();
for (int i = 0; i < numMeasurements; i++) {
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index b7bf8ab..4a3bd99 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -307,6 +307,12 @@
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "-1777196134": {
+ "message": "goodToGo(): No apps to animate, mPendingAnimations=%d",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
"-1770075711": {
"message": "Adding window client %s that is dead, aborting.",
"level": "WARN",
@@ -1219,6 +1225,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DragState.java"
},
+ "-681380736": {
+ "message": "Sandbox max bounds for uid %s to bounds %s due to letterboxing from mismatch with parent bounds? %s size compat mode %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-677449371": {
"message": "moveTaskToRootTask: moving task=%d to rootTaskId=%d toTop=%b",
"level": "DEBUG",
@@ -1981,12 +1993,6 @@
"group": "WM_DEBUG_STATES",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
- "194124419": {
- "message": "goodToGo(): Animation finished already, canceled=%s mPendingAnimations=%d",
- "level": "DEBUG",
- "group": "WM_DEBUG_REMOTE_ANIMATIONS",
- "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
- },
"200829729": {
"message": "ScreenRotationAnimation onAnimationEnd",
"level": "DEBUG",
@@ -2083,6 +2089,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DragState.java"
},
+ "269976641": {
+ "message": "goodToGo(): Animation canceled already",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
"274773837": {
"message": "applyAnimation: anim=%s nextAppTransition=ANIM_CLIP_REVEAL transit=%s Callers=%s",
"level": "VERBOSE",
diff --git a/data/keyboards/Vendor_0957_Product_0001.idc b/data/keyboards/Vendor_0957_Product_0001.idc
index e1f4346..39479ce 100644
--- a/data/keyboards/Vendor_0957_Product_0001.idc
+++ b/data/keyboards/Vendor_0957_Product_0001.idc
@@ -19,5 +19,4 @@
# Basic Parameters
keyboard.layout = Vendor_0957_Product_0001
-keyboard.characterMap = Vendor_0957_Product_0001
audio.mic = 1
\ No newline at end of file
diff --git a/data/keyboards/Vendor_248a_Product_8266.idc b/data/keyboards/Vendor_248a_Product_8266.idc
new file mode 100644
index 0000000..3021655
--- /dev/null
+++ b/data/keyboards/Vendor_248a_Product_8266.idc
@@ -0,0 +1,24 @@
+# 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.
+
+#
+# Input Device Configuration file for Google Reference RCU Remote.
+#
+#
+
+# Basic Parameters
+# Due to a memory error on early prototypes of the reference remote control
+# the VID/PID is mapped to 248a/8266 instead of 0957/0001
+keyboard.layout = Vendor_0957_Product_0001
+audio.mic = 1
\ No newline at end of file
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index c807882..2a6bbf3 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -25,6 +25,7 @@
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.annotation.UiThread;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
@@ -169,6 +170,21 @@
Collections.emptyMap();
/**
+ * Returns the shared memory that used for creating Typefaces.
+ *
+ * @return A SharedMemory used for creating Typeface. Maybe null if the lazy initialization is
+ * disabled or inside SystemServer or Zygote.
+ * @hide
+ */
+ @TestApi
+ public static @Nullable SharedMemory getSystemFontMapSharedMemory() {
+ if (ENABLE_LAZY_TYPEFACE_INITIALIZATION) {
+ Objects.requireNonNull(sSystemFontMapSharedMemory);
+ }
+ return sSystemFontMapSharedMemory;
+ }
+
+ /**
* @hide
*/
@UnsupportedAppUsage
@@ -1196,8 +1212,13 @@
}
}
- /** @hide */
- public static SharedMemory serializeFontMap(Map<String, Typeface> fontMap)
+ /**
+ * Create a serialized system font mappings.
+ *
+ * @hide
+ */
+ @TestApi
+ public static @NonNull SharedMemory serializeFontMap(@NonNull Map<String, Typeface> fontMap)
throws IOException, ErrnoException {
long[] nativePtrs = new long[fontMap.size()];
// The name table will not be large, so let's create a byte array in memory.
@@ -1229,9 +1250,14 @@
}
// buffer's byte order should be BIG_ENDIAN.
- /** @hide */
- @VisibleForTesting
- public static Map<String, Typeface> deserializeFontMap(ByteBuffer buffer) throws IOException {
+ /**
+ * Deserialize the font mapping from the serialized byte buffer.
+ *
+ * @hide
+ */
+ @TestApi
+ public static @NonNull Map<String, Typeface> deserializeFontMap(@NonNull ByteBuffer buffer)
+ throws IOException {
Map<String, Typeface> fontMap = new ArrayMap<>();
int typefacesBytesCount = buffer.getInt();
long[] nativePtrs = nativeReadTypefaces(buffer.slice());
diff --git a/graphics/java/android/graphics/drawable/RippleAnimationSession.java b/graphics/java/android/graphics/drawable/RippleAnimationSession.java
index 80f65f9..f3bf63b 100644
--- a/graphics/java/android/graphics/drawable/RippleAnimationSession.java
+++ b/graphics/java/android/graphics/drawable/RippleAnimationSession.java
@@ -27,8 +27,9 @@
import android.graphics.RecordingCanvas;
import android.graphics.animation.RenderNodeAnimator;
import android.util.ArraySet;
-import android.view.animation.DecelerateInterpolator;
+import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
+import android.view.animation.PathInterpolator;
import java.util.function.Consumer;
@@ -36,32 +37,41 @@
* @hide
*/
public final class RippleAnimationSession {
- private static final int ENTER_ANIM_DURATION = 350;
- private static final int EXIT_ANIM_OFFSET = ENTER_ANIM_DURATION;
- private static final int EXIT_ANIM_DURATION = 350;
+ private static final String TAG = "RippleAnimationSession";
+ private static final int ENTER_ANIM_DURATION = 300;
+ private static final int SLIDE_ANIM_DURATION = 450;
+ private static final int EXIT_ANIM_DURATION = 300;
private static final TimeInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
- // Matches R.interpolator.fast_out_slow_in but as we have no context we can't just import that
- private static final TimeInterpolator DECELERATE_INTERPOLATOR = new DecelerateInterpolator();
-
+ private static final TimeInterpolator PATH_INTERPOLATOR =
+ new PathInterpolator(.2f, 0, 0, 1f);
private Consumer<RippleAnimationSession> mOnSessionEnd;
- private AnimationProperties<Float, Paint> mProperties;
+ private final AnimationProperties<Float, Paint> mProperties;
private AnimationProperties<CanvasProperty<Float>, CanvasProperty<Paint>> mCanvasProperties;
private Runnable mOnUpdate;
private long mStartTime;
private boolean mForceSoftware;
- private ArraySet<Animator> mActiveAnimations = new ArraySet(3);
+ private final float mWidth, mHeight;
+ private final ValueAnimator mSparkle = ValueAnimator.ofFloat(0, 1);
+ private final ArraySet<Animator> mActiveAnimations = new ArraySet<>(3);
RippleAnimationSession(@NonNull AnimationProperties<Float, Paint> properties,
- boolean forceSoftware) {
+ boolean forceSoftware, float width, float height) {
mProperties = properties;
mForceSoftware = forceSoftware;
- }
+ mWidth = width;
+ mHeight = height;
- void end() {
- for (Animator anim: mActiveAnimations) {
- if (anim != null) anim.end();
- }
- mActiveAnimations.clear();
+ mSparkle.addUpdateListener(anim -> {
+ final long now = AnimationUtils.currentAnimationTimeMillis();
+ final long elapsed = now - mStartTime - ENTER_ANIM_DURATION;
+ final float phase = (float) elapsed / 1000f;
+ mProperties.getShader().setSecondsOffset(phase);
+ notifyUpdate();
+ });
+ mSparkle.setDuration(ENTER_ANIM_DURATION);
+ mSparkle.setStartDelay(ENTER_ANIM_DURATION);
+ mSparkle.setInterpolator(LINEAR_INTERPOLATOR);
+ mSparkle.setRepeatCount(ValueAnimator.INFINITE);
}
@NonNull RippleAnimationSession enter(Canvas canvas) {
@@ -70,17 +80,19 @@
} else {
enterSoftware();
}
- mStartTime = System.nanoTime();
+ mStartTime = AnimationUtils.currentAnimationTimeMillis();
return this;
}
@NonNull RippleAnimationSession exit(Canvas canvas) {
+ mSparkle.end();
if (isHwAccelerated(canvas)) exitHardware((RecordingCanvas) canvas);
else exitSoftware();
return this;
}
private void onAnimationEnd(Animator anim) {
+ notifyUpdate();
mActiveAnimations.remove(anim);
}
@@ -92,7 +104,6 @@
RippleAnimationSession setOnAnimationUpdated(@Nullable Runnable run) {
mOnUpdate = run;
- mProperties.setOnChange(mOnUpdate);
return this;
}
@@ -122,14 +133,12 @@
}
private long computeDelay() {
- long currentTime = System.nanoTime();
- long timePassed = (currentTime - mStartTime) / 1_000_000;
- long difference = EXIT_ANIM_OFFSET;
- return Math.max(difference - timePassed, 0);
+ final long timePassed = AnimationUtils.currentAnimationTimeMillis() - mStartTime;
+ return Math.max((long) SLIDE_ANIM_DURATION - timePassed, 0);
}
+
private void notifyUpdate() {
- Runnable onUpdate = mOnUpdate;
- if (onUpdate != null) onUpdate.run();
+ if (mOnUpdate != null) mOnUpdate.run();
}
RippleAnimationSession setForceSoftwareAnimation(boolean forceSw) {
@@ -153,7 +162,7 @@
}
});
exit.setTarget(canvas);
- exit.setInterpolator(DECELERATE_INTERPOLATOR);
+ exit.setInterpolator(LINEAR_INTERPOLATOR);
long delay = computeDelay();
exit.setStartDelay(delay);
@@ -161,36 +170,67 @@
mActiveAnimations.add(exit);
}
- private void enterHardware(RecordingCanvas can) {
+ private void enterHardware(RecordingCanvas canvas) {
AnimationProperties<CanvasProperty<Float>, CanvasProperty<Paint>>
props = getCanvasProperties();
RenderNodeAnimator expand =
new RenderNodeAnimator(props.getProgress(), .5f);
- expand.setTarget(can);
- expand.setDuration(ENTER_ANIM_DURATION);
- expand.addListener(new AnimatorListener(this));
+ RenderNodeAnimator slideX =
+ new RenderNodeAnimator(props.getX(), mWidth / 2);
+ RenderNodeAnimator slideY =
+ new RenderNodeAnimator(props.getY(), mHeight / 2);
+ expand.setTarget(canvas);
+ slideX.setTarget(canvas);
+ slideY.setTarget(canvas);
+ startAnimation(expand, slideX, slideY);
+ }
+
+ private void startAnimation(Animator expand,
+ Animator slideX, Animator slideY) {
+ expand.setDuration(SLIDE_ANIM_DURATION);
+ slideX.setDuration(SLIDE_ANIM_DURATION);
+ slideY.setDuration(SLIDE_ANIM_DURATION);
+ slideX.addListener(new AnimatorListener(this));
expand.setInterpolator(LINEAR_INTERPOLATOR);
+ slideX.setInterpolator(PATH_INTERPOLATOR);
+ slideY.setInterpolator(PATH_INTERPOLATOR);
expand.start();
+ slideX.start();
+ slideY.start();
+ if (!mSparkle.isRunning()) {
+ mSparkle.start();
+ mActiveAnimations.add(mSparkle);
+ }
mActiveAnimations.add(expand);
+ mActiveAnimations.add(slideX);
+ mActiveAnimations.add(slideY);
}
private void enterSoftware() {
ValueAnimator expand = ValueAnimator.ofFloat(0f, 0.5f);
+ ValueAnimator slideX = ValueAnimator.ofFloat(
+ mProperties.getX(), mWidth / 2);
+ ValueAnimator slideY = ValueAnimator.ofFloat(
+ mProperties.getY(), mHeight / 2);
expand.addUpdateListener(updatedAnimation -> {
notifyUpdate();
mProperties.getShader().setProgress((Float) expand.getAnimatedValue());
});
- expand.addListener(new AnimatorListener(this));
- expand.setInterpolator(LINEAR_INTERPOLATOR);
- expand.start();
- mActiveAnimations.add(expand);
+ slideX.addUpdateListener(anim -> {
+ float x = (float) slideX.getAnimatedValue();
+ float y = (float) slideY.getAnimatedValue();
+ mProperties.setOrigin(x, y);
+ mProperties.getShader().setOrigin(x, y);
+ });
+ startAnimation(expand, slideX, slideY);
}
@NonNull AnimationProperties<Float, Paint> getProperties() {
return mProperties;
}
- @NonNull AnimationProperties getCanvasProperties() {
+ @NonNull
+ AnimationProperties<CanvasProperty<Float>, CanvasProperty<Paint>> getCanvasProperties() {
if (mCanvasProperties == null) {
mCanvasProperties = new AnimationProperties<>(
CanvasProperty.createFloat(mProperties.getX()),
@@ -209,6 +249,7 @@
AnimatorListener(RippleAnimationSession session) {
mSession = session;
}
+
@Override
public void onAnimationStart(Animator animation) {
@@ -231,21 +272,12 @@
}
static class AnimationProperties<FloatType, PaintType> {
- private final FloatType mY;
- private FloatType mProgress;
- private FloatType mMaxRadius;
+ private final FloatType mProgress;
+ private final FloatType mMaxRadius;
private final PaintType mPaint;
- private final FloatType mX;
private final RippleShader mShader;
- private Runnable mOnChange;
-
- private void onChange() {
- if (mOnChange != null) mOnChange.run();
- }
-
- private void setOnChange(Runnable onChange) {
- mOnChange = onChange;
- }
+ private FloatType mX;
+ private FloatType mY;
AnimationProperties(FloatType x, FloatType y, FloatType maxRadius,
PaintType paint, FloatType progress, RippleShader shader) {
@@ -261,6 +293,11 @@
return mProgress;
}
+ void setOrigin(FloatType x, FloatType y) {
+ mX = x;
+ mY = y;
+ }
+
FloatType getX() {
return mX;
}
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 5024875..d6bbee9 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -48,6 +48,7 @@
import android.graphics.Rect;
import android.graphics.Shader;
import android.os.Build;
+import android.os.SystemProperties;
import android.util.AttributeSet;
import android.view.animation.LinearInterpolator;
@@ -109,17 +110,6 @@
* </pre>
*
* @attr ref android.R.styleable#RippleDrawable_color
- *
- * To change the ripple style, assign the value of "solid" or "patterned" to the android:rippleStyle
- * attribute.
- *
- * <pre>
- * <code><!-- A red ripple masked against an opaque rectangle. --/>
- * <ripple android:rippleStyle="patterned">
- * </ripple></code>
- * </pre>
- *
- * @attr ref android.R.styleable#RippleDrawable_rippleStyle
*/
public class RippleDrawable extends LayerDrawable {
/**
@@ -131,12 +121,14 @@
/**
* Ripple style where a solid circle is drawn. This is also the default style
* @see #setRippleStyle(int)
+ * @hide
*/
public static final int STYLE_SOLID = 0;
/**
* Ripple style where a circle shape with a patterned,
* noisy interior expands from the hotspot to the bounds".
* @see #setRippleStyle(int)
+ * @hide
*/
public static final int STYLE_PATTERNED = 1;
@@ -159,6 +151,9 @@
/** The maximum number of ripples supported. */
private static final int MAX_RIPPLES = 10;
private static final LinearInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
+ /** Temporary flag for teamfood. **/
+ private static final boolean FORCE_PATTERNED_STYLE =
+ SystemProperties.getBoolean("persist.material.patternedripple", false);
private final Rect mTempRect = new Rect();
@@ -361,7 +356,9 @@
}
} else {
if (focused || hovered) {
- enterPatternedBackgroundAnimation(focused, hovered);
+ if (!pressed) {
+ enterPatternedBackgroundAnimation(focused, hovered);
+ }
} else {
exitPatternedBackgroundAnimation();
}
@@ -571,7 +568,10 @@
mState.mMaxRadius = a.getDimensionPixelSize(
R.styleable.RippleDrawable_radius, mState.mMaxRadius);
- mState.mRippleStyle = a.getInteger(R.styleable.RippleDrawable_rippleStyle, STYLE_SOLID);
+ if (!FORCE_PATTERNED_STYLE) {
+ mState.mRippleStyle = a.getInteger(R.styleable.RippleDrawable_rippleStyle,
+ mState.mRippleStyle);
+ }
}
private void verifyRequiredAttributes(@NonNull TypedArray a) throws XmlPullParserException {
@@ -812,21 +812,25 @@
}
private void drawPatterned(@NonNull Canvas canvas) {
- final Rect bounds = getBounds();
+ final Rect bounds = getDirtyBounds();
final int saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
boolean useCanvasProps = shouldUseCanvasProps(canvas);
boolean changedHotspotBounds = !bounds.equals(mHotspotBounds);
if (isBounded()) {
- canvas.clipRect(mHotspotBounds);
+ canvas.clipRect(bounds);
}
- float x, y;
+ float x, y, w, h;
if (changedHotspotBounds) {
x = mHotspotBounds.exactCenterX();
y = mHotspotBounds.exactCenterY();
+ w = mHotspotBounds.width();
+ h = mHotspotBounds.height();
useCanvasProps = false;
} else {
x = mPendingX;
y = mPendingY;
+ w = bounds.width();
+ h = bounds.height();
}
boolean shouldAnimate = mRippleActive;
boolean shouldExit = mExitingAnimation;
@@ -837,9 +841,9 @@
drawPatternedBackground(canvas);
if (shouldAnimate && mRunningAnimations.size() <= MAX_RIPPLES) {
RippleAnimationSession.AnimationProperties<Float, Paint> properties =
- createAnimationProperties(x, y);
- mRunningAnimations.add(new RippleAnimationSession(properties, !useCanvasProps)
- .setOnAnimationUpdated(useCanvasProps ? null : () -> invalidateSelf(false))
+ createAnimationProperties(x, y, w, h);
+ mRunningAnimations.add(new RippleAnimationSession(properties, !useCanvasProps, w, h)
+ .setOnAnimationUpdated(() -> invalidateSelf(false))
.setOnSessionEnd(session -> {
mRunningAnimations.remove(session);
})
@@ -864,20 +868,8 @@
} else {
RippleAnimationSession.AnimationProperties<Float, Paint> p =
s.getProperties();
- float posX, posY;
- if (changedHotspotBounds) {
- posX = x;
- posY = y;
- if (p.getPaint().getShader() instanceof RippleShader) {
- RippleShader shader = (RippleShader) p.getPaint().getShader();
- shader.setOrigin(posX, posY);
- }
- } else {
- posX = p.getX();
- posY = p.getY();
- }
float radius = p.getMaxRadius();
- canvas.drawCircle(posX, posY, radius, p.getPaint());
+ canvas.drawCircle(p.getX(), p.getY(), radius, p.getPaint());
}
}
canvas.restoreToCount(saveCount);
@@ -905,14 +897,13 @@
private float computeRadius() {
Rect b = getDirtyBounds();
- float gap = 0;
- float radius = (float) Math.sqrt(b.width() * b.width() + b.height() * b.height()) / 2 + gap;
+ float radius = (float) Math.sqrt(b.width() * b.width() + b.height() * b.height()) / 2;
return radius;
}
@NonNull
private RippleAnimationSession.AnimationProperties<Float, Paint> createAnimationProperties(
- float x, float y) {
+ float x, float y, float w, float h) {
Paint p = new Paint(mRipplePaint);
float radius = mState.mMaxRadius;
RippleAnimationSession.AnimationProperties<Float, Paint> properties;
@@ -920,19 +911,19 @@
int color = mMaskColorFilter == null
? mState.mColor.getColorForState(getState(), Color.BLACK)
: mMaskColorFilter.getColor();
- color = color | 0xFF000000;
shader.setColor(color);
shader.setOrigin(x, y);
+ shader.setResolution(w, h);
+ shader.setSecondsOffset(0);
shader.setRadius(radius);
shader.setProgress(.0f);
properties = new RippleAnimationSession.AnimationProperties<>(
x, y, radius, p, 0f,
shader);
if (mMaskShader == null) {
- shader.setHasMask(false);
+ shader.setShader(null);
} else {
shader.setShader(mMaskShader);
- shader.setHasMask(true);
}
p.setShader(shader);
p.setColorFilter(null);
@@ -1160,7 +1151,7 @@
// The ripple timing depends on the paint's alpha value, so we need
// to push just the alpha channel into the paint and let the filter
// handle the full-alpha color.
- int maskColor = color | 0xFF000000;
+ int maskColor = mState.mRippleStyle == STYLE_PATTERNED ? color : color | 0xFF000000;
if (mMaskColorFilter.getColor() != maskColor) {
mMaskColorFilter = new PorterDuffColorFilter(maskColor, mMaskColorFilter.getMode());
}
@@ -1248,6 +1239,7 @@
* @see #STYLE_PATTERNED
*
* @param style The style of the ripple
+ * @hide
*/
public void setRippleStyle(@RippleStyle int style) throws IllegalArgumentException {
if (style == STYLE_SOLID || style == STYLE_PATTERNED) {
@@ -1260,6 +1252,7 @@
/**
* Get the current ripple style
* @return Ripple style
+ * @hide
*/
public @RippleStyle int getRippleStyle() {
return mState.mRippleStyle;
@@ -1276,7 +1269,7 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
ColorStateList mColor = ColorStateList.valueOf(Color.MAGENTA);
int mMaxRadius = RADIUS_AUTO;
- int mRippleStyle = STYLE_SOLID;
+ int mRippleStyle = FORCE_PATTERNED_STYLE ? STYLE_PATTERNED : STYLE_SOLID;
public RippleState(LayerState orig, RippleDrawable owner, Resources res) {
super(orig, owner, res);
diff --git a/graphics/java/android/graphics/drawable/RippleShader.java b/graphics/java/android/graphics/drawable/RippleShader.java
index 500efdd..2549277 100644
--- a/graphics/java/android/graphics/drawable/RippleShader.java
+++ b/graphics/java/android/graphics/drawable/RippleShader.java
@@ -17,58 +17,153 @@
package android.graphics.drawable;
import android.annotation.ColorInt;
-import android.annotation.NonNull;
import android.graphics.Color;
import android.graphics.RuntimeShader;
import android.graphics.Shader;
final class RippleShader extends RuntimeShader {
- private static final String SHADER = "uniform float2 in_origin;\n"
- + "uniform float in_maxRadius;\n"
+ private static final String SHADER_UNIFORMS = "uniform vec2 in_origin;\n"
+ "uniform float in_progress;\n"
+ + "uniform float in_maxRadius;\n"
+ + "uniform vec2 in_resolution;\n"
+ "uniform float in_hasMask;\n"
- + "uniform float4 in_color;\n"
- + "uniform shader in_shader;\n"
- + "float dist2(float2 p0, float2 pf) { return sqrt((pf.x - p0.x) * (pf.x - p0.x) + "
- + "(pf.y - p0.y) * (pf.y - p0.y)); }\n"
- + "float mod2(float a, float b) { return a - (b * floor(a / b)); }\n"
- + "float rand(float2 src) { return fract(sin(dot(src.xy, float2(12.9898, 78.233))) * "
- + "43758.5453123); }\n"
- + "float4 main(float2 p)\n"
- + "{\n"
- + " float fraction = in_progress;\n"
- + " float2 fragCoord = p;//sk_FragCoord.xy;\n"
- + " float maxDist = in_maxRadius;\n"
- + " float fragDist = dist2(in_origin, fragCoord.xy);\n"
- + " float circleRadius = maxDist * fraction;\n"
- + " float colorVal = (fragDist - circleRadius) / maxDist;\n"
- + " float d = fragDist < circleRadius \n"
- + " ? 1. - abs(colorVal * 3. * smoothstep(0., 1., fraction)) \n"
- + " : 1. - abs(colorVal * 5.);\n"
- + " d = smoothstep(0., 1., d);\n"
- + " float divider = 2.;\n"
- + " float x = floor(fragCoord.x / divider);\n"
- + " float y = floor(fragCoord.y / divider);\n"
- + " float density = .95;\n"
- + " d = rand(float2(x, y)) > density ? d : d * .2;\n"
- + " d = d * rand(float2(fraction, x * y));\n"
- + " float alpha = 1. - pow(fraction, 2.);\n"
- + " if (in_hasMask != 0.) {return sample(in_shader).a * in_color * d * alpha;}\n"
- + " return in_color * d * alpha;\n"
+ + "uniform float in_secondsOffset;\n"
+ + "uniform vec4 in_color;\n"
+ + "uniform shader in_shader;\n";
+ private static final String SHADER_LIB =
+ "float triangleNoise(vec2 n) {\n"
+ + " n = fract(n * vec2(5.3987, 5.4421));\n"
+ + " n += dot(n.yx, n.xy + vec2(21.5351, 14.3137));\n"
+ + " float xy = n.x * n.y;\n"
+ + " return fract(xy * 95.4307) + fract(xy * 75.04961) - 1.0;\n"
+ + "}"
+ + "const float PI = 3.1415926535897932384626;\n"
+ + "\n"
+ + "float threshold(float v, float l, float h) {\n"
+ + " return step(l, v) * (1.0 - step(h, v));\n"
+ + "}\n"
+ + "\n"
+ + "float sparkles(vec2 uv, float t) {\n"
+ + " float n = triangleNoise(uv);\n"
+ + " float s = 0.0;\n"
+ + " for (float i = 0; i < 4; i += 1) {\n"
+ + " float l = i * 0.25;\n"
+ + " float h = l + 0.025;\n"
+ + " float o = abs(sin(0.1 * PI * (t + i)));\n"
+ + " s += threshold(n + o, l, h);\n"
+ + " }\n"
+ + " return saturate(s);\n"
+ + "}\n"
+ + "\n"
+ + "float softCircle(vec2 uv, vec2 xy, float radius, float blur) {\n"
+ + " float blurHalf = blur * 0.5;\n"
+ + " float d = distance(uv, xy);\n"
+ + " return 1. - smoothstep(1. - blurHalf, 1. + blurHalf, d / radius);\n"
+ + "}\n"
+ + "\n"
+ + "float softRing(vec2 uv, vec2 xy, float radius, float blur) {\n"
+ + " float thickness = 0.4;\n"
+ + " float circle_outer = softCircle(uv, xy, radius + thickness * 0.5, blur);\n"
+ + " float circle_inner = softCircle(uv, xy, radius - thickness * 0.5, blur);\n"
+ + " return circle_outer - circle_inner;\n"
+ + "}\n"
+ + "\n"
+ + "struct Viewport {\n"
+ + " float aspect;\n"
+ + " vec2 uv;\n"
+ + " vec2 resolution_pixels;\n"
+ + "};\n"
+ + "\n"
+ + "Viewport getViewport(vec2 frag_coord, vec2 resolution_pixels) {\n"
+ + " Viewport v;\n"
+ + " v.aspect = resolution_pixels.y / resolution_pixels.x;\n"
+ + " v.uv = frag_coord / resolution_pixels;\n"
+ + " v.uv.y = (1.0 - v.uv.y) * v.aspect;\n"
+ + " v.resolution_pixels = resolution_pixels;\n"
+ + " return v;\n"
+ + "}\n"
+ + "\n"
+ + "vec2 getTouch(vec2 touch_position_pixels, Viewport viewport) {\n"
+ + " vec2 touch = touch_position_pixels / viewport.resolution_pixels;\n"
+ + " touch.y *= viewport.aspect;\n"
+ + " return touch;\n"
+ + "}\n"
+ + "\n"
+ + "struct Wave {\n"
+ + " float ring;\n"
+ + " float circle;\n"
+ + "};\n"
+ + "\n"
+ + "Wave getWave(Viewport viewport, vec2 touch, float progress) {\n"
+ + " float fade = pow((clamp(progress, 0.8, 1.0)), 8.);\n"
+ + " Wave w;\n"
+ + " w.ring = max(softRing(viewport.uv, touch, progress, 0.45) - fade, 0.);\n"
+ + " w.circle = softCircle(viewport.uv, touch, 2.0 * progress, 0.2) - progress;\n"
+ + " return w;\n"
+ + "}\n"
+ + "\n"
+ + "vec4 getRipple(vec4 color, float loudness, float sparkle, Wave wave) {\n"
+ + " float alpha = wave.ring * sparkle * loudness\n"
+ + " + wave.circle * color.a;\n"
+ + " return vec4(color.rgb, saturate(alpha));\n"
+ + "}\n"
+ + "\n"
+ + "float getRingMask(vec2 frag, vec2 center, float r, float progress) {\n"
+ + " float dist = distance(frag, center);\n"
+ + " float expansion = r * .6;\n"
+ + " r = r * min(1.,progress);\n"
+ + " float minD = max(r - expansion, 0.);\n"
+ + " float maxD = r + expansion;\n"
+ + " if (dist > maxD || dist < minD) return .0;\n"
+ + " return min(maxD - dist, dist - minD) / expansion; \n"
+ + "}\n"
+ + "\n"
+ + "float subProgress(float start, float end, float progress) {\n"
+ + " float sub = clamp(progress, start, end);\n"
+ + " return (sub - start) / (end - start); \n"
+ "}\n";
+ private static final String SHADER_MAIN = "vec4 main(vec2 p) {\n"
+ + " float fadeIn = subProgress(0., 0.175, in_progress);\n"
+ + " float fadeOutNoise = subProgress(0.375, 1., in_progress);\n"
+ + " float fadeOutRipple = subProgress(0.375, 0.75, in_progress);\n"
+ + " Viewport vp = getViewport(p, in_resolution);\n"
+ + " vec2 touch = getTouch(in_origin, vp);\n"
+ + " Wave w = getWave(vp, touch, in_progress * 0.25);\n"
+ + " float ring = getRingMask(p, in_origin, in_maxRadius, fadeIn);\n"
+ + " float alpha = min(fadeIn, 1. - fadeOutNoise);\n"
+ + " float sparkle = sparkles(p, in_progress * 0.25 + in_secondsOffset)\n"
+ + " * ring * alpha;\n"
+ + " vec4 r = getRipple(in_color, 1., sparkle, w);\n"
+ + " float fade = min(fadeIn, 1.-fadeOutRipple);\n"
+ + " vec4 circle = vec4(in_color.rgb, softCircle(p, in_origin, in_maxRadius "
+ + " * fadeIn, 0.2) * fade * in_color.a);\n"
+ + " float mask = in_hasMask == 1. ? sample(in_shader).a > 0. ? 1. : 0. : 1.;\n"
+ + " return mix(circle, vec4(1.), sparkle * mask);\n"
+ + "}";
+ private static final String SHADER = SHADER_UNIFORMS + SHADER_LIB + SHADER_MAIN;
RippleShader() {
super(SHADER, false);
}
- public void setShader(@NonNull Shader s) {
- setInputShader("in_shader", s);
+ public void setShader(Shader shader) {
+ if (shader != null) {
+ setInputShader("in_shader", shader);
+ }
+ setUniform("in_hasMask", shader == null ? 0 : 1);
}
public void setRadius(float radius) {
setUniform("in_maxRadius", radius);
}
+ /**
+ * Continuous offset used as noise phase.
+ */
+ public void setSecondsOffset(float t) {
+ setUniform("in_secondsOffset", t);
+ }
+
public void setOrigin(float x, float y) {
setUniform("in_origin", new float[] {x, y});
}
@@ -77,13 +172,16 @@
setUniform("in_progress", progress);
}
- public void setHasMask(boolean hasMask) {
- setUniform("in_hasMask", hasMask ? 1 : 0);
- }
-
+ /**
+ * Color of the circle that's under the sparkles. Sparkles will always be white.
+ */
public void setColor(@ColorInt int colorIn) {
Color color = Color.valueOf(colorIn);
this.setUniform("in_color", new float[] {color.red(),
color.green(), color.blue(), color.alpha()});
}
+
+ public void setResolution(float w, float h) {
+ setUniform("in_resolution", w, h);
+ }
}
diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
index ed789f0..5501569 100644
--- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java
+++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
@@ -20,7 +20,7 @@
import android.annotation.Nullable;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
-import android.security.usermanager.IKeystoreUserManager;
+import android.security.maintenance.IKeystoreMaintenance;
import android.system.keystore2.Domain;
import android.system.keystore2.ResponseCode;
import android.util.Log;
@@ -34,9 +34,9 @@
public static final int SYSTEM_ERROR = ResponseCode.SYSTEM_ERROR;
- private static IKeystoreUserManager getService() {
- return IKeystoreUserManager.Stub.asInterface(
- ServiceManager.checkService("android.security.usermanager"));
+ private static IKeystoreMaintenance getService() {
+ return IKeystoreMaintenance.Stub.asInterface(
+ ServiceManager.checkService("android.security.maintenance"));
}
/**
diff --git a/keystore/java/android/security/keystore/AttestationUtils.java b/keystore/java/android/security/keystore/AttestationUtils.java
index f48da74..cd77d9c 100644
--- a/keystore/java/android/security/keystore/AttestationUtils.java
+++ b/keystore/java/android/security/keystore/AttestationUtils.java
@@ -22,7 +22,6 @@
import android.annotation.SystemApi;
import android.content.Context;
import android.os.Build;
-import android.security.KeyStore;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterCertificateChain;
import android.security.keymaster.KeymasterDefs;
@@ -32,9 +31,14 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.SecureRandom;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.security.spec.ECGenParameterSpec;
import java.util.Collection;
+import java.util.Random;
import java.util.Set;
/**
@@ -223,24 +227,49 @@
@NonNull public static X509Certificate[] attestDeviceIds(Context context,
@NonNull int[] idTypes, @NonNull byte[] attestationChallenge) throws
DeviceIdAttestationException {
- final KeymasterArguments attestArgs = prepareAttestationArgumentsForDeviceId(
- context, idTypes, attestationChallenge);
+ String keystoreAlias = generateRandomAlias();
+ KeyGenParameterSpec.Builder builder =
+ new KeyGenParameterSpec.Builder(keystoreAlias, KeyProperties.PURPOSE_SIGN)
+ .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
+ .setDigests(KeyProperties.DIGEST_SHA256)
+ .setAttestationChallenge(attestationChallenge);
- // Perform attestation.
- final KeymasterCertificateChain outChain = new KeymasterCertificateChain();
- final int errorCode = KeyStore.getInstance().attestDeviceIds(attestArgs, outChain);
- if (errorCode != KeyStore.NO_ERROR) {
- throw new DeviceIdAttestationException("Unable to perform attestation",
- KeyStore.getKeyStoreException(errorCode));
+ if (idTypes != null) {
+ builder.setAttestationIds(idTypes);
+ builder.setDevicePropertiesAttestationIncluded(true);
}
try {
- return parseCertificateChain(outChain);
- } catch (KeyAttestationException e) {
- throw new DeviceIdAttestationException(e.getMessage(), e);
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
+ KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
+ keyPairGenerator.initialize(builder.build());
+ keyPairGenerator.generateKeyPair();
+
+ KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ keyStore.load(null);
+
+ X509Certificate[] certificateChain =
+ (X509Certificate[]) keyStore.getCertificateChain(keystoreAlias);
+
+ keyStore.deleteEntry(keystoreAlias);
+
+ return certificateChain;
+ } catch (Exception e) {
+ throw new DeviceIdAttestationException("Unable to perform attestation", e);
}
}
+ private static String generateRandomAlias() {
+ Random random = new SecureRandom();
+ StringBuilder builder = new StringBuilder();
+ // Pick random uppercase letters, A-Z. 20 of them gives us ~94 bits of entropy, which
+ // should prevent any conflicts with app-selected aliases, even for very unlucky users.
+ for (int i = 0; i < 20; ++i) {
+ builder.append(random.nextInt(26) + 'A');
+ }
+ return builder.toString();
+ }
+
/**
* Returns true if the attestation chain provided is a valid key attestation chain.
* @hide
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 72735a7..5cb2c3b 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -467,8 +467,8 @@
*
* @return The numeric namespace as configured in the keystore2_key_contexts files of Android's
* SEPolicy.
- * TODO b/171806779 link to public Keystore 2.0 documentation.
- * See bug for more details for now.
+ * See <a href="https://source.android.com/security/keystore#access-control">
+ * Keystore 2.0 access control</a>
* @hide
*/
@SystemApi
@@ -1042,9 +1042,9 @@
* keys between system and vendor components, e.g., WIFI settings and WPA supplicant.
*
* @param namespace Numeric SELinux namespace as configured in keystore2_key_contexts
- * of Android's SEPolicy.
- * TODO b/171806779 link to public Keystore 2.0 documentation.
- * See bug for more details for now.
+ * of Android's SEPolicy.
+ * See <a href="https://source.android.com/security/keystore#access-control">
+ * Keystore 2.0 access control</a>
* @return this Builder object.
*
* @hide
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
index d36695b..fa852e3 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
@@ -340,11 +340,11 @@
* @param keyStore The keystore2 backend.
* @param alias The alias of the key in the Keystore database.
* @param namespace The a Keystore namespace. This is used by system api only to request
- * Android system specific keystore namespace, which can be configured
- * in the device's SEPolicy. Third party apps and most system components
- * set this parameter to -1 to indicate their application specific namespace.
- * TODO b/171806779 link to public Keystore 2.0 documentation.
- * See bug for more details for now.
+ * Android system specific keystore namespace, which can be configured
+ * in the device's SEPolicy. Third party apps and most system components
+ * set this parameter to -1 to indicate their application specific namespace.
+ * See <a href="https://source.android.com/security/keystore#access-control">
+ * Keystore 2.0 access control</a>
* @hide
**/
@NonNull
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java
index 7ce9014..57a9dd2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java
@@ -143,14 +143,14 @@
@ImeAnimationFlags
public int onImeStartPositioning(int displayId, int hiddenTop, int shownTop,
boolean imeShouldShow, boolean imeIsFloating, SurfaceControl.Transaction t) {
- mHiddenTop = hiddenTop;
- mShownTop = shownTop;
- mTargetShown = imeShouldShow;
if (!isDividerVisible()) {
return 0;
}
- final boolean splitIsVisible = !getView().isHidden();
+ mHiddenTop = hiddenTop;
+ mShownTop = shownTop;
+ mTargetShown = imeShouldShow;
mSecondaryHasFocus = getSecondaryHasFocus(displayId);
+ final boolean splitIsVisible = !getView().isHidden();
final boolean targetAdjusted = splitIsVisible && imeShouldShow && mSecondaryHasFocus
&& !imeIsFloating && !getLayout().mDisplayLayout.isLandscape()
&& !mSplits.mSplitScreenController.isMinimized();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index 725f87d..580861c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -121,6 +121,19 @@
}
};
+ private final float[] mTmpValues = new float[9];
+ private final Runnable mUpdateEmbeddedMatrix = () -> {
+ if (mPipMenuView == null || mPipMenuView.getViewRootImpl() == null) {
+ return;
+ }
+ mMoveTransform.getValues(mTmpValues);
+ try {
+ mPipMenuView.getViewRootImpl().getAccessibilityEmbeddedConnection()
+ .setScreenMatrix(mTmpValues);
+ } catch (RemoteException e) {
+ }
+ };
+
public PhonePipMenuController(Context context, PipMediaController mediaController,
SystemWindows systemWindows, ShellExecutor mainExecutor,
Handler mainHandler) {
@@ -306,6 +319,11 @@
} else {
mApplier.scheduleApply(params);
}
+
+ if (mPipMenuView.getViewRootImpl() != null) {
+ mPipMenuView.getHandler().removeCallbacks(mUpdateEmbeddedMatrix);
+ mPipMenuView.getHandler().post(mUpdateEmbeddedMatrix);
+ }
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
index 0d64407..8ab405b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -32,7 +32,6 @@
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
-import android.annotation.Nullable;
import android.app.PendingIntent.CanceledException;
import android.app.RemoteAction;
import android.content.ComponentName;
@@ -52,10 +51,8 @@
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
-import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewRootImpl;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
@@ -198,6 +195,11 @@
}
@Override
+ public boolean shouldDelayChildPressedState() {
+ return true;
+ }
+
+ @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (!mAllowTouches) {
return false;
@@ -287,18 +289,6 @@
}
}
- @Nullable SurfaceControl getWindowSurfaceControl() {
- final ViewRootImpl root = getViewRootImpl();
- if (root == null) {
- return null;
- }
- final SurfaceControl out = root.getSurfaceControl();
- if (out != null && out.isValid()) {
- return out;
- }
- return null;
- }
-
/**
* Different from {@link #hideMenu()}, this function does not try to finish this menu activity
* and instead, it fades out the controls by setting the alpha to 0 directly without menu
@@ -398,8 +388,20 @@
return true;
});
+ // Update the expand button only if it should show with the menu
+ expandContainer.setVisibility(mMenuState == MENU_STATE_FULL
+ ? View.VISIBLE
+ : View.INVISIBLE);
+
+ FrameLayout.LayoutParams expandedLp =
+ (FrameLayout.LayoutParams) expandContainer.getLayoutParams();
if (mActions.isEmpty() || mMenuState == MENU_STATE_CLOSE || mMenuState == MENU_STATE_NONE) {
actionsContainer.setVisibility(View.INVISIBLE);
+
+ // Update the expand container margin to adjust the center of the expand button to
+ // account for the existence of the action container
+ expandedLp.topMargin = 0;
+ expandedLp.bottomMargin = 0;
} else {
actionsContainer.setVisibility(View.VISIBLE);
if (mActionsGroup != null) {
@@ -455,14 +457,12 @@
// Update the expand container margin to adjust the center of the expand button to
// account for the existence of the action container
- FrameLayout.LayoutParams expandedLp =
- (FrameLayout.LayoutParams) expandContainer.getLayoutParams();
expandedLp.topMargin = getResources().getDimensionPixelSize(
R.dimen.pip_action_padding);
expandedLp.bottomMargin = getResources().getDimensionPixelSize(
R.dimen.pip_expand_container_edge_margin);
- expandContainer.requestLayout();
}
+ expandContainer.requestLayout();
}
private void notifyMenuStateChange(int menuState, boolean resize, Runnable callback) {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
index ecc066b..5a96a7c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
@@ -17,7 +17,6 @@
package com.android.wm.shell.flicker.helpers
import android.app.Instrumentation
-import android.graphics.Point
import android.media.session.MediaController
import android.media.session.MediaSessionManager
import android.os.SystemClock
@@ -135,11 +134,8 @@
expandPipWindow(wmHelper)
val exitPipObject = uiDevice.findObject(By.res(SYSTEMUI_PACKAGE, "dismiss"))
requireNotNull(exitPipObject) { "PIP window dismiss button not found" }
- val coordinatesInWindow = exitPipObject.visibleBounds
- val windowOffset = wmHelper.getWindowRegion(component).bounds
- val newCoordinates = Point(windowOffset.left + coordinatesInWindow.centerX(),
- windowOffset.top + coordinatesInWindow.centerY())
- uiDevice.click(newCoordinates.x, newCoordinates.y)
+ val dismissButtonBounds = exitPipObject.visibleBounds
+ uiDevice.click(dismissButtonBounds.centerX(), dismissButtonBounds.centerY())
}
// Wait for animation to complete.
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index aba0f1b..63b831d 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -97,8 +97,8 @@
"libincfs",
"libutils",
"libz",
- "libziparchive",
],
+ static_libs: ["libziparchive_for_incfs"],
static: {
enabled: false,
},
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index d663c52..607ef72 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -388,11 +388,10 @@
"liblog",
"libminikin",
"libz",
- "libziparchive",
"libjpeg",
],
- static_libs: ["libnativehelper_lazy"],
+ static_libs: ["libnativehelper_lazy", "libziparchive_for_incfs"],
target: {
android: {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 9793300..800c580 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -576,6 +576,7 @@
if (requireSwap) {
if (mExpectSurfaceStats) {
+ reportMetricsWithPresentTime();
std::lock_guard lock(mLast4FrameInfosMutex);
std::pair<FrameInfo*, int64_t>& next = mLast4FrameInfos.next();
next.first = mCurrentFrameInfo;
@@ -656,8 +657,6 @@
}
}
- instance->reportMetricsWithPresentTime();
-
if (frameInfo != nullptr) {
if (gpuCompleteTime == -1) {
gpuCompleteTime = frameInfo->get(FrameInfoIndex::SwapBuffersCompleted);
diff --git a/libs/hwui/utils/PaintUtils.h b/libs/hwui/utils/PaintUtils.h
index 09c6a4f..a8f2d9a 100644
--- a/libs/hwui/utils/PaintUtils.h
+++ b/libs/hwui/utils/PaintUtils.h
@@ -52,18 +52,10 @@
return mode == SkBlendMode::kSrcOver || mode == SkBlendMode::kSrc;
}
- static bool isBlendedShader(const SkShader* shader) {
- if (shader == nullptr) {
- return false;
- }
- return !shader->isOpaque();
- }
+ static bool isBlendedShader(const SkShader* shader) { return shader && !shader->isOpaque(); }
static bool isBlendedColorFilter(const SkColorFilter* filter) {
- if (filter == nullptr) {
- return false;
- }
- return (filter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag) == 0;
+ return filter && !filter->isAlphaUnchanged();
}
static inline SkBlendMode getBlendModeDirect(const SkPaint* paint) {
diff --git a/media/Android.bp b/media/Android.bp
index 9268b22..a66236e 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -27,6 +27,9 @@
aidl_interface {
name: "media_permission-aidl",
unstable: true,
+ host_supported: true,
+ vendor_available: true,
+ double_loadable: true,
local_include_dir: "aidl",
srcs: [
"aidl/android/media/permission/Identity.aidl",
diff --git a/media/aidl/android/media/permission/Identity.aidl b/media/aidl/android/media/permission/Identity.aidl
index 361497d..3638904 100644
--- a/media/aidl/android/media/permission/Identity.aidl
+++ b/media/aidl/android/media/permission/Identity.aidl
@@ -22,11 +22,11 @@
*/
parcelable Identity {
/** Linux user ID. */
- int uid;
+ int uid = -1;
/** Linux process ID. */
- int pid;
+ int pid = -1;
/** Package name. If null, the first package owned by the given uid will be assumed. */
- @nullable String packageName;
+ @nullable @utf8InCpp String packageName;
/** Attribution tag. Mostly used for diagnostic purposes. */
- @nullable String attributionTag;
+ @nullable @utf8InCpp String attributionTag;
}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 1cef0922..e8e2631 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -6729,7 +6729,7 @@
*/
public Map<Integer, Boolean> getSurroundFormats() {
Map<Integer, Boolean> surroundFormats = new HashMap<>();
- int status = AudioSystem.getSurroundFormats(surroundFormats, false);
+ int status = AudioSystem.getSurroundFormats(surroundFormats);
if (status != AudioManager.SUCCESS) {
// fail and bail!
Log.e(TAG, "getSurroundFormats failed:" + status);
@@ -6762,20 +6762,17 @@
/**
* @hide
* Returns all surround formats that are reported by the connected HDMI device.
- * The keys are not affected by calling setSurroundFormatEnabled(), and the values
- * are not affected by calling setSurroundFormatEnabled() when in AUTO mode.
- * This information can used to show the AUTO setting for SurroundSound.
+ * The return values are not affected by calling setSurroundFormatEnabled.
*
- * @return a map where the key is a surround format and
- * the value indicates the surround format is enabled or not
+ * @return a list of surround formats
*/
- public Map<Integer, Boolean> getReportedSurroundFormats() {
- Map<Integer, Boolean> reportedSurroundFormats = new HashMap<>();
- int status = AudioSystem.getSurroundFormats(reportedSurroundFormats, true);
+ public ArrayList<Integer> getReportedSurroundFormats() {
+ ArrayList<Integer> reportedSurroundFormats = new ArrayList<>();
+ int status = AudioSystem.getReportedSurroundFormats(reportedSurroundFormats);
if (status != AudioManager.SUCCESS) {
// fail and bail!
Log.e(TAG, "getReportedSurroundFormats failed:" + status);
- return new HashMap<Integer, Boolean>(); // Always return a map.
+ return new ArrayList<Integer>(); // Always return a list.
}
return reportedSurroundFormats;
}
@@ -7087,26 +7084,22 @@
* <pre class="prettyprint">
* // Get an AudioManager instance
* AudioManager audioManager = Context.getSystemService(AudioManager.class);
- * try {
- * AudioDeviceInfo speakerDevice = null;
- * List<AudioDeviceInfo> devices = audioManager.getAvailableCommunicationDevices();
- * for (AudioDeviceInfo device : devices) {
- * if (device.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
- * speakerDevice = device;
- * break;
- * }
+ * AudioDeviceInfo speakerDevice = null;
+ * List<AudioDeviceInfo> devices = audioManager.getAvailableCommunicationDevices();
+ * for (AudioDeviceInfo device : devices) {
+ * if (device.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
+ * speakerDevice = device;
+ * break;
* }
- * if (speakerDevice != null) {
- * // Turn speakerphone ON.
- * boolean result = audioManager.setCommunicationDevice(speakerDevice);
- * if (!result) {
- * // Handle error.
- * }
- * // Turn speakerphone OFF.
- * audioManager.clearCommunicationDevice();
+ * }
+ * if (speakerDevice != null) {
+ * // Turn speakerphone ON.
+ * boolean result = audioManager.setCommunicationDevice(speakerDevice);
+ * if (!result) {
+ * // Handle error.
* }
- * } catch (IllegalArgumentException e) {
- * // Handle exception.
+ * // Turn speakerphone OFF.
+ * audioManager.clearCommunicationDevice();
* }
* </pre>
* @param device the requested audio device.
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index bf04b66..d7112d6 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -16,6 +16,8 @@
package android.media;
+import static android.media.permission.PermissionUtil.myIdentity;
+
import android.annotation.CallbackExecutor;
import android.annotation.FloatRange;
import android.annotation.IntDef;
@@ -26,9 +28,11 @@
import android.annotation.TestApi;
import android.app.ActivityThread;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
import android.media.MediaRecorder.Source;
import android.media.audiopolicy.AudioMix;
import android.media.audiopolicy.AudioPolicy;
+import android.media.permission.Identity;
import android.media.projection.MediaProjection;
import android.os.Binder;
import android.os.Build;
@@ -54,6 +58,7 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -352,6 +357,32 @@
@RequiresPermission(android.Manifest.permission.RECORD_AUDIO)
public AudioRecord(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
int sessionId) throws IllegalArgumentException {
+ this(attributes, format, bufferSizeInBytes, sessionId, ActivityThread.currentApplication());
+ }
+
+ /**
+ * @hide
+ * Class constructor with {@link AudioAttributes} and {@link AudioFormat}.
+ * @param attributes a non-null {@link AudioAttributes} instance. Use
+ * {@link AudioAttributes.Builder#setCapturePreset(int)} for configuring the audio
+ * source for this instance.
+ * @param format a non-null {@link AudioFormat} instance describing the format of the data
+ * that will be recorded through this AudioRecord. See {@link AudioFormat.Builder} for
+ * configuring the audio format parameters such as encoding, channel mask and sample rate.
+ * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is written
+ * to during the recording. New audio data can be read from this buffer in smaller chunks
+ * than this size. See {@link #getMinBufferSize(int, int, int)} to determine the minimum
+ * required buffer size for the successful creation of an AudioRecord instance. Using values
+ * smaller than getMinBufferSize() will result in an initialization failure.
+ * @param sessionId ID of audio session the AudioRecord must be attached to, or
+ * {@link AudioManager#AUDIO_SESSION_ID_GENERATE} if the session isn't known at construction
+ * time. See also {@link AudioManager#generateAudioSessionId()} to obtain a session ID before
+ * construction.
+ * @param context An optional context to pull an attribution tag from.
+ * @throws IllegalArgumentException
+ */
+ private AudioRecord(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
+ int sessionId, @Nullable Context context) throws IllegalArgumentException {
mRecordingState = RECORDSTATE_STOPPED;
if (attributes == null) {
@@ -414,15 +445,21 @@
audioBuffSizeCheck(bufferSizeInBytes);
+ Identity identity = myIdentity(context);
+ if (identity.packageName == null) {
+ // Command line utility
+ identity.packageName = "uid:" + Binder.getCallingUid();
+ }
+
int[] sampleRate = new int[] {mSampleRate};
int[] session = new int[1];
session[0] = sessionId;
//TODO: update native initialization when information about hardware init failure
// due to capture device already open is available.
- int initResult = native_setup( new WeakReference<AudioRecord>(this),
+ int initResult = native_setup(new WeakReference<AudioRecord>(this),
mAudioAttributes, sampleRate, mChannelMask, mChannelIndexMask,
mAudioFormat, mNativeBufferSizeInBytes,
- session, getCurrentOpPackageName(), 0 /*nativeRecordInJavaObj*/);
+ session, identity, 0 /*nativeRecordInJavaObj*/);
if (initResult != SUCCESS) {
loge("Error code "+initResult+" when initializing native AudioRecord object.");
return; // with mState == STATE_UNINITIALIZED
@@ -434,15 +471,6 @@
mState = STATE_INITIALIZED;
}
- private String getCurrentOpPackageName() {
- String opPackageName = ActivityThread.currentOpPackageName();
- if (opPackageName != null) {
- return opPackageName;
- }
- // Command line utility
- return "uid:" + Binder.getCallingUid();
- }
-
/**
* A constructor which explicitly connects a Native (C++) AudioRecord. For use by
* the AudioRecordRoutingProxy subclass.
@@ -492,7 +520,7 @@
0 /*mAudioFormat*/,
0 /*mNativeBufferSizeInBytes*/,
session,
- ActivityThread.currentOpPackageName(),
+ myIdentity(null),
nativeRecordInJavaObj);
if (initResult != SUCCESS) {
loge("Error code "+initResult+" when initializing native AudioRecord object.");
@@ -548,6 +576,7 @@
private AudioPlaybackCaptureConfiguration mAudioPlaybackCaptureConfiguration;
private AudioAttributes mAttributes;
private AudioFormat mFormat;
+ private Context mContext;
private int mBufferSizeInBytes;
private int mSessionId = AudioManager.AUDIO_SESSION_ID_GENERATE;
private int mPrivacySensitive = PRIVACY_SENSITIVE_DEFAULT;
@@ -583,6 +612,18 @@
}
/**
+ * Sets the context the record belongs to.
+ * @param context a non-null {@link Context} instance
+ * @return the same Builder instance.
+ */
+ public @NonNull Builder setContext(@NonNull Context context) {
+ Objects.requireNonNull(context);
+ // keep reference, we only copy the data when building
+ mContext = context;
+ return this;
+ }
+
+ /**
* @hide
* To be only used by system components. Allows specifying non-public capture presets
* @param attributes a non-null {@link AudioAttributes} instance that contains the capture
@@ -793,7 +834,7 @@
* mFormat.getBytesPerSample(mFormat.getEncoding());
}
final AudioRecord record = new AudioRecord(
- mAttributes, mFormat, mBufferSizeInBytes, mSessionId);
+ mAttributes, mFormat, mBufferSizeInBytes, mSessionId, mContext);
if (record.getState() == STATE_UNINITIALIZED) {
// release is not necessary
throw new UnsupportedOperationException("Cannot create AudioRecord");
@@ -2035,15 +2076,32 @@
// Native methods called from the Java side
//--------------------
- @UnsupportedAppUsage
- private native final int native_setup(Object audiorecord_this,
+ /**
+ * @deprecated Use native_setup that takes an Identity object
+ * @return
+ */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R,
+ publicAlternatives = "{@code AudioRecord.Builder}")
+ @Deprecated
+ private int native_setup(Object audiorecordThis,
Object /*AudioAttributes*/ attributes,
int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
int buffSizeInBytes, int[] sessionId, String opPackageName,
- long nativeRecordInJavaObj);
+ long nativeRecordInJavaObj) {
+ Identity identity = myIdentity(null);
+ identity.packageName = opPackageName;
+
+ return native_setup(audiorecordThis, attributes, sampleRate, channelMask, channelIndexMask,
+ audioFormat, buffSizeInBytes, sessionId, identity, nativeRecordInJavaObj);
+ }
+
+ private native int native_setup(Object audiorecordThis,
+ Object /*AudioAttributes*/ attributes,
+ int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
+ int buffSizeInBytes, int[] sessionId, Identity identity, long nativeRecordInJavaObj);
// TODO remove: implementation calls directly into implementation of native_release()
- private native final void native_finalize();
+ private native void native_finalize();
/**
* @hide
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index f1f6cb1..8134d6f 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -1699,8 +1699,10 @@
public static native int getMicrophones(ArrayList<MicrophoneInfo> microphonesInfo);
/** @hide */
- public static native int getSurroundFormats(Map<Integer, Boolean> surroundFormats,
- boolean reported);
+ public static native int getSurroundFormats(Map<Integer, Boolean> surroundFormats);
+
+ /** @hide */
+ public static native int getReportedSurroundFormats(ArrayList<Integer> surroundFormats);
/**
* @hide
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 9176dae..3de78bb 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -18,6 +18,7 @@
import static android.Manifest.permission.BIND_IMS_SERVICE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.media.permission.PermissionUtil.myIdentity;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
@@ -34,6 +35,7 @@
import android.graphics.SurfaceTexture;
import android.media.SubtitleController.Anchor;
import android.media.SubtitleTrack.RenderingWidget;
+import android.media.permission.Identity;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -53,6 +55,7 @@
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
@@ -684,11 +687,14 @@
mTimeProvider = new TimeProvider(this);
mOpenSubtitleSources = new Vector<InputStream>();
+ Identity identity = myIdentity(null);
+ // set the package name to empty if it was null
+ identity.packageName = TextUtils.emptyIfNull(identity.packageName);
+
/* Native setup requires a weak reference to our object.
* It's easier to create it here than in C++.
*/
- native_setup(new WeakReference<MediaPlayer>(this),
- getCurrentOpPackageName());
+ native_setup(new WeakReference<MediaPlayer>(this), identity);
baseRegisterPlayer(sessionId);
}
@@ -2471,7 +2477,7 @@
private native final int native_setMetadataFilter(Parcel request);
private static native final void native_init();
- private native void native_setup(Object mediaplayerThis, @NonNull String opPackageName);
+ private native void native_setup(Object mediaplayerThis, @NonNull Identity identity);
private native final void native_finalize();
/**
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 49a4cc6..87e1e5b 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -16,6 +16,8 @@
package android.media;
+import static android.media.permission.PermissionUtil.myIdentity;
+
import android.annotation.CallbackExecutor;
import android.annotation.FloatRange;
import android.annotation.IntDef;
@@ -25,7 +27,9 @@
import android.annotation.SystemApi;
import android.app.ActivityThread;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
import android.hardware.Camera;
+import android.media.permission.Identity;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -48,6 +52,7 @@
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -127,9 +132,21 @@
/**
* Default constructor.
+ *
+ * @deprecated Use {@link #MediaRecorder(Context)} instead
*/
+ @Deprecated
public MediaRecorder() {
+ this(ActivityThread.currentApplication());
+ }
+ /**
+ * Default constructor.
+ *
+ * @param context Context the recorder belongs to
+ */
+ public MediaRecorder(@NonNull Context context) {
+ Objects.requireNonNull(context);
Looper looper;
if ((looper = Looper.myLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
@@ -140,12 +157,11 @@
}
mChannelCount = 1;
- String packageName = ActivityThread.currentPackageName();
/* Native setup requires a weak reference to our object.
* It's easier to create it here than in C++.
*/
- native_setup(new WeakReference<MediaRecorder>(this), packageName,
- ActivityThread.currentOpPackageName());
+ native_setup(new WeakReference<MediaRecorder>(this),
+ ActivityThread.currentPackageName(), myIdentity(context));
}
/**
@@ -1740,12 +1756,22 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private static native final void native_init();
- @UnsupportedAppUsage
- private native final void native_setup(Object mediarecorder_this,
- String clientName, String opPackageName) throws IllegalStateException;
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R,
+ publicAlternatives = "{@link MediaRecorder}")
+ private void native_setup(Object mediarecorderThis,
+ String clientName, String opPackageName) throws IllegalStateException {
+ Identity identity = myIdentity(null);
+ identity.packageName = opPackageName;
+
+ native_setup(mediarecorderThis, clientName, identity);
+ }
+
+ private native void native_setup(Object mediarecorderThis,
+ String clientName, Identity identity)
+ throws IllegalStateException;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- private native final void native_finalize();
+ private native void native_finalize();
@UnsupportedAppUsage
private native void setParameter(String nameValuePair);
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index dc9c58e..b4db305 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -60,6 +60,7 @@
public final class MediaRouter2 {
private static final String TAG = "MR2";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final Object sSystemRouterLock = new Object();
private static final Object sRouterLock = new Object();
// The maximum time for the old routing controller available after transfer.
@@ -67,8 +68,8 @@
// The manager request ID representing that no manager is involved.
private static final long MANAGER_REQUEST_ID_NONE = MediaRoute2ProviderService.REQUEST_ID_NONE;
- @GuardedBy("sRouterLock")
- private static Map<String, MediaRouter2> sMediaRouter2Map = new ArrayMap<>();
+ @GuardedBy("sSystemRouterLock")
+ private static Map<String, MediaRouter2> sSystemMediaRouter2Map = new ArrayMap<>();
private static MediaRouter2Manager sManager;
@GuardedBy("sRouterLock")
@@ -76,6 +77,7 @@
private final Context mContext;
private final IMediaRouterService mMediaRouterService;
+ private final Object mLock = new Object();
private final CopyOnWriteArrayList<RouteCallbackRecord> mRouteCallbackRecords =
new CopyOnWriteArrayList<>();
@@ -88,27 +90,29 @@
new CopyOnWriteArrayList<>();
private final String mClientPackageName;
+ private final ManagerCallback mManagerCallback;
+
private final String mPackageName;
- @GuardedBy("sRouterLock")
+ @GuardedBy("mLock")
final Map<String, MediaRoute2Info> mRoutes = new ArrayMap<>();
final RoutingController mSystemController;
- @GuardedBy("sRouterLock")
+ @GuardedBy("mLock")
private RouteDiscoveryPreference mDiscoveryPreference = RouteDiscoveryPreference.EMPTY;
// TODO: Make MediaRouter2 is always connected to the MediaRouterService.
- @GuardedBy("sRouterLock")
+ @GuardedBy("mLock")
MediaRouter2Stub mStub;
- @GuardedBy("sRouterLock")
+ @GuardedBy("mLock")
private final Map<String, RoutingController> mNonSystemRoutingControllers = new ArrayMap<>();
private final AtomicInteger mNextRequestId = new AtomicInteger(1);
final Handler mHandler;
- @GuardedBy("sRouterLock")
+ @GuardedBy("mLock")
private boolean mShouldUpdateRoutes = true;
private volatile List<MediaRoute2Info> mFilteredRoutes = Collections.emptyList();
private volatile OnGetControllerHintsListener mOnGetControllerHintsListener;
@@ -130,6 +134,11 @@
/**
* Gets an instance of the media router which controls the app's media routing.
* Returns {@code null} if the given package name is invalid.
+ * <p>
+ * Note: For media routers created with this method, the discovery preference passed to
+ * {@link #registerRouteCallback} will have no effect. The callback will be called accordingly
+ * with the client app's discovery preference. Therefore, it is recommended to pass
+ * {@link RouteDiscoveryPreference#EMPTY} there.
*
* @param clientPackageName the package name of the app to control
* @hide
@@ -149,15 +158,17 @@
return null;
}
- synchronized (sRouterLock) {
- MediaRouter2 instance = sMediaRouter2Map.get(clientPackageName);
+ synchronized (sSystemRouterLock) {
+ MediaRouter2 instance = sSystemMediaRouter2Map.get(clientPackageName);
if (instance == null) {
// TODO: Add permission check here using MODIFY_AUDIO_ROUTING.
if (sManager == null) {
sManager = MediaRouter2Manager.getInstance(context.getApplicationContext());
}
instance = new MediaRouter2(context, clientPackageName);
- sMediaRouter2Map.put(clientPackageName, instance);
+ sSystemMediaRouter2Map.put(clientPackageName, instance);
+ // TODO: Remove router instance once it is not needed.
+ instance.registerManagerCallback();
}
return instance;
}
@@ -192,11 +203,14 @@
}
mSystemController = new SystemRoutingController(currentSystemSessionInfo);
+ // Only used by system MediaRouter2.
mClientPackageName = null;
+ mManagerCallback = null;
}
private MediaRouter2(Context context, String clientPackageName) {
mClientPackageName = clientPackageName;
+ mManagerCallback = new ManagerCallback();
mContext = context;
mMediaRouterService = null;
mPackageName = null;
@@ -220,8 +234,8 @@
}
/**
- * Gets the target package name of the app which this media router controls.
- * This is only non-null when the router instance is created with the target package name.
+ * Gets the client package name of the app which this media router controls.
+ * This is only non-null when the router instance is created with the client package name.
*
* @see #getInstance(Context, String)
* @hide
@@ -245,6 +259,9 @@
Objects.requireNonNull(executor, "executor must not be null");
Objects.requireNonNull(routeCallback, "callback must not be null");
Objects.requireNonNull(preference, "preference must not be null");
+ if (isSystemRouter()) {
+ preference = RouteDiscoveryPreference.EMPTY;
+ }
RouteCallbackRecord record = new RouteCallbackRecord(executor, routeCallback, preference);
@@ -253,7 +270,11 @@
// is happening but it's okay because either this or the other registration should be done.
mRouteCallbackRecords.addIfAbsent(record);
- synchronized (sRouterLock) {
+ if (isSystemRouter()) {
+ return;
+ }
+
+ synchronized (mLock) {
if (mStub == null) {
MediaRouter2Stub stub = new MediaRouter2Stub();
try {
@@ -289,7 +310,11 @@
return;
}
- synchronized (sRouterLock) {
+ if (isSystemRouter()) {
+ return;
+ }
+
+ synchronized (mLock) {
if (mStub == null) {
return;
}
@@ -326,22 +351,37 @@
}
/**
+ * Gets the list of all discovered routes.
+ * This list includes the routes that are not related to the client app.
+ * <p>
+ * This will return an empty list for non-system media routers.
+ *
+ * @hide
+ */
+ //@SystemApi
+ public List<MediaRoute2Info> getAllRoutes() {
+ if (isSystemRouter()) {
+ return sManager.getAllRoutes();
+ }
+ return Collections.emptyList();
+ }
+
+ /**
* Gets the unmodifiable list of {@link MediaRoute2Info routes} currently
* known to the media router.
* <p>
* Please note that the list can be changed before callbacks are invoked.
* </p>
- *
* @return the list of routes that contains at least one of the route features in discovery
* preferences registered by the application
*/
@NonNull
public List<MediaRoute2Info> getRoutes() {
- if (mClientPackageName != null) {
+ if (isSystemRouter()) {
return sManager.getAvailableRoutes(mClientPackageName);
}
- synchronized (sRouterLock) {
+ synchronized (mLock) {
if (mShouldUpdateRoutes) {
mShouldUpdateRoutes = false;
@@ -449,7 +489,7 @@
* @see TransferCallback#onTransferFailure
*/
public void transferTo(@NonNull MediaRoute2Info route) {
- if (mClientPackageName != null) {
+ if (isSystemRouter()) {
sManager.selectRoute(mClientPackageName, route);
return;
}
@@ -464,7 +504,7 @@
* controls the media routing, this method is a no-op.
*/
public void stop() {
- if (mClientPackageName != null) {
+ if (isSystemRouter()) {
List<RoutingSessionInfo> sessionInfos = sManager.getRoutingSessions(mClientPackageName);
RoutingSessionInfo sessionToRelease = sessionInfos.get(sessionInfos.size() - 1);
sManager.releaseSession(sessionToRelease);
@@ -481,7 +521,7 @@
*/
//@SystemApi
public void transfer(@NonNull RoutingController controller, @NonNull MediaRoute2Info route) {
- if (mClientPackageName != null) {
+ if (isSystemRouter()) {
sManager.transfer(controller.getRoutingSessionInfo(), route);
return;
}
@@ -490,7 +530,7 @@
Objects.requireNonNull(route, "route must not be null");
boolean routeFound;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
// TODO: Check thread-safety
routeFound = mRoutes.containsKey(route.getId());
}
@@ -526,7 +566,7 @@
}
MediaRouter2Stub stub;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
stub = mStub;
}
if (stub != null) {
@@ -576,7 +616,7 @@
public List<RoutingController> getControllers() {
// TODO: Do not create the controller instances every time,
// Instead, update the list using the sessions' ID and session related callbacks.
- if (mClientPackageName != null) {
+ if (isSystemRouter()) {
return sManager.getRoutingSessions(mClientPackageName).stream()
.map(info -> new RoutingController(info))
.collect(Collectors.toList());
@@ -584,7 +624,7 @@
List<RoutingController> result = new ArrayList<>();
result.add(0, mSystemController);
- synchronized (sRouterLock) {
+ synchronized (mLock) {
result.addAll(mNonSystemRoutingControllers.values());
}
return result;
@@ -603,7 +643,7 @@
Objects.requireNonNull(route, "route must not be null");
MediaRouter2Stub stub;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
stub = mStub;
}
if (stub != null) {
@@ -627,7 +667,7 @@
List<MediaRoute2Info> removedRoutes = new ArrayList<>();
List<MediaRoute2Info> changedRoutes = new ArrayList<>();
- synchronized (sRouterLock) {
+ synchronized (mLock) {
List<String> currentRoutesIds = currentRoutes.stream().map(MediaRoute2Info::getId)
.collect(Collectors.toList());
@@ -685,7 +725,7 @@
void addRoutesOnHandler(List<MediaRoute2Info> routes) {
List<MediaRoute2Info> addedRoutes = new ArrayList<>();
- synchronized (sRouterLock) {
+ synchronized (mLock) {
for (MediaRoute2Info route : routes) {
mRoutes.put(route.getId(), route);
if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
@@ -701,7 +741,7 @@
void removeRoutesOnHandler(List<MediaRoute2Info> routes) {
List<MediaRoute2Info> removedRoutes = new ArrayList<>();
- synchronized (sRouterLock) {
+ synchronized (mLock) {
for (MediaRoute2Info route : routes) {
mRoutes.remove(route.getId());
if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
@@ -717,7 +757,7 @@
void changeRoutesOnHandler(List<MediaRoute2Info> routes) {
List<MediaRoute2Info> changedRoutes = new ArrayList<>();
- synchronized (sRouterLock) {
+ synchronized (mLock) {
for (MediaRoute2Info route : routes) {
mRoutes.put(route.getId(), route);
if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
@@ -789,7 +829,7 @@
newController.setRoutingSessionInfo(sessionInfo);
} else {
newController = new RoutingController(sessionInfo);
- synchronized (sRouterLock) {
+ synchronized (mLock) {
mNonSystemRoutingControllers.put(newController.getId(), newController);
}
}
@@ -812,7 +852,7 @@
}
RoutingController matchingController;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
matchingController = mNonSystemRoutingControllers.get(sessionInfo.getId());
}
@@ -840,7 +880,7 @@
}
RoutingController matchingController;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
matchingController = mNonSystemRoutingControllers.get(sessionInfo.getId());
}
@@ -868,7 +908,7 @@
if (oldSession.isSystemSession()) {
controller = getSystemController();
} else {
- synchronized (sRouterLock) {
+ synchronized (mLock) {
controller = mNonSystemRoutingControllers.get(oldSession.getId());
}
}
@@ -878,6 +918,22 @@
requestCreateController(controller, route, managerRequestId);
}
+ /**
+ * Returns whether this router is created with {@link #getInstance(Context, String)}.
+ * This kind of router can control the target app's media routing.
+ */
+ private boolean isSystemRouter() {
+ return mClientPackageName != null;
+ }
+
+ /**
+ * Registers {@link MediaRouter2Manager.Callback} for getting events.
+ */
+ private void registerManagerCallback() {
+ // Using direct executor here, since MediaRouter2Manager also posts to the main handler.
+ sManager.registerCallback(Runnable::run, mManagerCallback);
+ }
+
private List<MediaRoute2Info> filterRoutes(List<MediaRoute2Info> routes,
RouteDiscoveryPreference discoveryRequest) {
return routes.stream()
@@ -1236,7 +1292,7 @@
}
MediaRouter2Stub stub;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
stub = mStub;
}
if (stub != null) {
@@ -1283,7 +1339,7 @@
}
MediaRouter2Stub stub;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
stub = mStub;
}
if (stub != null) {
@@ -1318,7 +1374,7 @@
}
MediaRouter2Stub stub;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
stub = mStub;
}
if (stub != null) {
@@ -1352,7 +1408,7 @@
return;
}
MediaRouter2Stub stub;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
stub = mStub;
}
if (stub != null) {
@@ -1386,7 +1442,7 @@
mState = CONTROLLER_STATE_RELEASING;
}
- synchronized (sRouterLock) {
+ synchronized (mLock) {
// It could happen if the controller is released by the another thread
// in between two locks
if (!mNonSystemRoutingControllers.remove(getId(), this)) {
@@ -1415,7 +1471,7 @@
mState = CONTROLLER_STATE_RELEASED;
}
- synchronized (sRouterLock) {
+ synchronized (mLock) {
mNonSystemRoutingControllers.remove(getId(), this);
if (shouldReleaseSession && mStub != null) {
@@ -1483,7 +1539,7 @@
}
private List<MediaRoute2Info> getRoutesWithIds(List<String> routeIds) {
- synchronized (sRouterLock) {
+ synchronized (mLock) {
return routeIds.stream().map(mRoutes::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
@@ -1665,4 +1721,79 @@
MediaRouter2.this, oldSession, route, managerRequestId));
}
}
+
+ class ManagerCallback implements MediaRouter2Manager.Callback {
+
+ @Override
+ public void onRoutesAdded(@NonNull List<MediaRoute2Info> routes) {
+ List<MediaRoute2Info> filteredRoutes =
+ sManager.filterRoutesForPackage(routes, mClientPackageName);
+ if (filteredRoutes.isEmpty()) {
+ return;
+ }
+ for (RouteCallbackRecord record: mRouteCallbackRecords) {
+ record.mExecutor.execute(
+ () -> record.mRouteCallback.onRoutesAdded(filteredRoutes));
+ }
+ }
+
+ @Override
+ public void onRoutesRemoved(@NonNull List<MediaRoute2Info> routes) {
+ List<MediaRoute2Info> filteredRoutes =
+ sManager.filterRoutesForPackage(routes, mClientPackageName);
+ if (filteredRoutes.isEmpty()) {
+ return;
+ }
+ for (RouteCallbackRecord record: mRouteCallbackRecords) {
+ record.mExecutor.execute(
+ () -> record.mRouteCallback.onRoutesRemoved(filteredRoutes));
+ }
+ }
+
+ @Override
+ public void onRoutesChanged(@NonNull List<MediaRoute2Info> routes) {
+ List<MediaRoute2Info> filteredRoutes =
+ sManager.filterRoutesForPackage(routes, mClientPackageName);
+ if (filteredRoutes.isEmpty()) {
+ return;
+ }
+ for (RouteCallbackRecord record: mRouteCallbackRecords) {
+ record.mExecutor.execute(
+ () -> record.mRouteCallback.onRoutesChanged(filteredRoutes));
+ }
+ }
+
+ @Override
+ public void onSessionUpdated(@NonNull RoutingSessionInfo session) {
+ // TODO: Call ControllerCallback.onControllerUpdated
+ }
+
+ @Override
+ public void onTransferred(@NonNull RoutingSessionInfo oldSession,
+ @Nullable RoutingSessionInfo newSession) {
+ // TODO: Call TransferCallback.onTransfer
+ }
+
+ @Override
+ public void onTransferFailed(@NonNull RoutingSessionInfo session,
+ @NonNull MediaRoute2Info route) {
+ // TODO: Call TransferCallback.onTransferFailure
+ }
+
+ @Override
+ public void onSessionReleased(@NonNull RoutingSessionInfo session) {
+ // TODO: Call TransferCallback.onStop()
+ }
+
+ @Override
+ public void onPreferredFeaturesChanged(@NonNull String packageName,
+ @NonNull List<String> preferredFeatures) {
+ // Does nothing.
+ }
+
+ @Override
+ public void onRequestFailed(int reason) {
+ // Does nothing.
+ }
+ }
}
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index 5e732f9..ca619d4 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -237,6 +237,36 @@
}
/**
+ * Returns a list of routes which are related to the given package name in the given route list.
+ */
+ @NonNull
+ public List<MediaRoute2Info> filterRoutesForPackage(@NonNull List<MediaRoute2Info> routes,
+ @NonNull String packageName) {
+ Objects.requireNonNull(routes, "routes must not be null");
+ Objects.requireNonNull(packageName, "packageName must not be null");
+
+ List<RoutingSessionInfo> sessions = getRoutingSessions(packageName);
+ RoutingSessionInfo sessionInfo = sessions.get(sessions.size() - 1);
+
+ List<MediaRoute2Info> result = new ArrayList<>();
+ List<String> preferredFeatures = mPreferredFeaturesMap.get(packageName);
+ if (preferredFeatures == null) {
+ preferredFeatures = Collections.emptyList();
+ }
+
+ synchronized (mRoutesLock) {
+ for (MediaRoute2Info route : routes) {
+ if (route.hasAnyFeatures(preferredFeatures)
+ || sessionInfo.getSelectedRoutes().contains(route.getId())
+ || sessionInfo.getTransferableRoutes().contains(route.getId())) {
+ result.add(route);
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
* Gets the system routing session associated with no specific application.
*/
@NonNull
diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java
index 67a4a4b..fd3c405 100644
--- a/media/java/android/media/audiofx/AudioEffect.java
+++ b/media/java/android/media/audiofx/AudioEffect.java
@@ -16,6 +16,8 @@
package android.media.audiofx;
+import static android.media.permission.PermissionUtil.myIdentity;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -23,11 +25,11 @@
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.annotation.TestApi;
-import android.app.ActivityThread;
import android.compat.annotation.UnsupportedAppUsage;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceInfo;
import android.media.AudioSystem;
+import android.media.permission.Identity;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -515,10 +517,11 @@
}
// native initialization
+ // TODO b/182469354: Make consistent with AudioRecord
int initResult = native_setup(new WeakReference<AudioEffect>(this),
type.toString(), uuid.toString(), priority, audioSession,
deviceType, deviceAddress,
- id, desc, ActivityThread.currentOpPackageName(), probe);
+ id, desc, myIdentity(null), probe);
if (initResult != SUCCESS && initResult != ALREADY_EXISTS) {
Log.e(TAG, "Error code " + initResult
+ " when initializing AudioEffect.");
@@ -1385,7 +1388,7 @@
private native final int native_setup(Object audioeffect_this, String type,
String uuid, int priority, int audioSession,
int deviceType, String deviceAddress, int[] id, Object[] desc,
- String opPackageName, boolean probe);
+ Identity identity, boolean probe);
private native final void native_finalize();
diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java
index a5da648..58c9e65 100644
--- a/media/java/android/media/audiofx/Visualizer.java
+++ b/media/java/android/media/audiofx/Visualizer.java
@@ -16,8 +16,10 @@
package android.media.audiofx;
-import android.app.ActivityThread;
+import static android.media.permission.PermissionUtil.myIdentity;
+
import android.compat.annotation.UnsupportedAppUsage;
+import android.media.permission.Identity;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
@@ -217,9 +219,11 @@
synchronized (mStateLock) {
mState = STATE_UNINITIALIZED;
+
// native initialization
+ // TODO b/182469354: make consistent with AudioRecord
int result = native_setup(new WeakReference<Visualizer>(this), audioSession, id,
- ActivityThread.currentOpPackageName());
+ myIdentity(null));
if (result != SUCCESS && result != ALREADY_EXISTS) {
Log.e(TAG, "Error code "+result+" when initializing Visualizer.");
switch (result) {
@@ -686,7 +690,7 @@
private native final int native_setup(Object audioeffect_this,
int audioSession,
int[] id,
- String opPackageName);
+ Identity identity);
@GuardedBy("mStateLock")
private native final void native_finalize();
diff --git a/media/java/android/media/metrics/NetworkEvent.java b/media/java/android/media/metrics/NetworkEvent.java
index 098885c..18660682 100644
--- a/media/java/android/media/metrics/NetworkEvent.java
+++ b/media/java/android/media/metrics/NetworkEvent.java
@@ -113,10 +113,11 @@
*
* @hide
*/
- public NetworkEvent(@NetworkType int type, long timeSinceCreatedMillis, Bundle extras) {
+ public NetworkEvent(@NetworkType int type, long timeSinceCreatedMillis,
+ @Nullable Bundle extras) {
this.mNetworkType = type;
this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
- this.mExtras = extras.deepCopy();
+ this.mExtras = extras == null ? null : extras.deepCopy();
}
/**
diff --git a/media/java/android/media/metrics/PlaybackErrorEvent.java b/media/java/android/media/metrics/PlaybackErrorEvent.java
index b23b4d2..ccf848b 100644
--- a/media/java/android/media/metrics/PlaybackErrorEvent.java
+++ b/media/java/android/media/metrics/PlaybackErrorEvent.java
@@ -65,12 +65,12 @@
int errorCode,
int subErrorCode,
long timeSinceCreatedMillis,
- Bundle extras) {
+ @Nullable Bundle extras) {
this.mExceptionStack = exceptionStack;
this.mErrorCode = errorCode;
this.mSubErrorCode = subErrorCode;
this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
- this.mExtras = extras.deepCopy();
+ this.mExtras = extras == null ? null : extras.deepCopy();
}
/** @hide */
diff --git a/media/java/android/media/metrics/PlaybackMetrics.java b/media/java/android/media/metrics/PlaybackMetrics.java
index 7e7f44a..3ffd10f 100644
--- a/media/java/android/media/metrics/PlaybackMetrics.java
+++ b/media/java/android/media/metrics/PlaybackMetrics.java
@@ -194,7 +194,7 @@
long localBytesRead,
long networkTransferDurationMillis,
byte[] drmSessionId,
- Bundle extras) {
+ @Nullable Bundle extras) {
this.mMediaDurationMillis = mediaDurationMillis;
this.mStreamSource = streamSource;
this.mStreamType = streamType;
@@ -212,7 +212,7 @@
this.mLocalBytesRead = localBytesRead;
this.mNetworkTransferDurationMillis = networkTransferDurationMillis;
this.mDrmSessionId = drmSessionId;
- this.mExtras = extras.deepCopy();
+ this.mExtras = extras == null ? null : extras.deepCopy();
}
/**
diff --git a/media/java/android/media/metrics/PlaybackStateEvent.java b/media/java/android/media/metrics/PlaybackStateEvent.java
index dea8c1d..2bab5c9 100644
--- a/media/java/android/media/metrics/PlaybackStateEvent.java
+++ b/media/java/android/media/metrics/PlaybackStateEvent.java
@@ -138,10 +138,10 @@
public PlaybackStateEvent(
int state,
long timeSinceCreatedMillis,
- Bundle extras) {
+ @Nullable Bundle extras) {
this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
this.mState = state;
- this.mExtras = extras.deepCopy();
+ this.mExtras = extras == null ? null : extras.deepCopy();
}
/**
diff --git a/media/java/android/media/metrics/TrackChangeEvent.java b/media/java/android/media/metrics/TrackChangeEvent.java
index aa51978..a3eb4ad 100644
--- a/media/java/android/media/metrics/TrackChangeEvent.java
+++ b/media/java/android/media/metrics/TrackChangeEvent.java
@@ -167,7 +167,7 @@
this.mWidth = width;
this.mHeight = height;
this.mVideoFrameRate = videoFrameRate;
- this.mExtras = extras.deepCopy();
+ this.mExtras = extras == null ? null : extras.deepCopy();
}
/**
diff --git a/media/java/android/media/permission/PermissionUtil.java b/media/java/android/media/permission/PermissionUtil.java
index 315ee4f..92fe882 100644
--- a/media/java/android/media/permission/PermissionUtil.java
+++ b/media/java/android/media/permission/PermissionUtil.java
@@ -17,9 +17,12 @@
package android.media.permission;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityThread;
import android.content.Context;
import android.content.PermissionChecker;
import android.os.Binder;
+import android.os.Process;
import java.util.Objects;
@@ -49,6 +52,25 @@
*/
public class PermissionUtil {
/**
+ * Create an identity for the current process and the passed context.
+ *
+ * @param context The process the identity is for. If {@code null}, the process's default
+ * identity is chosen.
+ * @return The identity for the current process and context
+ */
+ public static @NonNull Identity myIdentity(@Nullable Context context) {
+ Identity identity = new Identity();
+
+ identity.pid = Process.myPid();
+ identity.uid = Process.myUid();
+ identity.packageName = context != null ? context.getOpPackageName()
+ : ActivityThread.currentOpPackageName();
+ identity.attributionTag = context != null ? context.getAttributionTag() : null;
+
+ return identity;
+ }
+
+ /**
* Authenticate an originator, where the binder call is coming from a middleman.
*
* The middleman is expected to hold a special permission to act as such, or else a
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index ce45504..f09dcde 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -84,6 +84,7 @@
"android.hardware.drm@1.4",
"android.hidl.memory@1.0",
"android.hidl.token@1.0-utils",
+ "media_permission-aidl-cpp",
],
header_libs: [
@@ -182,7 +183,7 @@
"libnativehelper",
"libutils",
"tv_tuner_aidl_interface-ndk_platform",
- "tv_tuner_resource_manager_aidl_interface-ndk_platform"
+ "tv_tuner_resource_manager_aidl_interface-ndk_platform",
],
static_libs: [
@@ -212,4 +213,3 @@
"-Wunreachable-code",
],
}
-
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 98ac5b9..a360759 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -17,6 +17,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaPlayer-JNI"
+#include "permission_utils.h"
#include "utils/Log.h"
#include <media/mediaplayer.h>
@@ -79,6 +80,8 @@
using namespace android;
using media::VolumeShaper;
+using media::permission::Identity;
+using media::permission::convertIdentity;
// ----------------------------------------------------------------------------
@@ -946,11 +949,11 @@
static void
android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
- jstring opPackageName)
+ jobject jIdentity)
{
ALOGV("native_setup");
- ScopedUtfChars opPackageNameStr(env, opPackageName);
- sp<MediaPlayer> mp = new MediaPlayer(opPackageNameStr.c_str());
+
+ sp<MediaPlayer> mp = new MediaPlayer(convertIdentity(env, jIdentity));
if (mp == NULL) {
jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
return;
@@ -1406,7 +1409,7 @@
{"native_setMetadataFilter", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_setMetadataFilter},
{"native_getMetadata", "(ZZLandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_getMetadata},
{"native_init", "()V", (void *)android_media_MediaPlayer_native_init},
- {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;)V",(void *)android_media_MediaPlayer_native_setup},
+ {"native_setup", "(Ljava/lang/Object;Landroid/media/permission/Identity;)V",(void *)android_media_MediaPlayer_native_setup},
{"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize},
{"getAudioSessionId", "()I", (void *)android_media_MediaPlayer_get_audio_session_id},
{"native_setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer_set_audio_session_id},
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index f99dc01..6641123 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -24,6 +24,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaRecorderJNI"
+#include "permission_utils.h"
#include <utils/Log.h>
#include <gui/Surface.h>
@@ -50,6 +51,8 @@
using namespace android;
+using android::media::permission::convertIdentity;
+
// ----------------------------------------------------------------------------
// helper function to extract a native Camera object from a Camera Java object
@@ -617,13 +620,12 @@
static void
android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
- jstring packageName, jstring opPackageName)
+ jstring packageName, jobject jIdentity)
{
ALOGV("setup");
- ScopedUtfChars opPackageNameStr(env, opPackageName);
+ sp<MediaRecorder> mr = new MediaRecorder(convertIdentity(env, jIdentity));
- sp<MediaRecorder> mr = new MediaRecorder(String16(opPackageNameStr.c_str()));
if (mr == NULL) {
jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
return;
@@ -869,7 +871,7 @@
{"native_reset", "()V", (void *)android_media_MediaRecorder_native_reset},
{"release", "()V", (void *)android_media_MediaRecorder_release},
{"native_init", "()V", (void *)android_media_MediaRecorder_native_init},
- {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V",
+ {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Landroid/media/permission/Identity;)V",
(void *)android_media_MediaRecorder_native_setup},
{"native_finalize", "()V", (void *)android_media_MediaRecorder_native_finalize},
{"native_setInputSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaRecorder_setInputSurface },
diff --git a/media/jni/audioeffect/Android.bp b/media/jni/audioeffect/Android.bp
index c2fc91d..bfed983 100644
--- a/media/jni/audioeffect/Android.bp
+++ b/media/jni/audioeffect/Android.bp
@@ -27,6 +27,11 @@
"libaudioclient",
"libaudioutils",
"libaudiofoundation",
+ "media_permission-aidl-cpp",
+ ],
+
+ export_shared_lib_headers: [
+ "media_permission-aidl-cpp",
],
version_script: "exports.lds",
diff --git a/media/jni/audioeffect/Visualizer.cpp b/media/jni/audioeffect/Visualizer.cpp
index a74ae53..8a52456 100644
--- a/media/jni/audioeffect/Visualizer.cpp
+++ b/media/jni/audioeffect/Visualizer.cpp
@@ -34,8 +34,8 @@
// ---------------------------------------------------------------------------
-Visualizer::Visualizer (const String16& opPackageName)
- : AudioEffect(opPackageName)
+Visualizer::Visualizer (const Identity& identity)
+ : AudioEffect(identity)
{
}
diff --git a/media/jni/audioeffect/Visualizer.h b/media/jni/audioeffect/Visualizer.h
index 8b6a62f..3ee91f0 100644
--- a/media/jni/audioeffect/Visualizer.h
+++ b/media/jni/audioeffect/Visualizer.h
@@ -20,6 +20,9 @@
#include <media/AudioEffect.h>
#include <system/audio_effects/effect_visualizer.h>
#include <utils/Thread.h>
+#include "android/media/permission/Identity.h"
+
+using namespace android::media::permission;
/**
* The Visualizer class enables application to retrieve part of the currently playing audio for
@@ -65,7 +68,7 @@
/* Constructor.
* See AudioEffect constructor for details on parameters.
*/
- explicit Visualizer(const String16& opPackageName);
+ explicit Visualizer(const Identity& identity);
~Visualizer();
diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp
index 0d53ab1..953b7e0 100644
--- a/media/jni/audioeffect/android_media_AudioEffect.cpp
+++ b/media/jni/audioeffect/android_media_AudioEffect.cpp
@@ -25,6 +25,7 @@
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
#include "media/AudioEffect.h"
+#include "permission_utils.h"
#include <nativehelper/ScopedUtfChars.h>
@@ -34,6 +35,8 @@
using namespace android;
+using media::permission::convertIdentity;
+
#define AUDIOEFFECT_SUCCESS 0
#define AUDIOEFFECT_ERROR (-1)
#define AUDIOEFFECT_ERROR_ALREADY_EXISTS (-2)
@@ -270,7 +273,7 @@
android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
jstring type, jstring uuid, jint priority, jint sessionId,
jint deviceType, jstring deviceAddress,
- jintArray jId, jobjectArray javadesc, jstring opPackageName, jboolean probe)
+ jintArray jId, jobjectArray javadesc, jobject jIdentity, jboolean probe)
{
ALOGV("android_media_AudioEffect_native_setup");
AudioEffectJniStorage* lpJniStorage = NULL;
@@ -283,8 +286,6 @@
jobject jdesc;
AudioDeviceTypeAddr device;
- ScopedUtfChars opPackageNameStr(env, opPackageName);
-
setAudioEffect(env, thiz, 0);
if (type != NULL) {
@@ -337,7 +338,7 @@
}
// create the native AudioEffect object
- lpAudioEffect = new AudioEffect(String16(opPackageNameStr.c_str()));
+ lpAudioEffect = new AudioEffect(convertIdentity(env, jIdentity));
if (lpAudioEffect == 0) {
ALOGE("Error creating AudioEffect");
goto setup_failure;
@@ -773,7 +774,7 @@
// Dalvik VM type signatures
static const JNINativeMethod gMethods[] = {
{"native_init", "()V", (void *)android_media_AudioEffect_native_init},
- {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;IIILjava/lang/String;[I[Ljava/lang/Object;Ljava/lang/String;Z)I",
+ {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;IIILjava/lang/String;[I[Ljava/lang/Object;Landroid/media/permission/Identity;Z)I",
(void *)android_media_AudioEffect_native_setup},
{"native_finalize", "()V", (void *)android_media_AudioEffect_native_finalize},
{"native_release", "()V", (void *)android_media_AudioEffect_native_release},
diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp
index 4c5970a..439715c 100644
--- a/media/jni/audioeffect/android_media_Visualizer.cpp
+++ b/media/jni/audioeffect/android_media_Visualizer.cpp
@@ -25,6 +25,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <utils/threads.h>
#include "Visualizer.h"
+#include "permission_utils.h"
#include <nativehelper/ScopedUtfChars.h>
@@ -347,7 +348,7 @@
static jint
android_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
- jint sessionId, jintArray jId, jstring opPackageName)
+ jint sessionId, jintArray jId, jobject jIdentity)
{
ALOGV("android_media_visualizer_native_setup");
VisualizerJniStorage* lpJniStorage = NULL;
@@ -355,8 +356,6 @@
sp<Visualizer> lpVisualizer;
jint* nId = NULL;
- ScopedUtfChars opPackageNameStr(env, opPackageName);
-
setVisualizer(env, thiz, 0);
lpJniStorage = new VisualizerJniStorage();
@@ -382,7 +381,7 @@
}
// create the native Visualizer object
- lpVisualizer = new Visualizer(String16(opPackageNameStr.c_str()));
+ lpVisualizer = new Visualizer(convertIdentity(env, jIdentity));
if (lpVisualizer == 0) {
ALOGE("Error creating Visualizer");
goto setup_failure;
@@ -679,7 +678,7 @@
// Dalvik VM type signatures
static const JNINativeMethod gMethods[] = {
{"native_init", "()V", (void *)android_media_visualizer_native_init},
- {"native_setup", "(Ljava/lang/Object;I[ILjava/lang/String;)I",
+ {"native_setup", "(Ljava/lang/Object;I[ILandroid/media/permission/Identity;)I",
(void *)android_media_visualizer_native_setup},
{"native_finalize", "()V", (void *)android_media_visualizer_native_finalize},
{"native_release", "()V", (void *)android_media_visualizer_native_release},
diff --git a/media/jni/soundpool/Android.bp b/media/jni/soundpool/Android.bp
index b3406cd..4227cd8 100644
--- a/media/jni/soundpool/Android.bp
+++ b/media/jni/soundpool/Android.bp
@@ -63,7 +63,7 @@
// Remove some pedantic stylistic requirements.
"-google-readability-casting", // C++ casts not always necessary and may be verbose
- "-google-readability-todo", // do not require TODO(info)
+ "-google-readability-todo", // do not require TODO(info)
"-google-build-using-namespace", // Reenable and fix later.
"-google-explicit-constructor", // found in StreamManager.h
@@ -100,7 +100,7 @@
tidy_checks: tidy_errors,
tidy_checks_as_errors: tidy_errors,
tidy_flags: [
- "-format-style=file",
+ "-format-style=file",
],
}
@@ -135,6 +135,7 @@
"libaudioclient",
"libmediandk",
"libbinder",
+ "media_permission-aidl-cpp",
],
cflags: [
diff --git a/media/jni/soundpool/Stream.cpp b/media/jni/soundpool/Stream.cpp
index 73e319a..abb0f12 100644
--- a/media/jni/soundpool/Stream.cpp
+++ b/media/jni/soundpool/Stream.cpp
@@ -17,6 +17,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "SoundPool::Stream"
#include <utils/Log.h>
+#include<android/media/permission/Identity.h>
#include "Stream.h"
@@ -24,6 +25,8 @@
namespace android::soundpool {
+using media::permission::Identity;
+
Stream::~Stream()
{
ALOGV("%s(%p)", __func__, this);
@@ -326,15 +329,17 @@
// do not create a new audio track if current track is compatible with sound parameters
+ Identity identity = Identity();
+ identity.packageName = mStreamManager->getOpPackageName();
+ // TODO b/182469354 make consistent with AudioRecord, add util for native source
newTrack = new AudioTrack(streamType, sampleRate, sound->getFormat(),
channelMask, sound->getIMemory(), AUDIO_OUTPUT_FLAG_FAST,
staticCallback, userData,
0 /*default notification frames*/, AUDIO_SESSION_ALLOCATE,
AudioTrack::TRANSFER_DEFAULT,
- nullptr /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/,
+ nullptr /*offloadInfo*/, identity,
mStreamManager->getAttributes(),
- false /*doNotReconnect*/, 1.0f /*maxRequiredSpeed*/,
- mStreamManager->getOpPackageName());
+ false /*doNotReconnect*/, 1.0f /*maxRequiredSpeed*/);
// Set caller name so it can be logged in destructor.
// MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_SOUNDPOOL
newTrack->setCallerName("soundpool");
diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml
index cdf4851..ed120b5 100644
--- a/packages/CompanionDeviceManager/res/values-af/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-af/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Kies \'n <xliff:g id="PROFILE_NAME">%1$s</xliff:g> om deur <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> bestuur te word"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"toestel"</string>
<string name="profile_name_watch" msgid="576290739483672360">"horlosie"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Stel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> om jou <xliff:g id="PROFILE_NAME">%2$s</xliff:g> te bestuur – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Jy het <xliff:g id="APP_NAME">%1$s</xliff:g> nodig om jou <xliff:g id="PROFILE_NAME">%2$s</xliff:g> te bestuur. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ja"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nee, dankie"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml
index a03ea0df..76f68e7 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"በ<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> የሚተዳደር <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ይምረጡ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"መሣሪያ"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ሰዓት"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> የእርስዎን <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> እንዲያስተዳድር ያቀናብሩት"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> የእርስዎን <xliff:g id="PROFILE_NAME">%2$s</xliff:g> ለማስተዳደር ያስፈልጋል። <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"አዎ"</string>
- <string name="consent_no" msgid="1335543792857823917">"አይ፣ አመሰግናለሁ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index 970c46b..92783a5 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"اختَر <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ليديره تطبيق <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"جهاز"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ساعة"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"اضبط <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> لإدارة <xliff:g id="PROFILE_NAME">%2$s</xliff:g> على <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"يجب توفّر تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> لإدارة <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"نعم"</string>
- <string name="consent_no" msgid="1335543792857823917">"لا، شكرًا"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml
index 477844c..34ce062 100644
--- a/packages/CompanionDeviceManager/res/values-as/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-as/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>এ পৰিচালনা কৰিব লগা এটা <xliff:g id="PROFILE_NAME">%1$s</xliff:g> বাছনি কৰক"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইচ"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ঘড়ী"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"আপোনাৰ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> পৰিচালনা কৰিবলৈ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ছেট কৰক - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"আপোনাৰ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> পৰিচালনা কৰিবলৈ <xliff:g id="APP_NAME">%1$s</xliff:g>ৰ আৱশ্যক। <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"হয়"</string>
- <string name="consent_no" msgid="1335543792857823917">"নালাগে, ধন্যবাদ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml
index f10c639..b07cad6 100644
--- a/packages/CompanionDeviceManager/res/values-az/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-az/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> tərəfindən idarə ediləcək <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
<string name="profile_name_watch" msgid="576290739483672360">"izləyin"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> profilinizin <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tərəfindən idarə olunmasını ayarlayın - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> profilinizi idarə etmək üçün <xliff:g id="APP_NAME">%1$s</xliff:g> tələb olunur. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Bəli"</string>
- <string name="consent_no" msgid="1335543792857823917">"Xeyr, çox sağolun"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
index e8542f3..edeaa77 100644
--- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Odaberite profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="profile_name_watch" msgid="576290739483672360">"sat"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Podesite aplikaciju <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da upravlja profilom <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je neophodna za upravljanje profilom <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Da"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ne, hvala"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml
index 13be6f2..9410d68 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Выберыце прыладу (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), якой будзе кіраваць праграма <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"прылада"</string>
<string name="profile_name_watch" msgid="576290739483672360">"гадзіннік"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Дазвольце праграме <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> кіраваць прыладай \"<xliff:g id="PROFILE_NAME">%2$s</xliff:g>\" – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Для кіравання прыладай \"<xliff:g id="PROFILE_NAME">%2$s</xliff:g>\" патрабуецца праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\". <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Так"</string>
- <string name="consent_no" msgid="1335543792857823917">"Не, дзякуй"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index 3bda5e6..4457dbd 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Изберете устройство (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), което да се управлява от <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
<string name="profile_name_watch" msgid="576290739483672360">"часовник"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Задайте <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да управлява устройството ви (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>) – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"За управление на <xliff:g id="PROFILE_NAME">%2$s</xliff:g> се изисква <xliff:g id="APP_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Да"</string>
- <string name="consent_no" msgid="1335543792857823917">"Не, благодаря"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index d3bc515..4aa7e74 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> বেছে নিন যেটি <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ম্যানেজ করবে"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইস"</string>
<string name="profile_name_watch" msgid="576290739483672360">"দেখুন"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"আপনার <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> ম্যানেজ করার জন্য <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> সেট করুন"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g>-কে আপনার <xliff:g id="PROFILE_NAME">%2$s</xliff:g>.ম্যানেজ করতে দিতে হবে। <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"হ্যাঁ"</string>
- <string name="consent_no" msgid="1335543792857823917">"না থাক"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index 905b306..8ffa327 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Odaberite uređaj <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="profile_name_watch" msgid="576290739483672360">"sat"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Postavite aplikaciju <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da upravlja vašim uređajem <xliff:g id="PROFILE_NAME">%2$s</xliff:g> — <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Potrebna je aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> za upravljanje uređajem <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Da"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ne, hvala"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml
index 86dc694..c9c186e 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Tria un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> perquè el gestioni <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositiu"</string>
<string name="profile_name_watch" msgid="576290739483672360">"rellotge"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Defineix que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> gestioni el teu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> (<strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>)"</string>
- <string name="profile_summary" msgid="2009764182871566255">"L\'aplicació <xliff:g id="APP_NAME">%1$s</xliff:g> és necessària per gestionar el teu <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Sí"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, gràcies"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index 389ccd0..b2ac32d 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Vyberte zařízení <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, které chcete spravovat pomocí aplikace <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"zařízení"</string>
<string name="profile_name_watch" msgid="576290739483672360">"hodinky"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Nastavit aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ke správě tohoto zařízení: <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Ke správě profilu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> je potřeba aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ano"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ne, díky"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml
index 5a31f9b..bc67948 100644
--- a/packages/CompanionDeviceManager/res/values-da/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-da/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Vælg den enhed (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), som skal administreres af <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhed"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ur"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Angiv <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> til administration af: <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> er nødvendig for at administrere: <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ja"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nej tak"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml
index b643eb2..1c7ec74 100644
--- a/packages/CompanionDeviceManager/res/values-de/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-de/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Gerät (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) auswählen, das von <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> verwaltet werden soll"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"Gerät"</string>
<string name="profile_name_watch" msgid="576290739483672360">"Smartwatch"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> zum Verwalten deines Geräts (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>) festlegen – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> ist erforderlich, um dein Gerät (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>) zu verwalten. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ja"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nein danke"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml
index 60de2ff..fed516f 100644
--- a/packages/CompanionDeviceManager/res/values-el/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-el/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Επιλέξτε ένα προφίλ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> για διαχείριση από την εφαρμογή <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"συσκευή"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ρολόι"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Ορίστε μια εφαρμογή <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> για διαχείριση του προφίλ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> απαιτείται για τη διαχείριση του προφίλ <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ναι"</string>
- <string name="consent_no" msgid="1335543792857823917">"Όχι, ευχαριστώ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
index 2fed1ae..4fd057f 100644
--- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Set <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> is needed to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Yes"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, thanks"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
index 2fed1ae..4fd057f 100644
--- a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Set <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> is needed to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Yes"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, thanks"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
index 2fed1ae..4fd057f 100644
--- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Set <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> is needed to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Yes"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, thanks"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
index 2fed1ae..4fd057f 100644
--- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Set <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> is needed to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Yes"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, thanks"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
index f3c4b1d..0e3902c 100644
--- a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Set <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> is needed to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Yes"</string>
- <string name="consent_no" msgid="1335543792857823917">"No thanks"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
index 4fbb57e..6b903c6 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Elige un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para que <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> lo administre"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="profile_name_watch" msgid="576290739483672360">"reloj"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Configura <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> para administrar <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Se requiere <xliff:g id="APP_NAME">%1$s</xliff:g> para administrar tu <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Sí"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, gracias"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml
index 5ca9305..0a2906a 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Elige un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para gestionarlo con <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="profile_name_watch" msgid="576290739483672360">"reloj"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Haz que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> gestione tu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Se necesita <xliff:g id="APP_NAME">%1$s</xliff:g> para gestionar tu <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Sí"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, gracias"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index 357f052..4958a17 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Valige seade <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, mida haldab rakendus <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"seade"</string>
<string name="profile_name_watch" msgid="576290739483672360">"käekell"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Määrake rakendus <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> haldama teie seadet <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> on vajalik teie seadme <xliff:g id="PROFILE_NAME">%2$s</xliff:g> haldamiseks. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Jah"</string>
- <string name="consent_no" msgid="1335543792857823917">"Tänan, ei"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index 14c7154..2a61fd5 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Aukeratu <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> aplikazioak kudeatu beharreko <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"gailua"</string>
<string name="profile_name_watch" msgid="576290739483672360">"erlojua"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Konfiguratu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> <xliff:g id="PROFILE_NAME">%2$s</xliff:g> (<strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>) kudea dezan"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> erabili behar duzu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> kudeatzeko. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Bai"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ez"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index 6bb9620..8d10230 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"انتخاب <xliff:g id="PROFILE_NAME">%1$s</xliff:g> برای مدیریت کردن با <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"دستگاه"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ساعت"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"تنظیم <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> برای مدیریت کردن <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"برای مدیریت کردن <xliff:g id="PROFILE_NAME">%2$s</xliff:g> به <xliff:g id="APP_NAME">%1$s</xliff:g> نیاز دارید. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"بله"</string>
- <string name="consent_no" msgid="1335543792857823917">"نه متشکرم"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index 5a9c1cd..cfa03af 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Valitse <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, jota <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> hallinnoi"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"laite"</string>
<string name="profile_name_watch" msgid="576290739483672360">"kello"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Aseta <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> profiilin (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>) hallinnoijaksi – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> tarvitaan profiilin (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>) hallinnointiin. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Kyllä"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ei kiitos"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index b31babd..d3cfc29 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Choisissez un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qui sera géré par <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="profile_name_watch" msgid="576290739483672360">"montre"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Utiliser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pour gérer votre <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"L\'application <xliff:g id="APP_NAME">%1$s</xliff:g> est requise pour gérer votre <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Oui"</string>
- <string name="consent_no" msgid="1335543792857823917">"Non merci"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml
index 08c93a2c..d82e390 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Sélectionner le/la <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qui sera géré(e) par <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="profile_name_watch" msgid="576290739483672360">"montre"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Définir <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pour la gestion de votre <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> est requis pour gérer votre <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Oui"</string>
- <string name="consent_no" msgid="1335543792857823917">"Non, merci"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index c95b90e..2a85398 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Escolle un perfil (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) para que o xestione a aplicación <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="profile_name_watch" msgid="576290739483672360">"reloxo"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Define a aplicación <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> para a xestión do teu perfil (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>): <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Necesítase a aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> para xestionar o teu perfil (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>). <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Si"</string>
- <string name="consent_no" msgid="1335543792857823917">"Non, grazas"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml
index 7e41042..6f52403 100644
--- a/packages/CompanionDeviceManager/res/values-gu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> દ્વારા મેનેજ કરવા માટે કોઈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> પસંદ કરો"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ડિવાઇસ"</string>
<string name="profile_name_watch" msgid="576290739483672360">"સ્માર્ટવૉચ"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"તમારા <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>ને મેનેજ કરવા માટે <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> સેટ કરો"</string>
- <string name="profile_summary" msgid="2009764182871566255">"તમારા <xliff:g id="PROFILE_NAME">%2$s</xliff:g>ને મેનેજ કરવા માટે <xliff:g id="APP_NAME">%1$s</xliff:g> જરૂરી છે. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"હા"</string>
- <string name="consent_no" msgid="1335543792857823917">"ના, આભાર"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index ac95cc6..9af9992 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"कोई <xliff:g id="PROFILE_NAME">%1$s</xliff:g> चुनें, ताकि उसे <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> की मदद से प्रबंधित किया जा सके"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"डिवाइस"</string>
<string name="profile_name_watch" msgid="576290739483672360">"स्मार्टवॉच"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"अपने <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> को प्रबंधित करने के लिए, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को सेट करें"</string>
- <string name="profile_summary" msgid="2009764182871566255">"आपके <xliff:g id="PROFILE_NAME">%2$s</xliff:g> को प्रबंधित करने के लिए, <xliff:g id="APP_NAME">%1$s</xliff:g> की ज़रूरत है. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"हां"</string>
- <string name="consent_no" msgid="1335543792857823917">"नहीं, रहने दें"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index df8451f..fe30ec4 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Odaberite profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="profile_name_watch" msgid="576290739483672360">"satom"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Postavite aplikaciju <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da upravlja vašim profilom <xliff:g id="PROFILE_NAME">%2$s</xliff:g> –- <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> potrebna je za upravljanje vašim <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Da"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ne, hvala"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml
index ff1c6c5..370d4df 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"A(z) <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> alkalmazással kezelni kívánt <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kiválasztása"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"eszköz"</string>
<string name="profile_name_watch" msgid="576290739483672360">"óra"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"A(z) <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> alkalmazás beállítása a(z) <xliff:g id="PROFILE_NAME">%2$s</xliff:g> (<strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>) kezelésére"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Szükség van a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazásra a(z) <xliff:g id="PROFILE_NAME">%2$s</xliff:g> kezeléséhez. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Igen"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nem"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml
index 194223d..fee55d0 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Ընտրեք <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ը, որը պետք է կառավարվի <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> հավելվածի կողմից"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"սարք"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ժամացույց"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Ընտրեք <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածը որպես <xliff:g id="PROFILE_NAME">%2$s</xliff:g>ի կառավարիչ․ <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Ձեր <xliff:g id="PROFILE_NAME">%2$s</xliff:g>ը կառավարելու համար անհրաժեշտ է <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը։ <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Այո"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ոչ, շնորհակալություն"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index 58bf3cb..498bf2c 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk dikelola oleh <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"perangkat"</string>
<string name="profile_name_watch" msgid="576290739483672360">"smartwatch"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Tetapkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> untuk mengelola <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Perlu <xliff:g id="APP_NAME">%1$s</xliff:g> untuk mengelola <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ya"</string>
- <string name="consent_no" msgid="1335543792857823917">"Tidak"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml
index cc5b989..bd12658 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Velja <xliff:g id="PROFILE_NAME">%1$s</xliff:g> sem <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> á að stjórna"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"tæki"</string>
<string name="profile_name_watch" msgid="576290739483672360">"úr"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Veita <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> stjórn á <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> er krafist til að stjórna <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Já"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nei, takk"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index 4cbefd8..40d4320 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Scegli un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> che sia gestito da <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="profile_name_watch" msgid="576290739483672360">"orologio"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Configura <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> per gestire il tuo <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"È richiesta l\'app <xliff:g id="APP_NAME">%1$s</xliff:g> per gestire il tuo <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Sì"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, grazie"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index 8663e56..807cdd4 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"בחירה של <xliff:g id="PROFILE_NAME">%1$s</xliff:g> לניהול באמצעות <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"מכשיר"</string>
<string name="profile_name_watch" msgid="576290739483672360">"שעון"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"הגדרה של <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> לניהול <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> נדרשת לניהול של <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"כן"</string>
- <string name="consent_no" msgid="1335543792857823917">"לא תודה"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml
index ca17336..92022be 100644
--- a/packages/CompanionDeviceManager/res/values-ja/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> の管理対象となる<xliff:g id="PROFILE_NAME">%1$s</xliff:g>の選択"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"デバイス"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ウォッチ"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> で <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> を管理するよう設定する"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> を管理するために <xliff:g id="APP_NAME">%1$s</xliff:g> が必要です。<xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"はい"</string>
- <string name="consent_no" msgid="1335543792857823917">"いいえ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index 300c94f..64a79b4 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"აირჩიეთ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, რომელიც უნდა მართოს <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>-მა"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"მოწყობილობა"</string>
<string name="profile_name_watch" msgid="576290739483672360">"საათი"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"დააყენეთ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>, რომ მართოს თქვენი <xliff:g id="PROFILE_NAME">%2$s</xliff:g> — <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"თქვენი <xliff:g id="PROFILE_NAME">%2$s</xliff:g>-ის სამართავად საჭიროა <xliff:g id="APP_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"დიახ"</string>
- <string name="consent_no" msgid="1335543792857823917">"არა, გმადლობთ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index 94d6c3e..edd5c0e 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> арқылы басқарылатын <xliff:g id="PROFILE_NAME">%1$s</xliff:g> құрылғысын таңдаңыз"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"құрылғы"</string>
<string name="profile_name_watch" msgid="576290739483672360">"сағат"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасына <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>) құрылғысын басқаруға рұқсат беру"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> құрылғысын басқару үшін <xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы керек. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Иә"</string>
- <string name="consent_no" msgid="1335543792857823917">"Жоқ, рақмет"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index db13fe7..36c02de 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"ជ្រើសរើស <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ដើម្បីឱ្យស្ថិតក្រោមការគ្រប់គ្រងរបស់ <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ឧបករណ៍"</string>
<string name="profile_name_watch" msgid="576290739483672360">"នាឡិកា"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"កំណត់ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ដើម្បីគ្រប់គ្រង <xliff:g id="PROFILE_NAME">%2$s</xliff:g> របស់អ្នក - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"ចាំបាច់ត្រូវមាន <xliff:g id="APP_NAME">%1$s</xliff:g> ដើម្បីគ្រប់គ្រង <xliff:g id="PROFILE_NAME">%2$s</xliff:g> របស់អ្នក។ <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"បាទ/ចាស"</string>
- <string name="consent_no" msgid="1335543792857823917">"ទេ អរគុណ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml
index 0225166..56c1557 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ಮೂಲಕ ನಿರ್ವಹಿಸಬೇಕಾದ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ಸಾಧನ"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ವೀಕ್ಷಿಸಿ"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"ನಿಮ್ಮ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> ಅನ್ನು ನಿರ್ವಹಿಸಲು, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಅನ್ನು ನಿರ್ವಹಿಸಿ"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು, <xliff:g id="APP_NAME">%1$s</xliff:g> ಅಗತ್ಯವಿದೆ. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ಹೌದು"</string>
- <string name="consent_no" msgid="1335543792857823917">"ಬೇಡ, ಧನ್ಯವಾದಗಳು"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index 1363e57..79c36dd 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>에서 관리할 <xliff:g id="PROFILE_NAME">%1$s</xliff:g>을(를) 선택"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"기기"</string>
<string name="profile_name_watch" msgid="576290739483672360">"시계"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>에서 <xliff:g id="PROFILE_NAME">%2$s</xliff:g>(<strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>)을(를) 관리하도록 설정"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> 프로필을 관리하려면 <xliff:g id="APP_NAME">%1$s</xliff:g> 앱이 필요합니다. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"예"</string>
- <string name="consent_no" msgid="1335543792857823917">"취소"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index c01e235..8a90b3d 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> тарабынан башкарылсын"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"түзмөк"</string>
<string name="profile_name_watch" msgid="576290739483672360">"саат"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> түзмөгүңүздү башкарсын"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> профилиңизди башкаруу үчүн <xliff:g id="APP_NAME">%1$s</xliff:g> керек. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ооба"</string>
- <string name="consent_no" msgid="1335543792857823917">"Жок, рахмат"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index 68218dd..a6564b3 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"ເລືອກ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ເພື່ອໃຫ້ຖືກຈັດການໂດຍ <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ອຸປະກອນ"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ໂມງ"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"ຕັ້ງ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ເພື່ອຈັດການ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> ຂອງທ່ານ"</string>
- <string name="profile_summary" msgid="2009764182871566255">"ຕ້ອງໃຊ້ <xliff:g id="APP_NAME">%1$s</xliff:g> ເພື່ອຈັດການ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> ຂອງທ່ານ. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ແມ່ນແລ້ວ"</string>
- <string name="consent_no" msgid="1335543792857823917">"ບໍ່, ຂອບໃຈ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index 5fd8280..382f1cf 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Jūsų <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, kurį valdys <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> (pasirinkite)"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"įrenginys"</string>
<string name="profile_name_watch" msgid="576290739483672360">"laikrodis"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Nustatyti, kad <xliff:g id="PROFILE_NAME">%2$s</xliff:g> <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> būtų valdomas programos <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Norint valdyti jūsų <xliff:g id="PROFILE_NAME">%2$s</xliff:g>, reikalinga programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Taip"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ne, ačiū"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml
index bf036ec..8d70bf7 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Profila (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) izvēle, ko pārvaldīt lietotnē <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ierīce"</string>
<string name="profile_name_watch" msgid="576290739483672360">"pulkstenis"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Lietotnes <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> iestatīšana profila (<xliff:g id="PROFILE_NAME">%2$s</xliff:g> — <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>) pārvaldībai"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Lai pārvaldītu profilu (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>), nepieciešama lietotne <xliff:g id="APP_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Jā"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nē, paldies"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml
index 427ca8f..5322e98 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Изберете <xliff:g id="PROFILE_NAME">%1$s</xliff:g> со којшто ќе управува <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"уред"</string>
<string name="profile_name_watch" msgid="576290739483672360">"часовник"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Поставете ја <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да управува со <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> е потребна за да управува со <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Да"</string>
- <string name="consent_no" msgid="1335543792857823917">"Не, фала"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml
index a48c45f..a9262c7 100644
--- a/packages/CompanionDeviceManager/res/values-ml/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ഉപയോഗിച്ച് മാനേജ് ചെയ്യുന്നതിന് ഒരു <xliff:g id="PROFILE_NAME">%1$s</xliff:g> തിരഞ്ഞെടുക്കുക"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ഉപകരണം"</string>
<string name="profile_name_watch" msgid="576290739483672360">"വാച്ച്"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"നിങ്ങളുടെ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> മാനേജ് ചെയ്യുന്നതിന് <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> സജ്ജീകരിക്കുക - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്ന ആപ്പിന് നിങ്ങളുടെ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> മാനേജ് ചെയ്യേണ്ടതുണ്ട്. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"വേണം"</string>
- <string name="consent_no" msgid="1335543792857823917">"വേണ്ട"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml
index 7ac20e6..3032864 100644
--- a/packages/CompanionDeviceManager/res/values-mn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>-н удирдах<xliff:g id="PROFILE_NAME">%1$s</xliff:g>-г сонгоно уу"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"төхөөрөмж"</string>
<string name="profile_name_watch" msgid="576290739483672360">"цаг"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g>-аа удирдахын тулд <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-г тохируулна уу - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Таны <xliff:g id="PROFILE_NAME">%2$s</xliff:g>-г удирдахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> шаардлагатай. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Тийм"</string>
- <string name="consent_no" msgid="1335543792857823917">"Үгүй, баярлалаа"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index 144698b..01dae7d 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> द्वारे व्यवस्थापित करण्यासाठी <xliff:g id="PROFILE_NAME">%1$s</xliff:g> निवडा"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"डिव्हाइस"</string>
<string name="profile_name_watch" msgid="576290739483672360">"पाहा"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"तुमची <xliff:g id="PROFILE_NAME">%2$s</xliff:g> व्यवस्थापित करण्यासाठी <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> सेट करा - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"तुमची <xliff:g id="PROFILE_NAME">%2$s</xliff:g> व्यवस्थापित करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> आवश्यक आहे. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"होय"</string>
- <string name="consent_no" msgid="1335543792857823917">"नाही, नको"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml
index 7bea2c9..4e0f58b 100644
--- a/packages/CompanionDeviceManager/res/values-ms/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk diurus oleh <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"peranti"</string>
<string name="profile_name_watch" msgid="576290739483672360">"jam tangan"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Tetapkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> untuk mengurus <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> anda"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> diperlukan untuk mengurus <xliff:g id="PROFILE_NAME">%2$s</xliff:g> anda. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ya"</string>
- <string name="consent_no" msgid="1335543792857823917">"Tidak perlu"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml
index 9c2783c..050c8ce 100644
--- a/packages/CompanionDeviceManager/res/values-my/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-my/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> က စီမံခန့်ခွဲရန် <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ကို ရွေးချယ်ပါ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"စက်"</string>
<string name="profile_name_watch" msgid="576290739483672360">"နာရီ"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"သင်၏ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> ကို စီမံခန့်ခွဲရန် <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ကို သတ်မှတ်ပါ"</string>
- <string name="profile_summary" msgid="2009764182871566255">"သင်၏ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> ကို စီမံခန့်ခွဲရန် <xliff:g id="APP_NAME">%1$s</xliff:g> ကို လိုအပ်ပါသည်။ <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Yes"</string>
- <string name="consent_no" msgid="1335543792857823917">"မလိုပါ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml
index 26fbb03..a8e2203 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Velg <xliff:g id="PROFILE_NAME">%1$s</xliff:g> som skal administreres av <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
<string name="profile_name_watch" msgid="576290739483672360">"klokke"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Angi <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> for å administrere <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> kreves for å administrere <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ja"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nei takk"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml
index f289b37..45bfb5f 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"आफूले <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> प्रयोग गरी व्यवस्थापन गर्न चाहेको <xliff:g id="PROFILE_NAME">%1$s</xliff:g> चयन गर्नुहोस्"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"यन्त्र"</string>
<string name="profile_name_watch" msgid="576290739483672360">"घडी"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"आफ्नो <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> व्यवस्थापन गर्न <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> तोक्नुहोस्"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> व्यवस्थापन गर्न <xliff:g id="APP_NAME">%1$s</xliff:g> इन्स्टल गर्नु पर्ने हुन्छ। <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"अँ"</string>
- <string name="consent_no" msgid="1335543792857823917">"सहमत छुइनँ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml
index 0c9cdffd..e7e0390 100644
--- a/packages/CompanionDeviceManager/res/values-nl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Een <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kiezen om te beheren met <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"apparaat"</string>
<string name="profile_name_watch" msgid="576290739483672360">"horloge"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> instellen om je <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> te beheren"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Je hebt <xliff:g id="APP_NAME">%1$s</xliff:g> nodig om je <xliff:g id="PROFILE_NAME">%2$s</xliff:g> te beheren. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ja"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nee, bedankt"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml
index c8c680f..1f516fa 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ଦ୍ୱାରା ପରିଚାଳିତ ହେବା ପାଇଁ ଏକ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>କୁ ବାଛନ୍ତୁ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ଡିଭାଇସ୍"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ୱାଚ୍"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"ଆପଣଙ୍କ <xliff:g id="PROFILE_NAME">%2$s</xliff:g>କୁ ପରିଚାଳନା କରିବା ପାଇଁ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>କୁ ସେଟ୍ କରନ୍ତୁ - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"ଆପଣଙ୍କ <xliff:g id="PROFILE_NAME">%2$s</xliff:g>କୁ ପରିଚାଳନା କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆବଶ୍ୟକ। <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ହଁ"</string>
- <string name="consent_no" msgid="1335543792857823917">"ନା, ଧନ୍ୟବାଦ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index 0da9410..03693dc 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤੇ ਜਾਣ ਲਈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ਚੁਣੋ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ਡੀਵਾਈਸ"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ਸਮਾਰਟ-ਵਾਚ"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ ਤੁਹਾਡਾ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਲਈ ਸੈੱਟ ਕਰੋ"</string>
- <string name="profile_summary" msgid="2009764182871566255">"ਤੁਹਾਡੇ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਲਈ <xliff:g id="APP_NAME">%1$s</xliff:g> ਦੀ ਲੋੜ ਹੈ। <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ਹਾਂ"</string>
- <string name="consent_no" msgid="1335543792857823917">"ਨਹੀਂ ਧੰਨਵਾਦ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index b07af57..7adf064 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Wybierz profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, którym ma zarządzać aplikacja <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"urządzenie"</string>
<string name="profile_name_watch" msgid="576290739483672360">"zegarek"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Ustaw aplikację <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> do zarządzania profilem <xliff:g id="PROFILE_NAME">%2$s</xliff:g> na urządzeniu <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest wymagana do zarządzania profilem <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Tak"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nie, dziękuję"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
index 16906f6..b5ddc6d 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerenciado pelo app <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="profile_name_watch" msgid="576290739483672360">"relógio"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Defina o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> como gerenciador do seu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> (<strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>)"</string>
- <string name="profile_summary" msgid="2009764182871566255">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> é necessário para gerenciar seu <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Sim"</string>
- <string name="consent_no" msgid="1335543792857823917">"Agora não"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
index 745d163..c06ac7d 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerido pela app <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="profile_name_watch" msgid="576290739483672360">"relógio"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Defina a app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> para gerir o seu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> é necessária para gerir o seu <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Sim"</string>
- <string name="consent_no" msgid="1335543792857823917">"Não, obrigado"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml
index 16906f6..b5ddc6d 100644
--- a/packages/CompanionDeviceManager/res/values-pt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerenciado pelo app <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="profile_name_watch" msgid="576290739483672360">"relógio"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Defina o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> como gerenciador do seu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> (<strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>)"</string>
- <string name="profile_summary" msgid="2009764182871566255">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> é necessário para gerenciar seu <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Sim"</string>
- <string name="consent_no" msgid="1335543792857823917">"Agora não"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml
index 187cfbdf..437e8dc 100644
--- a/packages/CompanionDeviceManager/res/values-ro/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Alegeți un profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> pe care să îl gestioneze <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispozitiv"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ceas"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Setați <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pentru a vă gestiona profilul <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> este necesară pentru a vă gestiona profilul <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Da"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nu, mulțumesc"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml
index 8dd9a39..d087959 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Выберите устройство (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), которым будет управлять приложение <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
<string name="profile_name_watch" msgid="576290739483672360">"часы"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Разрешите приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> управлять устройством <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>)"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" необходимо для управления устройством (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>). <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Да"</string>
- <string name="consent_no" msgid="1335543792857823917">"Нет"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml
index 9e7c02e..365b6bf 100644
--- a/packages/CompanionDeviceManager/res/values-si/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-si/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> මගින් කළමනාකරණය කරනු ලැබීමට <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ක් තෝරන්න"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"උපාංගය"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ඔරලෝසුව"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ඔබගේ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> කළමනාකරණය කිරීමට සකසන්න - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"ඔබගේ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> කළමනාකරණය කිරීමට <xliff:g id="APP_NAME">%1$s</xliff:g> අවශ්යයි. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ඔව්"</string>
- <string name="consent_no" msgid="1335543792857823917">"එපා, ස්තුතියි"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml
index 55a47c2..d5c099a 100644
--- a/packages/CompanionDeviceManager/res/values-sk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Vyberte profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, ktorý bude spravovať aplikácia <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"zariadenie"</string>
<string name="profile_name_watch" msgid="576290739483672360">"hodinky"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Nastavte aplikáciu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>, aby spravovala profil <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Na správu profilu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> je potrebná aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Áno"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nie, vďaka"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index 159afd5..d855db1 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Izbira naprave <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, ki jo bo upravljala aplikacija <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"naprava"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ura"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Nastavitev aplikacije <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>, ki bo upravljala napravo <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Za upravljanje naprave <xliff:g id="PROFILE_NAME">%2$s</xliff:g> potrebujete aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Da"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ne, hvala"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index 6fa759c..7335446 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Zgjidh një profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> që do të menaxhohet nga <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"pajisja"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ora inteligjente"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Cakto <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> që të menaxhojë profilin tënd <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Nevojitet <xliff:g id="APP_NAME">%1$s</xliff:g> për të menaxhuar profilin tënd të <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Po"</string>
- <string name="consent_no" msgid="1335543792857823917">"Jo, faleminderit"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml
index fdbbe8e..f3f65e1 100644
--- a/packages/CompanionDeviceManager/res/values-sr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Одаберите профил <xliff:g id="PROFILE_NAME">%1$s</xliff:g> којим ће управљати апликација <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"уређај"</string>
<string name="profile_name_watch" msgid="576290739483672360">"сат"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Подесите апликацију <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да управља профилом <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је неопходна за управљање профилом <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Да"</string>
- <string name="consent_no" msgid="1335543792857823917">"Не, хвала"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml
index bfd2516..5741668 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Välj en <xliff:g id="PROFILE_NAME">%1$s</xliff:g> för hantering av <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
<string name="profile_name_watch" msgid="576290739483672360">"klocka"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Konfigurera <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> för att hantera din <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> krävs för att hantera din <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ja"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nej tack"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml
index 437ae7f..357eb4a 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Chagua <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ili idhibitiwe na <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"kifaa"</string>
<string name="profile_name_watch" msgid="576290739483672360">"saa"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Weka <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ili udhibiti <xliff:g id="PROFILE_NAME">%2$s</xliff:g> yako - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> linahitajika ili kudhibiti <xliff:g id="PROFILE_NAME">%2$s</xliff:g> yako. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ndiyo"</string>
- <string name="consent_no" msgid="1335543792857823917">"Hapana"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index 9b4a720..651d9e2 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ஆப்ஸ் நிர்வகிக்கக்கூடிய <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ஐத் தேர்ந்தெடுங்கள்"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"சாதனம்"</string>
<string name="profile_name_watch" msgid="576290739483672360">"வாட்ச்"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> ஐ நிர்வகிக்க <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அமையுங்கள்"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> ஐ நிர்வகிக்க <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் வேண்டும். <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ஆம்"</string>
- <string name="consent_no" msgid="1335543792857823917">"வேண்டாம்"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml
index 6e785de..9c3e334 100644
--- a/packages/CompanionDeviceManager/res/values-te/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-te/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ద్వారా మేనేజ్ చేయబడటానికి ఒక <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ను ఎంచుకోండి"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"పరికరం"</string>
<string name="profile_name_watch" msgid="576290739483672360">"వాచ్"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"మీ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>ను మేనేజ్ చేయడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ను సెటప్ చేయండి"</string>
- <string name="profile_summary" msgid="2009764182871566255">"మీ <xliff:g id="PROFILE_NAME">%2$s</xliff:g>ను మేనేజ్ చేయడానికి <xliff:g id="APP_NAME">%1$s</xliff:g> అవసరం ఉంది. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"అవును"</string>
- <string name="consent_no" msgid="1335543792857823917">"వద్దు, ధన్యవాదాలు"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml
index b727d42..557515a 100644
--- a/packages/CompanionDeviceManager/res/values-th/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-th/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"เลือก<xliff:g id="PROFILE_NAME">%1$s</xliff:g>ที่จะให้มีการจัดการโดย <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"อุปกรณ์"</string>
<string name="profile_name_watch" msgid="576290739483672360">"นาฬิกา"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"ตั้งค่า <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ให้จัดการ<xliff:g id="PROFILE_NAME">%2$s</xliff:g>ของคุณ - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"ต้องใช้ <xliff:g id="APP_NAME">%1$s</xliff:g> ในการจัดการ<xliff:g id="PROFILE_NAME">%2$s</xliff:g> <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ใช่"</string>
- <string name="consent_no" msgid="1335543792857823917">"ไม่เป็นไร"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml
index a93282a..6cbf2e8 100644
--- a/packages/CompanionDeviceManager/res/values-tl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Pumili ng <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para pamahalaan ng <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="profile_name_watch" msgid="576290739483672360">"relo"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Itakda ang <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> para pamahalaan ang iyong <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Kailangan ang <xliff:g id="APP_NAME">%1$s</xliff:g> para pamahalaan ang iyong <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Oo"</string>
- <string name="consent_no" msgid="1335543792857823917">"Huwag na lang"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index 3abe064..bc1ab31 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> tarafından yönetilecek bir <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
<string name="profile_name_watch" msgid="576290739483672360">"saat"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasını, <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> cihazınızı yönetecek şekilde ayarlayın"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="PROFILE_NAME">%2$s</xliff:g> yönetimi için gereklidir. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Evet"</string>
- <string name="consent_no" msgid="1335543792857823917">"Hayır, teşekkürler"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml
index 161d95e..33477c8 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Виберіть <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, яким керуватиме додаток <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"пристрій"</string>
<string name="profile_name_watch" msgid="576290739483672360">"годинник"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Налаштуйте додаток <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>, щоб керувати своїм пристроєм <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>)"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Щоб керувати своїм пристроєм (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>), вам потрібен додаток <xliff:g id="APP_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Так"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ні, дякую"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index dce1815..83e20d8 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> کے ذریعے نظم کئے جانے کیلئے <xliff:g id="PROFILE_NAME">%1$s</xliff:g> کو منتخب کریں"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"آلہ"</string>
<string name="profile_name_watch" msgid="576290739483672360">"دیکھیں"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"اپنے <xliff:g id="PROFILE_NAME">%2$s</xliff:g> کا نظم کرنے کے لیے <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو سیٹ کریں - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"آپ کے <xliff:g id="PROFILE_NAME">%2$s</xliff:g> کا نظم کرنے کے لیے <xliff:g id="APP_NAME">%1$s</xliff:g> کی ضرورت ہے۔ <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ہاں"</string>
- <string name="consent_no" msgid="1335543792857823917">"نہیں شکریہ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index 2ca27b5..b16db73 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> boshqaradigan <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qurilmasini tanlang"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"qurilma"</string>
<string name="profile_name_watch" msgid="576290739483672360">"soat"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong> qurilmalarini boshqarish uchun <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasini sozlang"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> qurilmasini boshqarish uchun <xliff:g id="APP_NAME">%1$s</xliff:g> zarur. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ha"</string>
- <string name="consent_no" msgid="1335543792857823917">"Kerak emas"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml
index 06a1ab6..75d2de37 100644
--- a/packages/CompanionDeviceManager/res/values-vi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Chọn một <xliff:g id="PROFILE_NAME">%1$s</xliff:g> sẽ do <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> quản lý"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"thiết bị"</string>
<string name="profile_name_watch" msgid="576290739483672360">"đồng hồ"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Đặt <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> để quản lý <xliff:g id="PROFILE_NAME">%2$s</xliff:g> của bạn – <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Cần có <xliff:g id="APP_NAME">%1$s</xliff:g> để quản lý <xliff:g id="PROFILE_NAME">%2$s</xliff:g> của bạn. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Có"</string>
- <string name="consent_no" msgid="1335543792857823917">"Không, cảm ơn"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
index 12bfcf3..788f8f9 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"选择要由<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"设备"</string>
<string name="profile_name_watch" msgid="576290739483672360">"手表"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"设为由<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>管理您的<xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"若要管理<xliff:g id="PROFILE_NAME">%2$s</xliff:g>,您需要使用<xliff:g id="APP_NAME">%1$s</xliff:g>。<xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"好"</string>
- <string name="consent_no" msgid="1335543792857823917">"不用了"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index 0c583b2..576f3f4 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"選擇由 <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> 管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
<string name="profile_name_watch" msgid="576290739483672360">"手錶"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"設定 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 來管理您的 <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"必須使用 <xliff:g id="APP_NAME">%1$s</xliff:g> 來管理您的<xliff:g id="PROFILE_NAME">%2$s</xliff:g>。<xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"是"</string>
- <string name="consent_no" msgid="1335543792857823917">"不用了,謝謝"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index 519f0e8..8a50658 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"選擇要讓「<xliff:g id="APP_NAME">%2$s</xliff:g>」<strong></strong>管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
<string name="profile_name_watch" msgid="576290739483672360">"手錶"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"授權讓「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>管理你的<xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"如要管理你的<xliff:g id="PROFILE_NAME">%2$s</xliff:g>,必須使用「<xliff:g id="APP_NAME">%1$s</xliff:g>」。<xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"是"</string>
- <string name="consent_no" msgid="1335543792857823917">"不用了,謝謝"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml
index 7721b54..fc3f19d 100644
--- a/packages/CompanionDeviceManager/res/values-zu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Khetha i-<xliff:g id="PROFILE_NAME">%1$s</xliff:g> ezophathwa yi-<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"idivayisi"</string>
<string name="profile_name_watch" msgid="576290739483672360">"buka"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Setha i-<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ukuba iphathe i-<xliff:g id="PROFILE_NAME">%2$s</xliff:g> - <strong><xliff:g id="DEVICE_NAME">%3$s</xliff:g></strong>"</string>
- <string name="profile_summary" msgid="2009764182871566255">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> iyadingeka ukuphatha i-<xliff:g id="PROFILE_NAME">%2$s</xliff:g> yakho. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Yebo"</string>
- <string name="consent_no" msgid="1335543792857823917">"Cha ngiyabonga"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt
index 6df57c1..5b64d52 100644
--- a/packages/Connectivity/framework/api/module-lib-current.txt
+++ b/packages/Connectivity/framework/api/module-lib-current.txt
@@ -8,7 +8,7 @@
public class ConnectivityManager {
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 @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @Nullable android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
+ method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
}
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index bbf4559..3314af5 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -20,6 +20,7 @@
import static android.net.NetworkRequest.Type.BACKGROUND_REQUEST;
import static android.net.NetworkRequest.Type.LISTEN;
import static android.net.NetworkRequest.Type.REQUEST;
+import static android.net.NetworkRequest.Type.TRACK_BEST;
import static android.net.NetworkRequest.Type.TRACK_DEFAULT;
import static android.net.NetworkRequest.Type.TRACK_SYSTEM_DEFAULT;
import static android.net.QosCallback.QosCallbackRegistrationException;
@@ -4190,6 +4191,18 @@
}
/**
+ * @hide
+ */
+ // TODO: Make it public api.
+ @SuppressLint("ExecutorRegistration")
+ public void registerBestMatchingNetworkCallback(@NonNull NetworkRequest request,
+ @NonNull NetworkCallback networkCallback, @NonNull Handler handler) {
+ final NetworkCapabilities nc = request.networkCapabilities;
+ final CallbackHandler cbHandler = new CallbackHandler(handler);
+ sendRequestForNetwork(nc, networkCallback, 0, TRACK_BEST, TYPE_NONE, cbHandler);
+ }
+
+ /**
* Requests bandwidth update for a given {@link Network} and returns whether the update request
* is accepted by ConnectivityService. Once accepted, ConnectivityService will poll underlying
* network connection for updated bandwidth information. The caller will be notified via
@@ -4979,10 +4992,10 @@
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
})
public void requestBackgroundNetwork(@NonNull NetworkRequest request,
- @Nullable Handler handler, @NonNull NetworkCallback networkCallback) {
+ @NonNull Handler handler, @NonNull NetworkCallback networkCallback) {
final NetworkCapabilities nc = request.networkCapabilities;
sendRequestForNetwork(nc, networkCallback, 0, BACKGROUND_REQUEST,
- TYPE_NONE, handler == null ? getDefaultHandler() : new CallbackHandler(handler));
+ TYPE_NONE, new CallbackHandler(handler));
}
/**
diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
index 17a8ee1..aa69756 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
@@ -114,6 +114,10 @@
* for the network (if any) that satisfies the default Internet
* request.
*
+ * - TRACK_BEST, which causes the framework to send callbacks about
+ * the single, highest scoring current network (if any) that matches
+ * the specified NetworkCapabilities.
+ *
* - BACKGROUND_REQUEST, like REQUEST but does not cause any networks
* to retain the NET_CAPABILITY_FOREGROUND capability. A network with
* no foreground requests is in the background. A network that has
@@ -136,6 +140,7 @@
REQUEST,
BACKGROUND_REQUEST,
TRACK_SYSTEM_DEFAULT,
+ TRACK_BEST,
};
/**
diff --git a/packages/Connectivity/service/Android.bp b/packages/Connectivity/service/Android.bp
index 2fb9f72..f630cea 100644
--- a/packages/Connectivity/service/Android.bp
+++ b/packages/Connectivity/service/Android.bp
@@ -60,12 +60,14 @@
"services.core",
"services.net",
"unsupportedappusage",
+ "ServiceConnectivityResources",
],
static_libs: [
"modules-utils-os",
"net-utils-device-common",
"net-utils-framework-common",
"netd-client",
+ "PlatformProperties",
],
apex_available: [
"//apex_available:platform",
@@ -76,7 +78,7 @@
java_library {
name: "service-connectivity",
installable: true,
- static_libs:[
+ static_libs: [
"service-connectivity-pre-jarjar",
],
jarjar_rules: "jarjar-rules.txt",
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/Android.bp b/packages/Connectivity/service/ServiceConnectivityResources/Android.bp
new file mode 100644
index 0000000..f2446b7
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/Android.bp
@@ -0,0 +1,35 @@
+//
+// 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.
+//
+
+// APK to hold all the wifi overlayable resources.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_app {
+ name: "ServiceConnectivityResources",
+ sdk_version: "system_current",
+ resource_dirs: [
+ "res",
+ ],
+ privileged: true,
+ export_package_resources: true,
+ apex_available: [
+ "com.android.tethering",
+ ],
+ // TODO: use a dedicated cert once generated
+ certificate: "platform",
+}
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/AndroidManifest.xml b/packages/Connectivity/service/ServiceConnectivityResources/AndroidManifest.xml
new file mode 100644
index 0000000..2c30302
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?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.
+ */
+-->
+<!-- Manifest for connectivity resources APK -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.connectivity.resources"
+ coreApp="true"
+ android:versionCode="1"
+ android:versionName="S-initial">
+ <application
+ android:label="@string/connectivityResourcesAppLabel"
+ android:defaultToDeviceProtectedStorage="true"
+ android:directBootAware="true">
+ <!-- This is only used to identify this app by resolving the action.
+ The activity is never actually triggered. -->
+ <activity android:name="android.app.Activity" android:exported="true" android:enabled="true">
+ <intent-filter>
+ <action android:name="com.android.server.connectivity.intent.action.SERVICE_CONNECTIVITY_RESOURCES_APK" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml
new file mode 100644
index 0000000..7d98c76
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values/config.xml
@@ -0,0 +1,45 @@
+<?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.
+ -->
+
+<!-- Configuration values for ConnectivityService
+ DO NOT EDIT THIS FILE for specific device configuration; instead, use a Runtime Resources
+ Overlay package following the overlayable.xml configuration in the same directory:
+ https://source.android.com/devices/architecture/rros -->
+<resources>
+
+ <!-- Configuration hook for the URL returned by ConnectivityManager#getCaptivePortalServerUrl.
+ If empty, the returned value is controlled by Settings.Global.CAPTIVE_PORTAL_HTTP_URL,
+ and if that value is empty, the framework will use a hard-coded default.
+ This is *NOT* a URL that will always be used by the system network validation to detect
+ captive portals: NetworkMonitor may use different strategies and will not necessarily use
+ this URL. NetworkMonitor behaviour should be configured with NetworkStack resource overlays
+ instead. -->
+ <!--suppress CheckTagEmptyBody -->
+ <string translatable="false" name="config_networkCaptivePortalServerUrl"></string>
+
+ <!-- The maximum duration (in milliseconds) we expect a network transition to take -->
+ <integer name="config_networkTransitionTimeout">60000</integer>
+
+ <!-- Configuration of network interfaces that support WakeOnLAN -->
+ <string-array translatable="false" name="config_wakeonlan_supported_interfaces">
+ <!--
+ <item>wlan0</item>
+ <item>eth0</item>
+ -->
+ </string-array>
+
+</resources>
\ No newline at end of file
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml
new file mode 100644
index 0000000..00ec2df
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values/overlayable.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <overlayable name="ServiceConnectivityResourcesConfig">
+ <policy type="product|system|vendor">
+ <!-- Configuration values for ConnectivityService -->
+ <item type="string" name="config_networkCaptivePortalServerUrl"/>
+ <item type="integer" name="config_networkTransitionTimeout"/>
+ <item type="array" name="config_wakeonlan_supported_interfaces"/>
+
+
+ </policy>
+ </overlayable>
+</resources>
diff --git a/packages/Connectivity/service/ServiceConnectivityResources/res/values/strings.xml b/packages/Connectivity/service/ServiceConnectivityResources/res/values/strings.xml
new file mode 100644
index 0000000..2c7b992
--- /dev/null
+++ b/packages/Connectivity/service/ServiceConnectivityResources/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?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.
+ -->
+<resources>
+ <!-- The System Connectivity Resources package is an internal system package that provides
+ configuration values for system networking that were pre-configured in the device. This
+ is the name of the package to display in the list of system apps. [CHAR LIMIT=40] -->
+ <string name="connectivityResourcesAppLabel">System Connectivity Resources</string>
+</resources>
\ No newline at end of file
diff --git a/packages/Connectivity/service/jarjar-rules.txt b/packages/Connectivity/service/jarjar-rules.txt
index d8c60a4..a7b419b 100644
--- a/packages/Connectivity/service/jarjar-rules.txt
+++ b/packages/Connectivity/service/jarjar-rules.txt
@@ -1,3 +1,4 @@
+rule android.sysprop.** com.android.connectivity.sysprop.@1
rule com.android.net.module.util.** com.android.connectivity.net-utils.@1
rule com.android.modules.utils.** com.android.connectivity.modules-utils.@1
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
index 4ef5e2b..59ea9f0 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
@@ -320,7 +320,7 @@
}
}
- private void installScratch() throws IOException, InterruptedException {
+ private void installScratch() throws IOException {
final long scratchSize = mDynSystem.suggestScratchSize();
Thread thread = new Thread() {
@Override
@@ -347,7 +347,11 @@
publishProgress(progress);
}
- Thread.sleep(100);
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ // Ignore the error.
+ }
}
if (mInstallationSession == null) {
@@ -361,7 +365,7 @@
}
}
- private void installUserdata() throws IOException, InterruptedException {
+ private void installUserdata() throws IOException {
Thread thread = new Thread(() -> {
mInstallationSession = mDynSystem.createPartition("userdata", mUserdataSize, false);
});
@@ -383,7 +387,11 @@
publishProgress(progress);
}
- Thread.sleep(100);
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ // Ignore the error.
+ }
}
if (mInstallationSession == null) {
@@ -397,8 +405,7 @@
}
}
- private void installImages()
- throws IOException, InterruptedException, ImageValidationException {
+ private void installImages() throws IOException, ImageValidationException {
if (mStream != null) {
if (mIsZip) {
installStreamingZipUpdate();
@@ -410,14 +417,12 @@
}
}
- private void installStreamingGzUpdate()
- throws IOException, InterruptedException, ImageValidationException {
+ private void installStreamingGzUpdate() throws IOException, ImageValidationException {
Log.d(TAG, "To install a streaming GZ update");
installImage("system", mSystemSize, new GZIPInputStream(mStream));
}
- private void installStreamingZipUpdate()
- throws IOException, InterruptedException, ImageValidationException {
+ private void installStreamingZipUpdate() throws IOException, ImageValidationException {
Log.d(TAG, "To install a streaming ZIP update");
ZipInputStream zis = new ZipInputStream(mStream);
@@ -432,8 +437,7 @@
}
}
- private void installLocalZipUpdate()
- throws IOException, InterruptedException, ImageValidationException {
+ private void installLocalZipUpdate() throws IOException, ImageValidationException {
Log.d(TAG, "To install a local ZIP update");
Enumeration<? extends ZipEntry> entries = mZipFile.entries();
@@ -449,7 +453,7 @@
}
private boolean installImageFromAnEntry(ZipEntry entry, InputStream is)
- throws IOException, InterruptedException, ImageValidationException {
+ throws IOException, ImageValidationException {
String name = entry.getName();
Log.d(TAG, "ZipEntry: " + name);
@@ -473,7 +477,7 @@
}
private void installImage(String partitionName, long uncompressedSize, InputStream is)
- throws IOException, InterruptedException, ImageValidationException {
+ throws IOException, ImageValidationException {
SparseInputStream sis = new SparseInputStream(new BufferedInputStream(is));
@@ -504,7 +508,11 @@
return;
}
- Thread.sleep(100);
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ // Ignore the error.
+ }
}
if (mInstallationSession == null) {
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
index ed49bf4..231babe 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
@@ -20,4 +20,8 @@
],
sdk_version: "system_current",
min_sdk_version: "21",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.cellbroadcast",
+ ],
}
diff --git a/packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down_24dp.xml b/packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down.xml
similarity index 86%
rename from packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down_24dp.xml
rename to packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down.xml
index 827d0b5..0544526 100644
--- a/packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down_24dp.xml
+++ b/packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down.xml
@@ -16,11 +16,11 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="24"
- android:viewportHeight="24"
+ android:viewportWidth="18"
+ android:viewportHeight="18"
android:width="24dp"
android:height="24dp">
<path
android:pathData="M7 10l5 5 5 -5z"
- android:fillColor="?android:attr/textColorPrimary"/>
-</vector>
\ No newline at end of file
+ android:fillColor="@android:color/black"/>
+</vector>
diff --git a/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml
index 263c16b..b38e3e3 100644
--- a/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml
+++ b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml
@@ -24,21 +24,21 @@
android:bottom="8dp">
<shape>
<corners
- android:radius="20dp"/>
+ android:radius="28dp"/>
<solid
- android:color="?android:attr/colorPrimary"/>
+ android:color="?android:attr/colorAccent"/>
<stroke
- android:color="#1f000000"
+ android:color="?android:attr/colorPrimary"
android:width="1dp"/>
<size
- android:height="32dp"/>
+ android:height="@dimen/spinner_height"/>
</shape>
</item>
<item
android:gravity="center|end"
- android:width="24dp"
- android:height="24dp"
- android:end="4dp"
- android:drawable="@drawable/arrow_drop_down_24dp"/>
+ android:width="18dp"
+ android:height="18dp"
+ android:end="8dp"
+ android:drawable="@drawable/arrow_drop_down"/>
</layer-list>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down_24dp.xml b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_dropdown_background.xml
similarity index 60%
copy from packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down_24dp.xml
copy to packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_dropdown_background.xml
index 827d0b5..8cac988 100644
--- a/packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down_24dp.xml
+++ b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_dropdown_background.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2018 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.
@@ -15,12 +15,19 @@
limitations under the License.
-->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="24"
- android:viewportHeight="24"
- android:width="24dp"
- android:height="24dp">
- <path
- android:pathData="M7 10l5 5 5 -5z"
- android:fillColor="?android:attr/textColorPrimary"/>
-</vector>
\ No newline at end of file
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item>
+ <shape>
+ <solid
+ android:color="?android:attr/colorAccent"/>
+ </shape>
+ </item>
+
+ <item>
+ <shape>
+ <solid android:color="#BBFFFFFF"/>
+ </shape>
+ </item>
+
+</layer-list>
diff --git a/packages/SystemUI/res/drawable/controls_dialog_bg.xml b/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_dropdown_view.xml
similarity index 65%
copy from packages/SystemUI/res/drawable/controls_dialog_bg.xml
copy to packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_dropdown_view.xml
index 1ccb176..a342c84 100644
--- a/packages/SystemUI/res/drawable/controls_dialog_bg.xml
+++ b/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_dropdown_view.xml
@@ -14,8 +14,12 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="?android:attr/colorBackground" />
- <corners android:radius="@dimen/notification_corner_radius" />
-</shape>
+
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ style="@style/SettingsSpinnerTitleBar"
+ android:gravity="center_vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/settings_spinner_dropdown_background"/>
diff --git a/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_view.xml b/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_view.xml
index bdd370f..75de34e 100644
--- a/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_view.xml
+++ b/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_view.xml
@@ -19,7 +19,5 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="@style/SettingsSpinnerTitleBar"
- android:maxLines="1"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:ellipsize="marquee"/>
+ android:layout_height="wrap_content"/>
diff --git a/packages/SystemUI/res/drawable/controls_dialog_bg.xml b/packages/SettingsLib/SettingsSpinner/res/values/dimens.xml
similarity index 66%
rename from packages/SystemUI/res/drawable/controls_dialog_bg.xml
rename to packages/SettingsLib/SettingsSpinner/res/values/dimens.xml
index 1ccb176..d526df6 100644
--- a/packages/SystemUI/res/drawable/controls_dialog_bg.xml
+++ b/packages/SettingsLib/SettingsSpinner/res/values/dimens.xml
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 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.
@@ -14,8 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="?android:attr/colorBackground" />
- <corners android:radius="@dimen/notification_corner_radius" />
-</shape>
+
+<resources>
+ <dimen name="spinner_height">36dp</dimen>
+ <dimen name="spinner_padding_top_or_bottom">8dp</dimen>
+</resources>
diff --git a/packages/SettingsLib/SettingsSpinner/res/values/styles.xml b/packages/SettingsLib/SettingsSpinner/res/values/styles.xml
index 8af20e2..f665f38 100644
--- a/packages/SettingsLib/SettingsSpinner/res/values/styles.xml
+++ b/packages/SettingsLib/SettingsSpinner/res/values/styles.xml
@@ -18,9 +18,13 @@
<resources>
<style name="SettingsSpinnerTitleBar">
<item name="android:textAppearance">?android:attr/textAppearanceButton</item>
+ <item name="android:textColor">@android:color/black</item>
+ <item name="android:maxLines">1</item>
+ <item name="android:ellipsize">marquee</item>
+ <item name="android:minHeight">@dimen/spinner_height</item>
<item name="android:paddingStart">16dp</item>
<item name="android:paddingEnd">36dp</item>
- <item name="android:paddingTop">8dp</item>
- <item name="android:paddingBottom">8dp</item>
+ <item name="android:paddingTop">@dimen/spinner_padding_top_or_bottom</item>
+ <item name="android:paddingBottom">@dimen/spinner_padding_top_or_bottom</item>
</style>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java
index 5ef8f7a..0be80a9f 100644
--- a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java
+++ b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java
@@ -121,4 +121,11 @@
int mode) {
super(context, attrs, defStyleAttr, defStyleRes, mode, null);
}
-}
\ No newline at end of file
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ setDropDownVerticalOffset(getMeasuredHeight() - (int) getContext().getResources()
+ .getDimension(R.dimen.spinner_padding_top_or_bottom));
+ }
+}
diff --git a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinnerAdapter.java b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinnerAdapter.java
index a8ca0d8..83da512 100644
--- a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinnerAdapter.java
+++ b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinnerAdapter.java
@@ -30,8 +30,7 @@
public class SettingsSpinnerAdapter<T> extends ArrayAdapter<T> {
private static final int DEFAULT_RESOURCE = R.layout.settings_spinner_view;
- private static final int DFAULT_DROPDOWN_RESOURCE =
- android.R.layout.simple_spinner_dropdown_item;
+ private static final int DFAULT_DROPDOWN_RESOURCE = R.layout.settings_spinner_dropdown_view;
private final LayoutInflater mDefaultInflater;
/**
diff --git a/packages/SettingsLib/SettingsTheme/Android.bp b/packages/SettingsLib/SettingsTheme/Android.bp
index bda863a..73459c2 100644
--- a/packages/SettingsLib/SettingsTheme/Android.bp
+++ b/packages/SettingsLib/SettingsTheme/Android.bp
@@ -18,4 +18,8 @@
sdk_version: "system_current",
min_sdk_version: "21",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.cellbroadcast",
+ ],
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index ed2b6c9..e8e10a4 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -153,6 +153,7 @@
VALIDATORS.put(Secure.DOZE_TAP_SCREEN_GESTURE, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.DOZE_WAKE_DISPLAY_GESTURE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.DOZE_QUICK_PICKUP_GESTURE, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.NFC_PAYMENT_DEFAULT_COMPONENT, COMPONENT_NAME_VALIDATOR);
VALIDATORS.put(
Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN, NON_NEGATIVE_INTEGER_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index e427981..400742b 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -1937,8 +1937,11 @@
if (UserHandle.getAppId(Binder.getCallingUid()) < Process.FIRST_APPLICATION_UID) {
return;
}
- checkReadableAnnotation(settingsType, settingName);
ApplicationInfo ai = getCallingApplicationInfoOrThrow();
+ if (ai.isSystemApp() || ai.isSignedWithPlatformKey()) {
+ return;
+ }
+ checkReadableAnnotation(settingsType, settingName);
if (!ai.isInstantApp()) {
return;
}
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 4dc6d14..c520568 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -745,6 +745,7 @@
Settings.Secure.SILENCE_GESTURE,
Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
+ Settings.Secure.DOZE_QUICK_PICKUP_GESTURE,
Settings.Secure.FACE_UNLOCK_RE_ENROLL,
Settings.Secure.TAP_GESTURE,
Settings.Secure.NEARBY_SHARING_COMPONENT, // not user configurable
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b6d942a..e0097df 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -578,7 +578,7 @@
<!-- People Space UI Screen -->
<activity android:name=".people.PeopleSpaceActivity"
- android:label="People"
+ android:label="@string/people_tile_title"
android:enabled="true"
android:exported="true"
android:theme="@android:style/Theme.Material.NoActionBar">
@@ -592,7 +592,7 @@
<!-- People Space Widget -->
<receiver
android:name=".people.widget.PeopleSpaceWidgetProvider"
- android:label="People Space"
+ android:label="@string/people_tile_title"
android:enabled="true"
android:exported="true">
<intent-filter>
@@ -751,6 +751,17 @@
android:visibleToInstantApps="true">
</activity>
+ <activity android:name=".controls.ui.ControlsActivity"
+ android:label="@string/quick_controls_title"
+ android:theme="@style/Theme.ControlsActivity"
+ android:excludeFromRecents="true"
+ android:showWhenLocked="true"
+ android:showForAllUsers="true"
+ android:launchMode="singleInstance"
+ android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
+ android:visibleToInstantApps="true">
+ </activity>
+
<receiver android:name=".controls.management.ControlsRequestReceiver"
android:exported="true">
<intent-filter>
diff --git a/packages/SystemUI/res/drawable/qs_footer_action_chip_background.xml b/packages/SystemUI/res/drawable/qs_footer_action_chip_background.xml
new file mode 100644
index 0000000..34675ab
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_footer_action_chip_background.xml
@@ -0,0 +1,37 @@
+<?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.
+ -->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:insetTop="@dimen/qs_footer_action_inset"
+ android:insetBottom="@dimen/qs_footer_action_inset">
+ <ripple
+ android:color="?android:attr/colorControlHighlight"
+ android:height="44dp">
+ <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">
+ <stroke android:width="1dp" android:color="@color/qs_footer_action_border"/>
+ <solid android:color="@android:color/transparent"/>
+ <corners android:radius="@dimen/screenshot_button_corner_radius"/>
+ </shape>
+ </item>
+ </ripple>
+</inset>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_footer_action_chip_background_borderless.xml b/packages/SystemUI/res/drawable/qs_footer_action_chip_background_borderless.xml
new file mode 100644
index 0000000..596ed71
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_footer_action_chip_background_borderless.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.
+ -->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:insetTop="@dimen/qs_footer_action_inset"
+ android:insetBottom="@dimen/qs_footer_action_inset">
+ <ripple
+ android:color="?android:attr/colorControlHighlight">
+ <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="@android:color/transparent"/>
+ <corners android:radius="@dimen/screenshot_button_corner_radius"/>
+ </shape>
+ </item>
+ </ripple>
+</inset>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/auth_biometric_contents.xml b/packages/SystemUI/res/layout/auth_biometric_contents.xml
index aed067c..eef37ab 100644
--- a/packages/SystemUI/res/layout/auth_biometric_contents.xml
+++ b/packages/SystemUI/res/layout/auth_biometric_contents.xml
@@ -39,37 +39,34 @@
<Space android:id="@+id/space_above_icon"
android:layout_width="match_parent"
- android:layout_height="48dp"
- android:visibility="visible" />
+ android:layout_height="48dp" />
- <!-- Use a frame layout since certain biometrics (such as UDFPS) require the icon to be centered
- within a certain area on the display. This makes it easy to 1) guarantee max size, and
- 2) center the icon within the reserved area. -->
- <FrameLayout android:id="@+id/biometric_icon_frame"
+ <FrameLayout
+ android:id="@+id/biometric_icon_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal">
+
<ImageView
android:id="@+id/biometric_icon"
android:layout_width="@dimen/biometric_dialog_biometric_icon_size"
android:layout_height="@dimen/biometric_dialog_biometric_icon_size"
android:layout_gravity="center"
android:scaleType="fitXY" />
+
</FrameLayout>
- <!-- For sensors such as UDFPS, this view is used during custom measurement/layoutto add extra
+ <!-- For sensors such as UDFPS, this view is used during custom measurement/layout to add extra
padding so that the biometric icon is always in the right physical position. -->
<Space android:id="@+id/space_below_icon"
android:layout_width="match_parent"
- android:layout_height="0dp"
- android:visibility="gone" />
+ android:layout_height="12dp" />
<TextView
android:id="@+id/indicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="24dp"
- android:paddingVertical="12dp"
android:textSize="12sp"
android:gravity="center_horizontal"
android:accessibilityLiveRegion="polite"
@@ -84,6 +81,7 @@
style="?android:attr/buttonBarStyle"
android:orientation="horizontal"
android:paddingTop="16dp">
+
<Space android:id="@+id/leftSpacer"
android:layout_width="8dp"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/controls_detail_dialog.xml b/packages/SystemUI/res/layout/controls_detail_dialog.xml
index ee5315a..28fc863 100644
--- a/packages/SystemUI/res/layout/controls_detail_dialog.xml
+++ b/packages/SystemUI/res/layout/controls_detail_dialog.xml
@@ -20,8 +20,8 @@
android:id="@+id/control_detail_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginTop="@dimen/controls_activity_view_top_offset"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:background="@android:color/black">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -30,7 +30,7 @@
<ImageView
android:id="@+id/control_detail_close"
android:contentDescription="@string/accessibility_desc_close"
- android:src="@drawable/ic_close"
+ android:src="@drawable/ic_arrow_back"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:tint="@color/control_primary_text"
android:layout_width="48dp"
@@ -56,7 +56,6 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
- android:background="@android:color/black"
android:orientation="vertical" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/controls_in_dialog.xml b/packages/SystemUI/res/layout/controls_fullscreen.xml
similarity index 86%
rename from packages/SystemUI/res/layout/controls_in_dialog.xml
rename to packages/SystemUI/res/layout/controls_fullscreen.xml
index 983999f..1b2d2e2 100644
--- a/packages/SystemUI/res/layout/controls_in_dialog.xml
+++ b/packages/SystemUI/res/layout/controls_fullscreen.xml
@@ -20,11 +20,8 @@
android:id="@+id/control_detail_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginVertical="@dimen/controls_activity_view_top_offset"
- android:layout_marginHorizontal="@dimen/controls_activity_view_side_offset"
- android:padding="8dp"
android:orientation="vertical"
- android:background="@drawable/controls_dialog_bg">
+ android:background="@android:color/black">
<com.android.systemui.globalactions.MinHeightScrollView
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/controls_with_favorites.xml b/packages/SystemUI/res/layout/controls_with_favorites.xml
index b060afd..9d01148 100644
--- a/packages/SystemUI/res/layout/controls_with_favorites.xml
+++ b/packages/SystemUI/res/layout/controls_with_favorites.xml
@@ -25,8 +25,21 @@
<!-- make sure the header stays centered in the layout by adding a spacer -->
<Space
+ android:id="@+id/controls_spacer"
android:layout_width="@dimen/controls_header_menu_size"
- android:layout_height="1dp" />
+ android:layout_height="1dp"
+ android:visibility="gone" />
+
+ <ImageView
+ android:id="@+id/controls_close"
+ android:contentDescription="@string/accessibility_desc_close"
+ android:src="@drawable/ic_close"
+ android:background="?android:attr/selectableItemBackgroundBorderless"
+ android:tint="@color/control_primary_text"
+ android:layout_width="@dimen/controls_header_menu_size"
+ android:layout_height="@dimen/controls_header_menu_size"
+ android:padding="12dp"
+ android:visibility="gone" />
<!-- need to keep this outer view in order to have a correctly sized anchor
for the dropdown menu, as well as dropdown background in the right place -->
<LinearLayout
diff --git a/packages/SystemUI/res/layout/people_space_activity.xml b/packages/SystemUI/res/layout/people_space_activity.xml
index 07af01b..1784cae 100644
--- a/packages/SystemUI/res/layout/people_space_activity.xml
+++ b/packages/SystemUI/res/layout/people_space_activity.xml
@@ -25,19 +25,30 @@
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="vertical"
- android:padding="16dp"
+ android:padding="24dp"
android:clipChildren="false"
android:clipToPadding="false">
<TextView
- android:id="@+id/select_conversation"
- android:text="@string/select_conversation_text"
- android:layout_width="match_parent"
+ android:id="@+id/select_conversation_title"
+ android:gravity="center"
+ android:text="@string/select_conversation_title"
+ android:layout_width="wrap_content"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
android:textSize="24sp"
android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"/>
+
+ <TextView
+ android:id="@+id/select_conversation"
+ android:gravity="center"
+ android:text="@string/select_conversation_text"
+ android:layout_width="match_parent"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+ android:textSize="16sp"
+ android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
- android:paddingBottom="16dp" />
+ android:padding="24dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/people_space_placeholder_layout.xml b/packages/SystemUI/res/layout/people_space_placeholder_layout.xml
new file mode 100644
index 0000000..3ced1ff
--- /dev/null
+++ b/packages/SystemUI/res/layout/people_space_placeholder_layout.xml
@@ -0,0 +1,75 @@
+<!--
+ ~ 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.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+ <LinearLayout
+ android:background="@drawable/people_space_tile_view_card"
+ android:id="@+id/item"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:gravity="center"
+ android:paddingVertical="2dp"
+ android:paddingHorizontal="8dp"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <ImageView
+ android:background="@drawable/ic_person"
+ android:id="@+id/person_icon_only"
+ android:layout_width="60dp"
+ android:layout_height="60dp"/>
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:paddingStart="8dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:id="@+id/availability"
+ android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:background="@drawable/circle_green_10dp"/>
+ <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>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_carrier.xml b/packages/SystemUI/res/layout/qs_carrier.xml
index a5b8cfa..c521dc2 100644
--- a/packages/SystemUI/res/layout/qs_carrier.xml
+++ b/packages/SystemUI/res/layout/qs_carrier.xml
@@ -28,13 +28,6 @@
android:clipToPadding="false"
android:focusable="true" >
- <include
- layout="@layout/mobile_signal_group"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="@dimen/qs_carrier_margin_width"
- android:visibility="gone" />
-
<com.android.systemui.util.AutoMarqueeTextView
android:id="@+id/qs_carrier_text"
android:layout_width="wrap_content"
@@ -46,4 +39,11 @@
android:singleLine="true"
android:maxEms="7"/>
+ <include
+ layout="@layout/mobile_signal_group"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/qs_carrier_margin_width"
+ android:visibility="gone" />
+
</com.android.systemui.qs.carrier.QSCarrier>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml
index 93dd1a1..0217972 100644
--- a/packages/SystemUI/res/layout/qs_footer_impl.xml
+++ b/packages/SystemUI/res/layout/qs_footer_impl.xml
@@ -89,7 +89,7 @@
android:background="?android:attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:clipToPadding="false"
- android:contentDescription="@string/accessibility_quick_settings_edit"
+ android:contentDescription="@string/accessibility_quick_settings_power_menu"
android:focusable="true"
android:padding="@dimen/qs_footer_icon_padding"
android:src="@*android:drawable/ic_lock_power_off"
diff --git a/packages/SystemUI/res/layout/qs_footer_impl_two_lines.xml b/packages/SystemUI/res/layout/qs_footer_impl_two_lines.xml
new file mode 100644
index 0000000..726e69f
--- /dev/null
+++ b/packages/SystemUI/res/layout/qs_footer_impl_two_lines.xml
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 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.
+-->
+
+<!-- Extends FrameLayout -->
+<com.android.systemui.qs.QSFooterView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/qs_footer"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/qs_footer_height"
+ android:layout_marginStart="@dimen/qs_footer_margin"
+ android:layout_marginEnd="@dimen/qs_footer_margin"
+ android:background="@android:color/transparent"
+ android:baselineAligned="false"
+ android:clickable="false"
+ android:clipChildren="false"
+ android:clipToPadding="false">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="48dp"
+ android:layout_gravity="center_vertical">
+
+ <TextView
+ android:id="@+id/build"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:paddingStart="@dimen/qs_tile_margin_horizontal"
+ android:paddingEnd="4dp"
+ android:layout_weight="1"
+ android:clickable="true"
+ android:ellipsize="marquee"
+ android:focusable="true"
+ android:gravity="center_vertical"
+ android:singleLine="true"
+ android:textAppearance="@style/TextAppearance.QS.Status"
+ android:visibility="gone" />
+
+ <com.android.systemui.qs.PageIndicator
+ android:id="@+id/footer_page_indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_vertical"
+ android:visibility="gone" />
+
+ <View
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/qs_footer_actions_container"
+ android:layout_width="match_parent"
+ android:layout_height="48dp"
+ android:gravity="center_vertical">
+
+ <com.android.systemui.statusbar.AlphaOptimizedImageView
+ android:id="@android:id/edit"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/qs_footer_action_button_size"
+ android:layout_marginEnd="@dimen/qs_tile_margin_horizontal"
+ android:layout_weight="1"
+ android:background="@drawable/qs_footer_action_chip_background"
+ android:clickable="true"
+ android:clipToPadding="false"
+ android:contentDescription="@string/accessibility_quick_settings_edit"
+ android:focusable="true"
+ android:padding="@dimen/qs_footer_icon_padding"
+ android:src="@*android:drawable/ic_mode_edit"
+ android:tint="?android:attr/colorForeground" />
+
+ <com.android.systemui.statusbar.phone.MultiUserSwitch
+ android:id="@+id/multi_user_switch"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/qs_footer_action_button_size"
+ android:layout_marginEnd="@dimen/qs_tile_margin_horizontal"
+ android:layout_weight="1"
+ android:background="@drawable/qs_footer_action_chip_background"
+ android:focusable="true">
+
+ <ImageView
+ android:id="@+id/multi_user_avatar"
+ android:layout_width="@dimen/multi_user_avatar_expanded_size"
+ android:layout_height="@dimen/multi_user_avatar_expanded_size"
+ android:layout_gravity="center"
+ android:scaleType="centerInside" />
+ </com.android.systemui.statusbar.phone.MultiUserSwitch>
+
+ <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
+ android:id="@+id/settings_button_container"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/qs_footer_action_button_size"
+ android:layout_marginEnd="@dimen/qs_tile_margin_horizontal"
+ android:background="@drawable/qs_footer_action_chip_background"
+ android:layout_weight="1"
+ android:clipChildren="false"
+ android:clipToPadding="false">
+
+ <com.android.systemui.statusbar.phone.SettingsButton
+ android:id="@+id/settings_button"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/qs_footer_action_button_size"
+ android:layout_gravity="center"
+ android:contentDescription="@string/accessibility_quick_settings_settings"
+ android:background="@drawable/qs_footer_action_chip_background_borderless"
+ android:padding="@dimen/qs_footer_icon_padding"
+ android:scaleType="centerInside"
+ android:src="@drawable/ic_settings"
+ android:tint="?android:attr/colorForeground" />
+
+ <com.android.systemui.statusbar.AlphaOptimizedImageView
+ android:id="@+id/tuner_icon"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingStart="36dp"
+ android:paddingEnd="4dp"
+ android:src="@drawable/tuner"
+ android:tint="?android:attr/textColorTertiary"
+ android:visibility="invisible" />
+
+ </com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
+
+ <com.android.systemui.statusbar.AlphaOptimizedImageView
+ android:id="@+id/pm_lite"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/qs_footer_action_button_size"
+ android:layout_weight="1"
+ android:background="@drawable/qs_footer_action_chip_background"
+ android:clickable="true"
+ android:clipToPadding="false"
+ android:focusable="true"
+ android:padding="@dimen/qs_footer_icon_padding"
+ android:src="@*android:drawable/ic_lock_power_off"
+ android:contentDescription="@string/accessibility_quick_settings_power_menu"
+ android:tint="?android:attr/colorForeground" />
+
+ </LinearLayout>
+ </LinearLayout>
+
+</com.android.systemui.qs.QSFooterView>
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index 77f1743..d29cf87 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -42,7 +42,10 @@
android:background="@android:color/transparent"
android:focusable="true"
android:accessibilityTraversalBefore="@android:id/edit">
- <include layout="@layout/qs_footer_impl" />
+ <ViewStub
+ android:id="@+id/qs_footer_stub"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
<include layout="@layout/qs_media_divider"
android:id="@+id/divider"/>
</com.android.systemui.qs.QSPanel>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index c36f7cd..4241724 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -36,6 +36,7 @@
<color name="qs_user_detail_icon_muted">#FFFFFFFF</color> <!-- not so muted after all -->
<color name="qs_tile_disabled_color">#9E9E9E</color> <!-- 38% black -->
<color name="qs_customize_decoration">@color/GM2_grey_300</color>
+ <color name="qs_footer_action_border">#2E312C</color>
<!-- The color of the background in the separated list of the Global Actions menu -->
<color name="global_actions_separated_background">#F5F5F5</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index b75a0bc..92d9ca9 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -107,7 +107,7 @@
<!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
<string name="quick_settings_tiles_stock" translatable="false">
- wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse,reduce_brightness,cameratoggle,mictoggle,controls
+ wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse,reduce_brightness,cameratoggle,mictoggle,controls,alarm
</string>
<!-- The tiles to display in QuickSettings -->
@@ -180,6 +180,9 @@
<!-- Doze: duration to avoid false pickup gestures triggered by notification vibrations -->
<integer name="doze_pickup_vibration_threshold">2000</integer>
+ <!-- Doze: quick pickup duration to stay in AOD until the next gesture is triggered -->
+ <integer name="doze_quick_pickup_aod_duration">5000</integer>
+
<!-- Type of a sensor that provides a low-power estimate of the desired display
brightness, suitable to listen to while the device is asleep (e.g. during
always-on display) -->
@@ -577,6 +580,9 @@
<!-- Whether wallet view is shown in landscape / seascape orientations -->
<bool name="global_actions_show_landscape_wallet_view">false</bool>
+ <!-- Package name of the preferred system app to perform eSOS action -->
+ <string name="config_preferredEmergencySosPackage" translatable="false"></string>
+
<!-- Whether to use the split 2-column notification shade -->
<bool name="config_use_split_notification_shade">false</bool>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 392eb49..885cd25 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -167,15 +167,11 @@
and the notification won't use this much, but is measured with wrap_content -->
<dimen name="notification_messaging_actions_min_height">196dp</dimen>
- <!-- Height of a call notification. Note that this is an upper bound
- and the notification won't use this much, but is measured with wrap_content -->
- <dimen name="call_notification_full_height">172dp</dimen>
-
<!-- a threshold in dp per second that is considered fast scrolling -->
<dimen name="scroll_fast_threshold">1500dp</dimen>
<!-- Height of a the shelf with the notification icons -->
- <dimen name="notification_shelf_height">32dp</dimen>
+ <dimen name="notification_shelf_height">48dp</dimen>
<!-- Minimum height of a notification to be interactable -->
<dimen name="notification_min_interaction_height">40dp</dimen>
@@ -415,6 +411,9 @@
<!-- The size of each of the icon buttons in the QS footer -->
<dimen name="qs_footer_action_button_size">@dimen/qs_footer_height</dimen>
+ <!-- (48dp - 44dp) / 2 -->
+ <dimen name="qs_footer_action_inset">2dp</dimen>
+
<!-- Margins on each side of QS Footer -->
<dimen name="qs_footer_margin">2dp</dimen>
diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml
index e551892..8cd5757 100644
--- a/packages/SystemUI/res/values/flags.xml
+++ b/packages/SystemUI/res/values/flags.xml
@@ -46,4 +46,6 @@
<bool name="flag_navigation_bar_overlay">false</bool>
<bool name="flag_pm_lite">false</bool>
+
+ <bool name="flag_alarm_tile">false</bool>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 783f80c..6207449 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2312,6 +2312,9 @@
<!-- accessibility label for button to edit quick settings [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_edit">Edit order of settings.</string>
+ <!-- accessibility label for button to open power menu [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_power_menu">Power menu</string>
+
<!-- accessibility label for paging indicator in quick settings [CHAR LIMITi=NONE] -->
<string name="accessibility_quick_settings_page">Page <xliff:g name="current_page" example="1">%1$d</xliff:g> of <xliff:g name="num_pages" example="2">%2$d</xliff:g></string>
@@ -2808,44 +2811,44 @@
<!-- Text to display when copying the build number off QS [CHAR LIMIT=NONE]-->
<string name="build_number_copy_toast">Build number copied to clipboard.</string>
- <!-- Status for last interaction with exact time [CHAR LIMIT=120] -->
- <string name="last_interaction_status" translatable="false">Last chatted <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
- <!-- Status for last interaction when less than a certain time window [CHAR LIMIT=120] -->
- <string name="last_interaction_status_less_than" translatable="false">Last chatted less than <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
- <!-- Status for last interaction when over a certain time window [CHAR LIMIT=120] -->
- <string name="last_interaction_status_over" translatable="false">Last chatted over <xliff:g id="duration" example="1 week">%1$s</xliff:g> ago</string>
- <!-- Status for conversation without interaction data [CHAR LIMIT=120] -->
- <string name="basic_status" translatable="false">Open conversation</string>
- <!-- Status for conversation without interaction data [CHAR LIMIT=120] -->
- <string name="select_conversation_text" translatable="false">Select one conversation to show in your widget:</string>
- <!-- Timestamp for notification with exact time [CHAR LIMIT=120] -->
- <string name="timestamp" translatable="false"><xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
- <!-- Timestamp for notification when less than a certain time window [CHAR LIMIT=120] -->
- <string name="less_than_timestamp" translatable="false">Less than <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
- <!-- Timestamp for notification when over a certain time window [CHAR LIMIT=120] -->
- <string name="over_timestamp" translatable="false">Over <xliff:g id="duration" example="1 week">%1$s</xliff:g> ago</string>
- <!-- Status text for a birthday today [CHAR LIMIT=30] -->
- <string name="birthday_status" translatable="false">Birthday</string>
- <!-- Status text for an upcoming birthday [CHAR LIMIT=30] -->
- <string name="upcoming_birthday_status" translatable="false">Birthday soon</string>
- <!-- Status text for an anniversary [CHAR LIMIT=30] -->
- <string name="anniversary_status" translatable="false">Anniversary</string>
- <!-- Status text for sharing location [CHAR LIMIT=30] -->
- <string name="location_status" translatable="false">Sharing location</string>
- <!-- Status text for a new story posted [CHAR LIMIT=30] -->
- <string name="new_story_status" translatable="false">New story</string>
- <!-- Status text for watching a video [CHAR LIMIT=30] -->
- <string name="video_status" translatable="false">Watching</string>
- <!-- Status text for listening to audio [CHAR LIMIT=30] -->
- <string name="audio_status" translatable="false">Listening</string>
- <!-- Status text for playing a game [CHAR LIMIT=30] -->
- <string name="game_status" translatable="false">Playing</string>
- <!-- Empty user name before user has selected a friend [CHAR LIMIT=30] -->
- <string name="empty_user_name" translatable="false">Your friend</string>
- <!-- Empty status shown before user has selected a friend [CHAR LIMIT=30] -->
- <string name="empty_status" translatable="false">Their status</string>
- <!-- Default text for missed call notifications [CHAR LIMIT=30] -->
- <string name="missed_call" translatable="false">Missed call</string>
+ <!-- Status for conversation without interaction data [CHAR LIMIT=120] -->
+ <string name="basic_status">Open conversation</string>
+ <!--Title text for Conversation widget set up screen [CHAR LIMIT=180] -->
+ <string name="select_conversation_title">Conversation widgets</string>
+ <!--Text explaining to tap a conversation to select it show in their Conversation widget [CHAR LIMIT=180] -->
+ <string name="select_conversation_text">Tap a conversation to add it to your Home screen</string>
+ <!-- Timestamp for notification with exact time [CHAR LIMIT=25] -->
+ <string name="timestamp"><xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
+ <!-- Timestamp for notification when less than a certain time window [CHAR LIMIT=25] -->
+ <string name="less_than_timestamp">Less than <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
+ <!-- Timestamp for notification when over a certain time window [CHAR LIMIT=25] -->
+ <string name="over_timestamp">Over <xliff:g id="duration" example="1 week">%1$s</xliff:g> ago</string>
+ <!-- Status text on the Conversation widget for a birthday today [CHAR LIMIT=20] -->
+ <string name="birthday_status">Birthday</string>
+ <!-- Status text on the Conversation widget for an upcoming birthday [CHAR LIMIT=20] -->
+ <string name="upcoming_birthday_status">Birthday soon</string>
+ <!-- Status text on the Conversation widget for an anniversary [CHAR LIMIT=20] -->
+ <string name="anniversary_status">Anniversary</string>
+ <!-- Status text on the Conversation widget for sharing location [CHAR LIMIT=20] -->
+ <string name="location_status">Sharing location</string>
+ <!-- Status text on the Conversation widget for a new story posted [CHAR LIMIT=20] -->
+ <string name="new_story_status">New story</string>
+ <!-- Status text on the Conversation widget for watching a video [CHAR LIMIT=20] -->
+ <string name="video_status">Watching</string>
+ <!-- Status text on the Conversation widget for listening to audio [CHAR LIMIT=20] -->
+ <string name="audio_status">Listening</string>
+ <!-- Status text on the Conversation widget for playing a game [CHAR LIMIT=20] -->
+ <string name="game_status">Playing</string>
+ <!-- Empty user name before user has selected a friend for their Conversation widget [CHAR LIMIT=20] -->
+ <string name="empty_user_name">Friends</string>
+ <!-- Empty status shown before user has selected a friend for their Conversation widget [CHAR LIMIT=20] -->
+ <string name="empty_status">Let’s chat tonight!</string>
+ <!-- Default text for missed call notifications on their Conversation widget [CHAR LIMIT=20] -->
+ <string name="missed_call">Missed call</string>
+ <!-- Description text for adding a Conversation widget [CHAR LIMIT=100] -->
+ <string name="people_tile_description">See recent messages, missed calls, and status updates</string>
+ <!-- Title text displayed for the Conversation widget [CHAR LIMIT=50] -->
+ <string name="people_tile_title">Conversation</string>
<!-- Title to display in a notification when ACTION_BATTERY_CHANGED.EXTRA_PRESENT field is false
[CHAR LIMIT=NONE] -->
@@ -2858,4 +2861,7 @@
<string name="qs_remove_labels" translatable="false"></string>
<string name="qs_tile_label_fontFamily" translatable="false">@*android:string/config_headlineFontFamily</string>
+
+ <!-- Secondary label for alarm tile when there is no next alarm information [CHAR LIMIT=20] -->
+ <string name="qs_alarm_tile_no_alarm">No alarm set</string>
</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index ec26b8d..fb885cb 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -244,6 +244,8 @@
<item name="android:paddingTop">12dp</item>
<item name="android:paddingHorizontal">24dp</item>
<item name="android:textSize">24sp</item>
+ <item name="android:singleLine">true</item>
+ <item name="android:ellipsize">marquee</item>
</style>
<style name="TextAppearance.AuthCredential.Subtitle">
@@ -251,6 +253,8 @@
<item name="android:paddingTop">8dp</item>
<item name="android:paddingHorizontal">24dp</item>
<item name="android:textSize">16sp</item>
+ <item name="android:singleLine">true</item>
+ <item name="android:ellipsize">marquee</item>
</style>
<style name="TextAppearance.AuthCredential.Description">
@@ -258,6 +262,8 @@
<item name="android:paddingTop">8dp</item>
<item name="android:paddingHorizontal">24dp</item>
<item name="android:textSize">14sp</item>
+ <item name="android:singleLine">true</item>
+ <item name="android:ellipsize">marquee</item>
</style>
<style name="TextAppearance.AuthCredential.Error">
@@ -643,6 +649,16 @@
<item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
</style>
+ <style name="Theme.ControlsActivity" parent="@android:style/Theme.DeviceDefault.NoActionBar">
+ <item name="android:windowActivityTransitions">true</item>
+ <item name="android:windowContentTransitions">false</item>
+ <item name="android:windowIsTranslucent">false</item>
+ <item name="android:windowBackground">@android:color/transparent</item>
+ <item name="android:windowAnimationStyle">@null</item>
+ <item name="android:statusBarColor">@*android:color/transparent</item>
+ <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
+ </style>
+
<style name="Theme.CreateUser" parent="@style/Theme.SystemUI">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#33000000</item>
@@ -654,30 +670,12 @@
<item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
</style>
- <style name="Theme.SystemUI.Dialog.Control.DetailPanel" parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar">
- <item name="android:windowAnimationStyle">@style/Animation.Bottomsheet</item>
- <item name="android:windowFullscreen">true</item>
+ <style name="Theme.SystemUI.Dialog.Control.DetailPanel" parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar">
+ <item name="android:windowFullscreen">false</item>
<item name="android:windowIsFloating">false</item>
- <item name="android:windowBackground">@null</item>
- <item name="android:backgroundDimEnabled">true</item>
- </style>
-
- <style name="Animation.Bottomsheet">
- <item name="android:windowEnterAnimation">@anim/bottomsheet_in</item>
- <item name="android:windowExitAnimation">@anim/bottomsheet_out</item>
- </style>
-
- <style name="Theme.SystemUI.Dialog.Control.LockScreen" parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar">
- <item name="android:windowAnimationStyle">@style/Animation.ControlDialog</item>
- <item name="android:windowFullscreen">true</item>
- <item name="android:windowIsFloating">false</item>
- <item name="android:windowBackground">@null</item>
- <item name="android:backgroundDimEnabled">true</item>
- </style>
-
- <style name="Animation.ControlDialog">
- <item name="android:windowEnterAnimation">@*android:anim/dialog_enter</item>
- <item name="android:windowExitAnimation">@*android:anim/dialog_exit</item>
+ <item name="android:windowBackground">@android:color/black</item>
+ <item name="android:backgroundDimEnabled">false</item>
+ <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
</style>
<style name="Control" />
diff --git a/packages/SystemUI/res/xml/people_space_widget_info.xml b/packages/SystemUI/res/xml/people_space_widget_info.xml
index fbdac5e1..35188d8 100644
--- a/packages/SystemUI/res/xml/people_space_widget_info.xml
+++ b/packages/SystemUI/res/xml/people_space_widget_info.xml
@@ -20,8 +20,9 @@
android:minResizeWidth="110dp"
android:minResizeHeight="55dp"
android:updatePeriodMillis="60000"
- android:previewImage="@drawable/ic_person"
+ android:description="@string/people_tile_description"
+ android:previewLayout="@layout/people_space_placeholder_layout"
android:resizeMode="horizontal|vertical"
android:configure="com.android.systemui.people.PeopleSpaceActivity"
- android:initialLayout="@layout/people_space_widget">
+ android:initialLayout="@layout/people_space_placeholder_layout">
</appwidget-provider>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index a4054be..69e6ed0 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -2077,8 +2077,6 @@
boolean shouldListenForUdfps() {
return shouldListenForFingerprint()
&& !mBouncer
- && mStatusBarState != StatusBarState.SHADE_LOCKED
- && mStatusBarState != StatusBarState.FULLSCREEN_USER_SWITCHER
&& mStrongAuthTracker.hasUserAuthenticatedSinceBoot();
}
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 3852b24..fba34e0 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -367,7 +367,7 @@
}
/**
- * @param view The view to be dismissed
+ * @param animView The view to be dismissed
* @param velocity The desired pixels/second speed at which the view should move
* @param endAction The action to perform at the end
* @param delay The delay after which we should start
@@ -477,12 +477,8 @@
public void snapChild(final View animView, final float targetLeft, float velocity) {
final boolean canBeDismissed = mCallback.canChildBeDismissed(animView);
- AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- onTranslationUpdate(animView, (float) animation.getAnimatedValue(), canBeDismissed);
- }
- };
+ AnimatorUpdateListener updateListener = animation -> onTranslationUpdate(animView,
+ (float) animation.getAnimatedValue(), canBeDismissed);
Animator anim = getViewTranslationAnimator(animView, targetLeft, updateListener);
if (anim == null) {
@@ -501,8 +497,6 @@
mSnappingChild = false;
if (!wasCancelled) {
updateSwipeProgressFromOffset(animView, canBeDismissed);
- onChildSnappedBack(animView, targetLeft);
- mCallback.onChildSnappedBack(animView, targetLeft);
resetSwipeState();
}
}
@@ -513,6 +507,7 @@
mFlingAnimationUtils.apply(anim, getTranslation(animView), targetLeft, velocity,
maxDistance);
anim.start();
+ mCallback.onChildSnappedBack(animView, targetLeft);
}
/**
@@ -594,13 +589,12 @@
if (!mIsSwiping && !mMenuRowIntercepting) {
if (mCallback.getChildAtPosition(ev) != null) {
-
// We are dragging directly over a card, make sure that we also catch the gesture
// even if nobody else wants the touch event.
+ mTouchedView = mCallback.getChildAtPosition(ev);
onInterceptTouchEvent(ev);
return true;
} else {
-
// We are not doing anything, make sure the long press callback
// is not still ticking like a bomb waiting to go off.
cancelLongPress();
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index e85cafa..d3168c8 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -170,7 +170,9 @@
boolean visible = false;
if (mView != null) {
visible = mView.isShowing();
- mWindowManager.removeView(mView);
+ if (mView.isAttachedToWindow()) {
+ mWindowManager.removeView(mView);
+ }
}
mView = (AssistOrbContainer) LayoutInflater.from(mContext).inflate(
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricUdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricUdfpsView.java
index cc608ef..007080b 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricUdfpsView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricUdfpsView.java
@@ -16,17 +16,22 @@
package com.android.systemui.biometrics;
+import android.annotation.IdRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.graphics.Insets;
import android.graphics.Rect;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.Surface;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowManager;
+import android.widget.FrameLayout;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
/**
@@ -51,53 +56,38 @@
mSensorProps = prop;
}
- /**
- * For devices where the sensor is too high up, calculates the amount of padding necessary to
- * move/center the biometric icon within the sensor's physical location.
- */
- static int calculateBottomSpacerHeight(int displayHeightPx, int navbarHeightPx,
- int dialogBottomMarginPx, @NonNull View buttonBar, @NonNull View textIndicator,
- @NonNull FingerprintSensorPropertiesInternal sensorProperties) {
- final int sensorDistanceFromBottom = displayHeightPx - sensorProperties.sensorLocationY
- - sensorProperties.sensorRadius;
-
- final int spacerHeight = sensorDistanceFromBottom
- - textIndicator.getMeasuredHeight()
- - buttonBar.getMeasuredHeight()
- - dialogBottomMarginPx
- - navbarHeightPx;
-
- Log.d(TAG, "Display height: " + displayHeightPx
- + ", Distance from bottom: " + sensorDistanceFromBottom
- + ", Bottom margin: " + dialogBottomMarginPx
- + ", Navbar height: " + navbarHeightPx
- + ", Spacer height: " + spacerHeight);
-
- return spacerHeight;
+ @Override
+ @NonNull
+ AuthDialog.LayoutParams onMeasureInternal(int width, int height) {
+ final int displayRotation = getDisplay().getRotation();
+ switch (displayRotation) {
+ case Surface.ROTATION_0:
+ return onMeasureInternalPortrait(width, height);
+ case Surface.ROTATION_90:
+ case Surface.ROTATION_270:
+ return onMeasureInternalLandscape(width, height);
+ default:
+ Log.e(TAG, "Unsupported display rotation: " + displayRotation);
+ return super.onMeasureInternal(width, height);
+ }
}
- @Override
- AuthDialog.LayoutParams onMeasureInternal(int width, int height) {
- final View spaceBelowIcon = findViewById(R.id.space_below_icon);
- spaceBelowIcon.setVisibility(View.VISIBLE);
-
+ @NonNull
+ private AuthDialog.LayoutParams onMeasureInternalPortrait(int width, int height) {
// Get the height of the everything below the icon. Currently, that's the indicator and
- // button bar
- final View textIndicator = findViewById(R.id.indicator);
- final View buttonBar = findViewById(R.id.button_bar);
+ // button bar.
+ final int textIndicatorHeight = getViewHeightPx(R.id.indicator);
+ final int buttonBarHeight = getViewHeightPx(R.id.button_bar);
// Figure out where the bottom of the sensor anim should be.
// Navbar + dialogMargin + buttonBar + textIndicator + spacerHeight = sensorDistFromBottom
- final int dialogBottomMarginPx = getResources()
- .getDimensionPixelSize(R.dimen.biometric_dialog_border_padding);
- final WindowManager wm = getContext().getSystemService(WindowManager.class);
- final Rect bounds = wm.getCurrentWindowMetrics().getBounds();
- final int navbarHeight = wm.getCurrentWindowMetrics().getWindowInsets()
- .getInsets(WindowInsets.Type.navigationBars()).toRect().height();
- final int displayHeight = bounds.height();
-
- final int spacerHeight = calculateBottomSpacerHeight(displayHeight, navbarHeight,
- dialogBottomMarginPx, buttonBar, textIndicator, mSensorProps);
+ final int dialogMargin = getDialogMarginPx();
+ final WindowManager windowManager = getContext().getSystemService(WindowManager.class);
+ final int displayHeight = getWindowBounds(windowManager).height();
+ final Insets navbarInsets = getNavbarInsets(windowManager);
+ final int bottomSpacerHeight = calculateBottomSpacerHeightForPortrait(
+ mSensorProps, displayHeight, textIndicatorHeight, buttonBarHeight,
+ dialogMargin, navbarInsets.bottom);
// Go through each of the children and do the custom measurement.
int totalHeight = 0;
@@ -105,22 +95,25 @@
final int sensorDiameter = mSensorProps.sensorRadius * 2;
for (int i = 0; i < numChildren; i++) {
final View child = getChildAt(i);
-
if (child.getId() == R.id.biometric_icon_frame) {
- // Create a frame that's exactly the size of the sensor circle
- child.measure(
- MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY));
- } else if (child.getId() == R.id.biometric_icon) {
- // Icon should never be larger than the circle
- child.measure(
+ final FrameLayout iconFrame = (FrameLayout) child;
+ final View icon = iconFrame.getChildAt(0);
+
+ // Ensure that the icon is never larger than the sensor.
+ icon.measure(
MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST));
+
+ // Create a frame that's exactly the height of the sensor circle.
+ iconFrame.measure(
+ MeasureSpec.makeMeasureSpec(
+ child.getLayoutParams().width, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY));
} else if (child.getId() == R.id.space_above_icon) {
child.measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(child.getLayoutParams().height,
- MeasureSpec.EXACTLY));
+ MeasureSpec.makeMeasureSpec(
+ child.getLayoutParams().height, MeasureSpec.EXACTLY));
} else if (child.getId() == R.id.button_bar) {
child.measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
@@ -128,8 +121,9 @@
MeasureSpec.EXACTLY));
} else if (child.getId() == R.id.space_below_icon) {
// Set the spacer height so the fingerprint icon is on the physical sensor area
- child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(spacerHeight, MeasureSpec.EXACTLY));
+ child.measure(
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(bottomSpacerHeight, MeasureSpec.EXACTLY));
} else {
child.measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
@@ -143,4 +137,184 @@
return new AuthDialog.LayoutParams(width, totalHeight);
}
+
+ @NonNull
+ private AuthDialog.LayoutParams onMeasureInternalLandscape(int width, int height) {
+ // Find the spacer height needed to vertically align the icon with the sensor.
+ final int titleHeight = getViewHeightPx(R.id.title);
+ final int subtitleHeight = getViewHeightPx(R.id.subtitle);
+ final int descriptionHeight = getViewHeightPx(R.id.description);
+ final int topSpacerHeight = getViewHeightPx(R.id.space_above_icon);
+ final int textIndicatorHeight = getViewHeightPx(R.id.indicator);
+ final int buttonBarHeight = getViewHeightPx(R.id.button_bar);
+ final WindowManager windowManager = getContext().getSystemService(WindowManager.class);
+ final Insets navbarInsets = getNavbarInsets(windowManager);
+ final int bottomSpacerHeight = calculateBottomSpacerHeightForLandscape(titleHeight,
+ subtitleHeight, descriptionHeight, topSpacerHeight, textIndicatorHeight,
+ buttonBarHeight, navbarInsets.bottom);
+
+ // Find the spacer width needed to horizontally align the icon with the sensor.
+ final int displayWidth = getWindowBounds(windowManager).width();
+ final int dialogMargin = getDialogMarginPx();
+ final int horizontalInset = navbarInsets.left + navbarInsets.right;
+ final int horizontalSpacerWidth = calculateHorizontalSpacerWidthForLandscape(
+ mSensorProps, displayWidth, dialogMargin, horizontalInset);
+
+ final int sensorDiameter = mSensorProps.sensorRadius * 2;
+ final int remeasuredWidth = sensorDiameter + 2 * horizontalSpacerWidth;
+
+ int remeasuredHeight = 0;
+ final int numChildren = getChildCount();
+ for (int i = 0; i < numChildren; i++) {
+ final View child = getChildAt(i);
+ if (child.getId() == R.id.biometric_icon_frame) {
+ final FrameLayout iconFrame = (FrameLayout) child;
+ final View icon = iconFrame.getChildAt(0);
+
+ // Ensure that the icon is never larger than the sensor.
+ icon.measure(
+ MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST),
+ MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST));
+
+ // Create a frame that's exactly the height of the sensor circle.
+ iconFrame.measure(
+ MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY));
+ } else if (child.getId() == R.id.space_above_icon || child.getId() == R.id.button_bar) {
+ // Adjust the width of the top spacer and button bar while preserving their heights.
+ child.measure(
+ MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(
+ child.getLayoutParams().height, MeasureSpec.EXACTLY));
+ } else if (child.getId() == R.id.space_below_icon) {
+ // Adjust the bottom spacer height to align the fingerprint icon with the sensor.
+ child.measure(
+ MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(bottomSpacerHeight, MeasureSpec.EXACTLY));
+ } else {
+ // Use the remeasured width for all other child views.
+ child.measure(
+ MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
+ }
+
+ if (child.getVisibility() != View.GONE) {
+ remeasuredHeight += child.getMeasuredHeight();
+ }
+ }
+
+ return new AuthDialog.LayoutParams(remeasuredWidth, remeasuredHeight);
+ }
+
+ private int getViewHeightPx(@IdRes int viewId) {
+ final View view = findViewById(viewId);
+ return view != null ? view.getMeasuredHeight() : 0;
+ }
+
+ private int getDialogMarginPx() {
+ return getResources().getDimensionPixelSize(R.dimen.biometric_dialog_border_padding);
+ }
+
+ @NonNull
+ private static Insets getNavbarInsets(@Nullable WindowManager windowManager) {
+ return windowManager != null && windowManager.getCurrentWindowMetrics() != null
+ ? windowManager.getCurrentWindowMetrics().getWindowInsets()
+ .getInsets(WindowInsets.Type.navigationBars())
+ : Insets.NONE;
+ }
+
+ @NonNull
+ private static Rect getWindowBounds(@Nullable WindowManager windowManager) {
+ return windowManager != null && windowManager.getCurrentWindowMetrics() != null
+ ? windowManager.getCurrentWindowMetrics().getBounds()
+ : new Rect();
+ }
+
+ /**
+ * For devices in portrait orientation where the sensor is too high up, calculates the amount of
+ * padding necessary to center the biometric icon within the sensor's physical location.
+ */
+ @VisibleForTesting
+ static int calculateBottomSpacerHeightForPortrait(
+ @NonNull FingerprintSensorPropertiesInternal sensorProperties, int displayHeightPx,
+ int textIndicatorHeightPx, int buttonBarHeightPx, int dialogMarginPx,
+ int navbarBottomInsetPx) {
+
+ final int sensorDistanceFromBottom = displayHeightPx
+ - sensorProperties.sensorLocationY
+ - sensorProperties.sensorRadius;
+
+ final int spacerHeight = sensorDistanceFromBottom
+ - textIndicatorHeightPx
+ - buttonBarHeightPx
+ - dialogMarginPx
+ - navbarBottomInsetPx;
+
+ Log.d(TAG, "Display height: " + displayHeightPx
+ + ", Distance from bottom: " + sensorDistanceFromBottom
+ + ", Bottom margin: " + dialogMarginPx
+ + ", Navbar bottom inset: " + navbarBottomInsetPx
+ + ", Bottom spacer height (portrait): " + spacerHeight);
+
+ return spacerHeight;
+ }
+
+ /**
+ * For devices in landscape orientation where the sensor is too high up, calculates the amount
+ * of padding necessary to center the biometric icon within the sensor's physical location.
+ */
+ @VisibleForTesting
+ static int calculateBottomSpacerHeightForLandscape(int titleHeightPx, int subtitleHeightPx,
+ int descriptionHeightPx, int topSpacerHeightPx, int textIndicatorHeightPx,
+ int buttonBarHeightPx, int navbarBottomInsetPx) {
+
+ final int dialogHeightAboveIcon = titleHeightPx
+ + subtitleHeightPx
+ + descriptionHeightPx
+ + topSpacerHeightPx;
+
+ final int dialogHeightBelowIcon = textIndicatorHeightPx + buttonBarHeightPx;
+
+ final int bottomSpacerHeight = dialogHeightAboveIcon
+ - dialogHeightBelowIcon
+ - navbarBottomInsetPx;
+
+ Log.d(TAG, "Title height: " + titleHeightPx
+ + ", Subtitle height: " + subtitleHeightPx
+ + ", Description height: " + descriptionHeightPx
+ + ", Top spacer height: " + topSpacerHeightPx
+ + ", Text indicator height: " + textIndicatorHeightPx
+ + ", Button bar height: " + buttonBarHeightPx
+ + ", Navbar bottom inset: " + navbarBottomInsetPx
+ + ", Bottom spacer height (landscape): " + bottomSpacerHeight);
+
+ return bottomSpacerHeight;
+ }
+
+ /**
+ * For devices in landscape orientation where the sensor is too left/right, calculates the
+ * amount of padding necessary to center the biometric icon within the sensor's physical
+ * location.
+ */
+ @VisibleForTesting
+ static int calculateHorizontalSpacerWidthForLandscape(
+ @NonNull FingerprintSensorPropertiesInternal sensorProperties, int displayWidthPx,
+ int dialogMarginPx, int navbarHorizontalInsetPx) {
+
+ final int sensorDistanceFromEdge = displayWidthPx
+ - sensorProperties.sensorLocationY
+ - sensorProperties.sensorRadius;
+
+ final int horizontalPadding = sensorDistanceFromEdge
+ - dialogMarginPx
+ - navbarHorizontalInsetPx;
+
+ Log.d(TAG, "Display width: " + displayWidthPx
+ + ", Distance from edge: " + sensorDistanceFromEdge
+ + ", Dialog margin: " + dialogMarginPx
+ + ", Navbar horizontal inset: " + navbarHorizontalInsetPx
+ + ", Horizontal spacer width (landscape): " + horizontalPadding);
+
+ return horizontalPadding;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index 18206ef..d59a865 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -742,6 +742,7 @@
* @param height Height to constrain the measurements to.
* @return See {@link AuthDialog.LayoutParams}
*/
+ @NonNull
AuthDialog.LayoutParams onMeasureInternal(int width, int height) {
int totalHeight = 0;
final int numChildren = getChildCount();
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 935f893..d05e927 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -32,8 +32,10 @@
import android.os.Looper;
import android.os.UserManager;
import android.util.Log;
+import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
+import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
@@ -433,6 +435,29 @@
+ mConfig.mPromptInfo.getAuthenticators());
}
+ if (mBiometricView instanceof AuthBiometricUdfpsView) {
+ final int displayRotation = getDisplay().getRotation();
+ switch (displayRotation) {
+ case Surface.ROTATION_0:
+ mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM);
+ setScrollViewGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
+ break;
+ case Surface.ROTATION_90:
+ mPanelController.setPosition(AuthPanelController.POSITION_RIGHT);
+ setScrollViewGravity(Gravity.CENTER_VERTICAL | Gravity.RIGHT);
+ break;
+ case Surface.ROTATION_270:
+ mPanelController.setPosition(AuthPanelController.POSITION_LEFT);
+ setScrollViewGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
+ break;
+ default:
+ Log.e(TAG, "Unsupported display rotation: " + displayRotation);
+ mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM);
+ setScrollViewGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
+ break;
+ }
+ }
+
if (mConfig.mSkipIntro) {
mContainerState = STATE_SHOWING;
} else {
@@ -476,6 +501,13 @@
}
}
+ private void setScrollViewGravity(int gravity) {
+ final FrameLayout.LayoutParams params =
+ (FrameLayout.LayoutParams) mBiometricScrollView.getLayoutParams();
+ params.gravity = gravity;
+ mBiometricScrollView.setLayoutParams(params);
+ }
+
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java
index 11503fb..fa50f89 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java
@@ -18,6 +18,7 @@
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
+import android.annotation.IntDef;
import android.content.Context;
import android.graphics.Outline;
import android.util.Log;
@@ -27,10 +28,20 @@
import com.android.systemui.R;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Controls the back panel and its animations for the BiometricPrompt UI.
*/
public class AuthPanelController extends ViewOutlineProvider {
+ public static final int POSITION_BOTTOM = 1;
+ public static final int POSITION_LEFT = 2;
+ public static final int POSITION_RIGHT = 3;
+
+ @IntDef({POSITION_BOTTOM, POSITION_LEFT, POSITION_RIGHT})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Position {}
private static final String TAG = "BiometricPrompt/AuthPanelController";
private static final boolean DEBUG = false;
@@ -38,6 +49,7 @@
private final Context mContext;
private final View mPanelView;
+ @Position private int mPosition = POSITION_BOTTOM;
private boolean mUseFullScreen;
private int mContainerWidth;
@@ -51,21 +63,44 @@
@Override
public void getOutline(View view, Outline outline) {
- final int left = (mContainerWidth - mContentWidth) / 2;
- final int right = mContainerWidth - left;
+ final int left = getLeftBound(mPosition);
+ final int right = left + mContentWidth;
- // If the content fits within the container, shrink the height to wrap the content.
- // Otherwise, set the outline to be the display size minus the margin - the content within
- // is scrollable.
- final int top = mContentHeight < mContainerHeight
- ? mContainerHeight - mContentHeight - mMargin
- : mMargin;
+ // If the content fits in the container, shrink the height to wrap it. Otherwise, expand to
+ // fill the display (minus the margin), since the content is scrollable.
+ final int top = getTopBound(mPosition);
+ final int bottom = Math.min(top + mContentHeight, mContainerHeight - mMargin);
- // TODO(b/139954942) Likely don't need to "+1" after we resolve the navbar styling.
- final int bottom = mContainerHeight - mMargin + 1;
outline.setRoundRect(left, top, right, bottom, mCornerRadius);
}
+ private int getLeftBound(@Position int position) {
+ switch (position) {
+ case POSITION_BOTTOM:
+ return (mContainerWidth - mContentWidth) / 2;
+ case POSITION_LEFT:
+ return mMargin;
+ case POSITION_RIGHT:
+ return mContainerWidth - mContentWidth - mMargin;
+ default:
+ Log.e(TAG, "Unrecognized position: " + position);
+ return getLeftBound(POSITION_BOTTOM);
+ }
+ }
+
+ private int getTopBound(@Position int position) {
+ switch (position) {
+ case POSITION_BOTTOM:
+ return Math.max(mContainerHeight - mContentHeight - mMargin, mMargin);
+ case POSITION_LEFT:
+ case POSITION_RIGHT:
+ return Math.max((mContainerHeight - mContentHeight) / 2, mMargin);
+ default:
+ Log.e(TAG, "Unrecognized position: " + position);
+ return getTopBound(POSITION_BOTTOM);
+ }
+ }
+
public void setContainerDimensions(int containerWidth, int containerHeight) {
if (DEBUG) {
Log.v(TAG, "Container Width: " + containerWidth + " Height: " + containerHeight);
@@ -74,6 +109,10 @@
mContainerHeight = containerHeight;
}
+ public void setPosition(@Position int position) {
+ mPosition = position;
+ }
+
public void setUseFullScreen(boolean fullScreen) {
mUseFullScreen = fullScreen;
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 1d789ca..4b6a8f6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -451,6 +451,7 @@
mStatusBar.addExpansionChangedListener(mStatusBarExpansionListener);
mStatusBarStateController.addCallback(mStatusBarStateListener);
+ mStatusBarStateListener.onStateChanged(mStatusBarStateController.getState());
mWindowManager.addView(mView, computeLayoutParams(animation));
mView.setOnTouchListener(mOnTouchListener);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
index 14eca1b..667b7a7 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
@@ -122,6 +122,8 @@
@NonNull
PointF getNextGuidedEnrollmentPoint() {
final int index = mLocationsEnrolled - NUM_CENTER_TOUCHES;
- return mGuidedEnrollmentPoints.get(index % mGuidedEnrollmentPoints.size());
+ final PointF originalPoint = mGuidedEnrollmentPoints
+ .get(index % mGuidedEnrollmentPoints.size());
+ return new PointF(originalPoint.x * 0.5f, originalPoint.y * 0.5f);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java
index 64576a9..f7fe14a 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java
@@ -22,7 +22,6 @@
import android.view.MotionEvent;
import java.util.List;
-import java.util.Queue;
import javax.inject.Inject;
import javax.inject.Named;
@@ -49,8 +48,7 @@
@Override
Result calculateFalsingResult(double historyPenalty, double historyConfidence) {
List<MotionEvent> secondTapEvents = getRecentMotionEvents();
- Queue<? extends List<MotionEvent>> historicalEvents = getHistoricalEvents();
- List<MotionEvent> firstTapEvents = historicalEvents.peek();
+ List<MotionEvent> firstTapEvents = getPriorMotionEvents();
StringBuilder reason = new StringBuilder();
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java
index dbfeacf..f40045b 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java
@@ -21,7 +21,6 @@
import com.android.systemui.util.sensors.ProximitySensor;
import java.util.List;
-import java.util.Queue;
/**
* Base class for rules that determine False touches.
@@ -40,8 +39,8 @@
return mDataProvider.getRecentMotionEvents();
}
- Queue<? extends List<MotionEvent>> getHistoricalEvents() {
- return mDataProvider.getHistoricalMotionEvents();
+ List<MotionEvent> getPriorMotionEvents() {
+ return mDataProvider.getPriorMotionEvents();
}
MotionEvent getFirstMotionEvent() {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
index 4bacc15..336f13f 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
@@ -23,13 +23,9 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.statusbar.policy.BatteryController;
-import com.android.systemui.util.time.SystemClock;
import java.util.ArrayList;
-import java.util.Deque;
-import java.util.LinkedList;
import java.util.List;
-import java.util.Queue;
import javax.inject.Inject;
@@ -40,24 +36,23 @@
public class FalsingDataProvider {
private static final long MOTION_EVENT_AGE_MS = 1000;
- private static final long EXTENDED_MOTION_EVENT_AGE_MS = 30 * 1000;
private static final float THREE_HUNDRED_SIXTY_DEG = (float) (2 * Math.PI);
private final int mWidthPixels;
private final int mHeightPixels;
private final BatteryController mBatteryController;
- private final SystemClock mSystemClock;
private final float mXdpi;
private final float mYdpi;
private final List<SessionListener> mSessionListeners = new ArrayList<>();
private final List<MotionEventListener> mMotionEventListeners = new ArrayList<>();
- private final List<GestureCompleteListener> mGestuerCompleteListeners = new ArrayList<>();
+ private final List<GestureCompleteListener> mGestureCompleteListeners = new ArrayList<>();
private @Classifier.InteractionType int mInteractionType;
- private final Deque<TimeLimitedMotionEventBuffer> mExtendedMotionEvents = new LinkedList<>();
private TimeLimitedMotionEventBuffer mRecentMotionEvents =
new TimeLimitedMotionEventBuffer(MOTION_EVENT_AGE_MS);
+ private List<MotionEvent> mPriorMotionEvents;
+
private boolean mDirty = true;
private float mAngle = 0;
@@ -66,14 +61,12 @@
private boolean mJustUnlockedWithFace;
@Inject
- public FalsingDataProvider(DisplayMetrics displayMetrics, BatteryController batteryController,
- SystemClock systemClock) {
+ public FalsingDataProvider(DisplayMetrics displayMetrics, BatteryController batteryController) {
mXdpi = displayMetrics.xdpi;
mYdpi = displayMetrics.ydpi;
mWidthPixels = displayMetrics.widthPixels;
mHeightPixels = displayMetrics.heightPixels;
mBatteryController = batteryController;
- mSystemClock = systemClock;
FalsingClassifier.logInfo("xdpi, ydpi: " + getXdpi() + ", " + getYdpi());
FalsingClassifier.logInfo("width, height: " + getWidthPixels() + ", " + getHeightPixels());
@@ -111,10 +104,10 @@
private void completePriorGesture() {
if (!mRecentMotionEvents.isEmpty()) {
- mGestuerCompleteListeners.forEach(listener -> listener.onGestureComplete(
+ mGestureCompleteListeners.forEach(listener -> listener.onGestureComplete(
mRecentMotionEvents.get(mRecentMotionEvents.size() - 1).getEventTime()));
- mExtendedMotionEvents.addFirst(mRecentMotionEvents);
+ mPriorMotionEvents = mRecentMotionEvents;
}
}
@@ -140,14 +133,8 @@
return mRecentMotionEvents;
}
- /** Returns recent gestures, exclusive of the most recent gesture. Newer gestures come first. */
- public Queue<? extends List<MotionEvent>> getHistoricalMotionEvents() {
- long nowMs = mSystemClock.uptimeMillis();
-
- mExtendedMotionEvents.removeIf(
- motionEvents -> motionEvents.isFullyExpired(nowMs - EXTENDED_MOTION_EVENT_AGE_MS));
-
- return mExtendedMotionEvents;
+ public List<MotionEvent> getPriorMotionEvents() {
+ return mPriorMotionEvents;
}
/**
@@ -344,12 +331,12 @@
/** Register a {@link GestureCompleteListener}. */
public void addGestureCompleteListener(GestureCompleteListener listener) {
- mGestuerCompleteListeners.add(listener);
+ mGestureCompleteListeners.add(listener);
}
/** Unregister a {@link GestureCompleteListener}. */
public void removeGestureCompleteListener(GestureCompleteListener listener) {
- mGestuerCompleteListeners.remove(listener);
+ mGestureCompleteListeners.remove(listener);
}
void onSessionStarted() {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
index 7969b4e..e5da389 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
@@ -42,18 +42,6 @@
mMotionEvents = new LinkedList<>();
}
- /**
- * Returns true if the most recent event in the buffer is past the expiration time.
- *
- * This method does not mutate the underlying data. This method does imply that, if the supplied
- * expiration time is old enough and a new {@link MotionEvent} gets added to the buffer, all
- * prior events would be removed.
- */
- public boolean isFullyExpired(long expirationMs) {
- return mMotionEvents.isEmpty()
- || mMotionEvents.getLast().getEventTime() <= expirationMs;
- }
-
private void ejectOldEvents() {
if (mMotionEvents.isEmpty()) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
index fbdeb30..ed625de 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
@@ -31,6 +31,7 @@
import com.android.systemui.controls.management.ControlsRequestDialog
import com.android.systemui.controls.ui.ControlActionCoordinator
import com.android.systemui.controls.ui.ControlActionCoordinatorImpl
+import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.controls.ui.ControlsUiControllerImpl
import com.android.systemui.dagger.SysUISingleton
@@ -113,4 +114,9 @@
abstract fun provideControlsRequestDialog(
activity: ControlsRequestDialog
): Activity
+
+ @Binds
+ @IntoMap
+ @ClassKey(ControlsActivity::class)
+ abstract fun provideControlsActivity(activity: ControlsActivity): Activity
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
index fc89783..7dd1d28 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
@@ -32,7 +32,7 @@
import com.android.systemui.controls.CustomIconCache
import com.android.systemui.controls.controller.ControlsControllerImpl
import com.android.systemui.controls.controller.StructureInfo
-import com.android.systemui.controls.ui.ControlsDialog
+import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.globalactions.GlobalActionsComponent
import com.android.systemui.settings.CurrentUserTracker
@@ -112,7 +112,11 @@
if (backToGlobalActions) {
globalActionsComponent.handleShowGlobalActionsMenu()
} else {
- ControlsDialog(applicationContext, broadcastDispatcher).show(uiController)
+ val i = Intent().apply {
+ component = ComponentName(applicationContext, ControlsActivity::class.java)
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
+ }
+ startActivity(i)
}
animateExitAndFinish()
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
index 2d647a9..3099014 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
@@ -40,7 +40,7 @@
import com.android.systemui.controls.TooltipManager
import com.android.systemui.controls.controller.ControlsControllerImpl
import com.android.systemui.controls.controller.StructureInfo
-import com.android.systemui.controls.ui.ControlsDialog
+import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.globalactions.GlobalActionsComponent
@@ -352,7 +352,11 @@
if (backToGlobalActions) {
globalActionsComponent.handleShowGlobalActionsMenu()
} else {
- ControlsDialog(applicationContext, broadcastDispatcher).show(uiController)
+ val i = Intent().apply {
+ component = ComponentName(applicationContext, ControlsActivity::class.java)
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
+ }
+ startActivity(i)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
index d5e41d0..fa1c41f 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
@@ -32,7 +32,7 @@
import com.android.systemui.R
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.controls.controller.ControlsController
-import com.android.systemui.controls.ui.ControlsDialog
+import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -116,7 +116,11 @@
if (backToGlobalActions) {
globalActionsComponent.handleShowGlobalActionsMenu()
} else {
- ControlsDialog(applicationContext, broadcastDispatcher).show(uiController)
+ val i = Intent().apply {
+ component = ComponentName(applicationContext, ControlsActivity::class.java)
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
+ }
+ startActivity(i)
}
animateExitAndFinish()
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
index d06568a..0db15e8 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
@@ -16,6 +16,7 @@
package com.android.systemui.controls.ui
+import android.content.Context
import android.service.controls.Control
/**
@@ -24,8 +25,8 @@
*/
interface ControlActionCoordinator {
- // Handle actions launched from GlobalActionsDialog or ControlDialog
- var startedFromGlobalActions: Boolean
+ // If launched from an Activity, continue within this stack
+ var activityContext: Context?
/**
* Close any dialogs which may have been open
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
index 6b300f4..58a5981 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
@@ -18,6 +18,7 @@
import android.annotation.MainThread
import android.app.Dialog
+import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
@@ -60,7 +61,7 @@
private var pendingAction: Action? = null
private var actionsInProgress = mutableSetOf<String>()
- override var startedFromGlobalActions: Boolean = true
+ override var activityContext: Context? = null
companion object {
private const val RESPONSE_TIMEOUT_IN_MILLIS = 3000L
@@ -83,7 +84,7 @@
bouncerOrRun(createAction(cvh.cws.ci.controlId, {
cvh.layout.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK)
if (cvh.usePanel()) {
- showDialog(cvh, control.getAppIntent().getIntent())
+ showDetail(cvh, control.getAppIntent().getIntent())
} else {
cvh.action(CommandAction(templateId))
}
@@ -109,7 +110,7 @@
// Long press snould only be called when there is valid control state, otherwise ignore
cvh.cws.control?.let {
cvh.layout.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
- showDialog(cvh, it.getAppIntent().getIntent())
+ showDetail(cvh, it.getAppIntent().getIntent())
}
}, false /* blockable */))
}
@@ -151,10 +152,16 @@
activityStarter.dismissKeyguardThenExecute({
Log.d(ControlsUiController.TAG, "Device unlocked, invoking controls action")
if (closeDialog) {
- if (startedFromGlobalActions) {
+ activityContext?.let {
+ val i = Intent().apply {
+ component = ComponentName(context, ControlsActivity::class.java)
+ addFlags(
+ Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
+ putExtra(ControlsUiController.BACK_TO_GLOBAL_ACTIONS, false)
+ }
+ it.startActivity(i)
+ } ?: run {
globalActionsComponent.handleShowGlobalActionsMenu()
- } else {
- ControlsDialog(context, broadcastDispatcher).show(lazyUiController.get())
}
} else {
action.invoke()
@@ -170,9 +177,9 @@
bgExecutor.execute { vibrator.vibrate(effect) }
}
- private fun showDialog(cvh: ControlViewHolder, intent: Intent) {
+ private fun showDetail(cvh: ControlViewHolder, intent: Intent) {
bgExecutor.execute {
- val activities: List<ResolveInfo> = cvh.context.packageManager.queryIntentActivities(
+ val activities: List<ResolveInfo> = context.packageManager.queryIntentActivities(
intent,
PackageManager.MATCH_DEFAULT_ONLY
)
@@ -180,8 +187,8 @@
uiExecutor.execute {
// make sure the intent is valid before attempting to open the dialog
if (activities.isNotEmpty() && taskViewFactory.isPresent) {
- taskViewFactory.get().create(cvh.context, uiExecutor, {
- dialog = DetailDialog(cvh, it, intent).also {
+ taskViewFactory.get().create(context, uiExecutor, {
+ dialog = DetailDialog(activityContext, it, intent, cvh).also {
it.setOnDismissListener { _ -> dialog = null }
it.show()
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
new file mode 100644
index 0000000..a35b792
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
@@ -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.systemui.controls.ui
+
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+import android.view.WindowInsets
+import android.view.WindowInsets.Type
+
+import com.android.systemui.R
+import com.android.systemui.controls.management.ControlsAnimations
+import com.android.systemui.util.LifecycleActivity
+import javax.inject.Inject
+
+/**
+ * Displays Device Controls inside an activity
+ */
+class ControlsActivity @Inject constructor(
+ private val uiController: ControlsUiController
+) : LifecycleActivity() {
+
+ private lateinit var parent: ViewGroup
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ setContentView(R.layout.controls_fullscreen)
+
+ requireViewById<ViewGroup>(R.id.control_detail_root).apply {
+ setOnApplyWindowInsetsListener {
+ v: View, insets: WindowInsets ->
+ v.apply {
+ val l = getPaddingLeft()
+ val t = getPaddingTop()
+ val r = getPaddingRight()
+ setPadding(l, t, r, insets.getInsets(Type.systemBars()).bottom)
+ }
+
+ WindowInsets.CONSUMED
+ }
+ }
+ }
+
+ override fun onStart() {
+ super.onStart()
+
+ parent = requireViewById<ViewGroup>(R.id.global_actions_controls)
+ parent.alpha = 0f
+ uiController.show(parent, { animateExitAndFinish() }, this)
+ }
+
+ override fun onResume() {
+ super.onResume()
+
+ ControlsAnimations.enterAnimation(parent).start()
+ }
+
+ override fun onBackPressed() {
+ animateExitAndFinish()
+ }
+
+ override fun onStop() {
+ super.onStop()
+
+ uiController.hide()
+ }
+
+ private fun animateExitAndFinish() {
+ ControlsAnimations.exitAnimation(parent, { finish() }).start()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialog.kt
deleted file mode 100644
index 537334a..0000000
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialog.kt
+++ /dev/null
@@ -1,91 +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.systemui.controls.ui
-
-import android.app.Dialog
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import android.content.IntentFilter
-import android.view.View
-import android.view.ViewGroup
-import android.view.WindowManager
-
-import com.android.systemui.Interpolators
-import com.android.systemui.R
-import com.android.systemui.broadcast.BroadcastDispatcher
-import javax.inject.Inject
-
-/**
- * Show the controls space inside a dialog, as from the lock screen.
- */
-class ControlsDialog @Inject constructor(
- thisContext: Context,
- val broadcastDispatcher: BroadcastDispatcher
-) : Dialog(thisContext, R.style.Theme_SystemUI_Dialog_Control_LockScreen) {
-
- private val receiver = object : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- val action = intent.getAction()
- if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
- dismiss()
- }
- }
- }
-
- init {
- window.setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG)
- window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
- or WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
-
- setContentView(R.layout.controls_in_dialog)
-
- requireViewById<ViewGroup>(R.id.control_detail_root).apply {
- setOnClickListener { dismiss() }
- (getParent() as View).setOnClickListener { dismiss() }
- }
- }
-
- fun show(
- controller: ControlsUiController
- ): ControlsDialog {
- super.show()
-
- val vg = requireViewById<ViewGroup>(com.android.systemui.R.id.global_actions_controls)
- vg.alpha = 0f
- controller.show(vg, { dismiss() }, false /* startedFromGlobalActions */)
-
- vg.animate()
- .alpha(1f)
- .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
- .setDuration(300)
-
- val filter = IntentFilter()
- filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
- broadcastDispatcher.registerReceiver(receiver, filter)
-
- return this
- }
-
- override fun dismiss() {
- broadcastDispatcher.unregisterReceiver(receiver)
-
- if (!isShowing()) return
-
- super.dismiss()
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
index 20bdf60..f86948e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
@@ -17,6 +17,7 @@
package com.android.systemui.controls.ui
import android.content.ComponentName
+import android.content.Context
import android.service.controls.Control
import android.service.controls.actions.ControlAction
import android.view.ViewGroup
@@ -30,7 +31,7 @@
public const val BACK_TO_GLOBAL_ACTIONS = "back_to_global_actions"
}
- fun show(parent: ViewGroup, onDismiss: Runnable, startedFromGlobalActions: Boolean)
+ fun show(parent: ViewGroup, onDismiss: Runnable, activityContext: Context?)
fun hide()
/**
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index c94d85a..0f7f48f 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -148,7 +148,7 @@
override fun show(
parent: ViewGroup,
onDismiss: Runnable,
- startedFromGlobalActions: Boolean
+ activityContext: Context?
) {
Log.d(ControlsUiController.TAG, "show()")
this.parent = parent
@@ -156,7 +156,7 @@
hidden = false
retainCache = false
- controlActionCoordinator.startedFromGlobalActions = startedFromGlobalActions
+ controlActionCoordinator.activityContext = activityContext
allStructures = controlsController.get().getFavorites()
selectedStructure = loadPreference(allStructures)
@@ -193,7 +193,7 @@
controlViewsById.clear()
controlsById.clear()
- show(parent, onDismiss, controlActionCoordinator.startedFromGlobalActions)
+ show(parent, onDismiss, controlActionCoordinator.activityContext)
val showAnim = ObjectAnimator.ofFloat(parent, "alpha", 0.0f, 1.0f)
showAnim.setInterpolator(DecelerateInterpolator(1.0f))
showAnim.setDuration(FADE_IN_MILLIS)
@@ -268,7 +268,7 @@
intent.putExtra(ControlsUiController.EXTRA_ANIMATE, true)
intent.putExtra(
ControlsUiController.BACK_TO_GLOBAL_ACTIONS,
- controlActionCoordinator.startedFromGlobalActions
+ controlActionCoordinator.activityContext == null
)
onDismiss.run()
@@ -392,6 +392,17 @@
val inflater = LayoutInflater.from(context)
inflater.inflate(R.layout.controls_with_favorites, parent, true)
+ if (controlActionCoordinator.activityContext == null) {
+ parent.requireViewById<View>(R.id.controls_spacer).apply {
+ visibility = View.VISIBLE
+ }
+ } else {
+ parent.requireViewById<ImageView>(R.id.controls_close).apply {
+ setOnClickListener { _: View -> onDismiss.run() }
+ visibility = View.VISIBLE
+ }
+ }
+
val maxColumns = findMaxColumns()
val listView = parent.requireViewById(R.id.global_actions_controls_list) as ViewGroup
@@ -502,6 +513,8 @@
override fun hide() {
hidden = true
+ controlActionCoordinator.activityContext = null
+
closeDialogs(true)
controlsController.get().unsubscribe()
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
index 020694d..9c788df 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
@@ -22,8 +22,8 @@
import android.app.Dialog
import android.app.PendingIntent
import android.content.ComponentName
+import android.content.Context
import android.content.Intent
-import android.provider.Settings
import android.view.View
import android.view.ViewGroup
import android.view.WindowInsets
@@ -35,18 +35,20 @@
import com.android.wm.shell.TaskView
/**
- * A dialog that provides an {@link ActivityView}, allowing the application to provide
+ * A dialog that provides an {@link TaskView}, allowing the application to provide
* additional information and actions pertaining to a {@link android.service.controls.Control}.
* The activity being launched is specified by {@link android.service.controls.Control#getAppIntent}.
*/
class DetailDialog(
- val cvh: ControlViewHolder,
- val activityView: TaskView,
- val intent: Intent
-) : Dialog(cvh.context, R.style.Theme_SystemUI_Dialog_Control_DetailPanel) {
-
+ val activityContext: Context?,
+ val taskView: TaskView,
+ val intent: Intent,
+ val cvh: ControlViewHolder
+) : Dialog(
+ activityContext ?: cvh.context,
+ R.style.Theme_SystemUI_Dialog_Control_DetailPanel
+) {
companion object {
- private const val PANEL_TOP_OFFSET = "systemui.controls_panel_top_offset"
/*
* Indicate to the activity that it is being rendered in a bottomsheet, and they
* should optimize the layout for a smaller space.
@@ -71,10 +73,19 @@
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
launchIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
- activityView.startActivity(
- PendingIntent.getActivity(context, 0, launchIntent,
- PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE),
- null, ActivityOptions.makeBasic())
+ val options = activityContext?.let {
+ ActivityOptions.makeCustomAnimation(
+ it,
+ 0 /* enterResId */,
+ 0 /* exitResId */
+ )
+ } ?: ActivityOptions.makeBasic()
+ taskView.startActivity(
+ PendingIntent.getActivity(context, 0, launchIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE),
+ null,
+ options
+ )
}
override fun onTaskRemovalStarted(taskId: Int) {
@@ -92,7 +103,10 @@
}
init {
- window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY)
+ if (activityContext == null) {
+ window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY)
+ }
+
// To pass touches to the task inside TaskView.
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)
window.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY)
@@ -100,7 +114,7 @@
setContentView(R.layout.controls_detail_dialog)
requireViewById<ViewGroup>(R.id.controls_activity_view).apply {
- addView(activityView)
+ addView(taskView)
}
requireViewById<ImageView>(R.id.control_detail_close).apply {
@@ -120,48 +134,34 @@
// consume all insets to achieve slide under effect
window.getDecorView().setOnApplyWindowInsetsListener {
- _: View, insets: WindowInsets ->
- activityView.apply {
+ v: View, insets: WindowInsets ->
+ taskView.apply {
val l = getPaddingLeft()
val t = getPaddingTop()
val r = getPaddingRight()
setPadding(l, t, r, insets.getInsets(Type.systemBars()).bottom)
}
+ val l = v.getPaddingLeft()
+ val b = v.getPaddingBottom()
+ val r = v.getPaddingRight()
+ v.setPadding(l, insets.getInsets(Type.systemBars()).top, r, b)
+
WindowInsets.CONSUMED
}
- requireViewById<ViewGroup>(R.id.control_detail_root).apply {
- // use flag only temporarily for testing
- val resolver = cvh.context.contentResolver
- val defaultOffsetInPx = cvh.context.resources
- .getDimensionPixelSize(R.dimen.controls_activity_view_top_offset)
- val offsetInPx = Settings.Secure.getInt(resolver, PANEL_TOP_OFFSET, defaultOffsetInPx)
-
- val lp = getLayoutParams() as ViewGroup.MarginLayoutParams
- lp.topMargin = offsetInPx
- setLayoutParams(lp)
-
- setOnClickListener { dismiss() }
- (getParent() as View).setOnClickListener { dismiss() }
- }
-
if (ScreenDecorationsUtils.supportsRoundedCornersOnWindows(context.getResources())) {
val cornerRadius = context.resources
.getDimensionPixelSize(R.dimen.controls_activity_view_corner_radius)
- activityView.setCornerRadius(cornerRadius.toFloat())
+ taskView.setCornerRadius(cornerRadius.toFloat())
}
- }
- override fun show() {
- activityView.setListener(cvh.uiExecutor, stateCallback)
-
- super.show()
+ taskView.setListener(cvh.uiExecutor, stateCallback)
}
override fun dismiss() {
if (!isShowing()) return
- activityView.release()
+ taskView.release()
super.dismiss()
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index c26cc44..d8ade2b 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -225,8 +225,8 @@
* Appends wake-display event to the logs.
* @param wake if we're waking up or sleeping.
*/
- public void traceWakeDisplay(boolean wake) {
- mLogger.logWakeDisplay(wake);
+ public void traceWakeDisplay(boolean wake, @Reason int reason) {
+ mLogger.logWakeDisplay(wake, reason);
}
/**
@@ -380,6 +380,7 @@
case REASON_SENSOR_WAKE_UP: return "wakeup";
case REASON_SENSOR_TAP: return "tap";
case REASON_SENSOR_UDFPS_LONG_PRESS: return "udfps";
+ case REASON_SENSOR_QUICK_PICKUP: return "quickPickup";
default: throw new IllegalArgumentException("invalid reason: " + pulseReason);
}
}
@@ -389,7 +390,7 @@
PULSE_REASON_SENSOR_SIGMOTION, REASON_SENSOR_PICKUP, REASON_SENSOR_DOUBLE_TAP,
PULSE_REASON_SENSOR_LONG_PRESS, PULSE_REASON_DOCKING, REASON_SENSOR_WAKE_UP,
PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, REASON_SENSOR_TAP,
- REASON_SENSOR_UDFPS_LONG_PRESS})
+ REASON_SENSOR_UDFPS_LONG_PRESS, REASON_SENSOR_QUICK_PICKUP})
public @interface Reason {}
public static final int PULSE_REASON_NONE = -1;
public static final int PULSE_REASON_INTENT = 0;
@@ -403,6 +404,7 @@
public static final int PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN = 8;
public static final int REASON_SENSOR_TAP = 9;
public static final int REASON_SENSOR_UDFPS_LONG_PRESS = 10;
+ public static final int REASON_SENSOR_QUICK_PICKUP = 11;
- public static final int TOTAL_REASONS = 11;
+ public static final int TOTAL_REASONS = 12;
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
index fddefae..9bc74be 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
@@ -16,6 +16,7 @@
package com.android.systemui.doze
+import android.view.Display
import com.android.systemui.doze.DozeLog.Reason
import com.android.systemui.doze.DozeLog.reasonToString
import com.android.systemui.log.LogBuffer
@@ -161,17 +162,18 @@
fun logDisplayStateChanged(displayState: Int) {
buffer.log(TAG, INFO, {
- int1 = displayState
+ str1 = Display.stateToString(displayState)
}, {
- "Display state changed to $int1"
+ "Display state changed to $str1"
})
}
- fun logWakeDisplay(isAwake: Boolean) {
+ fun logWakeDisplay(isAwake: Boolean, @Reason reason: Int) {
buffer.log(TAG, DEBUG, {
bool1 = isAwake
+ int1 = reason
}, {
- "Display wakefulness changed, isAwake=$bool1"
+ "Display wakefulness changed, isAwake=$bool1, reason=${reasonToString(int1)}"
})
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index c542e5b..52c9f16 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -113,6 +113,8 @@
mCallback = callback;
mProximitySensor = proximitySensor;
+ boolean udfpsEnrolled =
+ authController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser());
boolean alwaysOn = mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT);
mSensors = new TriggerSensor[] {
new TriggerSensor(
@@ -159,7 +161,7 @@
findSensorWithType(config.udfpsLongPressSensorType()),
"doze_pulse_on_auth",
true /* settingDef */,
- authController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser()),
+ udfpsEnrolled,
DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS,
true /* reports touch coordinates */,
true /* touchscreen */,
@@ -181,6 +183,15 @@
false /* touchscreen */,
mConfig.getWakeLockScreenDebounce(),
dozeLog),
+ new TriggerSensor(
+ findSensorWithType(config.quickPickupSensorType()),
+ Settings.Secure.DOZE_QUICK_PICKUP_GESTURE,
+ false /* setting default */,
+ config.quickPickupSensorEnabled(KeyguardUpdateMonitor.getCurrentUser())
+ && udfpsEnrolled,
+ DozeLog.REASON_SENSOR_QUICK_PICKUP,
+ false /* touchCoords */,
+ false /* touchscreen */, dozeLog),
};
setProxListening(false); // Don't immediately start listening when we register.
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index c617f3d..04b4670 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -42,10 +42,13 @@
import com.android.systemui.Dependency;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.doze.dagger.DozeScope;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.util.Assert;
+import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.sensors.AsyncSensorManager;
import com.android.systemui.util.sensors.ProximitySensor;
import com.android.systemui.util.settings.SecureSettings;
@@ -76,6 +79,7 @@
* Assuming that the screen should start on.
*/
private static boolean sWakeDisplaySensorState = true;
+ private Runnable mQuickPickupDozeCancellable;
private static final int PROXIMITY_TIMEOUT_DELAY_MS = 500;
@@ -96,6 +100,8 @@
private final ProximitySensor.ProximityCheck mProxCheck;
private final BroadcastDispatcher mBroadcastDispatcher;
private final AuthController mAuthController;
+ private final DelayableExecutor mMainExecutor;
+ private final DelayableExecutor mBgExecutor;
private long mNotificationPulseTime;
private boolean mPulsePending;
@@ -135,7 +141,10 @@
DOZING_UPDATE_SENSOR_TAP(441),
@UiEvent(doc = "Dozing updated because on display auth was triggered from AOD.")
- DOZING_UPDATE_AUTH_TRIGGERED(657);
+ DOZING_UPDATE_AUTH_TRIGGERED(657),
+
+ @UiEvent(doc = "Dozing updated because quick pickup sensor woke up.")
+ DOZING_UPDATE_QUICK_PICKUP(708);
private final int mId;
@@ -160,6 +169,7 @@
case 8: return DOZING_UPDATE_SENSOR_WAKE_LOCKSCREEN;
case 9: return DOZING_UPDATE_SENSOR_TAP;
case 10: return DOZING_UPDATE_AUTH_TRIGGERED;
+ case 11: return DOZING_UPDATE_QUICK_PICKUP;
default: return null;
}
}
@@ -172,7 +182,8 @@
WakeLock wakeLock, DockManager dockManager,
ProximitySensor proximitySensor, ProximitySensor.ProximityCheck proxCheck,
DozeLog dozeLog, BroadcastDispatcher broadcastDispatcher,
- SecureSettings secureSettings, AuthController authController) {
+ SecureSettings secureSettings, AuthController authController,
+ @Main DelayableExecutor mainExecutor, @Background DelayableExecutor bgExecutor) {
mContext = context;
mDozeHost = dozeHost;
mConfig = config;
@@ -189,6 +200,8 @@
mDozeLog = dozeLog;
mBroadcastDispatcher = broadcastDispatcher;
mAuthController = authController;
+ mMainExecutor = mainExecutor;
+ mBgExecutor = bgExecutor;
}
@Override
@@ -262,18 +275,22 @@
boolean isTap = pulseReason == DozeLog.REASON_SENSOR_TAP;
boolean isPickup = pulseReason == DozeLog.REASON_SENSOR_PICKUP;
boolean isLongPress = pulseReason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS;
- boolean isWakeDisplay = pulseReason == DozeLog.REASON_SENSOR_WAKE_UP;
- boolean isWakeLockScreen = pulseReason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN;
+ boolean isWakeOnPresence = pulseReason == DozeLog.REASON_SENSOR_WAKE_UP;
+ boolean isWakeOnReach = pulseReason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN;
boolean isUdfpsLongPress = pulseReason == DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS;
- boolean wakeEvent = rawValues != null && rawValues.length > 0 && rawValues[0] != 0;
+ boolean isQuickPickup = pulseReason == DozeLog.REASON_SENSOR_QUICK_PICKUP;
+ boolean isWakeDisplayEvent = isQuickPickup || ((isWakeOnPresence || isWakeOnReach)
+ && rawValues != null && rawValues.length > 0 && rawValues[0] != 0);
- if (isWakeDisplay) {
- onWakeScreen(wakeEvent, mMachine.isExecutingTransition() ? null : mMachine.getState());
+ if (isWakeOnPresence || isQuickPickup) {
+ onWakeScreen(isQuickPickup || isWakeDisplayEvent,
+ mMachine.isExecutingTransition() ? null : mMachine.getState(),
+ pulseReason);
} else if (isLongPress) {
requestPulse(pulseReason, true /* alreadyPerformedProxCheck */,
null /* onPulseSuppressedListener */);
- } else if (isWakeLockScreen) {
- if (wakeEvent) {
+ } else if (isWakeOnReach) {
+ if (isWakeDisplayEvent) {
requestPulse(pulseReason, true /* alreadyPerformedProxCheck */,
null /* onPulseSuppressedListener */);
}
@@ -370,13 +387,17 @@
* @param state The current state, or null if the state could not be determined due to enqueued
* transitions.
*/
- private void onWakeScreen(boolean wake, @Nullable DozeMachine.State state) {
- mDozeLog.traceWakeDisplay(wake);
- sWakeDisplaySensorState = wake;
+ private void onWakeScreen(boolean wake, @Nullable DozeMachine.State state, int reason) {
+ mDozeLog.traceWakeDisplay(wake, reason);
+ final boolean isWakeOnPresence = reason == DozeLog.REASON_SENSOR_WAKE_UP;
+ final boolean isQuickPickup = reason == DozeLog.REASON_SENSOR_QUICK_PICKUP;
+ if (isWakeOnPresence) {
+ sWakeDisplaySensorState = wake;
+ }
if (wake) {
proximityCheckThenCall((result) -> {
- if (result != null && result) {
+ if (result != null && result) {
// In pocket, drop event.
return;
}
@@ -385,26 +406,51 @@
// Logs AOD open due to sensor wake up.
mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING)
.setType(MetricsEvent.TYPE_OPEN)
- .setSubtype(DozeLog.REASON_SENSOR_WAKE_UP));
+ .setSubtype(reason));
+
+ if (isQuickPickup) {
+ // schedule runnable to go back to DOZE
+ onQuickPickup();
+ }
+ } else if (state == DozeMachine.State.DOZE_AOD && isQuickPickup) {
+ // elongate time in DOZE_AOD, schedule new runnable to go back to DOZE
+ onQuickPickup();
}
- }, true /* alreadyPerformedProxCheck */, DozeLog.REASON_SENSOR_WAKE_UP);
+ }, isQuickPickup /* alreadyPerformedProxCheck */, reason);
} else {
boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED);
boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING);
+ boolean pulse = (state == DozeMachine.State.DOZE_REQUEST_PULSE)
+ || (state == DozeMachine.State.DOZE_PULSING)
+ || (state == DozeMachine.State.DOZE_PULSING_BRIGHT);
+ boolean docked = (state == DozeMachine.State.DOZE_AOD_DOCKED);
if (!pausing && !paused) {
+ if (isQuickPickup && (pulse || docked)) {
+ return;
+ }
mMachine.requestState(DozeMachine.State.DOZE);
// Logs AOD close due to sensor wake up.
mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING)
.setType(MetricsEvent.TYPE_CLOSE)
- .setSubtype(DozeLog.REASON_SENSOR_WAKE_UP));
+ .setSubtype(reason));
}
}
}
+ private void onQuickPickup() {
+ cancelQuickPickupDelayableDoze();
+ mQuickPickupDozeCancellable = mMainExecutor.executeDelayed(() -> {
+ onWakeScreen(false,
+ mMachine.isExecutingTransition() ? null : mMachine.getState(),
+ DozeLog.REASON_SENSOR_QUICK_PICKUP);
+ }, mDozeParameters.getQuickPickupAodDuration());
+ }
+
@Override
public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
switch (newState) {
case INITIALIZED:
+ sWakeDisplaySensorState = true;
mBroadcastReceiver.register(mBroadcastDispatcher);
mDozeHost.addCallback(mHostCallback);
mDockManager.addListener(mDockEventListener);
@@ -417,7 +463,7 @@
mWantSensors = true;
mWantTouchScreenSensors = true;
if (newState == DozeMachine.State.DOZE_AOD && !sWakeDisplaySensorState) {
- onWakeScreen(false, newState);
+ onWakeScreen(false, newState, DozeLog.REASON_SENSOR_WAKE_UP);
}
break;
case DOZE_AOD_PAUSED:
@@ -437,6 +483,7 @@
mDozeSensors.requestTemporaryDisable();
break;
case FINISH:
+ cancelQuickPickupDelayableDoze();
mBroadcastReceiver.unregister(mBroadcastDispatcher);
mDozeHost.removeCallback(mHostCallback);
mDockManager.removeListener(mDockEventListener);
@@ -460,6 +507,17 @@
mDozeSensors.setListening(mWantSensors, mWantTouchScreenSensors);
}
+ /**
+ * Cancels last scheduled Runnable that transitions to STATE_DOZE (blank screen) after
+ * going into STATE_AOD (AOD screen) from the quick pickup gesture.
+ */
+ private void cancelQuickPickupDelayableDoze() {
+ if (mQuickPickupDozeCancellable != null) {
+ mQuickPickupDozeCancellable.run();
+ mQuickPickupDozeCancellable = null;
+ }
+ }
+
private void checkTriggersAtInit() {
if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR
|| mDozeHost.isBlockingDoze()
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index d85b101..461a730 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -79,7 +79,6 @@
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.util.ArraySet;
-import android.util.FeatureFlagUtils;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.IWindowManager;
@@ -114,7 +113,6 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.EmergencyAffordanceManager;
-import com.android.internal.util.ScreenRecordHelper;
import com.android.internal.util.ScreenshotHelper;
import com.android.internal.view.RotationPolicy;
import com.android.internal.widget.LockPatternUtils;
@@ -242,7 +240,6 @@
private final boolean mShowSilentToggle;
private final EmergencyAffordanceManager mEmergencyAffordanceManager;
private final ScreenshotHelper mScreenshotHelper;
- private final ScreenRecordHelper mScreenRecordHelper;
private final ActivityStarter mActivityStarter;
private final SysuiColorExtractor mSysuiColorExtractor;
private final IStatusBarService mStatusBarService;
@@ -378,7 +375,6 @@
mEmergencyAffordanceManager = new EmergencyAffordanceManager(context);
mScreenshotHelper = new ScreenshotHelper(context);
- mScreenRecordHelper = new ScreenRecordHelper(context);
mConfigurationController.addCallback(this);
@@ -979,7 +975,7 @@
}
@VisibleForTesting
- class ScreenshotAction extends SinglePressAction implements LongPressAction {
+ class ScreenshotAction extends SinglePressAction {
final String KEY_SYSTEM_NAV_2BUTTONS = "system_nav_2buttons";
public ScreenshotAction() {
@@ -1024,18 +1020,6 @@
return NAV_BAR_MODE_2BUTTON == mContext.getResources().getInteger(
com.android.internal.R.integer.config_navBarInteractionMode);
}
-
-
- @Override
- public boolean onLongPress() {
- if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SCREENRECORD_LONG_PRESS)) {
- mUiEventLogger.log(GlobalActionsEvent.GA_SCREENSHOT_LONG_PRESS);
- mScreenRecordHelper.launchRecordPrompt();
- } else {
- onPress();
- }
- return true;
- }
}
@VisibleForTesting
@@ -2236,7 +2220,7 @@
private void showControls(ControlsUiController controller) {
mControlsUiController = controller;
mControlsUiController.show(mControlsView, this::dismissForControlsActivity,
- true /* startedFromGlobalActions */);
+ null /* activityContext */);
}
private boolean isWalletViewAvailable() {
@@ -2465,7 +2449,7 @@
});
if (mControlsUiController != null) {
mControlsUiController.show(mControlsView, this::dismissForControlsActivity,
- true /* startedFromGlobalActions */);
+ null /* activityContext */);
}
mBackgroundDrawable.setAlpha(0);
@@ -2641,7 +2625,7 @@
mGlobalActionsLayout.updateList();
if (mControlsUiController != null) {
mControlsUiController.show(mControlsView, this::dismissForControlsActivity,
- true /* startedFromGlobalActions */);
+ null /* activityContext */);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 088743c..9e3be69 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -609,20 +609,21 @@
if (mVocab != null) {
app = mVocab.getOrDefault(mPackageName, -1);
}
- // Check if we are within the tightest bounds beyond which
- // we would not need to run the ML model.
- boolean withinRange = x < mMLEnableWidth + mLeftInset
- || x >= (mDisplaySize.x - mMLEnableWidth - mRightInset);
- if (!withinRange) {
+
+ // Denotes whether we should proceed with the gesture. Even if it is false, we may want to
+ // log it assuming it is not invalid due to exclusion.
+ boolean withinRange = x < mEdgeWidthLeft + mLeftInset
+ || x >= (mDisplaySize.x - mEdgeWidthRight - mRightInset);
+ if (withinRange) {
int results = -1;
- if (mUseMLModel && (results = getBackGesturePredictionsCategory(x, y, app)) != -1) {
- withinRange = results == 1;
- } else {
- // Denotes whether we should proceed with the gesture.
- // Even if it is false, we may want to log it assuming
- // it is not invalid due to exclusion.
- withinRange = x < mEdgeWidthLeft + mLeftInset
- || x >= (mDisplaySize.x - mEdgeWidthRight - mRightInset);
+
+ // Check if we are within the tightest bounds beyond which we would not need to run the
+ // ML model
+ boolean withinMinRange = x < mMLEnableWidth + mLeftInset
+ || x >= (mDisplaySize.x - mMLEnableWidth - mRightInset);
+ if (!withinMinRange && mUseMLModel
+ && (results = getBackGesturePredictionsCategory(x, y, app)) != -1) {
+ withinRange = (results == 1);
}
}
@@ -726,7 +727,7 @@
mGestureLog.removeFirst();
}
mGestureLog.addLast(String.format(
- "Gesture [%d,alw=%B,%B, %B,%B,disp=%s,wl=%d,il=%d,wr=%d,ir=%d,excl=%s]",
+ "Gesture [%d,alw=%B,%B,%B,%B,disp=%s,wl=%d,il=%d,wr=%d,ir=%d,excl=%s]",
System.currentTimeMillis(), mAllowGesture, mIsOnLeftEdge, mIsBackGestureAllowed,
QuickStepContract.isBackGestureDisabled(mSysUiFlags), mDisplaySize,
mEdgeWidthLeft, mLeftInset, mEdgeWidthRight, mRightInset, mExcludeRegion));
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
index a69ec27..378e49d 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
@@ -35,6 +35,7 @@
import com.android.systemui.R;
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
+import com.android.systemui.people.widget.PeopleTileKey;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import java.util.List;
@@ -117,7 +118,7 @@
String pkg = tile.getPackageName();
String status =
PeopleSpaceUtils.getLastInteractionString(mContext,
- tile.getLastInteractionTimestamp(), true);
+ tile.getLastInteractionTimestamp());
tileView.setStatus(status);
tileView.setName(tile.getUserName().toString());
@@ -138,7 +139,9 @@
+ mAppWidgetId);
}
}
- mPeopleSpaceWidgetManager.addNewWidget(tile, mAppWidgetId);
+ PeopleTileKey key = new PeopleTileKey(
+ tile.getId(), tile.getUserHandle().getIdentifier(), tile.getPackageName());
+ mPeopleSpaceWidgetManager.addNewWidget(mAppWidgetId, key);
finishActivity();
}
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
index 502c95c..aa45178 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
@@ -52,9 +52,7 @@
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.provider.ContactsContract;
import android.provider.Settings;
import android.service.notification.ConversationChannelWrapper;
@@ -71,10 +69,11 @@
import com.android.internal.logging.UiEventLogger;
import com.android.internal.util.ArrayUtils;
import com.android.settingslib.utils.ThreadUtils;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.people.widget.AppWidgetOptionsHelper;
import com.android.systemui.people.widget.LaunchConversationActivity;
import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
+import com.android.systemui.people.widget.PeopleTileKey;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -106,7 +105,6 @@
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 OPTIONS_PEOPLE_SPACE_TILE = "options_people_space_tile";
public static final String PACKAGE_NAME = "package_name";
public static final String USER_ID = "user_id";
public static final String SHORTCUT_ID = "shortcut_id";
@@ -115,6 +113,9 @@
public static final int INVALID_WIDGET_ID = -1;
public static final int INVALID_USER_ID = -1;
+ public static final PeopleTileKey EMPTY_KEY =
+ new PeopleTileKey(EMPTY_STRING, INVALID_USER_ID, EMPTY_STRING);
+
private static final Pattern DOUBLE_EXCLAMATION_PATTERN = Pattern.compile("[!][!]+");
private static final Pattern DOUBLE_QUESTION_PATTERN = Pattern.compile("[?][?]+");
private static final Pattern ANY_DOUBLE_MARK_PATTERN = Pattern.compile("[!?][!?]+");
@@ -200,67 +201,76 @@
AppWidgetManager appWidgetManager, IPeopleManager peopleManager) {
Map<Integer, PeopleSpaceTile> widgetIdToTile = new HashMap<>();
for (int appWidgetId : appWidgetIds) {
- PeopleSpaceTile tile = getPeopleSpaceTile(peopleManager, appWidgetManager, context,
- appWidgetId);
+ PeopleSpaceTile tile = getPeopleSpaceTile(
+ context, appWidgetId, appWidgetManager, peopleManager);
if (tile == null) {
if (DEBUG) Log.d(TAG, "Matching conversation not found for shortcut ID");
//TODO: Delete app widget id when crash is fixed (b/172932636)
continue;
}
-
- if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + ", " + tile.getUserName());
- RemoteViews views = createRemoteViews(context, tile, appWidgetId);
-
- // Tell the AppWidgetManager to perform an update on the current app widget.
- appWidgetManager.updateAppWidget(appWidgetId, views);
-
+ updateAppWidgetOptionsAndView(appWidgetManager, context, appWidgetId, tile);
widgetIdToTile.put(appWidgetId, tile);
}
getBirthdaysOnBackgroundThread(context, appWidgetManager, widgetIdToTile, appWidgetIds);
}
+ /**
+ * Returns a {@link PeopleSpaceTile} based on the {@code appWidgetId}. If the PeopleSpaceTile
+ * isn't cached, store it in AppWidgetOptions.
+ */
@Nullable
- public static PeopleSpaceTile getPeopleSpaceTile(IPeopleManager peopleManager,
- AppWidgetManager appWidgetManager,
- Context context, int appWidgetId) {
+ public static PeopleSpaceTile getPeopleSpaceTile(Context context, int appWidgetId,
+ AppWidgetManager appWidgetManager, IPeopleManager peopleManager) {
+ // First, check if tile is cached in AppWidgetOptions.
+ PeopleSpaceTile tile = AppWidgetOptionsHelper.getPeopleTile(appWidgetManager, appWidgetId);
+ if (tile != null) {
+ if (DEBUG) Log.d(TAG, "People Tile is cached for widget: " + appWidgetId);
+ return tile;
+ }
+
+ // If not, we get the PeopleTileKey from SharedPreferences, retrieve the Conversation from
+ // persisted storage, and cache it in AppWidgetOptions.
+ SharedPreferences widgetSp = context.getSharedPreferences(
+ String.valueOf(appWidgetId),
+ Context.MODE_PRIVATE);
+ PeopleTileKey sharedPreferencesKey = new PeopleTileKey(
+ widgetSp.getString(SHORTCUT_ID, EMPTY_STRING),
+ widgetSp.getInt(USER_ID, INVALID_USER_ID),
+ widgetSp.getString(PACKAGE_NAME, EMPTY_STRING));
+
+ if (!sharedPreferencesKey.isValid()) {
+ Log.e(TAG, "Cannot find shortcut info for widgetId: " + appWidgetId);
+ return null;
+ }
+
+ if (DEBUG) Log.d(TAG, "PeopleTile key is present in sharedPreferences: " + appWidgetId);
+ // If tile is null, we need to retrieve from persisted storage.
+ return getPeopleTileFromPersistentStorage(context, sharedPreferencesKey, peopleManager);
+ }
+
+ /**
+ * Returns a {@link PeopleSpaceTile} based on {@link ConversationChannel} returned by
+ * {@link IPeopleManager}.
+ */
+ public static PeopleSpaceTile getPeopleTileFromPersistentStorage(Context context,
+ PeopleTileKey peopleTileKey, IPeopleManager peopleManager) {
try {
- // Migrate storage for existing users.
- SharedPreferences widgetSp = context.getSharedPreferences(String.valueOf(appWidgetId),
- Context.MODE_PRIVATE);
- String pkg = widgetSp.getString(PACKAGE_NAME, EMPTY_STRING);
- int userId = widgetSp.getInt(USER_ID, INVALID_USER_ID);
- String shortcutId = widgetSp.getString(SHORTCUT_ID, EMPTY_STRING);
- if (!validKey(shortcutId, pkg, userId)) {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
- shortcutId = sp.getString(String.valueOf(appWidgetId), null);
- if (shortcutId == null) {
- Log.e(TAG, "Cannot restore widget");
- return null;
- }
- migrateExistingUsersToNewStorage(context, shortcutId, appWidgetId);
- pkg = widgetSp.getString(PACKAGE_NAME, EMPTY_STRING);
- userId = widgetSp.getInt(USER_ID, INVALID_USER_ID);
- }
-
- // Check if tile is cached.
- Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
- PeopleSpaceTile tile = options.getParcelable(OPTIONS_PEOPLE_SPACE_TILE);
- if (tile != null) {
- return tile;
- }
-
- // If tile is null, we need to retrieve from persisted storage.
- if (DEBUG) {
- Log.d(TAG,
- "Retrieving from storage after reboots: " + shortcutId + " user: " + userId
- + " pkg: " + pkg);
- }
+ if (DEBUG) Log.d(TAG, "Retrieving Tile from storage: " + peopleTileKey.toString());
LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
- ConversationChannel channel = peopleManager.getConversation(pkg, userId, shortcutId);
+ if (launcherApps == null) {
+ Log.d(TAG, "LauncherApps is null");
+ return null;
+ }
+
+ ConversationChannel channel = peopleManager.getConversation(
+ peopleTileKey.getPackageName(),
+ peopleTileKey.getUserId(),
+ peopleTileKey.getShortcutId());
if (channel == null) {
Log.d(TAG, "Could not retrieve conversation from storage");
return null;
}
+
return new PeopleSpaceTile.Builder(channel, launcherApps).build();
} catch (Exception e) {
Log.e(TAG, "Failed to retrieve conversation for tile: " + e);
@@ -269,79 +279,46 @@
}
/** Returns stored widgets for the conversation specified. */
- public static Set<String> getStoredWidgetIds(SharedPreferences sp, String shortcutId,
- String packageName, int userId) {
- if (shortcutId == null || packageName == null) {
+ public static Set<String> getStoredWidgetIds(SharedPreferences sp, PeopleTileKey key) {
+ if (!key.isValid()) {
return new HashSet<>();
}
- String key = PeopleSpaceUtils.getKey(shortcutId, packageName, userId);
- return new HashSet<>(sp.getStringSet(key, new HashSet<>()));
- }
-
-
- /** Best-effort attempts to migrate existing users to the new storage format. */
- // TODO: Remove after sufficient time. Temporary migration storage for existing users.
- private static void migrateExistingUsersToNewStorage(Context context, String shortcutId,
- int appWidgetId) {
- try {
- List<PeopleSpaceTile> tiles =
- PeopleSpaceUtils.getTiles(context, INotificationManager.Stub.asInterface(
- ServiceManager.getService(Context.NOTIFICATION_SERVICE)),
- IPeopleManager.Stub.asInterface(
- ServiceManager.getService(Context.PEOPLE_SERVICE)),
- context.getSystemService(LauncherApps.class),
- Dependency.get(NotificationEntryManager.class));
- Optional<PeopleSpaceTile> entry = tiles.stream().filter(
- e -> e.getId().equals(shortcutId)).findFirst();
- if (entry.isPresent()) {
- if (DEBUG) Log.d(TAG, "Migrate storage for " + entry.get().getUserName());
- setStorageForTile(context, entry.get(), appWidgetId);
- } else {
- Log.e(TAG, "Could not migrate user. Delete old storage");
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
- SharedPreferences.Editor editor = sp.edit();
- editor.remove(String.valueOf(appWidgetId));
- editor.apply();
- }
- } catch (Exception e) {
- Log.e(TAG, "Could not query conversations");
- }
+ return new HashSet<>(sp.getStringSet(key.toString(), new HashSet<>()));
}
/** Sets all relevant storage for {@code appWidgetId} association to {@code tile}. */
- public static void setStorageForTile(Context context, PeopleSpaceTile tile, int appWidgetId) {
+ public static void setSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
+ int appWidgetId) {
// Write relevant persisted storage.
SharedPreferences widgetSp = context.getSharedPreferences(String.valueOf(appWidgetId),
Context.MODE_PRIVATE);
SharedPreferences.Editor widgetEditor = widgetSp.edit();
- widgetEditor.putString(PeopleSpaceUtils.PACKAGE_NAME, tile.getPackageName());
- widgetEditor.putString(PeopleSpaceUtils.SHORTCUT_ID, tile.getId());
- int userId = getUserId(tile);
- widgetEditor.putInt(PeopleSpaceUtils.USER_ID, userId);
+ widgetEditor.putString(PeopleSpaceUtils.PACKAGE_NAME, key.getPackageName());
+ widgetEditor.putString(PeopleSpaceUtils.SHORTCUT_ID, key.getShortcutId());
+ widgetEditor.putInt(PeopleSpaceUtils.USER_ID, key.getUserId());
widgetEditor.apply();
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sp.edit();
- editor.putString(String.valueOf(appWidgetId), tile.getId());
- String key = PeopleSpaceUtils.getKey(tile.getId(), tile.getPackageName(), userId);
- // Don't overwrite existing widgets with the same key.
- Set<String> storedWidgetIds = new HashSet<>(sp.getStringSet(key, new HashSet<>()));
- storedWidgetIds.add(String.valueOf(appWidgetId));
- editor.putStringSet(key, storedWidgetIds);
- editor.apply();
+ editor.putString(String.valueOf(appWidgetId), key.getShortcutId());
- // Write cached storage.
- updateAppWidgetOptionsAndView(AppWidgetManager.getInstance(context), context, appWidgetId,
- tile);
+ // Don't overwrite existing widgets with the same key.
+ Set<String> storedWidgetIds = new HashSet<>(
+ sp.getStringSet(key.toString(), new HashSet<>()));
+ storedWidgetIds.add(String.valueOf(appWidgetId));
+ editor.putStringSet(key.toString(), storedWidgetIds);
+ editor.apply();
}
/** Removes stored data when tile is deleted. */
- public static void removeStorageForTile(Context context, String key, int widgetId) {
+ public static void removeSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
+ int widgetId) {
// Delete widgetId mapping to key.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sp.edit();
- Set<String> storedWidgetIds = new HashSet<>(sp.getStringSet(key, new HashSet<>()));
+ Set<String> storedWidgetIds = new HashSet<>(
+ sp.getStringSet(key.toString(), new HashSet<>()));
storedWidgetIds.remove(String.valueOf(widgetId));
- editor.putStringSet(key, storedWidgetIds);
+ editor.putStringSet(key.toString(), storedWidgetIds);
editor.remove(String.valueOf(widgetId));
editor.apply();
@@ -361,12 +338,12 @@
Log.w(TAG, "NotificationEntryManager is null");
return tiles;
}
- Map<String, NotificationEntry> visibleNotifications = notificationEntryManager
+ Map<PeopleTileKey, NotificationEntry> visibleNotifications = notificationEntryManager
.getVisibleNotifications()
.stream()
.filter(entry -> entry.getRanking() != null
&& entry.getRanking().getConversationShortcutInfo() != null)
- .collect(Collectors.toMap(PeopleSpaceUtils::getKey, e -> e));
+ .collect(Collectors.toMap(PeopleTileKey::new, e -> e));
if (DEBUG) {
Log.d(TAG, "Number of visible notifications:" + visibleNotifications.size());
}
@@ -378,16 +355,15 @@
}
static PeopleSpaceTile augmentTileFromVisibleNotifications(Context context,
- PeopleSpaceTile tile, Map<String, NotificationEntry> visibleNotifications) {
- String shortcutId = tile.getId();
- String packageName = tile.getPackageName();
- int userId = getUserId(tile);
- String key = getKey(shortcutId, packageName, userId);
+ PeopleSpaceTile tile, Map<PeopleTileKey, NotificationEntry> visibleNotifications) {
+ PeopleTileKey key = new PeopleTileKey(
+ tile.getId(), getUserId(tile), tile.getPackageName());
+
if (!visibleNotifications.containsKey(key)) {
- if (DEBUG) Log.d(TAG, "No existing notifications for key:" + key);
+ if (DEBUG) Log.d(TAG, "No existing notifications for key:" + key.toString());
return tile;
}
- if (DEBUG) Log.d(TAG, "Augmenting tile from visible notifications, key:" + key);
+ if (DEBUG) Log.d(TAG, "Augmenting tile from visible notifications, key:" + key.toString());
return augmentTileFromNotification(context, tile, visibleNotifications.get(key).getSbn());
}
@@ -423,17 +399,6 @@
.build();
}
- private static void updateAppWidgetOptions(AppWidgetManager appWidgetManager, int appWidgetId,
- PeopleSpaceTile tile) {
- if (tile == null) {
- if (DEBUG) Log.d(TAG, "Requested to store null tile");
- return;
- }
- Bundle newOptions = new Bundle();
- newOptions.putParcelable(OPTIONS_PEOPLE_SPACE_TILE, tile);
- appWidgetManager.updateAppWidgetOptions(appWidgetId, newOptions);
- }
-
/** Creates a {@link RemoteViews} for {@code tile}. */
public static RemoteViews createRemoteViews(Context context,
PeopleSpaceTile tile, int appWidgetId) {
@@ -653,7 +618,7 @@
}
// TODO: Set subtext as Group Sender name once storing the name in PeopleSpaceTile.
views.setTextViewText(R.id.subtext, PeopleSpaceUtils.getLastInteractionString(
- context, tile.getLastInteractionTimestamp(), false));
+ context, tile.getLastInteractionTimestamp()));
return views;
}
@@ -662,7 +627,7 @@
RemoteViews views = new RemoteViews(
context.getPackageName(), R.layout.people_space_large_avatar_tile);
String status = PeopleSpaceUtils.getLastInteractionString(
- context, tile.getLastInteractionTimestamp(), true);
+ context, tile.getLastInteractionTimestamp());
views.setTextViewText(R.id.last_interaction, status);
return views;
}
@@ -808,8 +773,7 @@
}
/** Returns a readable status describing the {@code lastInteraction}. */
- public static String getLastInteractionString(Context context, long lastInteraction,
- boolean includeLastChatted) {
+ 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);
@@ -818,41 +782,20 @@
Duration durationSinceLastInteraction = Duration.ofMillis(now - lastInteraction);
MeasureFormat formatter = MeasureFormat.getInstance(Locale.getDefault(),
MeasureFormat.FormatWidth.WIDE);
- MeasureFormat shortFormatter = MeasureFormat.getInstance(Locale.getDefault(),
- MeasureFormat.FormatWidth.SHORT);
if (durationSinceLastInteraction.toHours() < MIN_HOUR) {
- if (includeLastChatted) {
- return context.getString(R.string.last_interaction_status_less_than,
- formatter.formatMeasures(new Measure(MIN_HOUR, MeasureUnit.HOUR)));
- }
- return context.getString(R.string.timestamp, shortFormatter.formatMeasures(
+ return context.getString(R.string.timestamp, formatter.formatMeasures(
new Measure(durationSinceLastInteraction.toMinutes(), MeasureUnit.MINUTE)));
} else if (durationSinceLastInteraction.toDays() < ONE_DAY) {
- if (includeLastChatted) {
- return context.getString(R.string.last_interaction_status,
- formatter.formatMeasures(
- new Measure(durationSinceLastInteraction.toHours(),
- MeasureUnit.HOUR)));
- }
- return context.getString(R.string.timestamp, shortFormatter.formatMeasures(
+ return context.getString(R.string.timestamp, formatter.formatMeasures(
new Measure(durationSinceLastInteraction.toHours(),
MeasureUnit.HOUR)));
} else if (durationSinceLastInteraction.toDays() < DAYS_IN_A_WEEK) {
- if (includeLastChatted) {
- return context.getString(R.string.last_interaction_status,
- formatter.formatMeasures(
- new Measure(durationSinceLastInteraction.toDays(),
- MeasureUnit.DAY)));
- }
- return context.getString(R.string.timestamp, shortFormatter.formatMeasures(
+ return context.getString(R.string.timestamp, formatter.formatMeasures(
new Measure(durationSinceLastInteraction.toHours(),
MeasureUnit.DAY)));
} else {
return context.getString(durationSinceLastInteraction.toDays() == DAYS_IN_A_WEEK
- ? (includeLastChatted ? R.string.last_interaction_status :
- R.string.timestamp) :
- (includeLastChatted ? R.string.last_interaction_status_over
- : R.string.over_timestamp),
+ ? R.string.timestamp : R.string.over_timestamp,
formatter.formatMeasures(
new Measure(durationSinceLastInteraction.toDays() / DAYS_IN_A_WEEK,
MeasureUnit.WEEK)));
@@ -957,11 +900,15 @@
removeBirthdayStatusIfPresent(appWidgetManager, context, storedTile, appWidgetId);
}
- /** Update app widget options and the current view. */
+ /** Updates tile in app widget options and the current view. */
public static void updateAppWidgetOptionsAndView(AppWidgetManager appWidgetManager,
Context context, int appWidgetId, PeopleSpaceTile tile) {
- updateAppWidgetOptions(appWidgetManager, appWidgetId, tile);
+ AppWidgetOptionsHelper.setPeopleTile(appWidgetManager, appWidgetId, tile);
+
+ if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + ", " + tile.getUserName());
RemoteViews views = createRemoteViews(context, tile, appWidgetId);
+
+ // Tell the AppWidgetManager to perform an update on the current app widget.
appWidgetManager.updateAppWidget(appWidgetId, views);
}
@@ -1006,44 +953,6 @@
return lookupKeysWithBirthdaysToday;
}
- static String getKey(NotificationEntry entry) {
- if (entry.getRanking() == null || entry.getRanking().getConversationShortcutInfo() == null
- || entry.getSbn() == null || entry.getSbn().getUser() == null) {
- return null;
- }
- return getKey(entry.getRanking().getConversationShortcutInfo().getId(),
- entry.getSbn().getPackageName(),
- entry.getSbn().getUser().getIdentifier());
- }
-
- /**
- * Returns the uniquely identifying key for the conversation.
- *
- * <p>{@code userId} will always be a number, so we put user ID as the
- * delimiter between the app-provided strings of shortcut ID and package name.
- *
- * <p>There aren't restrictions on shortcut ID characters, but there are restrictions requiring
- * a {@code packageName} to always start with a letter. This restriction means we are
- * guaranteed to avoid cases like "a/b/0/0/package.name" having two potential keys, as the first
- * case is impossible given the package name restrictions:
- * <ul>
- * <li>"a/b" + "/" + 0 + "/" + "0/packageName"</li>
- * <li>"a/b/0" + "/" + 0 + "/" + "packageName"</li>
- * </ul>
- */
- @Nullable
- public static String getKey(String shortcutId, String packageName, int userId) {
- if (!validKey(shortcutId, packageName, userId)) {
- return null;
- }
- return shortcutId + "/" + userId + "/" + packageName;
- }
-
- /** Returns whether the key is valid. */
- public static boolean validKey(String shortcutId, String packageName, int userId) {
- return !TextUtils.isEmpty(shortcutId) && !TextUtils.isEmpty(packageName) && userId >= 0;
- }
-
/** Returns the userId associated with a {@link PeopleSpaceTile} */
public static int getUserId(PeopleSpaceTile tile) {
return tile.getUserHandle().getIdentifier();
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/AppWidgetOptionsHelper.java b/packages/SystemUI/src/com/android/systemui/people/widget/AppWidgetOptionsHelper.java
new file mode 100644
index 0000000..df08ee4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/AppWidgetOptionsHelper.java
@@ -0,0 +1,91 @@
+/*
+ * 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.people.widget;
+
+import static com.android.systemui.people.PeopleSpaceUtils.DEBUG;
+import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_KEY;
+import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
+import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
+import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
+import static com.android.systemui.people.PeopleSpaceUtils.SHORTCUT_ID;
+import static com.android.systemui.people.PeopleSpaceUtils.USER_ID;
+
+import android.app.people.PeopleSpaceTile;
+import android.appwidget.AppWidgetManager;
+import android.os.Bundle;
+import android.util.Log;
+
+/** Helper class encapsulating AppWidgetOptions for People Tile. */
+public class AppWidgetOptionsHelper {
+ private static final String TAG = "AppWidgetOptionsHelper";
+
+ /** Key to store {@link PeopleSpaceTile} in AppWidgetOptions Bundle. */
+ public static final String OPTIONS_PEOPLE_TILE = "options_people_tile";
+
+ /** Sets {@link PeopleSpaceTile} in AppWidgetOptions. */
+ public static void setPeopleTile(AppWidgetManager appWidgetManager, int appWidgetId,
+ PeopleSpaceTile tile) {
+ if (tile == null) {
+ if (DEBUG) Log.d(TAG, "Requested to store null tile");
+ return;
+ }
+ Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
+ options.putParcelable(OPTIONS_PEOPLE_TILE, tile);
+ appWidgetManager.updateAppWidgetOptions(appWidgetId, options);
+ }
+
+ /** Gets {@link PeopleSpaceTile} from AppWidgetOptions. */
+ public static PeopleSpaceTile getPeopleTile(AppWidgetManager appWidgetManager,
+ int appWidgetId) {
+ Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
+ return options != null ? options.getParcelable(OPTIONS_PEOPLE_TILE) : null;
+ }
+
+ /** Sets {@link PeopleTileKey} in AppWidgetOptions. */
+ public static void setPeopleTileKey(AppWidgetManager appWidgetManager, int appWidgetId,
+ PeopleTileKey key) {
+ Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
+ options.putString(SHORTCUT_ID, key.getShortcutId());
+ options.putInt(USER_ID, key.getUserId());
+ options.putString(PACKAGE_NAME, key.getPackageName());
+ appWidgetManager.updateAppWidgetOptions(appWidgetId, options);
+ }
+
+ /** Gets {@link PeopleTileKey} from AppWidgetOptions. */
+ public static PeopleTileKey getPeopleTileKey(AppWidgetManager appWidgetManager,
+ int appWidgetId) {
+ Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
+ if (options == null) {
+ return EMPTY_KEY;
+ }
+ return getPeopleTileKeyFromBundle(options);
+ }
+
+ /** Gets {@link PeopleTileKey} from Bundle {@code options}. */
+ public static PeopleTileKey getPeopleTileKeyFromBundle(Bundle options) {
+ String pkg = options.getString(PACKAGE_NAME, EMPTY_STRING);
+ int userId = options.getInt(USER_ID, INVALID_USER_ID);
+ String shortcutId = options.getString(SHORTCUT_ID, EMPTY_STRING);
+ return new PeopleTileKey(shortcutId, userId, pkg);
+ }
+
+ /** Removes {@link PeopleTileKey} from AppWidgetOptions. */
+ public static void removePeopleTileKey(AppWidgetManager appWidgetManager,
+ int appWidgetId) {
+ setPeopleTileKey(appWidgetManager, appWidgetId, EMPTY_KEY);
+ }
+}
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 22ee9e8..7da9a80 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -16,6 +16,7 @@
package com.android.systemui.people.widget;
+import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
import static com.android.systemui.people.PeopleSpaceUtils.SHORTCUT_ID;
@@ -38,6 +39,7 @@
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
import android.net.Uri;
+import android.os.Bundle;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.preference.PreferenceManager;
@@ -78,8 +80,8 @@
private PeopleManager mPeopleManager;
public UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
@GuardedBy("mLock")
- public static Map<String, PeopleSpaceWidgetProvider.TileConversationListener> mListeners =
- new HashMap<>();
+ public static Map<PeopleTileKey, PeopleSpaceWidgetProvider.TileConversationListener>
+ mListeners = new HashMap<>();
@Inject
public PeopleSpaceWidgetManager(Context context) {
@@ -122,8 +124,8 @@
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0) == 0;
if (showSingleConversation) {
synchronized (mLock) {
- PeopleSpaceUtils.updateSingleConversationWidgets(mContext, widgetIds,
- mAppWidgetManager, mIPeopleManager);
+ PeopleSpaceUtils.updateSingleConversationWidgets(
+ mContext, widgetIds, mAppWidgetManager, mIPeopleManager);
}
}
} catch (Exception e) {
@@ -157,9 +159,11 @@
return;
}
synchronized (mLock) {
- Set<String> storedWidgetIds = getStoredWidgetIds(mSharedPrefs, sbnShortcutId,
- sbn.getPackageName(),
- UserHandle.getUserHandleForUid(sbn.getUid()).getIdentifier());
+ PeopleTileKey key = new PeopleTileKey(
+ sbnShortcutId,
+ UserHandle.getUserHandleForUid(sbn.getUid()).getIdentifier(),
+ sbn.getPackageName());
+ Set<String> storedWidgetIds = getStoredWidgetIds(mSharedPrefs, key);
for (String widgetIdString : storedWidgetIds) {
int widgetId = Integer.parseInt(widgetIdString);
if (DEBUG) Log.d(TAG, "Storing notification change, key:" + sbn.getKey());
@@ -177,9 +181,9 @@
public void updateWidgetsWithConversationChanged(ConversationChannel conversation) {
ShortcutInfo info = conversation.getShortcutInfo();
synchronized (mLock) {
- Set<String> storedWidgetIds = getStoredWidgetIds(mSharedPrefs, info.getId(),
- info.getPackage(),
- info.getUserId());
+ PeopleTileKey key = new PeopleTileKey(
+ info.getId(), info.getUserId(), info.getPackage());
+ Set<String> storedWidgetIds = getStoredWidgetIds(mSharedPrefs, key);
for (String widgetIdString : storedWidgetIds) {
if (DEBUG) {
Log.d(TAG,
@@ -197,9 +201,8 @@
*/
private void updateStorageAndViewWithConversationData(ConversationChannel conversation,
int appWidgetId) {
- PeopleSpaceTile storedTile = getPeopleSpaceTile(mIPeopleManager, mAppWidgetManager,
- mContext,
- appWidgetId);
+ PeopleSpaceTile storedTile = getPeopleSpaceTile(
+ mContext, appWidgetId, mAppWidgetManager, mIPeopleManager);
if (storedTile == null) {
if (DEBUG) Log.d(TAG, "Could not find stored tile to add conversation to");
return;
@@ -232,9 +235,8 @@
StatusBarNotification sbn,
PeopleSpaceUtils.NotificationAction notificationAction,
int appWidgetId) {
- PeopleSpaceTile storedTile = getPeopleSpaceTile(mIPeopleManager, mAppWidgetManager,
- mContext,
- appWidgetId);
+ PeopleSpaceTile storedTile = getPeopleSpaceTile(
+ mContext, appWidgetId, mAppWidgetManager, mIPeopleManager);
if (storedTile == null) {
if (DEBUG) Log.d(TAG, "Could not find stored tile to add notification to");
return;
@@ -312,18 +314,39 @@
}
};
- /** Adds {@code tile} mapped to {@code appWidgetId}. */
- public void addNewWidget(PeopleSpaceTile tile, int appWidgetId) {
+ /**
+ * Checks if this widget has been added externally, and this the first time we are learning
+ * about the widget. If so, the widget adder should have populated options with PeopleTileKey
+ * arguments.
+ */
+ public void onAppWidgetOptionsChanged(int appWidgetId, Bundle newOptions) {
+ // Check if this widget has been added externally, and this the first time we are
+ // learning about the widget. If so, the widget adder should have populated options with
+ // PeopleTileKey arguments.
+ if (DEBUG) Log.d(TAG, "onAppWidgetOptionsChanged called for widget: " + appWidgetId);
+ PeopleTileKey optionsKey = AppWidgetOptionsHelper.getPeopleTileKeyFromBundle(newOptions);
+ if (optionsKey.isValid()) {
+ if (DEBUG) {
+ Log.d(TAG, "PeopleTileKey was present in Options, shortcutId: "
+ + optionsKey.getShortcutId());
+ }
+ addNewWidget(appWidgetId, optionsKey);
+ AppWidgetOptionsHelper.removePeopleTileKey(mAppWidgetManager, appWidgetId);
+ }
+ }
+
+ /** Adds{@code tile} mapped to {@code appWidgetId}. */
+ public void addNewWidget(int appWidgetId, PeopleTileKey key) {
mUiEventLogger.log(PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_ADDED);
synchronized (mLock) {
- if (DEBUG) Log.d(TAG, "Add storage for : " + tile.getUserName());
- PeopleSpaceUtils.setStorageForTile(mContext, tile, appWidgetId);
+ if (DEBUG) Log.d(TAG, "Add storage for : " + key.getShortcutId());
+ PeopleSpaceUtils.setSharedPreferencesStorageForTile(mContext, key, appWidgetId);
}
try {
- if (DEBUG) Log.d(TAG, "Caching shortcut for PeopleTile: " + tile.getId());
- mLauncherApps.cacheShortcuts(tile.getPackageName(),
- Collections.singletonList(tile.getId()),
- tile.getUserHandle(), LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS);
+ if (DEBUG) Log.d(TAG, "Caching shortcut for PeopleTile: " + key.getShortcutId());
+ mLauncherApps.cacheShortcuts(key.getPackageName(),
+ Collections.singletonList(key.getShortcutId()),
+ UserHandle.of(key.getUserId()), LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS);
} catch (Exception e) {
Log.w(TAG, "Exception caching shortcut:" + e);
}
@@ -335,19 +358,16 @@
public void registerConversationListenerIfNeeded(int widgetId,
PeopleSpaceWidgetProvider.TileConversationListener newListener) {
// Retrieve storage needed for registration.
- String packageName;
- String shortcutId;
- int userId;
- String key;
+ PeopleTileKey key;
synchronized (mLock) {
SharedPreferences widgetSp = mContext.getSharedPreferences(String.valueOf(widgetId),
Context.MODE_PRIVATE);
- packageName = widgetSp.getString(PACKAGE_NAME, null);
- shortcutId = widgetSp.getString(SHORTCUT_ID, null);
- userId = widgetSp.getInt(USER_ID, INVALID_USER_ID);
- key = PeopleSpaceUtils.getKey(shortcutId, packageName, userId);
- if (key == null) {
- if (DEBUG) Log.e(TAG, "Could not register " + widgetId);
+ key = new PeopleTileKey(
+ widgetSp.getString(SHORTCUT_ID, EMPTY_STRING),
+ widgetSp.getInt(USER_ID, INVALID_USER_ID),
+ widgetSp.getString(PACKAGE_NAME, EMPTY_STRING));
+ if (!key.isValid()) {
+ if (DEBUG) Log.w(TAG, "Could not register listener for widget: " + widgetId);
return;
}
}
@@ -359,9 +379,9 @@
if (DEBUG) Log.d(TAG, "Register listener for " + widgetId + " with " + key);
mListeners.put(key, newListener);
}
- mPeopleManager.registerConversationListener(packageName,
- userId,
- shortcutId, newListener,
+ mPeopleManager.registerConversationListener(key.getPackageName(),
+ key.getUserId(),
+ key.getShortcutId(), newListener,
mContext.getMainExecutor());
}
@@ -371,27 +391,24 @@
if (DEBUG) Log.d(TAG, "Widget removed: " + widgetId);
mUiEventLogger.log(PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_DELETED);
// Retrieve storage needed for widget deletion.
- String packageName;
- String shortcutId;
- int userId;
- String key;
+ PeopleTileKey key;
Set<String> storedWidgetIdsForKey;
synchronized (mLock) {
SharedPreferences widgetSp = mContext.getSharedPreferences(String.valueOf(widgetId),
Context.MODE_PRIVATE);
- packageName = widgetSp.getString(PACKAGE_NAME, null);
- shortcutId = widgetSp.getString(SHORTCUT_ID, null);
- userId = widgetSp.getInt(USER_ID, INVALID_USER_ID);
- key = PeopleSpaceUtils.getKey(shortcutId, packageName, userId);
- if (key == null) {
+ key = new PeopleTileKey(
+ widgetSp.getString(SHORTCUT_ID, null),
+ widgetSp.getInt(USER_ID, INVALID_USER_ID),
+ widgetSp.getString(PACKAGE_NAME, null));
+ if (!key.isValid()) {
if (DEBUG) Log.e(TAG, "Could not delete " + widgetId);
return;
}
storedWidgetIdsForKey = new HashSet<>(
- mSharedPrefs.getStringSet(key, new HashSet<>()));
+ mSharedPrefs.getStringSet(key.toString(), new HashSet<>()));
}
synchronized (mLock) {
- PeopleSpaceUtils.removeStorageForTile(mContext, key, widgetId);
+ PeopleSpaceUtils.removeSharedPreferencesStorageForTile(mContext, key, widgetId);
}
// If another tile with the conversation is still stored, we need to keep the listener.
if (DEBUG) Log.d(TAG, "Stored widget IDs: " + storedWidgetIdsForKey.toString());
@@ -399,13 +416,13 @@
&& storedWidgetIdsForKey.size() == 1) {
if (DEBUG) Log.d(TAG, "Remove caching and listener");
unregisterConversationListener(key, widgetId);
- uncacheConversationShortcut(shortcutId, packageName, userId);
+ uncacheConversationShortcut(key);
}
}
}
/** Unregisters the conversation listener for {@code appWidgetId}. */
- private void unregisterConversationListener(String key, int appWidgetId) {
+ private void unregisterConversationListener(PeopleTileKey key, int appWidgetId) {
PeopleSpaceWidgetProvider.TileConversationListener registeredListener;
synchronized (mListeners) {
registeredListener = mListeners.get(key);
@@ -420,12 +437,12 @@
}
/** Uncaches the conversation shortcut. */
- private void uncacheConversationShortcut(String shortcutId, String packageName, int userId) {
+ private void uncacheConversationShortcut(PeopleTileKey key) {
try {
- if (DEBUG) Log.d(TAG, "Uncaching shortcut for PeopleTile: " + shortcutId);
- mLauncherApps.uncacheShortcuts(packageName,
- Collections.singletonList(shortcutId),
- UserHandle.of(userId),
+ if (DEBUG) Log.d(TAG, "Uncaching shortcut for PeopleTile: " + key.getShortcutId());
+ mLauncherApps.uncacheShortcuts(key.getPackageName(),
+ Collections.singletonList(key.getShortcutId()),
+ UserHandle.of(key.getUserId()),
LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS);
} catch (Exception e) {
Log.d(TAG, "Exception uncaching shortcut:" + e);
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java
index cccf7aa..3bc5b29 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java
@@ -22,6 +22,7 @@
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
+import android.os.Bundle;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -67,18 +68,21 @@
ensurePeopleSpaceWidgetManagerInitialized(context);
peopleSpaceWidgetManager.updateWidgets(appWidgetIds);
for (int appWidgetId : appWidgetIds) {
+ if (DEBUG) Log.d(TAG, "Ensure listener is registered for widget: " + appWidgetId);
PeopleSpaceWidgetProvider.TileConversationListener
newListener = new PeopleSpaceWidgetProvider.TileConversationListener();
peopleSpaceWidgetManager.registerConversationListenerIfNeeded(appWidgetId,
newListener);
}
- return;
}
- private void ensurePeopleSpaceWidgetManagerInitialized(Context context) {
- if (peopleSpaceWidgetManager == null) {
- peopleSpaceWidgetManager = new PeopleSpaceWidgetManager(context);
- }
+ /** Called when widget updates. */
+ @Override
+ public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager,
+ int appWidgetId, Bundle newOptions) {
+ super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
+ ensurePeopleSpaceWidgetManagerInitialized(context);
+ peopleSpaceWidgetManager.onAppWidgetOptionsChanged(appWidgetId, newOptions);
}
@Override
@@ -88,6 +92,12 @@
peopleSpaceWidgetManager.deleteWidgets(appWidgetIds);
}
+ private void ensurePeopleSpaceWidgetManagerInitialized(Context context) {
+ if (peopleSpaceWidgetManager == null) {
+ peopleSpaceWidgetManager = new PeopleSpaceWidgetManager(context);
+ }
+ }
+
@VisibleForTesting
public void setPeopleSpaceWidgetManager(PeopleSpaceWidgetManager manager) {
peopleSpaceWidgetManager = manager;
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetRemoteViewsFactory.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetRemoteViewsFactory.java
index 0503522..87b2a15 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetRemoteViewsFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetRemoteViewsFactory.java
@@ -106,7 +106,7 @@
PeopleSpaceTile tile = mTiles.get(i);
String status = PeopleSpaceUtils.getLastInteractionString(mContext,
- tile.getLastInteractionTimestamp(), true);
+ tile.getLastInteractionTimestamp());
personView.setTextViewText(R.id.status, status);
personView.setTextViewText(R.id.name, tile.getUserName().toString());
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleTileKey.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleTileKey.java
new file mode 100644
index 0000000..ac42cb0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleTileKey.java
@@ -0,0 +1,105 @@
+/*
+ * 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.people.widget;
+
+import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
+import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
+
+import android.text.TextUtils;
+
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+import java.util.Objects;
+
+/** Class that encapsulates fields identifying a Conversation. */
+public class PeopleTileKey {
+ private String mShortcutId;
+ private int mUserId;
+ private String mPackageName;
+
+ public PeopleTileKey(String shortcutId, int userId, String packageName) {
+ mShortcutId = shortcutId;
+ mUserId = userId;
+ mPackageName = packageName;
+ }
+
+ public PeopleTileKey(NotificationEntry entry) {
+ mShortcutId = entry.getRanking() != null
+ && entry.getRanking().getConversationShortcutInfo() != null
+ ? entry.getRanking().getConversationShortcutInfo().getId()
+ : EMPTY_STRING;
+ mUserId = entry.getSbn().getUser() != null
+ ? entry.getSbn().getUser().getIdentifier() : INVALID_USER_ID;
+ mPackageName = entry.getSbn().getPackageName();
+ }
+
+ public String getShortcutId() {
+ return mShortcutId;
+ }
+
+ public int getUserId() {
+ return mUserId;
+ }
+
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ /** Returns whether PeopleTileKey is valid/well-formed. */
+ public boolean isValid() {
+ return !TextUtils.isEmpty(mShortcutId) && !TextUtils.isEmpty(mPackageName) && mUserId >= 0;
+ }
+
+ /**
+ * Returns the uniquely identifying key for the conversation.
+ *
+ * <p>{@code userId} will always be a number, so we put user ID as the
+ * delimiter between the app-provided strings of shortcut ID and package name.
+ *
+ * <p>There aren't restrictions on shortcut ID characters, but there are restrictions requiring
+ * a {@code packageName} to always start with a letter. This restriction means we are
+ * guaranteed to avoid cases like "a/b/0/0/package.name" having two potential keys, as the first
+ * case is impossible given the package name restrictions:
+ * <ul>
+ * <li>"a/b" + "/" + 0 + "/" + "0/packageName"</li>
+ * <li>"a/b/0" + "/" + 0 + "/" + "packageName"</li>
+ * </ul>
+ */
+ @Override
+ public String toString() {
+ if (!isValid()) return null;
+ return mShortcutId + "/" + mUserId + "/" + mPackageName;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof PeopleTileKey)) {
+ return false;
+ }
+ final PeopleTileKey o = (PeopleTileKey) other;
+ return Objects.equals(o.toString(), this.toString());
+ }
+
+ @Override
+ public int hashCode() {
+ return mPackageName.hashCode() + Integer.valueOf(mUserId).hashCode()
+ + mShortcutId.hashCode();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
index 7e20be6..3d8784b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
@@ -94,7 +94,7 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mEdit = findViewById(android.R.id.edit);
+ mEdit = requireViewById(android.R.id.edit);
mPageIndicator = findViewById(R.id.footer_page_indicator);
@@ -104,14 +104,15 @@
mMultiUserSwitch = findViewById(R.id.multi_user_switch);
mMultiUserAvatar = mMultiUserSwitch.findViewById(R.id.multi_user_avatar);
- mActionsContainer = findViewById(R.id.qs_footer_actions_container);
+ mActionsContainer = requireViewById(R.id.qs_footer_actions_container);
mEditContainer = findViewById(R.id.qs_footer_actions_edit_container);
mBuildText = findViewById(R.id.build);
// RenderThread is doing more harm than good when touching the header (to expand quick
// settings), so disable it for this view
- ((RippleDrawable) mSettingsButton.getBackground()).setForceSoftware(true);
-
+ if (mSettingsButton.getBackground() instanceof RippleDrawable) {
+ ((RippleDrawable) mSettingsButton.getBackground()).setForceSoftware(true);
+ }
updateResources();
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
@@ -143,7 +144,7 @@
int defSpace = mContext.getResources().getDimensionPixelOffset(R.dimen.default_gear_space);
mSettingsCogAnimator = new Builder()
- .addFloat(mSettingsContainer, "translationX",
+ .addFloat(mSettingsButton, "translationX",
isLayoutRtl() ? (remaining - defSpace) : -(remaining - defSpace), 0)
.addFloat(mSettingsButton, "rotation", -120, 0)
.build();
@@ -173,12 +174,15 @@
@Nullable
private TouchAnimator createFooterAnimator() {
- return new TouchAnimator.Builder()
+ TouchAnimator.Builder builder = new TouchAnimator.Builder()
.addFloat(mActionsContainer, "alpha", 0, 1)
- .addFloat(mEditContainer, "alpha", 0, 1)
.addFloat(mPageIndicator, "alpha", 0, 1)
- .setStartDelay(0.9f)
- .build();
+ .addFloat(mBuildText, "alpha", 0, 1)
+ .setStartDelay(0.9f);
+ if (mEditContainer != null) {
+ builder.addFloat(mEditContainer, "alpha", 0, 1);
+ }
+ return builder.build();
}
/** */
@@ -273,8 +277,10 @@
mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
isTunerEnabled ? View.VISIBLE : View.INVISIBLE);
final boolean isDemo = UserManager.isDeviceInDemoMode(mContext);
- mMultiUserSwitch.setVisibility(showUserSwitcher() ? View.VISIBLE : View.INVISIBLE);
- mEditContainer.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
+ mMultiUserSwitch.setVisibility(showUserSwitcher() ? View.VISIBLE : View.GONE);
+ if (mEditContainer != null) {
+ mEditContainer.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
+ }
mSettingsButton.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
mBuildText.setVisibility(mExpanded && mShouldShowBuildText ? View.VISIBLE : View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
index 2bea72c..f1f4e16 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
@@ -153,8 +153,8 @@
@Override
protected void onViewAttached() {
- if (mShowPMLiteButton) {
- mPowerMenuLite.setVisibility(View.VISIBLE);
+ if (!mShowPMLiteButton) {
+ mPowerMenuLite.setVisibility(View.GONE);
}
mView.addOnLayoutChangeListener(
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 7657dce..ff9b912 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -32,6 +32,7 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewStub;
import android.widget.LinearLayout;
import com.android.internal.logging.UiEventLogger;
@@ -127,8 +128,21 @@
}
+ protected void inflateQSFooter(boolean newFooter) {
+ ViewStub stub = findViewById(R.id.qs_footer_stub);
+ if (stub != null) {
+ stub.setLayoutResource(
+ newFooter ? R.layout.qs_footer_impl_two_lines : R.layout.qs_footer_impl);
+ stub.inflate();
+ mFooter = findViewById(R.id.qs_footer);
+ }
+ }
+
void initialize(boolean sideLabels) {
mSideLabels = sideLabels;
+
+ inflateQSFooter(sideLabels);
+
mRegularTileLayout = createRegularTileLayout();
mTileLayout = mRegularTileLayout;
@@ -344,7 +358,6 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mFooter = findViewById(R.id.qs_footer);
mDivider = findViewById(R.id.divider);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 9b66b59..f51d7ef 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -55,6 +55,11 @@
applyBottomMargin((View) mRegularTileLayout);
}
+ @Override
+ protected void inflateQSFooter(boolean newFooter) {
+ // No footer
+ }
+
private void applyBottomMargin(View view) {
int margin = getResources().getDimensionPixelSize(R.dimen.qs_header_tile_margin_bottom);
MarginLayoutParams layoutParams = (MarginLayoutParams) view.getLayoutParams();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index 6983b38..9e5fe73 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -30,6 +30,7 @@
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.tiles.AirplaneModeTile;
+import com.android.systemui.qs.tiles.AlarmTile;
import com.android.systemui.qs.tiles.BatterySaverTile;
import com.android.systemui.qs.tiles.BluetoothTile;
import com.android.systemui.qs.tiles.CameraToggleTile;
@@ -91,6 +92,7 @@
private final Provider<CameraToggleTile> mCameraToggleTileProvider;
private final Provider<MicrophoneToggleTile> mMicrophoneToggleTileProvider;
private final Provider<DeviceControlsTile> mDeviceControlsTileProvider;
+ private final Provider<AlarmTile> mAlarmTileProvider;
private final Lazy<QSHost> mQsHostLazy;
private final Provider<CustomTile.Builder> mCustomTileBuilderProvider;
@@ -126,7 +128,8 @@
Provider<ReduceBrightColorsTile> reduceBrightColorsTileProvider,
Provider<CameraToggleTile> cameraToggleTileProvider,
Provider<MicrophoneToggleTile> microphoneToggleTileProvider,
- Provider<DeviceControlsTile> deviceControlsTileProvider) {
+ Provider<DeviceControlsTile> deviceControlsTileProvider,
+ Provider<AlarmTile> alarmTileProvider) {
mQsHostLazy = qsHostLazy;
mCustomTileBuilderProvider = customTileBuilderProvider;
@@ -157,6 +160,7 @@
mCameraToggleTileProvider = cameraToggleTileProvider;
mMicrophoneToggleTileProvider = microphoneToggleTileProvider;
mDeviceControlsTileProvider = deviceControlsTileProvider;
+ mAlarmTileProvider = alarmTileProvider;
}
public QSTile createTile(String tileSpec) {
@@ -218,6 +222,8 @@
return mMicrophoneToggleTileProvider.get();
case "controls":
return mDeviceControlsTileProvider.get();
+ case "alarm":
+ return mAlarmTileProvider.get();
}
// Custom tiles
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
new file mode 100644
index 0000000..dede627
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
@@ -0,0 +1,117 @@
+package com.android.systemui.qs.tiles
+
+import android.app.AlarmManager
+import android.app.AlarmManager.AlarmClockInfo
+import android.content.Intent
+import android.os.Handler
+import android.os.Looper
+import android.provider.AlarmClock
+import android.service.quicksettings.Tile
+import android.text.TextUtils
+import android.text.format.DateFormat
+import androidx.annotation.VisibleForTesting
+import com.android.internal.logging.MetricsLogger
+import com.android.systemui.R
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.statusbar.FeatureFlags
+import com.android.systemui.statusbar.policy.NextAlarmController
+import java.util.Locale
+import javax.inject.Inject
+
+class AlarmTile @Inject constructor(
+ host: QSHost,
+ @Background backgroundLooper: Looper,
+ @Main mainHandler: Handler,
+ metricsLogger: MetricsLogger,
+ statusBarStateController: StatusBarStateController,
+ activityStarter: ActivityStarter,
+ qsLogger: QSLogger,
+ private val featureFlags: FeatureFlags,
+ private val userTracker: UserTracker,
+ nextAlarmController: NextAlarmController
+) : QSTileImpl<QSTile.State>(
+ host,
+ backgroundLooper,
+ mainHandler,
+ metricsLogger,
+ statusBarStateController,
+ activityStarter,
+ qsLogger
+) {
+
+ private var lastAlarmInfo: AlarmManager.AlarmClockInfo? = null
+ private val icon = ResourceIcon.get(R.drawable.ic_alarm)
+ @VisibleForTesting
+ internal val defaultIntent = Intent(AlarmClock.ACTION_SET_ALARM)
+ private val callback = NextAlarmController.NextAlarmChangeCallback { nextAlarm ->
+ lastAlarmInfo = nextAlarm
+ refreshState()
+ }
+
+ init {
+ nextAlarmController.observe(this, callback)
+ }
+
+ override fun isAvailable(): Boolean {
+ return featureFlags.isAlarmTileAvailable
+ }
+
+ override fun newTileState(): QSTile.State {
+ return QSTile.State().apply {
+ handlesLongClick = false
+ }
+ }
+
+ private fun startDefaultSetAlarm() {
+ mActivityStarter.postStartActivityDismissingKeyguard(defaultIntent, 0)
+ }
+
+ override fun handleClick() {
+ lastAlarmInfo?.showIntent?.let {
+ mActivityStarter.postStartActivityDismissingKeyguard(it)
+ } ?: startDefaultSetAlarm()
+ }
+
+ override fun handleUpdateState(state: QSTile.State, arg: Any?) {
+ state.icon = icon
+ state.label = tileLabel
+ lastAlarmInfo?.let {
+ state.secondaryLabel = formatNextAlarm(it)
+ state.state = Tile.STATE_ACTIVE
+ } ?: run {
+ state.secondaryLabel = mContext.getString(R.string.qs_alarm_tile_no_alarm)
+ state.state = Tile.STATE_INACTIVE
+ }
+ state.contentDescription = TextUtils.concat(state.label, ", ", state.secondaryLabel)
+ }
+
+ override fun getTileLabel(): CharSequence {
+ return mContext.getString(R.string.status_bar_alarm)
+ }
+
+ private fun formatNextAlarm(info: AlarmClockInfo): String {
+ val skeleton = if (use24HourFormat()) "EHm" else "Ehma"
+ val pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton)
+ return DateFormat.format(pattern, info.triggerTime).toString()
+ }
+
+ private fun use24HourFormat(): Boolean {
+ return DateFormat.is24HourFormat(mContext, userTracker.userId)
+ }
+
+ override fun getMetricsCategory(): Int {
+ return 0
+ }
+
+ override fun getLongClickIntent(): Intent? {
+ return null
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
index 3b9f5dc..257d6a7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
@@ -16,6 +16,7 @@
package com.android.systemui.qs.tiles
+import android.content.ComponentName
import android.content.Intent
import android.os.Handler
import android.os.Looper
@@ -27,7 +28,8 @@
import com.android.systemui.controls.dagger.ControlsComponent
import com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE
import com.android.systemui.controls.management.ControlsListingController
-import com.android.systemui.controls.ui.ControlsDialog
+import com.android.systemui.controls.ui.ControlsActivity
+import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.ActivityStarter
@@ -40,7 +42,6 @@
import com.android.systemui.util.settings.GlobalSettings
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
-import javax.inject.Provider
class DeviceControlsTile @Inject constructor(
host: QSHost,
@@ -52,7 +53,6 @@
qsLogger: QSLogger,
private val controlsComponent: ControlsComponent,
private val featureFlags: FeatureFlags,
- private val dialogProvider: Provider<ControlsDialog>,
globalSettings: GlobalSettings
) : QSTileImpl<QSTile.State>(
host,
@@ -72,7 +72,6 @@
private var hasControlsApps = AtomicBoolean(false)
private val intent = Intent(Settings.ACTION_DEVICE_CONTROLS_SETTINGS)
- private var controlsDialog: ControlsDialog? = null
private val icon = ResourceIcon.get(R.drawable.ic_device_light)
private val listingCallback = object : ControlsListingController.ControlsListingCallback {
@@ -102,27 +101,19 @@
}
override fun handleDestroy() {
- dismissDialog()
super.handleDestroy()
}
- private fun createDialog() {
- if (controlsDialog?.isShowing != true) {
- controlsDialog = dialogProvider.get()
- }
- }
-
- private fun dismissDialog() {
- controlsDialog?.dismiss()?.also {
- controlsDialog = null
- }
- }
-
override fun handleClick() {
if (state.state == Tile.STATE_ACTIVE) {
mUiHandler.post {
- createDialog()
- controlsDialog?.show(controlsComponent.getControlsUiController().get())
+ mHost.collapsePanels()
+ val i = Intent().apply {
+ component = ComponentName(mContext, ControlsActivity::class.java)
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
+ putExtra(ControlsUiController.BACK_TO_GLOBAL_ACTIONS, false)
+ }
+ mContext.startActivity(i)
}
}
}
@@ -133,9 +124,6 @@
state.contentDescription = state.label
state.icon = icon
if (controlsComponent.isEnabled() && hasControlsApps.get()) {
- if (controlsDialog == null) {
- mUiHandler.post(this::createDialog)
- }
if (controlsComponent.getVisibility() == AVAILABLE) {
state.state = Tile.STATE_ACTIVE
state.secondaryLabel = ""
@@ -146,7 +134,6 @@
state.stateDescription = state.secondaryLabel
} else {
state.state = Tile.STATE_UNAVAILABLE
- dismissDialog()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
index c066619..bb8c367 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
@@ -136,7 +136,7 @@
case MotionEvent.ACTION_UP:
if (mCurrentDraggingBoundary != CropBoundary.NONE) {
// Commit the delta to the stored crop values.
- commitDeltas();
+ commitDeltas(mCurrentDraggingBoundary);
updateListener(event);
}
}
@@ -184,12 +184,12 @@
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- commitDeltas();
+ commitDeltas(boundary);
}
@Override
public void onAnimationCancel(Animator animation) {
- commitDeltas();
+ commitDeltas(boundary);
}
});
animator.setFloatValues(0f, 1f);
@@ -228,11 +228,14 @@
mCropInteractionListener = listener;
}
- private void commitDeltas() {
- mTopCrop += mTopDelta;
- mBottomCrop += mBottomDelta;
- mTopDelta = 0;
- mBottomDelta = 0;
+ private void commitDeltas(CropBoundary boundary) {
+ if (boundary == CropBoundary.TOP) {
+ mTopCrop += mTopDelta;
+ mTopDelta = 0;
+ } else if (boundary == CropBoundary.BOTTOM) {
+ mBottomCrop += mBottomDelta;
+ mBottomDelta = 0;
+ }
}
private void updateListener(MotionEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index 4dc846e..db99705 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -339,14 +339,22 @@
}
@Override
- public void onComplete(ImageTileSet imageTileSet) {
+ public void onComplete(ImageTileSet imageTileSet, int pageSize) {
Log.i(TAG, "Got tiles " + imageTileSet.getWidth() + " x "
+ imageTileSet.getHeight());
mPreview.setImageDrawable(imageTileSet.getDrawable());
updateCropLocation();
mMagnifierView.setDrawable(imageTileSet.getDrawable(),
imageTileSet.getWidth(), imageTileSet.getHeight());
- mCropView.animateBoundaryTo(CropView.CropBoundary.BOTTOM, 0.5f);
+ // Original boundaries go from the image tile set's y=0 to y=pageSize, so
+ // we animate to that as a starting crop position.
+ float topFraction = Math.max(0,
+ -imageTileSet.getTop() / (float) imageTileSet.getHeight());
+ float bottomFraction = Math.min(1f,
+ 1 - (imageTileSet.getBottom() - pageSize)
+ / (float) imageTileSet.getHeight());
+ mCropView.animateBoundaryTo(CropView.CropBoundary.TOP, topFraction);
+ mCropView.animateBoundaryTo(CropView.CropBoundary.BOTTOM, bottomFraction);
mBackgroundExecutor.execute(() -> saveCacheBitmap(imageTileSet));
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS b/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
new file mode 100644
index 0000000..9b3e386
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
@@ -0,0 +1,12 @@
+# Scroll Capture (Long Screenshots)
+# Bug component: 801322
+#
+# Referenced by:
+#
+# core/java/src/android/view/OWNERS
+# core/java/src/com/android/internal/view/OWNERS
+# core/tests/coretests/src/android/view/OWNERS
+# core/tests/coretests/src/com/android/internal/view/OWNERS
+
+mrcasey@google.com
+mrenouf@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
index b62e2c3..34094cd 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
@@ -171,7 +171,7 @@
if (mImageTileSet.isEmpty()) {
mCaptureCallback.onError();
} else {
- mCaptureCallback.onComplete(mImageTileSet);
+ mCaptureCallback.onComplete(mImageTileSet, session.getPageHeight());
}
}
@@ -179,7 +179,7 @@
* Callback for image capture completion or error.
*/
public interface ScrollCaptureCallback {
- void onComplete(ImageTileSet imageTileSet);
+ void onComplete(ImageTileSet imageTileSet, int pageHeight);
void onError();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
index 1d59257..c8e0d60 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
@@ -90,4 +90,8 @@
public boolean isPMLiteEnabled() {
return mFlagReader.isEnabled(R.bool.flag_pm_lite);
}
+
+ public boolean isAlarmTileAvailable() {
+ return mFlagReader.isEnabled(R.bool.flag_alarm_tile);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java
index 9920153..e090d0b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java
@@ -31,6 +31,7 @@
import com.android.internal.R;
import com.android.internal.widget.CachingIconView;
import com.android.internal.widget.ConversationLayout;
+import com.android.internal.widget.ImageFloatingTextView;
import com.android.internal.widget.NotificationExpandButton;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationContentView;
@@ -430,6 +431,8 @@
public static final int[] MARGIN_ADJUSTED_VIEWS = {
R.id.notification_headerless_view_column,
+ R.id.text,
+ R.id.big_text,
R.id.title,
R.id.notification_main_column,
R.id.notification_header};
@@ -458,6 +461,10 @@
if (target == null) {
return;
}
+ if (target instanceof ImageFloatingTextView) {
+ ((ImageFloatingTextView) target).setHasImage(iconVisible);
+ return;
+ }
final Integer data = (Integer) target.getTag(iconVisible
? com.android.internal.R.id.tag_margin_end_when_icon_visible
: com.android.internal.R.id.tag_margin_end_when_icon_gone);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 3496581..e119907 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -16,9 +16,6 @@
package com.android.systemui.statusbar;
-import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN_REVERSE;
-import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE;
-
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -34,7 +31,6 @@
import android.view.accessibility.AccessibilityNodeInfo;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.notification.NotificationUtils;
@@ -55,8 +51,6 @@
public class NotificationShelf extends ActivatableNotificationView implements
View.OnLayoutChangeListener, StateListener {
- private static final boolean USE_ANIMATIONS_WHEN_OPENING =
- SystemProperties.getBoolean("debug.icon_opening_animations", true);
private static final boolean ICON_ANMATIONS_WHILE_SCROLLING
= SystemProperties.getBoolean("debug.icon_scroll_animations", true);
private static final int TAG_CONTINUOUS_CLIPPING = R.id.continuous_clipping_tag;
@@ -174,18 +168,9 @@
float viewEnd = lastViewState.yTranslation + lastViewState.height;
viewState.copyFrom(lastViewState);
viewState.height = getIntrinsicHeight();
-
viewState.yTranslation = Math.max(Math.min(viewEnd, maxShelfEnd) - viewState.height,
getFullyClosedTranslation());
viewState.zTranslation = ambientState.getBaseZHeight();
- // For the small display size, it's not enough to make the icon not covered by
- // the top cutout so the denominator add the height of cutout.
- // Totally, (getIntrinsicHeight() * 2 + mCutoutHeight) should be smaller then
- // mAmbientState.getTopPadding().
- float openedAmount = (viewState.yTranslation - getFullyClosedTranslation())
- / (getIntrinsicHeight() * 2 + mCutoutHeight);
- openedAmount = Math.min(1.0f, openedAmount);
- viewState.openedAmount = openedAmount;
viewState.clipTopAmount = 0;
viewState.alpha = 1;
viewState.belowSpeedBump = mHostLayoutController.getSpeedBumpIndex() == 0;
@@ -220,11 +205,6 @@
View lastChild = mAmbientState.getLastVisibleBackgroundChild();
mNotGoneIndex = -1;
float interpolationStart = mMaxLayoutHeight - getIntrinsicHeight() * 2;
- float expandAmount = 0.0f;
- if (shelfStart >= interpolationStart) {
- expandAmount = (shelfStart - interpolationStart) / getIntrinsicHeight();
- expandAmount = Math.min(1.0f, expandAmount);
- }
// find the first view that doesn't overlap with the shelf
int notGoneIndex = 0;
int colorOfViewBeforeLast = NO_COLOR;
@@ -239,7 +219,6 @@
boolean scrollingFast = currentScrollVelocity > mScrollFastThreshold
|| (mAmbientState.isExpansionChanging()
&& Math.abs(mAmbientState.getExpandingVelocity()) > mScrollFastThreshold);
- boolean scrolling = currentScrollVelocity > 0;
boolean expandingAnimated = mAmbientState.isExpansionChanging()
&& !mAmbientState.isPanelTracking();
int baseZHeight = mAmbientState.getBaseZHeight();
@@ -249,8 +228,7 @@
ActivatableNotificationView previousAnv = null;
for (int i = 0; i < mHostLayoutController.getChildCount(); i++) {
- ExpandableView child = (ExpandableView) mHostLayoutController.getChildAt(i);
-
+ ExpandableView child = mHostLayoutController.getChildAt(i);
if (!child.needsClippingToShelf() || child.getVisibility() == GONE) {
continue;
}
@@ -268,9 +246,8 @@
int clipTop = updateNotificationClipHeight(child, notificationClipEnd, notGoneIndex);
clipTopAmount = Math.max(clipTop, clipTopAmount);
-
- float inShelfAmount = updateShelfTransformation(child, expandAmount, scrolling,
- scrollingFast, expandingAnimated, isLastChild);
+ final float inShelfAmount = updateShelfTransformation(child, scrollingFast,
+ expandingAnimated, isLastChild);
// If the current row is an ExpandableNotificationRow, update its color, roundedness,
// and icon state.
if (child instanceof ExpandableNotificationRow) {
@@ -498,56 +475,40 @@
/**
* @return the amount how much this notification is in the shelf
*/
- private float updateShelfTransformation(ExpandableView view, float expandAmount,
- boolean scrolling, boolean scrollingFast, boolean expandingAnimated,
- boolean isLastChild) {
- StatusBarIconView icon = view.getShelfIcon();
- NotificationIconContainer.IconState iconState = getIconState(icon);
+ private float updateShelfTransformation(ExpandableView view, boolean scrollingFast,
+ boolean expandingAnimated, boolean isLastChild) {
// Let calculate how much the view is in the shelf
float viewStart = view.getTranslationY();
int fullHeight = view.getActualHeight() + mPaddingBetweenElements;
float iconTransformStart = calculateIconTransformationStart(view);
- float transformDistance = getIntrinsicHeight() * 1.5f;
- transformDistance *= NotificationUtils.interpolate(1.f, 1.5f, expandAmount);
- transformDistance = Math.min(transformDistance, fullHeight);
-
// Let's make sure the transform distance is
// at most to the icon (relevant for conversations)
- transformDistance = Math.min(viewStart + fullHeight - iconTransformStart,
- transformDistance);
+ float transformDistance = Math.min(
+ viewStart + fullHeight - iconTransformStart,
+ getIntrinsicHeight());
if (isLastChild) {
fullHeight = Math.min(fullHeight, view.getMinHeight() - getIntrinsicHeight());
- transformDistance = Math.min(transformDistance, view.getMinHeight()
- - getIntrinsicHeight());
+ transformDistance = Math.min(
+ transformDistance,
+ view.getMinHeight() - getIntrinsicHeight());
}
float viewEnd = viewStart + fullHeight;
- handleCustomTransformHeight(view, expandingAnimated, iconState);
-
- float fullTransitionAmount;
- float iconTransitionAmount;
- float contentTransformationAmount;
+ float fullTransitionAmount = 0.0f;
+ float iconTransitionAmount = 0.0f;
float shelfStart = getTranslationY();
- boolean fullyInOrOut = true;
- if (viewEnd >= shelfStart && (!mAmbientState.isUnlockHintRunning() || view.isInShelf())
+
+ if (viewEnd >= shelfStart
+ && (!mAmbientState.isUnlockHintRunning() || view.isInShelf())
&& (mAmbientState.isShadeExpanded()
|| (!view.isPinned() && !view.isHeadsUpAnimatingAway()))) {
- if (viewStart < shelfStart) {
- if (iconState != null && iconState.hasCustomTransformHeight()) {
- fullHeight = iconState.customTransformHeight;
- transformDistance = iconState.customTransformHeight;
- }
+ if (viewStart < shelfStart) {
float fullAmount = (shelfStart - viewStart) / fullHeight;
fullAmount = Math.min(1.0f, fullAmount);
- float interpolatedAmount = Interpolators.ACCELERATE_DECELERATE.getInterpolation(
- fullAmount);
- interpolatedAmount = NotificationUtils.interpolate(
- interpolatedAmount, fullAmount, expandAmount);
- fullTransitionAmount = 1.0f - interpolatedAmount;
-
+ fullTransitionAmount = 1.0f - fullAmount;
if (isLastChild) {
// Reduce icon transform distance to completely fade in shelf icon
// by the time the notification icon fades out, and vice versa
@@ -558,37 +519,14 @@
}
iconTransitionAmount = MathUtils.constrain(iconTransitionAmount, 0.0f, 1.0f);
iconTransitionAmount = 1.0f - iconTransitionAmount;
- fullyInOrOut = false;
} else {
+ // Fully in shelf.
fullTransitionAmount = 1.0f;
iconTransitionAmount = 1.0f;
}
-
- // Transforming the content
- contentTransformationAmount = (shelfStart - viewStart) / transformDistance;
- contentTransformationAmount = Math.min(1.0f, contentTransformationAmount);
- contentTransformationAmount = 1.0f - contentTransformationAmount;
- } else {
- fullTransitionAmount = 0.0f;
- iconTransitionAmount = 0.0f;
- contentTransformationAmount = 0.0f;
}
- if (iconState != null && fullyInOrOut && !expandingAnimated && iconState.isLastExpandIcon) {
- iconState.isLastExpandIcon = false;
- iconState.customTransformHeight = NO_VALUE;
- }
-
- // Update the content transformation amount
- if (view.isAboveShelf() || view.showingPulsing()
- || (!isLastChild && iconState != null && !iconState.translateContent)) {
- contentTransformationAmount = 0.0f;
- }
- view.setContentTransformationAmount(contentTransformationAmount, isLastChild);
-
- // Update the positioning of the icon
- updateIconPositioning(view, iconTransitionAmount, fullTransitionAmount,
- transformDistance, scrolling, scrollingFast, expandingAnimated, isLastChild);
-
+ updateIconPositioning(view, iconTransitionAmount,
+ scrollingFast, expandingAnimated, isLastChild);
return fullTransitionAmount;
}
@@ -607,87 +545,31 @@
return start;
}
- private void handleCustomTransformHeight(ExpandableView view, boolean expandingAnimated,
- NotificationIconContainer.IconState iconState) {
- if (iconState != null && expandingAnimated && mAmbientState.getScrollY() == 0
- && !mAmbientState.isOnKeyguard() && !iconState.isLastExpandIcon) {
- // We are expanding animated. Because we switch to a linear interpolation in this case,
- // the last icon may be stuck in between the shelf position and the notification
- // position, which looks pretty bad. We therefore optimize this case by applying a
- // shorter transition such that the icon is either fully in the notification or we clamp
- // it into the shelf if it's close enough.
- // We need to persist this, since after the expansion, the behavior should still be the
- // same.
- float position = mAmbientState.getIntrinsicPadding()
- + mHostLayoutController.getPositionInLinearLayout(view);
- int maxShelfStart = mMaxLayoutHeight - getIntrinsicHeight();
- if (position < maxShelfStart && position + view.getIntrinsicHeight() >= maxShelfStart
- && view.getTranslationY() < position) {
- iconState.isLastExpandIcon = true;
- iconState.customTransformHeight = NO_VALUE;
- // Let's check if we're close enough to snap into the shelf
- boolean forceInShelf = mMaxLayoutHeight - getIntrinsicHeight() - position
- < getIntrinsicHeight();
- if (!forceInShelf) {
- // We are overlapping the shelf but not enough, so the icon needs to be
- // repositioned
- iconState.customTransformHeight = (int) (mMaxLayoutHeight
- - getIntrinsicHeight() - position);
- }
- }
- }
- }
-
private void updateIconPositioning(ExpandableView view, float iconTransitionAmount,
- float fullTransitionAmount, float iconTransformDistance, boolean scrolling,
boolean scrollingFast, boolean expandingAnimated, boolean isLastChild) {
StatusBarIconView icon = view.getShelfIcon();
NotificationIconContainer.IconState iconState = getIconState(icon);
if (iconState == null) {
return;
}
- boolean forceInShelf =
- iconState.isLastExpandIcon && !iconState.hasCustomTransformHeight();
boolean clampInShelf = iconTransitionAmount > 0.5f || isTargetClipped(view);
float clampedAmount = clampInShelf ? 1.0f : 0.0f;
if (iconTransitionAmount == clampedAmount) {
- iconState.noAnimations = (scrollingFast || expandingAnimated) && !forceInShelf;
- iconState.useFullTransitionAmount = iconState.noAnimations
- || (!ICON_ANMATIONS_WHILE_SCROLLING && iconTransitionAmount == 0.0f
- && scrolling);
- iconState.useLinearTransitionAmount = !ICON_ANMATIONS_WHILE_SCROLLING
- && iconTransitionAmount == 0.0f && !mAmbientState.isExpansionChanging();
- iconState.translateContent = mMaxLayoutHeight - getTranslationY()
- - getIntrinsicHeight() > 0;
+ iconState.noAnimations = (scrollingFast || expandingAnimated) && !isLastChild;
}
- if (!forceInShelf && (scrollingFast || (expandingAnimated
- && iconState.useFullTransitionAmount && !ViewState.isAnimatingY(icon)))) {
+ if (!isLastChild
+ && (scrollingFast || (expandingAnimated && !ViewState.isAnimatingY(icon)))) {
iconState.cancelAnimations(icon);
- iconState.useFullTransitionAmount = true;
iconState.noAnimations = true;
}
- if (iconState.hasCustomTransformHeight()) {
- iconState.useFullTransitionAmount = true;
- }
- if (iconState.isLastExpandIcon) {
- iconState.translateContent = false;
- }
float transitionAmount;
if (mAmbientState.isHiddenAtAll() && !view.isInShelf()) {
transitionAmount = mAmbientState.isFullyHidden() ? 1 : 0;
- } else if (isLastChild || !USE_ANIMATIONS_WHEN_OPENING
- || iconState.useFullTransitionAmount
- || iconState.useLinearTransitionAmount) {
- transitionAmount = iconTransitionAmount;
} else {
transitionAmount = iconTransitionAmount;
iconState.needsCannedAnimation = iconState.clampedAppearAmount != clampedAmount
&& !mNoAnimationsInThisFrame;
}
- iconState.iconAppearAmount = !USE_ANIMATIONS_WHEN_OPENING
- || iconState.useFullTransitionAmount
- ? fullTransitionAmount
- : transitionAmount;
iconState.clampedAppearAmount = clampedAmount;
setIconTransformationAmount(view, transitionAmount, isLastChild);
}
@@ -706,8 +588,7 @@
return endOfTarget >= getTranslationY() - mPaddingBetweenElements;
}
- private void setIconTransformationAmount(ExpandableView view,
- float transitionAmount,
+ private void setIconTransformationAmount(ExpandableView view, float transitionAmount,
boolean isLastChild) {
if (!(view instanceof ExpandableNotificationRow)) {
return;
@@ -718,32 +599,30 @@
if (iconState == null) {
return;
}
- iconState.hidden = transitionAmount == 0.0f && !iconState.isAnimating(icon);
- boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf();
- if (isAppearing) {
- iconState.hidden = true;
- iconState.iconAppearAmount = 0.0f;
- }
iconState.alpha = transitionAmount;
+ boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf();
+ iconState.hidden = isAppearing
+ || (view instanceof ExpandableNotificationRow
+ && ((ExpandableNotificationRow) view).isLowPriority()
+ && mShelfIcons.hasMaxNumDot())
+ || (transitionAmount == 0.0f && !iconState.isAnimating(icon))
+ || row.isAboveShelf()
+ || row.showingPulsing()
+ || (!row.isInShelf() && isLastChild)
+ || row.getTranslationZ() > mAmbientState.getBaseZHeight();
+ iconState.iconAppearAmount = iconState.hidden? 0f : transitionAmount;
+
// Fade in icons at shelf start
// This is important for conversation icons, which are badged and need x reset
iconState.xTranslation = mShelfIcons.getActualPaddingStart();
- boolean stayingInShelf = row.isInShelf() && !row.isTransformingIntoShelf();
+ final boolean stayingInShelf = row.isInShelf() && !row.isTransformingIntoShelf();
if (stayingInShelf) {
iconState.iconAppearAmount = 1.0f;
iconState.alpha = 1.0f;
- iconState.scaleX = 1.0f;
- iconState.scaleY = 1.0f;
iconState.hidden = false;
}
- if (row.isAboveShelf()
- || row.showingPulsing()
- || (!row.isInShelf() && (isLastChild && row.areGutsExposed()
- || row.getTranslationZ() > mAmbientState.getBaseZHeight()))) {
- iconState.hidden = true;
- }
int backgroundColor = getBackgroundColorWithoutTint();
int shelfColor = icon.getContrastedStaticDrawableColor(backgroundColor);
if (row.isShowingIcon() && shelfColor != StatusBarIconView.NO_COLOR) {
@@ -819,42 +698,6 @@
return ret;
}
- private void setOpenedAmount(float openedAmount) {
- mNoAnimationsInThisFrame = openedAmount == 1.0f && mOpenedAmount == 0.0f;
- mOpenedAmount = openedAmount;
- if (!mAmbientState.isPanelFullWidth() || mAmbientState.isDozing()) {
- // We don't do a transformation at all, lets just assume we are fully opened
- openedAmount = 1.0f;
- }
- int start = mRelativeOffset;
- if (isLayoutRtl()) {
- start = getWidth() - start - mCollapsedIcons.getWidth();
- }
- int width = (int) NotificationUtils.interpolate(
- start + mCollapsedIcons.getFinalTranslationX(),
- mShelfIcons.getWidth(),
- FAST_OUT_SLOW_IN_REVERSE.getInterpolation(openedAmount));
- mShelfIcons.setActualLayoutWidth(width);
- boolean hasOverflow = mCollapsedIcons.hasOverflow();
- int collapsedPadding = mCollapsedIcons.getPaddingEnd();
- if (!hasOverflow) {
- // we have to ensure that adding the low priority notification won't lead to an
- // overflow
- collapsedPadding -= mCollapsedIcons.getNoOverflowExtraPadding();
- } else {
- // Partial overflow padding will fill enough space to add extra dots
- collapsedPadding -= mCollapsedIcons.getPartialOverflowExtraPadding();
- }
- float padding = NotificationUtils.interpolate(collapsedPadding,
- mShelfIcons.getPaddingEnd(),
- openedAmount);
- mShelfIcons.setActualPaddingEnd(padding);
- float paddingStart = NotificationUtils.interpolate(start,
- mShelfIcons.getPaddingStart(), openedAmount);
- mShelfIcons.setActualPaddingStart(paddingStart);
- mShelfIcons.setOpenedAmount(openedAmount);
- }
-
public void setMaxLayoutHeight(int maxLayoutHeight) {
mMaxLayoutHeight = maxLayoutHeight;
}
@@ -947,7 +790,6 @@
}
private class ShelfState extends ExpandableViewState {
- private float openedAmount;
private boolean hasItemsInStableShelf;
@Override
@@ -957,7 +799,6 @@
}
super.applyToView(view);
- setOpenedAmount(openedAmount);
updateAppearance();
setHasItemsInStableShelf(hasItemsInStableShelf);
mShelfIcons.setAnimationsEnabled(mAnimationsEnabled);
@@ -970,7 +811,6 @@
}
super.animateTo(child, properties);
- setOpenedAmount(openedAmount);
updateAppearance();
setHasItemsInStableShelf(hasItemsInStableShelf);
mShelfIcons.setAnimationsEnabled(mAnimationsEnabled);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index d08f973..85a1aed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -146,17 +146,19 @@
private final ExpandableNotificationRow mSourceNotification;
private final ExpandAnimationParameters mParams;
private final Rect mWindowCrop = new Rect();
- private final float mNotificationCornerRadius;
- private float mCornerRadius;
private boolean mIsFullScreenLaunch = true;
private final SyncRtSurfaceTransactionApplier mSyncRtTransactionApplier;
- public AnimationRunner(ExpandableNotificationRow sourceNofitication) {
- mSourceNotification = sourceNofitication;
+ private final float mNotificationStartTopCornerRadius;
+ private final float mNotificationStartBottomCornerRadius;
+
+ AnimationRunner(ExpandableNotificationRow sourceNotification) {
+ mSourceNotification = sourceNotification;
mParams = new ExpandAnimationParameters();
mSyncRtTransactionApplier = new SyncRtSurfaceTransactionApplier(mSourceNotification);
- mNotificationCornerRadius = Math.max(mSourceNotification.getCurrentTopRoundness(),
- mSourceNotification.getCurrentBottomRoundness());
+ mNotificationStartTopCornerRadius = mSourceNotification.getCurrentBackgroundRadiusTop();
+ mNotificationStartBottomCornerRadius =
+ mSourceNotification.getCurrentBackgroundRadiusBottom();
}
@Override
@@ -224,7 +226,10 @@
+ notificationHeight,
primary.position.y + primary.sourceContainerBounds.bottom,
progress);
- mCornerRadius = MathUtils.lerp(mNotificationCornerRadius,
+ mParams.topCornerRadius = MathUtils.lerp(mNotificationStartTopCornerRadius,
+ mWindowCornerRadius, progress);
+ mParams.bottomCornerRadius = MathUtils.lerp(
+ mNotificationStartBottomCornerRadius,
mWindowCornerRadius, progress);
applyParamsToWindow(primary);
applyParamsToNotification(mParams);
@@ -309,12 +314,13 @@
Matrix m = new Matrix();
m.postTranslate(0, (float) (mParams.top - app.position.y));
mWindowCrop.set(mParams.left, 0, mParams.right, mParams.getHeight());
+ float cornerRadius = Math.min(mParams.topCornerRadius, mParams.bottomCornerRadius);
SurfaceParams params = new SurfaceParams.Builder(app.leash)
.withAlpha(1f)
.withMatrix(m)
.withWindowCrop(mWindowCrop)
.withLayer(app.prefixOrderIndex)
- .withCornerRadius(mCornerRadius)
+ .withCornerRadius(cornerRadius)
.withVisibility(true)
.build();
mSyncRtTransactionApplier.scheduleApply(params);
@@ -339,6 +345,8 @@
int bottom;
int startClipTopAmount;
int parentStartClipTopAmount;
+ float topCornerRadius;
+ float bottomCornerRadius;
public ExpandAnimationParameters() {
}
@@ -389,6 +397,14 @@
public float getStartTranslationZ() {
return startTranslationZ;
}
+
+ public float getTopCornerRadius() {
+ return topCornerRadius;
+ }
+
+ public float getBottomCornerRadius() {
+ return bottomCornerRadius;
+ }
}
public interface Callback {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
index 004cf99..b0d41f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
@@ -218,13 +218,18 @@
})
}
+ private fun ConversationState.shouldIncrementUnread(newBuilder: Notification.Builder) =
+ if (notification.flags and Notification.FLAG_ONLY_ALERT_ONCE != 0) {
+ false
+ } else {
+ val oldBuilder = Notification.Builder.recoverBuilder(context, notification)
+ Notification.areStyledNotificationsVisiblyDifferent(oldBuilder, newBuilder)
+ }
+
fun getUnreadCount(entry: NotificationEntry, recoveredBuilder: Notification.Builder): Int =
states.compute(entry.key) { _, state ->
val newCount = state?.run {
- val old = Notification.Builder.recoverBuilder(context, notification)
- val increment = Notification
- .areStyledNotificationsVisiblyDifferent(old, recoveredBuilder)
- if (increment) unreadCount + 1 else unreadCount
+ if (shouldIncrementUnread(recoveredBuilder)) unreadCount + 1 else unreadCount
} ?: 1
ConversationState(newCount, entry.sbn.notification)
}!!.unreadCount
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java
index 18806ef..5a3f48c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java
@@ -99,17 +99,11 @@
private boolean hasHighPriorityCharacteristics(NotificationEntry entry) {
return !hasUserSetImportance(entry)
- && (isImportantOngoing(entry)
- || entry.getSbn().getNotification().hasMediaSession()
+ && (entry.getSbn().getNotification().hasMediaSession()
|| isPeopleNotification(entry)
|| isMessagingStyle(entry));
}
- private boolean isImportantOngoing(NotificationEntry entry) {
- return entry.getSbn().getNotification().isForegroundService()
- && entry.getRanking().getImportance() >= NotificationManager.IMPORTANCE_LOW;
- }
-
private boolean isMessagingStyle(NotificationEntry entry) {
return Notification.MessagingStyle.class.equals(
entry.getSbn().getNotification().getNotificationStyle());
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 31d052d..18e5ead 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
@@ -883,8 +883,8 @@
}
private void applyBackgroundRoundness(float topRadius, float bottomRadius) {
- mBackgroundDimmed.setRoundness(topRadius, bottomRadius);
- mBackgroundNormal.setRoundness(topRadius, bottomRadius);
+ mBackgroundDimmed.setRadius(topRadius, bottomRadius);
+ mBackgroundNormal.setRadius(topRadius, bottomRadius);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 0f23b77..046fbd5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -166,7 +166,6 @@
private int mMaxSmallHeightLarge;
private int mMaxSmallHeightMedia;
private int mMaxExpandedHeight;
- private int mMaxCallHeight;
private int mIncreasedPaddingBetweenElements;
private int mNotificationLaunchHeight;
private boolean mMustStayOnScreen;
@@ -347,6 +346,9 @@
private SystemNotificationAsyncTask mSystemNotificationAsyncTask =
new SystemNotificationAsyncTask();
+ private float mTopRoundnessDuringExpandAnimation;
+ private float mBottomRoundnessDuringExpandAnimation;
+
/**
* Returns whether the given {@code statusBarNotification} is a system notification.
* <b>Note</b>, this should be run in the background thread if possible as it makes multiple IPC
@@ -687,7 +689,7 @@
// them a headerless design, then remove this hack.
smallHeight = mMaxSmallHeightLarge;
} else if (isCallLayout) {
- smallHeight = mMaxCallHeight;
+ smallHeight = mMaxExpandedHeight;
} else if (mUseIncreasedCollapsedHeight && layout == mPrivateLayout) {
smallHeight = mMaxSmallHeightLarge;
} else {
@@ -1621,8 +1623,6 @@
R.dimen.notification_min_height_media);
mMaxExpandedHeight = NotificationUtils.getFontScaledHeight(mContext,
R.dimen.notification_max_height);
- mMaxCallHeight = NotificationUtils.getFontScaledHeight(mContext,
- R.dimen.call_notification_full_height);
mMaxHeadsUpHeightBeforeN = NotificationUtils.getFontScaledHeight(mContext,
R.dimen.notification_max_heads_up_height_legacy);
mMaxHeadsUpHeightBeforeP = NotificationUtils.getFontScaledHeight(mContext,
@@ -2012,6 +2012,24 @@
return false;
}
+ @Override
+ public float getCurrentTopRoundness() {
+ if (mExpandAnimationRunning) {
+ return mTopRoundnessDuringExpandAnimation;
+ }
+
+ return super.getCurrentTopRoundness();
+ }
+
+ @Override
+ public float getCurrentBottomRoundness() {
+ if (mExpandAnimationRunning) {
+ return mBottomRoundnessDuringExpandAnimation;
+ }
+
+ return super.getCurrentBottomRoundness();
+ }
+
public void applyExpandAnimationParams(ExpandAnimationParameters params) {
if (params == null) {
return;
@@ -2027,17 +2045,22 @@
int top = params.getTop();
float interpolation = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(params.getProgress());
int startClipTopAmount = params.getStartClipTopAmount();
+ int clipTopAmount = (int) MathUtils.lerp(startClipTopAmount, 0, interpolation);
if (mNotificationParent != null) {
float parentY = mNotificationParent.getTranslationY();
top -= parentY;
mNotificationParent.setTranslationZ(translationZ);
+
+ // When the expanding notification is below its parent, the parent must be clipped
+ // exactly how it was clipped before the animation. When the expanding notification is
+ // on or above its parent (top <= 0), then the parent must be clipped exactly 'top'
+ // pixels to show the expanding notification, while still taking the decreasing
+ // notification clipTopAmount into consideration, so 'top + clipTopAmount'.
int parentStartClipTopAmount = params.getParentStartClipTopAmount();
- if (startClipTopAmount != 0) {
- int clipTopAmount = (int) MathUtils.lerp(parentStartClipTopAmount,
- parentStartClipTopAmount - startClipTopAmount,
- interpolation);
- mNotificationParent.setClipTopAmount(clipTopAmount);
- }
+ int parentClipTopAmount = Math.min(parentStartClipTopAmount,
+ top + clipTopAmount);
+ mNotificationParent.setClipTopAmount(parentClipTopAmount);
+
mNotificationParent.setExtraWidthForClipping(extraWidthForClipping);
float clipBottom = Math.max(params.getBottom(),
parentY + mNotificationParent.getActualHeight()
@@ -2046,12 +2069,15 @@
int minimumHeightForClipping = (int) (clipBottom - clipTop);
mNotificationParent.setMinimumHeightForClipping(minimumHeightForClipping);
} else if (startClipTopAmount != 0) {
- int clipTopAmount = (int) MathUtils.lerp(startClipTopAmount, 0, interpolation);
setClipTopAmount(clipTopAmount);
}
setTranslationY(top);
setActualHeight(params.getHeight());
+ mTopRoundnessDuringExpandAnimation = params.getTopCornerRadius() / mOutlineRadius;
+ mBottomRoundnessDuringExpandAnimation = params.getBottomCornerRadius() / mOutlineRadius;
+ invalidateOutline();
+
mBackgroundNormal.setExpandAnimationParams(params);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
index 85f556f..3728388 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
@@ -27,7 +27,6 @@
import android.view.View;
import android.view.ViewOutlineProvider;
-import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
@@ -83,8 +82,8 @@
private final ViewOutlineProvider mProvider = new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
- if (!mCustomOutline && mCurrentTopRoundness == 0.0f
- && mCurrentBottomRoundness == 0.0f && !mAlwaysRoundBothCorners
+ if (!mCustomOutline && getCurrentTopRoundness() == 0.0f
+ && getCurrentBottomRoundness() == 0.0f && !mAlwaysRoundBothCorners
&& !mTopAmountRounded) {
int translation = mShouldTranslateContents ? (int) getTranslation() : 0;
int left = Math.max(translation, 0);
@@ -135,10 +134,12 @@
? mOutlineRadius : getCurrentBackgroundRadiusBottom();
if (topRoundness + bottomRoundness > height) {
float overShoot = topRoundness + bottomRoundness - height;
- topRoundness -= overShoot * mCurrentTopRoundness
- / (mCurrentTopRoundness + mCurrentBottomRoundness);
- bottomRoundness -= overShoot * mCurrentBottomRoundness
- / (mCurrentTopRoundness + mCurrentBottomRoundness);
+ float currentTopRoundness = getCurrentTopRoundness();
+ float currentBottomRoundness = getCurrentBottomRoundness();
+ topRoundness -= overShoot * currentTopRoundness
+ / (currentTopRoundness + currentBottomRoundness);
+ bottomRoundness -= overShoot * currentBottomRoundness
+ / (currentTopRoundness + currentBottomRoundness);
}
getRoundedRectPath(left, top, right, bottom, topRoundness, bottomRoundness, mTmpPath);
return mTmpPath;
@@ -267,7 +268,7 @@
if (mTopAmountRounded) {
return mOutlineRadius;
}
- return mCurrentTopRoundness * mOutlineRadius;
+ return getCurrentTopRoundness() * mOutlineRadius;
}
public float getCurrentTopRoundness() {
@@ -278,8 +279,8 @@
return mCurrentBottomRoundness;
}
- protected float getCurrentBackgroundRadiusBottom() {
- return mCurrentBottomRoundness * mOutlineRadius;
+ public float getCurrentBackgroundRadiusBottom() {
+ return getCurrentBottomRoundness() * mOutlineRadius;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index ba03d01..73e0804 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -69,7 +69,6 @@
private float mContentTranslation;
protected boolean mLastInSection;
protected boolean mFirstInSection;
- boolean mIsBeingSwiped;
public ExpandableView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -174,14 +173,6 @@
return false;
}
- public void setIsBeingSwiped(boolean swiped) {
- mIsBeingSwiped = swiped;
- }
-
- public boolean isBeingSwiped() {
- return mIsBeingSwiped;
- }
-
public boolean isHeadsUpAnimatingAway() {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index 62d596b..9588563 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -224,10 +224,9 @@
}
/**
- * Sets the current top and bottom roundness amounts for this background, between 0.0 (not
- * rounded) and 1.0 (maximally rounded).
+ * Sets the current top and bottom radius for this background.
*/
- public void setRoundness(float topRoundness, float bottomRoundness) {
+ public void setRadius(float topRoundness, float bottomRoundness) {
if (topRoundness == mCornerRadii[0] && bottomRoundness == mCornerRadii[4]) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt
index 4541ebf..12e94cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt
@@ -34,7 +34,7 @@
) : NotificationTemplateViewWrapper(ctx, view, row) {
private val minHeightWithActions: Int =
- NotificationUtils.getFontScaledHeight(ctx, R.dimen.call_notification_full_height)
+ NotificationUtils.getFontScaledHeight(ctx, R.dimen.notification_max_height)
private val callLayout: CallLayout = view as CallLayout
private lateinit var conversationIconView: CachingIconView
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index d8ee102..2b194ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -34,7 +34,6 @@
import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.widget.CachingIconView;
import com.android.internal.widget.NotificationExpandButton;
import com.android.systemui.R;
import com.android.systemui.statusbar.CrossFadeHelper;
@@ -638,10 +637,6 @@
childState.location = parentState.location;
childState.inShelf = parentState.inShelf;
yPosition += intrinsicHeight;
- if (child.isExpandAnimationRunning()) {
- launchTransitionCompensation = -ambientState.getExpandAnimationTopChange();
- }
-
}
if (mOverflowNumber != null) {
ExpandableNotificationRow overflowView = mAttachedChildren.get(Math.min(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
index 45f5b31..b1ac12e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
@@ -18,6 +18,7 @@
import android.content.res.Resources;
import android.util.MathUtils;
+import android.view.View;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
@@ -47,6 +48,10 @@
private ExpandableNotificationRow mTrackedHeadsUp;
private float mAppearFraction;
+ private ExpandableView mSwipedView = null;
+ private ExpandableView mViewBeforeSwipedView = null;
+ private ExpandableView mViewAfterSwipedView = null;
+
@Inject
NotificationRoundnessManager(
KeyguardBypassController keyguardBypassController,
@@ -68,6 +73,11 @@
boolean updateViewWithoutCallback(ExpandableView view,
boolean animate) {
+ if (view == null
+ || view == mViewBeforeSwipedView
+ || view == mViewAfterSwipedView) {
+ return false;
+ }
float topRoundness = getRoundness(view, true /* top */);
float bottomRoundness = getRoundness(view, false /* top */);
boolean topChanged = view.setTopRoundness(topRoundness, animate);
@@ -105,9 +115,60 @@
return false;
}
+ void setViewsAffectedBySwipe(
+ ExpandableView viewBefore,
+ ExpandableView viewSwiped,
+ ExpandableView viewAfter,
+ boolean cornerAnimationsEnabled) {
+ if (!cornerAnimationsEnabled) {
+ return;
+ }
+ final boolean animate = true;
+
+ ExpandableView oldViewBefore = mViewBeforeSwipedView;
+ mViewBeforeSwipedView = viewBefore;
+ if (oldViewBefore != null) {
+ final float bottomRoundness = getRoundness(oldViewBefore, false /* top */);
+ oldViewBefore.setBottomRoundness(bottomRoundness, animate);
+ }
+ if (viewBefore != null) {
+ viewBefore.setBottomRoundness(1f, animate);
+ }
+
+ ExpandableView oldSwipedview = mSwipedView;
+ mSwipedView = viewSwiped;
+ if (oldSwipedview != null) {
+ final float bottomRoundness = getRoundness(oldSwipedview, false /* top */);
+ final float topRoundness = getRoundness(oldSwipedview, true /* top */);
+ oldSwipedview.setTopRoundness(topRoundness, animate);
+ oldSwipedview.setBottomRoundness(bottomRoundness, animate);
+ }
+ if (viewSwiped != null) {
+ viewSwiped.setTopRoundness(1f, animate);
+ viewSwiped.setBottomRoundness(1f, animate);
+ }
+
+ ExpandableView oldViewAfter = mViewAfterSwipedView;
+ mViewAfterSwipedView = viewAfter;
+ if (oldViewAfter != null) {
+ final float topRoundness = getRoundness(oldViewAfter, true /* top */);
+ oldViewAfter.setTopRoundness(topRoundness, animate);
+ }
+ if (viewAfter != null) {
+ viewAfter.setTopRoundness(1f, animate);
+ }
+ }
+
private float getRoundness(ExpandableView view, boolean top) {
+ if (view == null) {
+ return 0f;
+ }
+ if (view == mViewBeforeSwipedView
+ || view == mSwipedView
+ || view == mViewAfterSwipedView) {
+ return 1f;
+ }
if ((view.isPinned()
- || view.isBeingSwiped()
|| (view.isHeadsUpAnimatingAway()) && !mExpanded)) {
return 1.0f;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
index 6c8cdf6..b06f7d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
@@ -318,9 +318,6 @@
(child == null || row != null && nextBucket != row.entry.bucket)
if (isSectionBoundary && showHeaders) {
when (nextBucket) {
- BUCKET_HEADS_UP -> incomingState?.targetPosition = i + 1
- BUCKET_PEOPLE -> peopleState?.targetPosition = i + 1
- BUCKET_ALERTING -> alertingState?.targetPosition = i + 1
BUCKET_SILENT -> gentleState?.targetPosition = i + 1
}
}
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 417ff5e..970efd5 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
@@ -1025,8 +1025,7 @@
boolean clip = clipStart > start && clipStart < end
|| clipEnd >= start && clipEnd <= end;
clip &= !(first && mScrollAdapter.isScrolledToTop());
- child.setDistanceToTopRoundness(clip ? Math.max(start - clipStart, 0)
- : ExpandableView.NO_ROUNDNESS);
+ child.setDistanceToTopRoundness(ExpandableView.NO_ROUNDNESS);
first = false;
}
}
@@ -2292,9 +2291,7 @@
ExpandableView child = (ExpandableView) getChildAt(i);
if (child.getVisibility() != View.GONE
&& !(child instanceof StackScrollerDecorView)
- && child != mShelf
- && (mSwipeHelper.getSwipedView() != child
- || !child.getResources().getBoolean(R.bool.flag_notif_updates))) {
+ && child != mShelf) {
children.add(child);
}
}
@@ -4993,28 +4990,48 @@
mSwipedOutViews.add(v);
}
- void onSwipeBegin(View v) {
- if (v instanceof ExpandableView) {
- ExpandableView ev = (ExpandableView) v;
- ev.setIsBeingSwiped(true);
- mController.getNoticationRoundessManager()
- .updateViewWithoutCallback(ev, true /* animate */);
+ void onSwipeBegin(View viewSwiped) {
+ if (!(viewSwiped instanceof ExpandableNotificationRow)) {
+ return;
}
- requestDisallowInterceptTouchEvent(true);
+ final int indexOfSwipedView = indexOfChild(viewSwiped);
+ if (indexOfSwipedView < 0) {
+ return;
+ }
+ mSectionsManager.updateFirstAndLastViewsForAllSections(
+ mSections, getChildrenWithBackground());
+ View viewBefore = null;
+ if (indexOfSwipedView > 0) {
+ viewBefore = getChildAt(indexOfSwipedView - 1);
+ if (mSectionsManager.beginsSection(viewSwiped, viewBefore)) {
+ viewBefore = null;
+ }
+ }
+ View viewAfter = null;
+ if (indexOfSwipedView < getChildCount()) {
+ viewAfter = getChildAt(indexOfSwipedView + 1);
+ if (mSectionsManager.beginsSection(viewAfter, viewSwiped)) {
+ viewAfter = null;
+ }
+ }
+ mController.getNoticationRoundessManager()
+ .setViewsAffectedBySwipe((ExpandableView) viewBefore,
+ (ExpandableView) viewSwiped,
+ (ExpandableView) viewAfter,
+ getResources().getBoolean(R.bool.flag_notif_updates));
+
updateFirstAndLastBackgroundViews();
+ requestDisallowInterceptTouchEvent(true);
updateContinuousShadowDrawing();
updateContinuousBackgroundDrawing();
requestChildrenUpdate();
}
- void onSwipeEnd(View v) {
- if (v instanceof ExpandableView) {
- ExpandableView ev = (ExpandableView) v;
- ev.setIsBeingSwiped(false);
- mController.getNoticationRoundessManager()
- .updateViewWithoutCallback(ev, true /* animate */);
- }
+ void onSwipeEnd() {
updateFirstAndLastBackgroundViews();
+ mController.getNoticationRoundessManager()
+ .setViewsAffectedBySwipe(null, null, null,
+ getResources().getBoolean(R.bool.flag_notif_updates));
}
void setTopHeadsUpEntry(NotificationEntry topEntry) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 3997028..7baad1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -399,7 +399,7 @@
if (mView.getDismissAllInProgress()) {
return;
}
- mView.onSwipeEnd(view);
+ mView.onSwipeEnd();
if (view instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) view;
if (row.isHeadsUp()) {
@@ -459,7 +459,7 @@
@Override
public void onChildSnappedBack(View animView, float targetLeft) {
- mView.onSwipeEnd(animView);
+ mView.onSwipeEnd();
if (animView instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) animView;
if (row.isPinned() && !canChildBeDismissed(row)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 5d2203b..d7a98bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -28,14 +28,12 @@
import com.android.systemui.R;
import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.NotificationShelf;
-import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.row.FooterView;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
/**
@@ -156,7 +154,7 @@
private void updateClipping(StackScrollAlgorithmState algorithmState,
AmbientState ambientState) {
float drawStart = !ambientState.isOnKeyguard() ? ambientState.getTopPadding()
- + ambientState.getStackTranslation() + ambientState.getExpandAnimationTopChange()
+ + ambientState.getStackTranslation()
: 0;
float clipStart = 0;
int childCount = algorithmState.visibleChildren.size();
@@ -329,9 +327,6 @@
childViewState.location = ExpandableViewState.LOCATION_MAIN_AREA;
float inset = ambientState.getTopPadding() + ambientState.getStackTranslation()
+ ambientState.getSectionPadding();
- if (i <= algorithmState.getIndexOfExpandingNotification()) {
- inset += ambientState.getExpandAnimationTopChange();
- }
if (child.mustStayOnScreen() && childViewState.yTranslation >= 0) {
// Even if we're not scrolled away we're in view and we're also not in the
// shelf. We can relax the constraints and let us scroll off the top!
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index 85d8df8..c23f1ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -148,6 +148,11 @@
return getInt("doze.pickup.vibration.threshold", R.integer.doze_pickup_vibration_threshold);
}
+ public int getQuickPickupAodDuration() {
+ return getInt("doze.gesture.quickpickup.duration",
+ R.integer.doze_quick_pickup_aod_duration);
+ }
+
/**
* For how long a wallpaper can be visible in AoD before it fades aways.
* @return duration in millis.
@@ -175,6 +180,10 @@
return mDozeAlwaysOn && !mBatteryController.isAodPowerSave();
}
+ public boolean isQuickPickupEnabled() {
+ return mAmbientDisplayConfiguration.quickPickupSensorEnabled(UserHandle.USER_CURRENT);
+ }
+
/**
* Some screens need to be completely black before changing the display power mode,
* unexpected behavior might happen if this parameter isn't respected.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 9561851..6b144c6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -28,6 +28,7 @@
import android.graphics.drawable.Icon;
import android.util.AttributeSet;
import android.util.Property;
+import android.view.ContextThemeWrapper;
import android.view.View;
import android.view.animation.Interpolator;
@@ -35,6 +36,7 @@
import com.android.internal.statusbar.StatusBarIcon;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.settingslib.Utils;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.statusbar.AlphaOptimizedFrameLayout;
@@ -155,7 +157,6 @@
private int mCannedAnimationStartIndex = -1;
private int mSpeedBumpIndex = -1;
private int mIconSize;
- private float mOpenedAmount = 0.0f;
private boolean mDisallowNextAnimation;
private boolean mAnimationsEnabled = true;
private ArrayMap<String, ArrayList<StatusBarIcon>> mReplacingIcons;
@@ -169,6 +170,7 @@
private Rect mIsolatedIconLocation;
private int[] mAbsolutePosition = new int[2];
private View mIsolatedIconForAnimation;
+ private int mThemedTextColorPrimary;
public NotificationIconContainer(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -180,6 +182,10 @@
mDotPadding = getResources().getDimensionPixelSize(R.dimen.overflow_icon_dot_padding);
mStaticDotRadius = getResources().getDimensionPixelSize(R.dimen.overflow_dot_radius);
mStaticDotDiameter = 2 * mStaticDotRadius;
+ final Context themedContext = new ContextThemeWrapper(getContext(),
+ com.android.internal.R.style.Theme_DeviceDefault_DayNight);
+ mThemedTextColorPrimary = Utils.getColorAttr(themedContext,
+ com.android.internal.R.attr.textColorPrimary).getDefaultColor();
}
@Override
@@ -349,6 +355,10 @@
}
}
+ public boolean hasMaxNumDot() {
+ return mNumDots >= MAX_DOTS;
+ }
+
private boolean areAnimationsEnabled(StatusBarIconView icon) {
return mAnimationsEnabled || icon == mIsolatedIcon;
}
@@ -391,7 +401,6 @@
float overflowStart = getMaxOverflowStart();
mVisualOverflowStart = 0;
mFirstVisibleIconState = null;
- boolean hasAmbient = mSpeedBumpIndex != -1 && mSpeedBumpIndex < getChildCount();
for (int i = 0; i < childCount; i++) {
View view = getChildAt(i);
IconState iconState = mIconStates.get(view);
@@ -410,10 +419,9 @@
float drawingScale = mOnLockScreen && view instanceof StatusBarIconView
? ((StatusBarIconView) view).getIconScaleIncreased()
: 1f;
- if (mOpenedAmount != 0.0f) {
- noOverflowAfter = noOverflowAfter && !hasAmbient && !forceOverflow;
- }
- iconState.visibleState = StatusBarIconView.STATE_ICON;
+ iconState.visibleState = iconState.hidden
+ ? StatusBarIconView.STATE_HIDDEN
+ : StatusBarIconView.STATE_ICON;
boolean isOverflowing =
(translationX > (noOverflowAfter ? layoutEnd - mIconSize
@@ -598,10 +606,6 @@
mSpeedBumpIndex = speedBumpIndex;
}
- public void setOpenedAmount(float expandAmount) {
- mOpenedAmount = expandAmount;
- }
-
public boolean hasOverflow() {
return mNumDots > 0;
}
@@ -706,13 +710,8 @@
public boolean justAdded = true;
private boolean justReplaced;
public boolean needsCannedAnimation;
- public boolean useFullTransitionAmount;
- public boolean useLinearTransitionAmount;
- public boolean translateContent;
public int iconColor = StatusBarIconView.NO_COLOR;
public boolean noAnimations;
- public boolean isLastExpandIcon;
- public int customTransformHeight = NO_VALUE;
private final View mView;
private final Consumer<Property> mCannedAnimationEndListener;
@@ -734,8 +733,15 @@
StatusBarIconView icon = (StatusBarIconView) view;
boolean animate = false;
AnimationProperties animationProperties = null;
- boolean animationsAllowed = areAnimationsEnabled(icon) && !mDisallowNextAnimation
- && !noAnimations;
+ final boolean isLowPriorityIconChange =
+ (visibleState == StatusBarIconView.STATE_HIDDEN
+ && icon.getVisibleState() == StatusBarIconView.STATE_DOT)
+ || (visibleState == StatusBarIconView.STATE_DOT
+ && icon.getVisibleState() == StatusBarIconView.STATE_HIDDEN);
+ final boolean animationsAllowed = areAnimationsEnabled(icon)
+ && !mDisallowNextAnimation
+ && !noAnimations
+ && !isLowPriorityIconChange;
if (animationsAllowed) {
if (justAdded || justReplaced) {
super.applyToView(icon);
@@ -807,7 +813,8 @@
}
}
icon.setVisibleState(visibleState, animationsAllowed);
- icon.setIconColor(iconColor, needsCannedAnimation && animationsAllowed);
+ icon.setIconColor(mThemedTextColorPrimary,
+ needsCannedAnimation && animationsAllowed);
if (animate) {
animateTo(icon, animationProperties);
} else {
@@ -822,10 +829,6 @@
needsCannedAnimation = false;
}
- public boolean hasCustomTransformHeight() {
- return isLastExpandIcon && customTransformHeight != NO_VALUE;
- }
-
@Override
public void initFrom(View view) {
super.initFrom(view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 19b9895..626162d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -439,7 +439,6 @@
private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
private boolean mUserSetupComplete;
private int mQsNotificationTopPadding;
- private float mExpandOffset;
private boolean mHideIconsDuringNotificationLaunch = true;
private int mStackScrollerMeasuringPass;
private ArrayList<Consumer<ExpandableNotificationRow>>
@@ -2444,8 +2443,7 @@
}
startHeight = -mQs.getQsMinExpansionHeight();
}
- float translation = MathUtils.lerp(startHeight, 0, Math.min(1.0f, appearAmount))
- + mExpandOffset;
+ float translation = MathUtils.lerp(startHeight, 0, Math.min(1.0f, appearAmount));
return Math.min(0, translation);
}
@@ -3185,16 +3183,16 @@
}
public void applyExpandAnimationParams(ExpandAnimationParameters params) {
- mExpandOffset = params != null ? params.getTopChange() : 0;
- updateQsExpansion();
- if (params != null) {
- boolean hideIcons = params.getProgress(
- ActivityLaunchAnimator.ANIMATION_DELAY_ICON_FADE_IN, 100) == 0.0f;
- if (hideIcons != mHideIconsDuringNotificationLaunch) {
- mHideIconsDuringNotificationLaunch = hideIcons;
- if (!hideIcons) {
- mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
- }
+ if (params == null) {
+ return;
+ }
+
+ boolean hideIcons = params.getProgress(
+ ActivityLaunchAnimator.ANIMATION_DELAY_ICON_FADE_IN, 100) == 0.0f;
+ if (hideIcons != mHideIconsDuringNotificationLaunch) {
+ mHideIconsDuringNotificationLaunch = hideIcons;
+ if (!hideIcons) {
+ mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index 0c9ed66..1cb0be0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -89,30 +89,22 @@
@Override
protected void dispatchDraw(Canvas canvas) {
- // Invert the order of the scroll view and user switcher such that the notifications receive
- // touches first but the panel gets drawn above.
mDrawingOrderedChildren.clear();
mLayoutDrawingOrder.clear();
if (mKeyguardStatusBar.getVisibility() == View.VISIBLE) {
mDrawingOrderedChildren.add(mKeyguardStatusBar);
mLayoutDrawingOrder.add(mKeyguardStatusBar);
}
- if (mStackScroller.getVisibility() == View.VISIBLE) {
- mDrawingOrderedChildren.add(mStackScroller);
- mLayoutDrawingOrder.add(mStackScroller);
- }
if (mQsFrame.getVisibility() == View.VISIBLE) {
mDrawingOrderedChildren.add(mQsFrame);
mLayoutDrawingOrder.add(mQsFrame);
}
-
- if (mHasViewsAboveShelf) {
- // StackScroller needs to be on top
- mDrawingOrderedChildren.remove(mStackScroller);
+ if (mStackScroller.getVisibility() == View.VISIBLE) {
mDrawingOrderedChildren.add(mStackScroller);
+ mLayoutDrawingOrder.add(mStackScroller);
}
- // Let's now find the order that the view has when drawing regulary by sorting
+ // Let's now find the order that the view has when drawing regularly by sorting
mLayoutDrawingOrder.sort(mIndexComparator);
super.dispatchDraw(canvas);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 48c97a2..9b8b716 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -140,11 +140,13 @@
@Override
public void prepare(ScrimState previousState) {
final boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn();
+ final boolean quickPickupEnabled = mDozeParameters.isQuickPickupEnabled();
final boolean isDocked = mDockManager.isDocked();
mBlankScreen = mDisplayRequiresBlanking;
mFrontTint = Color.BLACK;
- mFrontAlpha = (alwaysOnEnabled || isDocked) ? mAodFrontScrimAlpha : 1f;
+ mFrontAlpha = (alwaysOnEnabled || isDocked || quickPickupEnabled)
+ ? mAodFrontScrimAlpha : 1f;
mBehindTint = Color.BLACK;
mBehindAlpha = ScrimController.TRANSPARENT;
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 0807f8a..117921d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -95,6 +95,7 @@
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.service.notification.StatusBarNotification;
+import android.text.TextUtils;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.EventLog;
@@ -4071,7 +4072,9 @@
private @Nullable Intent getEmergencyActionIntent() {
Intent emergencyIntent = new Intent(EmergencyGesture.ACTION_LAUNCH_EMERGENCY);
PackageManager pm = mContext.getPackageManager();
- ResolveInfo resolveInfo = pm.resolveActivity(emergencyIntent, /*flags=*/0);
+ List<ResolveInfo> emergencyActivities = pm.queryIntentActivities(emergencyIntent,
+ PackageManager.MATCH_SYSTEM_ONLY);
+ ResolveInfo resolveInfo = getTopEmergencySosInfo(emergencyActivities);
if (resolveInfo == null) {
Log.wtf(TAG, "Couldn't find an app to process the emergency intent.");
return null;
@@ -4082,6 +4085,34 @@
return emergencyIntent;
}
+ /**
+ * Select and return the "best" ResolveInfo for Emergency SOS Activity.
+ */
+ private @Nullable ResolveInfo getTopEmergencySosInfo(List<ResolveInfo> emergencyActivities) {
+ // No matched activity.
+ if (emergencyActivities == null || emergencyActivities.isEmpty()) {
+ return null;
+ }
+
+ // Of multiple matched Activities, give preference to the pre-set package name.
+ String preferredAppPackageName =
+ mContext.getString(R.string.config_preferredEmergencySosPackage);
+
+ // If there is no preferred app, then return first match.
+ if (TextUtils.isEmpty(preferredAppPackageName)) {
+ return emergencyActivities.get(0);
+ }
+
+ for (ResolveInfo emergencyInfo: emergencyActivities) {
+ // If activity is from the preferred app, use it.
+ if (TextUtils.equals(emergencyInfo.activityInfo.packageName, preferredAppPackageName)) {
+ return emergencyInfo;
+ }
+ }
+ // No matching activity: return first match
+ return emergencyActivities.get(0);
+ }
+
boolean isCameraAllowedByAdmin() {
if (mDevicePolicyManager.getCameraDisabled(null,
mLockscreenUserManager.getCurrentUserId())) {
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 34673f2..801ac96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -356,9 +356,6 @@
if (isActivityIntent || canBubble) {
mAssistManagerLazy.get().hideAssist();
}
- if (shouldCollapse()) {
- collapseOnMainThread();
- }
NotificationVisibility.NotificationLocation location =
NotificationLogger.getNotificationLocation(entry);
@@ -408,6 +405,12 @@
mMainThreadHandler.post(
() -> mBubblesManagerOptional.get().expandStackAndSelectBubble(entry));
}
+
+ // expandStackAndSelectBubble won't affect shouldCollapse, so we can collapse directly even
+ // if we are not on the main thread.
+ if (shouldCollapse()) {
+ collapseOnMainThread();
+ }
}
private void startNotificationIntent(
@@ -438,6 +441,9 @@
null, null, options);
mMainThreadHandler.post(() -> {
mActivityLaunchAnimator.setLaunchResult(launchResult, isActivityIntent);
+ if (shouldCollapse()) {
+ collapseOnMainThread();
+ }
});
} catch (RemoteException | PendingIntent.CanceledException e) {
// the stack trace isn't very helpful here.
@@ -465,11 +471,11 @@
mActivityLaunchAnimator.setLaunchResult(launchResult,
true /* isActivityIntent */);
removeHUN(row);
+ if (shouldCollapse()) {
+ mCommandQueue.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+ true /* force */);
+ }
});
- if (shouldCollapse()) {
- 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/toast/SystemUIToast.java b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java
index fab1655..fd19528 100644
--- a/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java
+++ b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java
@@ -19,14 +19,13 @@
import android.animation.Animator;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.Application;
import android.content.Context;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
@@ -35,6 +34,8 @@
import com.android.internal.R;
import com.android.launcher3.icons.IconFactory;
+import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.systemui.plugins.ToastPlugin;
/**
@@ -170,8 +171,13 @@
com.android.systemui.R.layout.text_toast, null);
((TextView) toastView.findViewById(com.android.systemui.R.id.text)).setText(mText);
- ((ImageView) toastView.findViewById(com.android.systemui.R.id.icon))
- .setImageDrawable(getBadgedIcon(mContext, mPackageName, mUserId));
+ Drawable icon = getBadgedIcon(mContext, mPackageName, mUserId);
+ if (icon == null) {
+ toastView.findViewById(com.android.systemui.R.id.icon).setVisibility(View.GONE);
+ } else {
+ ((ImageView) toastView.findViewById(com.android.systemui.R.id.icon))
+ .setImageDrawable(icon);
+ }
} else {
toastView = ToastPresenter.getTextToastView(mContext, mText);
}
@@ -217,18 +223,20 @@
*/
public static Drawable getBadgedIcon(@NonNull Context context, String packageName,
int userId) {
- final PackageManager packageManager = context.getPackageManager();
- try {
- final ApplicationInfo appInfo = packageManager.getApplicationInfoAsUser(
- packageName, PackageManager.GET_META_DATA, userId);
- UserHandle user = UserHandle.getUserHandleForUid(appInfo.uid);
- IconFactory iconFactory = IconFactory.obtain(context);
- Bitmap iconBmp = iconFactory.createBadgedIconBitmap(
- appInfo.loadUnbadgedIcon(packageManager), user, false).icon;
- return new BitmapDrawable(context.getResources(), iconBmp);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e("SystemUIToast", "could not load icon for package=" + packageName + " e=" + e);
+ final ApplicationsState appState =
+ ApplicationsState.getInstance((Application) context.getApplicationContext());
+ final AppEntry appEntry = appState.getEntry(packageName, userId);
+
+ if (!ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER.filterApp(appEntry)) {
return null;
}
+
+ final ApplicationInfo appInfo = appEntry.info;
+ UserHandle user = UserHandle.getUserHandleForUid(appInfo.uid);
+ IconFactory iconFactory = IconFactory.obtain(context);
+ Bitmap iconBmp = iconFactory.createBadgedIconBitmap(
+ appInfo.loadUnbadgedIcon(context.getPackageManager()), user, true).icon;
+ return new BitmapDrawable(context.getResources(), iconBmp);
+
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index eb95d16..b9d8d27 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -793,36 +793,6 @@
}
@Test
- public void testStartUdfpsServiceOnShadeLocked() {
- // GIVEN
- // - bouncer isn't showing
- // - user has authenticated since boot
- setKeyguardBouncerVisibility(false /* isVisible */);
- when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
-
- // WHEN the status bar state changes to SHADE_LOCKED
- mStatusBarStateListener.onStateChanged(StatusBarState.SHADE_LOCKED);
-
- // THEN we shouldn't listen for udfps
- assertThat(mKeyguardUpdateMonitor.shouldListenForUdfps()).isEqualTo(false);
- }
-
- @Test
- public void testStartUdfpsServiceOnFullscreenUserSwitcher() {
- // GIVEN
- // - bouncer isn't showing
- // - user has authenticated since boot
- setKeyguardBouncerVisibility(false /* isVisible */);
- when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
-
- // WHEN the status bar state changes to FULLSCREEN_USER_SWITCHER
- mStatusBarStateListener.onStateChanged(StatusBarState.FULLSCREEN_USER_SWITCHER);
-
- // THEN we shouldn't listen for udfps
- assertThat(mKeyguardUpdateMonitor.shouldListenForUdfps()).isEqualTo(false);
- }
-
- @Test
public void testStartUdfpsServiceNoAuthenticationSinceLastBoot() {
// GIVEN
// - bouncer isn't showing
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
index 49282ee..7f8be91 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
@@ -22,10 +22,8 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.content.Context;
import android.hardware.biometrics.PromptInfo;
@@ -333,16 +331,12 @@
}
@Test
- public void testUdfpsBottomSpacerCalculation() {
+ public void testUdfpsBottomSpacerHeightForPortrait() {
final int displayHeightPx = 3000;
final int navbarHeightPx = 10;
final int dialogBottomMarginPx = 20;
-
- final View buttonBar = mock(View.class);
- when(buttonBar.getMeasuredHeight()).thenReturn(100);
-
- final View textIndicator = mock(View.class);
- when(textIndicator.getMeasuredHeight()).thenReturn(200);
+ final int buttonBarHeightPx = 100;
+ final int textIndicatorHeightPx = 200;
final int sensorLocationX = 540;
final int sensorLocationY = 1600;
@@ -353,9 +347,47 @@
true /* resetLockoutRequiresHardwareAuthToken */, sensorLocationX, sensorLocationY,
sensorRadius);
- assertEquals(970, AuthBiometricUdfpsView.calculateBottomSpacerHeight(
- displayHeightPx, navbarHeightPx, dialogBottomMarginPx, buttonBar, textIndicator,
- props));
+ assertEquals(970,
+ AuthBiometricUdfpsView.calculateBottomSpacerHeightForPortrait(
+ props, displayHeightPx, textIndicatorHeightPx, buttonBarHeightPx,
+ dialogBottomMarginPx, navbarHeightPx
+ ));
+ }
+
+ @Test
+ public void testUdfpsBottomSpacerHeightForLandscape() {
+ final int titleHeightPx = 320;
+ final int subtitleHeightPx = 240;
+ final int descriptionHeightPx = 200;
+ final int topSpacerHeightPx = 550;
+ final int textIndicatorHeightPx = 190;
+ final int buttonBarHeightPx = 160;
+ final int navbarBottomInsetPx = 75;
+
+ assertEquals(885,
+ AuthBiometricUdfpsView.calculateBottomSpacerHeightForLandscape(
+ titleHeightPx, subtitleHeightPx, descriptionHeightPx, topSpacerHeightPx,
+ textIndicatorHeightPx, buttonBarHeightPx, navbarBottomInsetPx));
+ }
+
+ @Test
+ public void testUdfpsHorizontalSpacerWidthForLandscape() {
+ final int displayWidthPx = 3000;
+ final int dialogMarginPx = 20;
+ final int navbarHorizontalInsetPx = 75;
+
+ final int sensorLocationX = 540;
+ final int sensorLocationY = 1600;
+ final int sensorRadius = 100;
+ final FingerprintSensorPropertiesInternal props = new FingerprintSensorPropertiesInternal(
+ 0 /* sensorId */, SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
+ FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
+ true /* resetLockoutRequiresHardwareAuthToken */, sensorLocationX, sensorLocationY,
+ sensorRadius);
+
+ assertEquals(1205,
+ AuthBiometricUdfpsView.calculateHorizontalSpacerWidthForLandscape(
+ props, displayWidthPx, dialogMarginPx, navbarHorizontalInsetPx));
}
private PromptInfo buildPromptInfo(boolean allowDeviceCredential) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java
index 472ed7a..ca0a4aa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java
@@ -21,7 +21,6 @@
import android.util.DisplayMetrics;
import android.view.MotionEvent;
-import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.utils.leaks.FakeBatteryController;
import com.android.systemui.utils.leaks.LeakCheckedTest;
@@ -45,8 +44,7 @@
displayMetrics.widthPixels = 1000;
displayMetrics.heightPixels = 1000;
mFakeBatteryController = new FakeBatteryController(getLeakCheck());
- mDataProvider = new FalsingDataProvider(displayMetrics, mFakeBatteryController,
- new FakeSystemClock());
+ mDataProvider = new FalsingDataProvider(displayMetrics, mFakeBatteryController);
mDataProvider.setInteractionType(UNLOCK);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java
index 17c2700..4e17424 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java
@@ -19,7 +19,6 @@
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.anyList;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
@@ -35,8 +34,6 @@
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
-import java.util.Deque;
-import java.util.LinkedList;
import java.util.List;
@SmallTest
@@ -47,7 +44,7 @@
private static final long DOUBLE_TAP_TIMEOUT_MS = 100;
private List<MotionEvent> mMotionEvents = new ArrayList<>();
- private final Deque<List<MotionEvent>> mHistoricalMotionEvents = new LinkedList<>();
+ private List<MotionEvent> mPriorMotionEvents = new ArrayList<>();
@Mock
private FalsingDataProvider mDataProvider;
@@ -64,7 +61,7 @@
MockitoAnnotations.initMocks(this);
mClassifier = new DoubleTapClassifier(mDataProvider, mSingleTapClassifier, TOUCH_SLOP,
DOUBLE_TAP_TIMEOUT_MS);
- doReturn(mHistoricalMotionEvents).when(mDataProvider).getHistoricalMotionEvents();
+ when(mDataProvider.getPriorMotionEvents()).thenReturn(mPriorMotionEvents);
}
@After
@@ -177,9 +174,8 @@
}
private void archiveMotionEvents() {
- mHistoricalMotionEvents.addFirst(mMotionEvents);
- doReturn(mHistoricalMotionEvents).when(mDataProvider).getHistoricalMotionEvents();
+ mPriorMotionEvents = mMotionEvents;
+ when(mDataProvider.getPriorMotionEvents()).thenReturn(mPriorMotionEvents);
mMotionEvents = new ArrayList<>();
-
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
index be0cc97..ebdda67 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
@@ -26,7 +26,6 @@
import androidx.test.filters.SmallTest;
-import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.utils.leaks.FakeBatteryController;
import org.junit.After;
@@ -52,8 +51,7 @@
displayMetrics.ydpi = 100;
displayMetrics.widthPixels = 1000;
displayMetrics.heightPixels = 1000;
- mDataProvider = new FalsingDataProvider(displayMetrics, mFakeBatteryController,
- new FakeSystemClock());
+ mDataProvider = new FalsingDataProvider(displayMetrics, mFakeBatteryController);
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java
index 6e31259..901196f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java
@@ -89,20 +89,4 @@
assertThat(mBuffer.get(0), is(eventC));
assertThat(mBuffer.get(1), is(eventD));
}
-
- @Test
- public void testFullyExpired() {
- MotionEvent eventA = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
- MotionEvent eventB = MotionEvent.obtain(0, 1, MotionEvent.ACTION_MOVE, 0, 0, 0);
- MotionEvent eventC = MotionEvent.obtain(0, 2, MotionEvent.ACTION_MOVE, 0, 0, 0);
- MotionEvent eventD = MotionEvent.obtain(0, 3, MotionEvent.ACTION_UP, 0, 0, 0);
-
- mBuffer.add(eventA);
- mBuffer.add(eventB);
- mBuffer.add(eventC);
- mBuffer.add(eventD);
-
- assertThat(mBuffer.isFullyExpired(2), is(false));
- assertThat(mBuffer.isFullyExpired(6), is(true));
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
index 9fd9b47..1aeb0d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
@@ -60,6 +60,7 @@
when(config.tapSensorType()).thenReturn(null);
when(config.longPressSensorType()).thenReturn(null);
when(config.udfpsLongPressSensorType()).thenReturn(null);
+ when(config.quickPickupSensorType()).thenReturn(null);
when(config.tapGestureEnabled(anyInt())).thenReturn(true);
when(config.tapSensorAvailable()).thenReturn(true);
@@ -67,6 +68,7 @@
when(config.dozePickupSensorAvailable()).thenReturn(false);
when(config.wakeScreenGestureAvailable()).thenReturn(false);
+ when(config.quickPickupSensorEnabled(anyInt())).thenReturn(false);
doneHolder[0] = true;
return config;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index 27187a8..1817fdf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -104,7 +104,7 @@
mTriggers = new DozeTriggers(mContext, mHost, mAlarmManager, config, parameters,
asyncSensorManager, wakeLock, mDockManager, mProximitySensor,
mProximityCheck, mock(DozeLog.class), mBroadcastDispatcher, new FakeSettings(),
- mAuthController);
+ mAuthController, mExecutor, mExecutor);
mTriggers.setDozeMachine(mMachine);
waitForSensorManager();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
index 1062fae..eedf099 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
@@ -46,16 +46,12 @@
import android.telephony.TelephonyManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
-import android.util.FeatureFlagUtils;
import android.view.IWindowManager;
import android.view.View;
import android.view.WindowManagerPolicyConstants;
import android.widget.FrameLayout;
import androidx.test.filters.SmallTest;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.logging.MetricsLogger;
@@ -251,22 +247,6 @@
}
@Test
- public void testShouldLogScreenshotLongPress() {
- FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SCREENRECORD_LONG_PRESS, true);
- GlobalActionsDialog.ScreenshotAction screenshotAction =
- mGlobalActionsDialog.makeScreenshotActionForTesting();
- screenshotAction.onLongPress();
- verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_SCREENSHOT_LONG_PRESS);
-
- // Dismiss ScreenRecordDialog opened by the long press above.
- final UiObject2 cancelButton = getUiDevice().wait(
- Until.findObject(By.text(CANCEL_BUTTON)), UI_TIMEOUT_MILLIS);
- if (cancelButton != null) {
- cancelButton.click();
- }
- }
-
- @Test
public void testShouldShowScreenshot() {
mContext.getOrCreateTestableResources().addOverride(
com.android.internal.R.integer.config_navBarInteractionMode,
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 2a4b41c..3fed074 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,9 @@
import static android.app.people.ConversationStatus.ACTIVITY_NEW_STORY;
import static android.app.people.ConversationStatus.AVAILABILITY_AVAILABLE;
-import static com.android.systemui.people.PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_TILE;
import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
+import static com.android.systemui.people.PeopleSpaceUtils.getPeopleTileFromPersistentStorage;
+import static com.android.systemui.people.widget.AppWidgetOptionsHelper.OPTIONS_PEOPLE_TILE;
import static com.google.common.truth.Truth.assertThat;
@@ -76,6 +77,7 @@
import com.android.internal.appwidget.IAppWidgetService;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.people.widget.PeopleTileKey;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.SbnBuilder;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -232,7 +234,7 @@
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
Bundle options = new Bundle();
- options.putParcelable(OPTIONS_PEOPLE_SPACE_TILE, PERSON_TILE);
+ options.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT)))
@@ -500,7 +502,7 @@
.build();
PeopleSpaceTile actual = PeopleSpaceUtils
.augmentTileFromVisibleNotifications(mContext, tile,
- Map.of(PeopleSpaceUtils.getKey(mNotificationEntry1), mNotificationEntry1));
+ Map.of(new PeopleTileKey(mNotificationEntry1), mNotificationEntry1));
assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_TEXT_2);
}
@@ -515,7 +517,7 @@
.build();
PeopleSpaceTile actual = PeopleSpaceUtils
.augmentTileFromVisibleNotifications(mContext, tile,
- Map.of(PeopleSpaceUtils.getKey(mNotificationEntry1), mNotificationEntry1));
+ Map.of(new PeopleTileKey(mNotificationEntry1), mNotificationEntry1));
assertThat(actual.getNotificationContent()).isEqualTo(null);
}
@@ -818,6 +820,23 @@
assertEquals(statusContent.getText(), NOTIFICATION_CONTENT);
}
+ @Test
+ public void testGetPeopleTileFromPersistentStorageExistingConversation()
+ throws Exception {
+ when(mPeopleManager.getConversation(PACKAGE_NAME, 0, SHORTCUT_ID_1)).thenReturn(
+ getConversationChannelWithoutTimestamp(SHORTCUT_ID_1));
+ PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID_1, 0, PACKAGE_NAME);
+ PeopleSpaceTile tile = getPeopleTileFromPersistentStorage(mContext, key, mPeopleManager);
+ assertThat(tile.getId()).isEqualTo(key.getShortcutId());
+ }
+
+ @Test
+ public void testGetPeopleTileFromPersistentStorageNoConversation() {
+ PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID_2, 0, PACKAGE_NAME);
+ PeopleSpaceTile tile = getPeopleTileFromPersistentStorage(mContext, key, mPeopleManager);
+ assertThat(tile).isNull();
+ }
+
private ConversationChannelWrapper getConversationChannelWrapper(String shortcutId,
boolean importantConversation, long lastInteractionTimestamp) throws Exception {
ConversationChannelWrapper convo = new ConversationChannelWrapper();
@@ -843,4 +862,13 @@
eq(shortcutId))).thenReturn(lastInteractionTimestamp);
return convo;
}
+
+ private ConversationChannel getConversationChannelWithoutTimestamp(String shortcutId)
+ throws Exception {
+ ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
+ "name").build();
+ ConversationChannel convo = new ConversationChannel(shortcutInfo, 0, null, null,
+ 0L, false);
+ return convo;
+ }
}
\ No newline at end of file
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 f60fa09..aef75be 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
@@ -23,10 +23,11 @@
import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
import static android.app.people.ConversationStatus.ACTIVITY_GAME;
+import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
-import static com.android.systemui.people.PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_TILE;
import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
import static com.android.systemui.people.PeopleSpaceUtils.USER_ID;
+import static com.android.systemui.people.widget.AppWidgetOptionsHelper.OPTIONS_PEOPLE_TILE;
import static com.google.common.truth.Truth.assertThat;
@@ -104,13 +105,14 @@
private static final int WIDGET_ID_WITH_SHORTCUT = 1;
private static final int SECOND_WIDGET_ID_WITH_SHORTCUT = 3;
private static final int WIDGET_ID_WITHOUT_SHORTCUT = 2;
+ private static final int WIDGET_ID_WITH_KEY_IN_OPTIONS = 4;
private static final String SHORTCUT_ID = "101";
private static final String OTHER_SHORTCUT_ID = "102";
private static final String NOTIFICATION_KEY = "0|com.android.systemui.tests|0|null|0";
private static final String NOTIFICATION_CONTENT = "message text";
private static final Uri URI = Uri.parse("fake_uri");
private static final Icon ICON = Icon.createWithResource("package", R.drawable.ic_android);
- private static final String KEY = PeopleSpaceUtils.getKey(SHORTCUT_ID, TEST_PACKAGE_A, 0);
+ private static final PeopleTileKey KEY = new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A);
private static final Person PERSON = new Person.Builder()
.setName("name")
.setKey("abc")
@@ -172,10 +174,11 @@
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
+ clearStorage();
setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
Bundle options = new Bundle();
- options.putParcelable(PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_TILE, PERSON_TILE);
+ options.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT)))
.thenReturn(options);
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITHOUT_SHORTCUT)))
@@ -395,7 +398,7 @@
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
mBundleArgumentCaptor.capture());
Bundle bundle = mBundleArgumentCaptor.getValue();
- PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_SPACE_TILE);
+ PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
assertThat(tile.getStatuses()).containsExactly(status);
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
any());
@@ -439,7 +442,7 @@
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
mBundleArgumentCaptor.capture());
Bundle bundle = mBundleArgumentCaptor.getValue();
- PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_SPACE_TILE);
+ PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
assertThat(tile.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
assertThat(tile.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT);
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
@@ -473,7 +476,8 @@
throws Exception {
addSecondWidgetForPersonTile();
- PeopleSpaceUtils.removeStorageForTile(mContext, KEY, SECOND_WIDGET_ID_WITH_SHORTCUT);
+ PeopleSpaceUtils.removeSharedPreferencesStorageForTile(
+ mContext, KEY, SECOND_WIDGET_ID_WITH_SHORTCUT);
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
.setSbn(createNotification(
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false))
@@ -510,7 +514,7 @@
mBundleArgumentCaptor.capture());
Bundle bundle = requireNonNull(mBundleArgumentCaptor.getValue());
- PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_SPACE_TILE);
+ PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
assertThat(tile.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
assertThat(tile.getNotificationContent())
.isEqualTo(mContext.getString(R.string.missed_call));
@@ -536,7 +540,7 @@
mBundleArgumentCaptor.capture());
Bundle bundle = requireNonNull(mBundleArgumentCaptor.getValue());
- PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_SPACE_TILE);
+ PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
assertThat(tile.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
assertThat(tile.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT);
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
@@ -547,6 +551,7 @@
public void testUpdateNotificationRemovedIfExistingTile() throws Exception {
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+ setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
StatusBarNotification sbn = createNotification(
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false);
@@ -560,11 +565,11 @@
verify(mAppWidgetManager, times(2)).updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
mBundleArgumentCaptor.capture());
Bundle bundle = mBundleArgumentCaptor.getValue();
- PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_SPACE_TILE);
+ PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
assertThat(tile.getNotificationKey()).isEqualTo(null);
assertThat(tile.getNotificationContent()).isEqualTo(null);
assertThat(tile.getNotificationDataUri()).isEqualTo(null);
- verify(mAppWidgetManager, times(2)).updateAppWidget(anyInt(),
+ verify(mAppWidgetManager, times(2)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
any());
}
@@ -585,7 +590,7 @@
assertThat(widgetSp.getString(SHORTCUT_ID, null)).isNull();
assertThat(widgetSp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(INVALID_USER_ID);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
- assertThat(sp.getStringSet(KEY, new HashSet<>())).containsExactly(
+ assertThat(sp.getStringSet(KEY.toString(), new HashSet<>())).containsExactly(
String.valueOf(SECOND_WIDGET_ID_WITH_SHORTCUT));
// Check listener & shortcut caching remain for other widget.
verify(mPeopleManager, never()).unregisterConversationListener(any());
@@ -603,7 +608,7 @@
assertThat(secondWidgetSp.getString(PACKAGE_NAME, null)).isNull();
assertThat(secondWidgetSp.getString(SHORTCUT_ID, null)).isNull();
assertThat(secondWidgetSp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(INVALID_USER_ID);
- assertThat(sp.getStringSet(KEY, new HashSet<>())).isEmpty();
+ assertThat(sp.getStringSet(KEY.toString(), new HashSet<>())).isEmpty();
// Check listener is removed and shortcut is uncached.
verify(mPeopleManager, times(1)).unregisterConversationListener(any());
verify(mLauncherApps, times(1)).uncacheShortcuts(eq(TEST_PACKAGE_A),
@@ -611,13 +616,96 @@
eq(LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS));
}
+ @Test
+ public void testUpdateWidgetsWithEmptyOptionsAddsPeopleTileToOptions() throws Exception {
+ int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT};
+ when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+ when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT)))
+ .thenReturn(new Bundle());
+
+ mManager.updateWidgets(widgetIdsArray);
+ mClock.advanceTime(MIN_LINGER_DURATION);
+
+ // If we had to fetch Tile from persistent storage, we want to make sure we write it to
+ // options.
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ Bundle bundle = mBundleArgumentCaptor.getValue();
+ PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tile.getId()).isEqualTo(SHORTCUT_ID);
+ verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+ any());
+ }
+
+ @Test
+ public void testOnAppWidgetOptionsChangedNoWidgetAdded() {
+ Bundle newOptions = new Bundle();
+ newOptions.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
+ mManager.onAppWidgetOptionsChanged(SECOND_WIDGET_ID_WITH_SHORTCUT, newOptions);
+
+
+ // Check that options is not modified
+ verify(mAppWidgetManager, never()).updateAppWidgetOptions(
+ eq(SECOND_WIDGET_ID_WITH_SHORTCUT), any());
+ // Check listener is not added and shortcut is not cached.
+ verify(mPeopleManager, never()).registerConversationListener(any(), anyInt(), any(), any(),
+ any());
+ verify(mLauncherApps, never()).cacheShortcuts(any(), any(), any(), anyInt());
+ // Check no added storage.
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+ assertThat(sp.getStringSet(KEY.toString(), new HashSet<>()))
+ .doesNotContain(SECOND_WIDGET_ID_WITH_SHORTCUT);
+ SharedPreferences widgetSp = mContext.getSharedPreferences(
+ String.valueOf(SECOND_WIDGET_ID_WITH_SHORTCUT),
+ Context.MODE_PRIVATE);
+ assertThat(widgetSp.getString(PACKAGE_NAME, EMPTY_STRING)).isEqualTo(EMPTY_STRING);
+ assertThat(widgetSp.getString(SHORTCUT_ID, EMPTY_STRING)).isEqualTo(EMPTY_STRING);
+ assertThat(widgetSp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(INVALID_USER_ID);
+
+ }
+
+ @Test
+ public void testOnAppWidgetOptionsChangedWidgetAdded() {
+ Bundle newOptions = new Bundle();
+ newOptions.putString(PeopleSpaceUtils.SHORTCUT_ID, SHORTCUT_ID);
+ newOptions.putInt(USER_ID, 0);
+ newOptions.putString(PACKAGE_NAME, TEST_PACKAGE_A);
+ when(mAppWidgetManager.getAppWidgetOptions(eq(SECOND_WIDGET_ID_WITH_SHORTCUT)))
+ .thenReturn(newOptions);
+
+ mManager.onAppWidgetOptionsChanged(SECOND_WIDGET_ID_WITH_SHORTCUT, newOptions);
+
+ verify(mAppWidgetManager, times(1)).updateAppWidgetOptions(
+ eq(SECOND_WIDGET_ID_WITH_SHORTCUT), mBundleArgumentCaptor.capture());
+ Bundle bundle = mBundleArgumentCaptor.getValue();
+ assertThat(bundle.getString(PeopleSpaceUtils.SHORTCUT_ID, EMPTY_STRING))
+ .isEqualTo(EMPTY_STRING);
+ assertThat(bundle.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(INVALID_USER_ID);
+ assertThat(bundle.getString(PACKAGE_NAME, EMPTY_STRING)).isEqualTo(EMPTY_STRING);
+ verify(mLauncherApps, times(1)).cacheShortcuts(eq(TEST_PACKAGE_A),
+ eq(Arrays.asList(SHORTCUT_ID)), eq(UserHandle.of(0)),
+ eq(LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS));
+
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+ assertThat(sp.getStringSet(KEY.toString(), new HashSet<>())).contains(
+ String.valueOf(SECOND_WIDGET_ID_WITH_SHORTCUT));
+ SharedPreferences widgetSp = mContext.getSharedPreferences(
+ String.valueOf(SECOND_WIDGET_ID_WITH_SHORTCUT),
+ Context.MODE_PRIVATE);
+ assertThat(widgetSp.getString(PACKAGE_NAME, EMPTY_STRING)).isEqualTo(TEST_PACKAGE_A);
+ assertThat(widgetSp.getString(PeopleSpaceUtils.SHORTCUT_ID, EMPTY_STRING))
+ .isEqualTo(SHORTCUT_ID);
+ assertThat(widgetSp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(0);
+ }
+
/**
* Adds another widget for {@code PERSON_TILE} with widget ID: {@code
* SECOND_WIDGET_ID_WITH_SHORTCUT}.
*/
private void addSecondWidgetForPersonTile() {
Bundle options = new Bundle();
- options.putParcelable(PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_TILE, PERSON_TILE);
+ options.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
when(mAppWidgetManager.getAppWidgetOptions(eq(SECOND_WIDGET_ID_WITH_SHORTCUT)))
.thenReturn(options);
// Set the same Person associated on another People Tile widget ID.
@@ -676,6 +764,27 @@
.build();
}
+ private void clearStorage() {
+ SharedPreferences widgetSp1 = mContext.getSharedPreferences(
+ String.valueOf(WIDGET_ID_WITH_SHORTCUT),
+ Context.MODE_PRIVATE);
+ widgetSp1.edit().clear().commit();
+ SharedPreferences widgetSp2 = mContext.getSharedPreferences(
+ String.valueOf(WIDGET_ID_WITHOUT_SHORTCUT),
+ Context.MODE_PRIVATE);
+ widgetSp2.edit().clear().commit();
+ SharedPreferences widgetSp3 = mContext.getSharedPreferences(
+ String.valueOf(SECOND_WIDGET_ID_WITH_SHORTCUT),
+ Context.MODE_PRIVATE);
+ widgetSp3.edit().clear().commit();
+ SharedPreferences widgetSp4 = mContext.getSharedPreferences(
+ String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS),
+ Context.MODE_PRIVATE);
+ widgetSp4.edit().clear().commit();
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+ sp.edit().clear().commit();
+ }
+
private void setStorageForTile(String shortcutId, String packageName, int widgetId) {
SharedPreferences widgetSp = mContext.getSharedPreferences(
String.valueOf(widgetId),
@@ -689,7 +798,7 @@
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = sp.edit();
editor.putString(String.valueOf(widgetId), shortcutId);
- String key = PeopleSpaceUtils.getKey(shortcutId, packageName, 0);
+ String key = new PeopleTileKey(shortcutId, 0, packageName).toString();
Set<String> storedWidgetIds = new HashSet<>(sp.getStringSet(key, new HashSet<>()));
storedWidgetIds.add(String.valueOf(widgetId));
editor.putStringSet(key, storedWidgetIds);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt
new file mode 100644
index 0000000..a9d10e9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt
@@ -0,0 +1,147 @@
+package com.android.systemui.qs.tiles
+
+import android.app.AlarmManager
+import android.app.PendingIntent
+import android.os.Handler
+import android.service.quicksettings.Tile
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.statusbar.FeatureFlags
+import com.android.systemui.statusbar.policy.NextAlarmController
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.eq
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class AlarmTileTest : SysuiTestCase() {
+
+ @Mock
+ private lateinit var qsHost: QSHost
+ @Mock
+ private lateinit var metricsLogger: MetricsLogger
+ @Mock
+ private lateinit var statusBarStateController: StatusBarStateController
+ @Mock
+ private lateinit var activityStarter: ActivityStarter
+ @Mock
+ private lateinit var qsLogger: QSLogger
+ @Mock
+ private lateinit var featureFlags: FeatureFlags
+ @Mock
+ private lateinit var userTracker: UserTracker
+ @Mock
+ private lateinit var nextAlarmController: NextAlarmController
+ @Mock
+ private lateinit var uiEventLogger: UiEventLogger
+ @Mock
+ private lateinit var pendingIntent: PendingIntent
+ @Captor
+ private lateinit var callbackCaptor: ArgumentCaptor<NextAlarmController.NextAlarmChangeCallback>
+
+ private lateinit var testableLooper: TestableLooper
+ private lateinit var tile: AlarmTile
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ testableLooper = TestableLooper.get(this)
+
+ `when`(qsHost.context).thenReturn(mContext)
+ `when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
+
+ tile = AlarmTile(
+ qsHost,
+ testableLooper.looper,
+ Handler(testableLooper.looper),
+ metricsLogger,
+ statusBarStateController,
+ activityStarter,
+ qsLogger,
+ featureFlags,
+ userTracker,
+ nextAlarmController
+ )
+
+ verify(nextAlarmController).observe(eq(tile), capture(callbackCaptor))
+ tile.refreshState()
+ testableLooper.processAllMessages()
+ }
+
+ @Test
+ fun testNotAvailableFeatureFlag() {
+ `when`(featureFlags.isAlarmTileAvailable).thenReturn(false)
+ assertThat(tile.isAvailable).isFalse()
+ }
+
+ @Test
+ fun testAvailableFeatureFlag() {
+ `when`(featureFlags.isAlarmTileAvailable).thenReturn(true)
+ assertThat(tile.isAvailable).isTrue()
+ }
+
+ @Test
+ fun testDoesntHandleLongClick() {
+ assertThat(tile.state.handlesLongClick).isFalse()
+ }
+
+ @Test
+ fun testInactiveByDefault() {
+ assertThat(tile.state.state).isEqualTo(Tile.STATE_INACTIVE)
+ }
+
+ @Test
+ fun testInactiveAfterNullNextAlarm() {
+ callbackCaptor.value.onNextAlarmChanged(null)
+
+ testableLooper.processAllMessages()
+ assertThat(tile.state.state).isEqualTo(Tile.STATE_INACTIVE)
+ }
+
+ @Test
+ fun testActivityStartedWhenNullNextAlarm() {
+ callbackCaptor.value.onNextAlarmChanged(null)
+ tile.click()
+
+ testableLooper.processAllMessages()
+ verify(activityStarter).postStartActivityDismissingKeyguard(tile.defaultIntent, 0)
+ }
+
+ @Test
+ fun testActiveAfterNextAlarm() {
+ val alarmInfo = AlarmManager.AlarmClockInfo(1L, pendingIntent)
+ callbackCaptor.value.onNextAlarmChanged(alarmInfo)
+
+ testableLooper.processAllMessages()
+ assertThat(tile.state.state).isEqualTo(Tile.STATE_ACTIVE)
+ }
+
+ @Test
+ fun testActivityStartedWhenNextAlarm() {
+ val alarmInfo = AlarmManager.AlarmClockInfo(1L, pendingIntent)
+ callbackCaptor.value.onNextAlarmChanged(alarmInfo)
+ tile.click()
+
+ testableLooper.processAllMessages()
+ verify(activityStarter).postStartActivityDismissingKeyguard(pendingIntent)
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
index ccd9548..9363b248 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
@@ -17,6 +17,8 @@
package com.android.systemui.qs.tiles
import android.os.Handler
+import android.content.Context
+import android.content.Intent
import android.provider.Settings
import android.service.quicksettings.Tile
import android.testing.AndroidTestingRunner
@@ -30,7 +32,6 @@
import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.controls.dagger.ControlsComponent
import com.android.systemui.controls.management.ControlsListingController
-import com.android.systemui.controls.ui.ControlsDialog
import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.statusbar.StatusBarStateController
@@ -50,7 +51,9 @@
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.`when`
+import org.mockito.Mockito.doNothing
import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import java.util.Optional
@@ -80,8 +83,6 @@
private lateinit var controlsController: ControlsController
@Mock
private lateinit var featureFlags: FeatureFlags
- @Mock
- private lateinit var controlsDialog: ControlsDialog
private lateinit var globalSettings: GlobalSettings
@Mock
private lateinit var serviceInfo: ControlsServiceInfo
@@ -95,6 +96,7 @@
private lateinit var tile: DeviceControlsTile
private lateinit var secureSettings: SecureSettings
+ private lateinit var spiedContext: Context
private var featureEnabled = true
@Before
@@ -103,7 +105,9 @@
testableLooper = TestableLooper.get(this)
secureSettings = FakeSettings()
- `when`(qsHost.context).thenReturn(mContext)
+ spiedContext = spy(mContext)
+ doNothing().`when`(spiedContext).startActivity(any(Intent::class.java))
+ `when`(qsHost.context).thenReturn(spiedContext)
`when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
`when`(controlsController.available).thenReturn(true)
`when`(controlsComponent.isEnabled()).thenReturn(true)
@@ -276,7 +280,7 @@
tile.click()
testableLooper.processAllMessages()
- verify(controlsDialog, never()).show(any(ControlsUiController::class.java))
+ verify(spiedContext, never()).startActivity(any(Intent::class.java))
}
@Test
@@ -293,7 +297,7 @@
tile.click()
testableLooper.processAllMessages()
- verify(controlsDialog).show(controlsUiController)
+ verify(spiedContext).startActivity(any(Intent::class.java))
}
@Test
@@ -311,25 +315,7 @@
tile.click()
testableLooper.processAllMessages()
- verify(controlsDialog, never()).show(any(ControlsUiController::class.java))
- }
-
- @Test
- fun testDialogDismissedOnDestroy() {
- verify(controlsListingController).observe(
- any(LifecycleOwner::class.java),
- capture(listingCallbackCaptor)
- )
-
- listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
- testableLooper.processAllMessages()
-
- tile.click()
- testableLooper.processAllMessages()
-
- tile.destroy()
- testableLooper.processAllMessages()
- verify(controlsDialog).dismiss()
+ verify(spiedContext, never()).startActivity(any(Intent::class.java))
}
private fun createTile(): DeviceControlsTile {
@@ -343,7 +329,6 @@
qsLogger,
controlsComponent,
featureFlags,
- { controlsDialog },
globalSettings
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
index 14877ee..30708a7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
@@ -127,25 +127,7 @@
.getPeopleNotificationType(entry))
.thenReturn(TYPE_NON_PERSON);
- // THEN it has high priority
- assertTrue(mHighPriorityProvider.isHighPriority(entry));
- }
-
- @Test
- public void minImportanceForeground() {
- // GIVEN notification is low importance and is associated with a foreground service
- final Notification notification = mock(Notification.class);
- when(notification.isForegroundService()).thenReturn(true);
-
- final NotificationEntry entry = new NotificationEntryBuilder()
- .setNotification(notification)
- .setImportance(IMPORTANCE_MIN)
- .build();
- when(mPeopleNotificationIdentifier
- .getPeopleNotificationType(entry))
- .thenReturn(TYPE_NON_PERSON);
-
- // THEN it does NOT have high priority
+ // THEN it has low priority
assertFalse(mHighPriorityProvider.isHighPriority(entry));
}
@@ -155,7 +137,6 @@
// to less than IMPORTANCE_DEFAULT (ie: IMPORTANCE_LOW or IMPORTANCE_MIN)
final Notification notification = new Notification.Builder(mContext, "test")
.setStyle(new Notification.MessagingStyle(""))
- .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
.build();
final NotificationChannel channel = new NotificationChannel("a", "a",
IMPORTANCE_LOW);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
index 8cd7103..c1d2ea8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
@@ -322,23 +322,7 @@
}
@Test
- public void testPeopleFiltering_addHeadersFromShowingOnlyGentle() {
- enablePeopleFiltering();
-
- setStackState(
- GENTLE_HEADER,
- PERSON,
- ALERTING,
- GENTLE);
- mSectionsManager.updateSectionBoundaries();
-
- verify(mNssl).changeViewPosition(mSectionsManager.getSilentHeaderView(), 2);
- verify(mNssl).addView(mSectionsManager.getAlertingHeaderView(), 1);
- verify(mNssl).addView(mSectionsManager.getPeopleHeaderView(), 0);
- }
-
- @Test
- public void testPeopleFiltering_addAllHeaders() {
+ public void testPeopleFiltering_onlyAddSilentHeader() {
enablePeopleFiltering();
setStackState(
@@ -348,26 +332,6 @@
mSectionsManager.updateSectionBoundaries();
verify(mNssl).addView(mSectionsManager.getSilentHeaderView(), 2);
- verify(mNssl).addView(mSectionsManager.getAlertingHeaderView(), 1);
- verify(mNssl).addView(mSectionsManager.getPeopleHeaderView(), 0);
- }
-
- @Test
- public void testPeopleFiltering_moveAllHeaders() {
- enablePeopleFiltering();
-
- setStackState(
- PEOPLE_HEADER,
- ALERTING_HEADER,
- GENTLE_HEADER,
- PERSON,
- ALERTING,
- GENTLE);
- mSectionsManager.updateSectionBoundaries();
-
- verify(mNssl).changeViewPosition(mSectionsManager.getSilentHeaderView(), 4);
- verify(mNssl).changeViewPosition(mSectionsManager.getAlertingHeaderView(), 2);
- verify(mNssl).changeViewPosition(mSectionsManager.getPeopleHeaderView(), 0);
}
@Test
@@ -385,9 +349,7 @@
mSectionsManager.updateSectionBoundaries();
verifyMockStack(
- ChildType.INCOMING_HEADER,
ChildType.HEADS_UP,
- ChildType.PEOPLE_HEADER,
ChildType.PERSON,
ChildType.GENTLE_HEADER,
ChildType.GENTLE
@@ -408,10 +370,8 @@
mSectionsManager.updateSectionBoundaries();
verifyMockStack(
- ChildType.INCOMING_HEADER,
ChildType.HEADS_UP,
ChildType.HEADS_UP,
- ChildType.PEOPLE_HEADER,
ChildType.PERSON
);
}
@@ -428,7 +388,6 @@
mSectionsManager.updateSectionBoundaries();
verifyMockStack(
- ChildType.PEOPLE_HEADER,
ChildType.PERSON,
ChildType.PERSON
);
@@ -444,9 +403,7 @@
);
mSectionsManager.updateSectionBoundaries();
verifyMockStack(
- ChildType.INCOMING_HEADER,
ChildType.HEADS_UP,
- ChildType.PEOPLE_HEADER,
ChildType.PERSON
);
}
@@ -467,12 +424,9 @@
mSectionsManager.updateSectionBoundaries();
verifyMockStack(
- ChildType.INCOMING_HEADER,
ChildType.HEADS_UP,
ChildType.FSN,
- ChildType.PEOPLE_HEADER,
ChildType.PERSON,
- ChildType.ALERTING_HEADER,
ChildType.ALERTING,
ChildType.GENTLE_HEADER,
ChildType.GENTLE
@@ -517,7 +471,7 @@
}
@Test
- public void testRemoveIncomingHeader() {
+ public void testRemoveNonSilentHeader() {
enablePeopleFiltering();
enableMediaControls();
@@ -539,9 +493,7 @@
verifyMockStack(
ChildType.MEDIA_CONTROLS,
- ChildType.PEOPLE_HEADER,
ChildType.PERSON,
- ChildType.ALERTING_HEADER,
ChildType.ALERTING,
ChildType.ALERTING,
ChildType.ALERTING,
@@ -569,13 +521,10 @@
mSectionsManager.updateSectionBoundaries();
verifyMockStack(
- ChildType.INCOMING_HEADER,
ChildType.HEADS_UP,
ChildType.HEADS_UP,
ChildType.HEADS_UP,
- ChildType.PEOPLE_HEADER,
ChildType.PERSON,
- ChildType.ALERTING_HEADER,
ChildType.ALERTING
);
}
@@ -593,7 +542,6 @@
mSectionsManager.updateSectionBoundaries();
verifyMockStack(
- ChildType.ALERTING_HEADER,
ChildType.PERSON,
ChildType.ALERTING,
ChildType.GENTLE_HEADER,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index bdde822..8b5ba38 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -174,6 +174,7 @@
DozeLog.PULSE_REASON_SENSOR_LONG_PRESS,
DozeLog.PULSE_REASON_DOCKING,
DozeLog.REASON_SENSOR_WAKE_UP,
+ DozeLog.REASON_SENSOR_QUICK_PICKUP,
DozeLog.REASON_SENSOR_TAP));
HashSet<Integer> reasonsThatDontPulse = new HashSet<>(
Arrays.asList(DozeLog.REASON_SENSOR_PICKUP,
diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java
index 238bf0f..d420bd4 100644
--- a/rs/java/android/renderscript/Allocation.java
+++ b/rs/java/android/renderscript/Allocation.java
@@ -52,8 +52,12 @@
* <p>For more information about creating an application that uses RenderScript, read the
* <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
-
+@Deprecated
public class Allocation extends BaseObj {
private static final int MAX_NUMBER_IO_INPUT_ALLOC = 16;
diff --git a/rs/java/android/renderscript/AllocationAdapter.java b/rs/java/android/renderscript/AllocationAdapter.java
index 6d7e97e..17bc234 100644
--- a/rs/java/android/renderscript/AllocationAdapter.java
+++ b/rs/java/android/renderscript/AllocationAdapter.java
@@ -19,7 +19,11 @@
/**
* Only intended for use by generated reflected code.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class AllocationAdapter extends Allocation {
Type mWindow;
diff --git a/rs/java/android/renderscript/BaseObj.java b/rs/java/android/renderscript/BaseObj.java
index 7b5514b..ea8535d 100644
--- a/rs/java/android/renderscript/BaseObj.java
+++ b/rs/java/android/renderscript/BaseObj.java
@@ -27,7 +27,11 @@
* It is responsible for lifetime management and resource tracking. This class
* should not be used by a user application.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class BaseObj {
BaseObj(long id, RenderScript rs) {
rs.validate();
diff --git a/rs/java/android/renderscript/Byte2.java b/rs/java/android/renderscript/Byte2.java
index 3ad79e4..cb5cc47 100644
--- a/rs/java/android/renderscript/Byte2.java
+++ b/rs/java/android/renderscript/Byte2.java
@@ -20,7 +20,11 @@
/**
* Class for exposing the native RenderScript byte2 type back to the Android system.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Byte2 {
public byte x;
public byte y;
diff --git a/rs/java/android/renderscript/Byte3.java b/rs/java/android/renderscript/Byte3.java
index a138313..aca4e64 100644
--- a/rs/java/android/renderscript/Byte3.java
+++ b/rs/java/android/renderscript/Byte3.java
@@ -20,7 +20,11 @@
/**
* Class for exposing the native RenderScript byte3 type back to the Android system.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Byte3 {
public byte x;
public byte y;
diff --git a/rs/java/android/renderscript/Byte4.java b/rs/java/android/renderscript/Byte4.java
index fa4c13d..b30b6ed 100644
--- a/rs/java/android/renderscript/Byte4.java
+++ b/rs/java/android/renderscript/Byte4.java
@@ -20,7 +20,11 @@
/**
* Class for exposing the native RenderScript byte4 type back to the Android system.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Byte4 {
public byte x;
public byte y;
diff --git a/rs/java/android/renderscript/Double2.java b/rs/java/android/renderscript/Double2.java
index 4c7319d..e14228a 100644
--- a/rs/java/android/renderscript/Double2.java
+++ b/rs/java/android/renderscript/Double2.java
@@ -19,7 +19,12 @@
/**
* Vector version of the basic double type.
* Provides two double fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Double2 {
public double x;
public double y;
diff --git a/rs/java/android/renderscript/Double3.java b/rs/java/android/renderscript/Double3.java
index b819716..e52c902 100644
--- a/rs/java/android/renderscript/Double3.java
+++ b/rs/java/android/renderscript/Double3.java
@@ -19,7 +19,12 @@
/**
* Vector version of the basic double type.
* Provides three double fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Double3 {
public double x;
public double y;
diff --git a/rs/java/android/renderscript/Double4.java b/rs/java/android/renderscript/Double4.java
index e4829f7..a3e4a94 100644
--- a/rs/java/android/renderscript/Double4.java
+++ b/rs/java/android/renderscript/Double4.java
@@ -19,7 +19,12 @@
/**
* Vector version of the basic double type.
* Provides four double fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Double4 {
public double x;
public double y;
diff --git a/rs/java/android/renderscript/Element.java b/rs/java/android/renderscript/Element.java
index 0941907..f671953 100644
--- a/rs/java/android/renderscript/Element.java
+++ b/rs/java/android/renderscript/Element.java
@@ -51,7 +51,12 @@
* <p>For more information about creating an application that uses RenderScript, read the
* <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Element extends BaseObj {
int mSize;
Element[] mElements;
diff --git a/rs/java/android/renderscript/FieldPacker.java b/rs/java/android/renderscript/FieldPacker.java
index de1c497..aaa0fe8 100644
--- a/rs/java/android/renderscript/FieldPacker.java
+++ b/rs/java/android/renderscript/FieldPacker.java
@@ -26,7 +26,11 @@
* reflected code generated by the RS tool chain. It should not
* be called directly.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class FieldPacker {
public FieldPacker(int len) {
mPos = 0;
diff --git a/rs/java/android/renderscript/FileA3D.java b/rs/java/android/renderscript/FileA3D.java
index 7cc2825..f0a9fa7 100644
--- a/rs/java/android/renderscript/FileA3D.java
+++ b/rs/java/android/renderscript/FileA3D.java
@@ -36,6 +36,7 @@
* index entries for all the objects stored inside it.
*
**/
+@Deprecated
public class FileA3D extends BaseObj {
/**
diff --git a/rs/java/android/renderscript/Float2.java b/rs/java/android/renderscript/Float2.java
index e9f8ca7..1f6038c 100644
--- a/rs/java/android/renderscript/Float2.java
+++ b/rs/java/android/renderscript/Float2.java
@@ -19,7 +19,12 @@
/**
* Vector version of the basic float type.
* Provides two float fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Float2 {
public float x;
public float y;
diff --git a/rs/java/android/renderscript/Float3.java b/rs/java/android/renderscript/Float3.java
index 555bdf6..5f45716 100644
--- a/rs/java/android/renderscript/Float3.java
+++ b/rs/java/android/renderscript/Float3.java
@@ -19,7 +19,12 @@
/**
* Vector version of the basic float type.
* Provides three float fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Float3 {
public float x;
public float y;
diff --git a/rs/java/android/renderscript/Float4.java b/rs/java/android/renderscript/Float4.java
index 6541b2ec..7f3ba2c 100644
--- a/rs/java/android/renderscript/Float4.java
+++ b/rs/java/android/renderscript/Float4.java
@@ -19,7 +19,12 @@
/**
* Vector version of the basic float type.
* Provides four float fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Float4 {
public float x;
public float y;
diff --git a/rs/java/android/renderscript/Font.java b/rs/java/android/renderscript/Font.java
index e47ec4b..6f6f341 100644
--- a/rs/java/android/renderscript/Font.java
+++ b/rs/java/android/renderscript/Font.java
@@ -45,6 +45,7 @@
* them in the script to suit the user's rendering needs. Font colors work as a state machine.
* Every new call to draw text uses the last color set in the script.</p>
**/
+@Deprecated
public class Font extends BaseObj {
//These help us create a font by family name
diff --git a/rs/java/android/renderscript/Int2.java b/rs/java/android/renderscript/Int2.java
index 120957b..be0639f 100644
--- a/rs/java/android/renderscript/Int2.java
+++ b/rs/java/android/renderscript/Int2.java
@@ -19,7 +19,12 @@
/**
* Vector version of the basic int type.
* Provides two int fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Int2 {
public int x;
public int y;
diff --git a/rs/java/android/renderscript/Int3.java b/rs/java/android/renderscript/Int3.java
index 5431b9a7..38a602d 100644
--- a/rs/java/android/renderscript/Int3.java
+++ b/rs/java/android/renderscript/Int3.java
@@ -19,7 +19,12 @@
/**
* Vector version of the basic int type.
* Provides three int fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Int3 {
public int x;
public int y;
diff --git a/rs/java/android/renderscript/Int4.java b/rs/java/android/renderscript/Int4.java
index 1c0e2e2..52f7bb2 100644
--- a/rs/java/android/renderscript/Int4.java
+++ b/rs/java/android/renderscript/Int4.java
@@ -19,7 +19,12 @@
/**
* Vector version of the basic int type.
* Provides four int fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Int4 {
public int x;
public int y;
diff --git a/rs/java/android/renderscript/Long2.java b/rs/java/android/renderscript/Long2.java
index fabf204..1b3955b 100644
--- a/rs/java/android/renderscript/Long2.java
+++ b/rs/java/android/renderscript/Long2.java
@@ -19,7 +19,12 @@
/**
* Vector version of the basic long type.
* Provides two long fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Long2 {
public long x;
public long y;
diff --git a/rs/java/android/renderscript/Long3.java b/rs/java/android/renderscript/Long3.java
index 8e243cc..8be9c1c 100644
--- a/rs/java/android/renderscript/Long3.java
+++ b/rs/java/android/renderscript/Long3.java
@@ -19,7 +19,12 @@
/**
* Vector version of the basic long type.
* Provides three long fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Long3 {
public long x;
public long y;
diff --git a/rs/java/android/renderscript/Long4.java b/rs/java/android/renderscript/Long4.java
index 1a1ad74..75db51b 100644
--- a/rs/java/android/renderscript/Long4.java
+++ b/rs/java/android/renderscript/Long4.java
@@ -19,7 +19,12 @@
/**
* Vector version of the basic long type.
* Provides four long fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Long4 {
public long x;
public long y;
diff --git a/rs/java/android/renderscript/Matrix2f.java b/rs/java/android/renderscript/Matrix2f.java
index 048262d..5f5e709 100644
--- a/rs/java/android/renderscript/Matrix2f.java
+++ b/rs/java/android/renderscript/Matrix2f.java
@@ -20,7 +20,11 @@
/**
* Class for exposing the native RenderScript rs_matrix2x2 type back to the Android system.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Matrix2f {
/**
diff --git a/rs/java/android/renderscript/Matrix3f.java b/rs/java/android/renderscript/Matrix3f.java
index 9a4af777..b620eaf 100644
--- a/rs/java/android/renderscript/Matrix3f.java
+++ b/rs/java/android/renderscript/Matrix3f.java
@@ -20,7 +20,11 @@
/**
* Class for exposing the native RenderScript rs_matrix3x3 type back to the Android system.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Matrix3f {
/**
diff --git a/rs/java/android/renderscript/Matrix4f.java b/rs/java/android/renderscript/Matrix4f.java
index a9469c9..cdf06a6 100644
--- a/rs/java/android/renderscript/Matrix4f.java
+++ b/rs/java/android/renderscript/Matrix4f.java
@@ -22,7 +22,11 @@
/**
* Class for exposing the native RenderScript rs_matrix4x4 type back to the Android system.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Matrix4f {
/**
diff --git a/rs/java/android/renderscript/Mesh.java b/rs/java/android/renderscript/Mesh.java
index 1a4d1fd..f2fd5a9 100644
--- a/rs/java/android/renderscript/Mesh.java
+++ b/rs/java/android/renderscript/Mesh.java
@@ -40,6 +40,7 @@
* index sets or primitive types.
* </p>
**/
+@Deprecated
public class Mesh extends BaseObj {
/**
diff --git a/rs/java/android/renderscript/Program.java b/rs/java/android/renderscript/Program.java
index ff07218..3cadc93 100644
--- a/rs/java/android/renderscript/Program.java
+++ b/rs/java/android/renderscript/Program.java
@@ -32,7 +32,11 @@
* Program is a base class for all the objects that modify
* various stages of the graphics pipeline
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Program extends BaseObj {
static final int MAX_INPUT = 8;
static final int MAX_OUTPUT = 8;
diff --git a/rs/java/android/renderscript/ProgramFragment.java b/rs/java/android/renderscript/ProgramFragment.java
index 8805312..e2879d8 100644
--- a/rs/java/android/renderscript/ProgramFragment.java
+++ b/rs/java/android/renderscript/ProgramFragment.java
@@ -37,6 +37,7 @@
* </p>
*
**/
+@Deprecated
public class ProgramFragment extends Program {
ProgramFragment(long id, RenderScript rs) {
super(id, rs);
diff --git a/rs/java/android/renderscript/ProgramFragmentFixedFunction.java b/rs/java/android/renderscript/ProgramFragmentFixedFunction.java
index c741ce6..8dbf6f4 100644
--- a/rs/java/android/renderscript/ProgramFragmentFixedFunction.java
+++ b/rs/java/android/renderscript/ProgramFragmentFixedFunction.java
@@ -29,6 +29,7 @@
* blended with results of up to two texture lookups.</p
*
**/
+@Deprecated
public class ProgramFragmentFixedFunction extends ProgramFragment {
ProgramFragmentFixedFunction(long id, RenderScript rs) {
super(id, rs);
diff --git a/rs/java/android/renderscript/ProgramRaster.java b/rs/java/android/renderscript/ProgramRaster.java
index a21696c..8b538289 100644
--- a/rs/java/android/renderscript/ProgramRaster.java
+++ b/rs/java/android/renderscript/ProgramRaster.java
@@ -25,6 +25,7 @@
* Program raster is primarily used to specify whether point sprites are enabled and to control
* the culling mode. By default, back faces are culled.
**/
+@Deprecated
public class ProgramRaster extends BaseObj {
/**
diff --git a/rs/java/android/renderscript/ProgramStore.java b/rs/java/android/renderscript/ProgramStore.java
index 1952b88..c94d253 100644
--- a/rs/java/android/renderscript/ProgramStore.java
+++ b/rs/java/android/renderscript/ProgramStore.java
@@ -34,7 +34,11 @@
* framebuffer</li>
* </ul>
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class ProgramStore extends BaseObj {
/**
* Specifies the function used to determine whether a fragment
diff --git a/rs/java/android/renderscript/ProgramVertex.java b/rs/java/android/renderscript/ProgramVertex.java
index 9257234..ecd8a31 100644
--- a/rs/java/android/renderscript/ProgramVertex.java
+++ b/rs/java/android/renderscript/ProgramVertex.java
@@ -34,7 +34,6 @@
* The signatures don't have to be exact or in any strict order. As long as the input name in the shader
* matches a channel name and size available on the mesh, the runtime takes care of connecting the
* two. Unlike OpenGL, there is no need to link the vertex and fragment programs.</p>
- *
**/
package android.renderscript;
@@ -49,6 +48,7 @@
* geometric data in a user-defined way.
*
**/
+@Deprecated
public class ProgramVertex extends Program {
ProgramVertex(long id, RenderScript rs) {
diff --git a/rs/java/android/renderscript/ProgramVertexFixedFunction.java b/rs/java/android/renderscript/ProgramVertexFixedFunction.java
index 03c2eaf..4cf2f4c 100644
--- a/rs/java/android/renderscript/ProgramVertexFixedFunction.java
+++ b/rs/java/android/renderscript/ProgramVertexFixedFunction.java
@@ -27,6 +27,7 @@
* without writing any GLSL code.
*
**/
+@Deprecated
public class ProgramVertexFixedFunction extends ProgramVertex {
ProgramVertexFixedFunction(long id, RenderScript rs) {
diff --git a/rs/java/android/renderscript/RSDriverException.java b/rs/java/android/renderscript/RSDriverException.java
index 9e6507f..3d0f0bf 100644
--- a/rs/java/android/renderscript/RSDriverException.java
+++ b/rs/java/android/renderscript/RSDriverException.java
@@ -20,7 +20,12 @@
/**
* Base class for all exceptions thrown by the Android
* RenderScript
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class RSDriverException extends RSRuntimeException {
public RSDriverException(String string) {
super(string);
diff --git a/rs/java/android/renderscript/RSIllegalArgumentException.java b/rs/java/android/renderscript/RSIllegalArgumentException.java
index 5c68594..d0ac5b6 100644
--- a/rs/java/android/renderscript/RSIllegalArgumentException.java
+++ b/rs/java/android/renderscript/RSIllegalArgumentException.java
@@ -20,7 +20,12 @@
/**
* Base class for all exceptions thrown by the Android
* RenderScript
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class RSIllegalArgumentException extends RSRuntimeException {
public RSIllegalArgumentException(String string) {
super(string);
diff --git a/rs/java/android/renderscript/RSInvalidStateException.java b/rs/java/android/renderscript/RSInvalidStateException.java
index c881898..5eea419 100644
--- a/rs/java/android/renderscript/RSInvalidStateException.java
+++ b/rs/java/android/renderscript/RSInvalidStateException.java
@@ -20,7 +20,12 @@
/**
* Base class for all exceptions thrown by the Android
* RenderScript
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class RSInvalidStateException extends RSRuntimeException {
public RSInvalidStateException(String string) {
super(string);
diff --git a/rs/java/android/renderscript/RSRuntimeException.java b/rs/java/android/renderscript/RSRuntimeException.java
index b4b629e..d52a1c1 100644
--- a/rs/java/android/renderscript/RSRuntimeException.java
+++ b/rs/java/android/renderscript/RSRuntimeException.java
@@ -20,7 +20,12 @@
/**
* Base class for all exceptions thrown by the Android
* RenderScript
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class RSRuntimeException
extends java.lang.RuntimeException {
public RSRuntimeException(String string) {
diff --git a/rs/java/android/renderscript/RSSurfaceView.java b/rs/java/android/renderscript/RSSurfaceView.java
index 6bdde38..05c0112f 100644
--- a/rs/java/android/renderscript/RSSurfaceView.java
+++ b/rs/java/android/renderscript/RSSurfaceView.java
@@ -33,6 +33,7 @@
* <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
*/
+@Deprecated
public class RSSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mSurfaceHolder;
private RenderScriptGL mRS;
diff --git a/rs/java/android/renderscript/RSTextureView.java b/rs/java/android/renderscript/RSTextureView.java
index af3258a..ed68fc3 100644
--- a/rs/java/android/renderscript/RSTextureView.java
+++ b/rs/java/android/renderscript/RSTextureView.java
@@ -28,6 +28,7 @@
* to draw on.
*
*/
+@Deprecated
public class RSTextureView extends TextureView implements TextureView.SurfaceTextureListener {
private RenderScriptGL mRS;
private SurfaceTexture mSurfaceTexture;
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 806a25a7..855cfdc 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -44,7 +44,12 @@
* <p>For more information about creating an application that uses RenderScript, read the
* <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class RenderScript {
static final long TRACE_TAG = Trace.TRACE_TAG_RS;
diff --git a/rs/java/android/renderscript/RenderScriptCacheDir.java b/rs/java/android/renderscript/RenderScriptCacheDir.java
index 862d032..cd6e8b1 100644
--- a/rs/java/android/renderscript/RenderScriptCacheDir.java
+++ b/rs/java/android/renderscript/RenderScriptCacheDir.java
@@ -23,7 +23,11 @@
/**
* Used only for tracking the RenderScript cache directory.
* @hide
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class RenderScriptCacheDir {
/**
* Sets the directory to use as a persistent storage for the
diff --git a/rs/java/android/renderscript/RenderScriptGL.java b/rs/java/android/renderscript/RenderScriptGL.java
index dafaf36..d46dbf6 100644
--- a/rs/java/android/renderscript/RenderScriptGL.java
+++ b/rs/java/android/renderscript/RenderScriptGL.java
@@ -37,6 +37,7 @@
* <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
**/
+@Deprecated
public class RenderScriptGL extends RenderScript {
int mWidth;
int mHeight;
diff --git a/rs/java/android/renderscript/Sampler.java b/rs/java/android/renderscript/Sampler.java
index 70e88bc..06f036d 100644
--- a/rs/java/android/renderscript/Sampler.java
+++ b/rs/java/android/renderscript/Sampler.java
@@ -25,7 +25,12 @@
* android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE}; using a Sampler on
* an {@link android.renderscript.Allocation} that was not created with {@link
* android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE} is undefined.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Sampler extends BaseObj {
public enum Value {
NEAREST (0),
diff --git a/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java
index d1d3a76..f32a2f7 100644
--- a/rs/java/android/renderscript/Script.java
+++ b/rs/java/android/renderscript/Script.java
@@ -22,7 +22,12 @@
/**
* The parent class for all executable scripts. This should not be used by
* applications.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Script extends BaseObj {
/**
diff --git a/rs/java/android/renderscript/ScriptC.java b/rs/java/android/renderscript/ScriptC.java
index 00ebe57..1866a99 100644
--- a/rs/java/android/renderscript/ScriptC.java
+++ b/rs/java/android/renderscript/ScriptC.java
@@ -25,7 +25,12 @@
/**
* The superclass for all user-defined scripts. This is only
* intended to be used by the generated derived classes.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class ScriptC extends Script {
private static final String TAG = "ScriptC";
diff --git a/rs/java/android/renderscript/ScriptGroup.java b/rs/java/android/renderscript/ScriptGroup.java
index e0bdbfc..5cdb9cf 100644
--- a/rs/java/android/renderscript/ScriptGroup.java
+++ b/rs/java/android/renderscript/ScriptGroup.java
@@ -37,7 +37,12 @@
* Grouping kernels together allows for more efficient execution. For example,
* runtime and compiler optimization can be applied to reduce computation and
* communication overhead, and to make better use of the CPU and the GPU.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptGroup extends BaseObj {
private static final String TAG = "ScriptGroup";
IO mOutputs[];
diff --git a/rs/java/android/renderscript/ScriptIntrinsic.java b/rs/java/android/renderscript/ScriptIntrinsic.java
index 61211a2..8d65422 100644
--- a/rs/java/android/renderscript/ScriptIntrinsic.java
+++ b/rs/java/android/renderscript/ScriptIntrinsic.java
@@ -23,7 +23,12 @@
* operations.
*
* Not intended for direct use.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public abstract class ScriptIntrinsic extends Script {
ScriptIntrinsic(long id, RenderScript rs) {
super(id, rs);
diff --git a/rs/java/android/renderscript/ScriptIntrinsic3DLUT.java b/rs/java/android/renderscript/ScriptIntrinsic3DLUT.java
index ce149d9..7a2847e 100644
--- a/rs/java/android/renderscript/ScriptIntrinsic3DLUT.java
+++ b/rs/java/android/renderscript/ScriptIntrinsic3DLUT.java
@@ -23,7 +23,11 @@
* allocation. The 8 nearest values are sampled and linearly interpolated. The
* result is placed in the output.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsic3DLUT extends ScriptIntrinsic {
private Allocation mLUT;
private Element mElement;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
index 49a71b4..16cc799 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
@@ -29,7 +29,11 @@
*
* For detailed description of BLAS, please refer to http://www.netlib.org/blas/
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsicBLAS extends ScriptIntrinsic {
private Allocation mLUT;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBlend.java b/rs/java/android/renderscript/ScriptIntrinsicBlend.java
index fdcd61b..a1c79ef 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBlend.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBlend.java
@@ -19,7 +19,12 @@
/**
* Intrinsic kernels for blending two {@link android.renderscript.Allocation} objects.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class ScriptIntrinsicBlend extends ScriptIntrinsic {
ScriptIntrinsicBlend(long id, RenderScript rs) {
super(id, rs);
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBlur.java b/rs/java/android/renderscript/ScriptIntrinsicBlur.java
index 0891d51..68cbc3f 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBlur.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBlur.java
@@ -20,8 +20,11 @@
* Intrinsic Gausian blur filter. Applies a gaussian blur of the
* specified radius to all elements of an allocation.
*
- *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsicBlur extends ScriptIntrinsic {
private final float[] mValues = new float[9];
private Allocation mInput;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java b/rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java
index e8a299c..4a05cf5 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java
@@ -36,7 +36,12 @@
* Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4},
* {@link Element#F32}, {@link Element#F32_2}, {@link
* Element#F32_3}, and {@link Element#F32_4}.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsicColorMatrix extends ScriptIntrinsic {
private final Matrix4f mMatrix = new Matrix4f();
private final Float4 mAdd = new Float4();
diff --git a/rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java b/rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
index 9fe7b2d..4b9dff1 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
@@ -19,7 +19,11 @@
/**
* Intrinsic for applying a 3x3 convolve to an allocation.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsicConvolve3x3 extends ScriptIntrinsic {
private final float[] mValues = new float[9];
private Allocation mInput;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java b/rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
index 8518bb2..ed93c7e 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
@@ -19,7 +19,11 @@
/**
* Intrinsic for applying a 5x5 convolve to an allocation.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsicConvolve5x5 extends ScriptIntrinsic {
private final float[] mValues = new float[25];
private Allocation mInput;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicHistogram.java b/rs/java/android/renderscript/ScriptIntrinsicHistogram.java
index 0e8b36c..4a71bc8 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicHistogram.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicHistogram.java
@@ -19,8 +19,11 @@
/**
* Intrinsic Histogram filter.
*
- *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsicHistogram extends ScriptIntrinsic {
private Allocation mOut;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicLUT.java b/rs/java/android/renderscript/ScriptIntrinsicLUT.java
index e90462d..7d5b09f 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicLUT.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicLUT.java
@@ -21,7 +21,12 @@
* channel of the input has an independant lookup table. The
* tables are 256 entries in size and can cover the full value
* range of {@link Element#U8_4}.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsicLUT extends ScriptIntrinsic {
private final Matrix4f mMatrix = new Matrix4f();
private Allocation mTables;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicResize.java b/rs/java/android/renderscript/ScriptIntrinsicResize.java
index 45b0a64..a87fe95 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicResize.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicResize.java
@@ -18,7 +18,12 @@
/**
* Intrinsic for performing a resize of a 2D allocation.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public final class ScriptIntrinsicResize extends ScriptIntrinsic {
private Allocation mInput;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicYuvToRGB.java b/rs/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
index e64c911..a94f916 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
@@ -23,7 +23,12 @@
* The input allocation should be supplied in a supported YUV format
* as a YUV element Allocation. The output is RGBA; the alpha channel
* will be set to 255.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public final class ScriptIntrinsicYuvToRGB extends ScriptIntrinsic {
private Allocation mInput;
diff --git a/rs/java/android/renderscript/Short2.java b/rs/java/android/renderscript/Short2.java
index 24809f7..4565eb4 100644
--- a/rs/java/android/renderscript/Short2.java
+++ b/rs/java/android/renderscript/Short2.java
@@ -22,7 +22,12 @@
*
* Vector version of the basic short type.
* Provides two short fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Short2 {
public short x;
public short y;
diff --git a/rs/java/android/renderscript/Short3.java b/rs/java/android/renderscript/Short3.java
index 661db0a..3d70f07 100644
--- a/rs/java/android/renderscript/Short3.java
+++ b/rs/java/android/renderscript/Short3.java
@@ -19,7 +19,12 @@
/**
* Vector version of the basic short type.
* Provides three short fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Short3 {
public short x;
public short y;
diff --git a/rs/java/android/renderscript/Short4.java b/rs/java/android/renderscript/Short4.java
index a2d74f2..c90d648 100644
--- a/rs/java/android/renderscript/Short4.java
+++ b/rs/java/android/renderscript/Short4.java
@@ -19,7 +19,12 @@
/**
* Vector version of the basic short type.
* Provides four short fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Short4 {
public short x;
public short y;
diff --git a/rs/java/android/renderscript/Type.java b/rs/java/android/renderscript/Type.java
index dc23785..021fd06 100644
--- a/rs/java/android/renderscript/Type.java
+++ b/rs/java/android/renderscript/Type.java
@@ -42,7 +42,12 @@
* <p>For more information about creating an application that uses RenderScript, read the
* <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Type extends BaseObj {
int mDimX;
int mDimY;
diff --git a/rs/jni/Android.mk b/rs/jni/Android.mk
index e41073b..0caba42 100644
--- a/rs/jni/Android.mk
+++ b/rs/jni/Android.mk
@@ -25,7 +25,7 @@
frameworks/rs
LOCAL_CFLAGS += -Wno-unused-parameter
-LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code -Wno-deprecated-declarations
LOCAL_MODULE:= librs_jni
LOCAL_LICENSE_KINDS:= SPDX-license-identifier-Apache-2.0
diff --git a/services/api/Android.bp b/services/api/Android.bp
index e69de29..b8ca548 100644
--- a/services/api/Android.bp
+++ b/services/api/Android.bp
@@ -0,0 +1,29 @@
+// 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 {
+ default_visibility: ["//visibility:private"],
+}
+
+filegroup {
+ name: "non-updatable-system-server-current.txt",
+ srcs: ["non-updatable-current.txt"],
+ visibility: ["//frameworks/base/api"],
+}
+
+filegroup {
+ name: "non-updatable-system-server-removed.txt",
+ srcs: ["non-updatable-removed.txt"],
+ visibility: ["//frameworks/base/api"],
+}
\ No newline at end of file
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 52237c9..4b56845 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -766,6 +766,7 @@
.get(association.getPackageName());
if (serviceConnector != null) {
serviceConnector.unbind();
+ restartBleScan();
}
}
}
@@ -1067,11 +1068,19 @@
}
void onDeviceDisconnected(String address) {
- Slog.d(LOG_TAG, "onDeviceConnected(address = " + address + ")");
+ Slog.d(LOG_TAG, "onDeviceDisconnected(address = " + address + ")");
mCurrentlyConnectedDevices.remove(address);
- onDeviceDisappeared(address);
+ Date lastSeen = mDevicesLastNearby.get(address);
+ if (isDeviceDisappeared(lastSeen)) {
+ onDeviceDisappeared(address);
+ }
+ }
+
+ private boolean isDeviceDisappeared(Date lastSeen) {
+ return lastSeen == null || System.currentTimeMillis() - lastSeen.getTime()
+ >= DEVICE_DISAPPEARED_UNBIND_TIMEOUT_MS;
}
private ServiceConnector<ICompanionDeviceService> getDeviceListenerServiceConnector(
@@ -1172,8 +1181,7 @@
String address = mDevicesLastNearby.keyAt(i);
Date lastNearby = mDevicesLastNearby.valueAt(i);
- if (System.currentTimeMillis() - lastNearby.getTime()
- >= DEVICE_DISAPPEARED_UNBIND_TIMEOUT_MS) {
+ if (isDeviceDisappeared(lastNearby)) {
for (Association association : getAllAssociations(address)) {
if (association.isNotifyOnDeviceNearby()) {
getDeviceListenerServiceConnector(association).unbind();
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 8ccfad6..0eb7daf 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -223,6 +223,7 @@
"java/com/android/server/TestNetworkService.java",
"java/com/android/server/connectivity/AutodestructReference.java",
"java/com/android/server/connectivity/ConnectivityConstants.java",
+ "java/com/android/server/connectivity/ConnectivityResources.java",
"java/com/android/server/connectivity/DnsManager.java",
"java/com/android/server/connectivity/KeepaliveTracker.java",
"java/com/android/server/connectivity/LingerMonitor.java",
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 07b473c..72d32636 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -175,6 +175,7 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.sysprop.NetworkProperties;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -186,10 +187,8 @@
import android.util.SparseIntArray;
import com.android.connectivity.aidl.INetworkAgent;
-import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.IBatteryStats;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.LocationPermissionChecker;
@@ -201,8 +200,8 @@
import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
import com.android.net.module.util.NetworkCapabilitiesUtils;
import com.android.net.module.util.PermissionUtils;
-import com.android.server.am.BatteryStatsService;
import com.android.server.connectivity.AutodestructReference;
+import com.android.server.connectivity.ConnectivityResources;
import com.android.server.connectivity.DnsManager;
import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
import com.android.server.connectivity.KeepaliveTracker;
@@ -217,7 +216,6 @@
import com.android.server.connectivity.ProxyTracker;
import com.android.server.connectivity.QosCallbackTracker;
import com.android.server.net.NetworkPolicyManagerInternal;
-import com.android.server.utils.PriorityDump;
import libcore.io.IoUtils;
@@ -319,6 +317,7 @@
private boolean mRestrictBackground;
private final Context mContext;
+ private final ConnectivityResources mResources;
// The Context is created for UserHandle.ALL.
private final Context mUserAllContext;
private final Dependencies mDeps;
@@ -607,7 +606,6 @@
private Intent mInitialBroadcast;
private PowerManager.WakeLock mNetTransitionWakeLock;
- private int mNetTransitionWakeLockTimeout;
private final PowerManager.WakeLock mPendingIntentWakeLock;
// A helper object to track the current default HTTP proxy. ConnectivityService needs to tell
@@ -884,27 +882,59 @@
}
private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this);
+ final LocalPriorityDump mPriorityDumper = new LocalPriorityDump();
/**
* Helper class which parses out priority arguments and dumps sections according to their
* priority. If priority arguments are omitted, function calls the legacy dump command.
*/
- private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
- @Override
- public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
- doDump(fd, pw, new String[] {DIAG_ARG}, asProto);
- doDump(fd, pw, new String[] {SHORT_ARG}, asProto);
+ private class LocalPriorityDump {
+ private static final String PRIORITY_ARG = "--dump-priority";
+ private static final String PRIORITY_ARG_HIGH = "HIGH";
+ private static final String PRIORITY_ARG_NORMAL = "NORMAL";
+
+ LocalPriorityDump() {}
+
+ private void dumpHigh(FileDescriptor fd, PrintWriter pw) {
+ doDump(fd, pw, new String[] {DIAG_ARG});
+ doDump(fd, pw, new String[] {SHORT_ARG});
}
- @Override
- public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
- doDump(fd, pw, args, asProto);
+ private void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) {
+ doDump(fd, pw, args);
}
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
- doDump(fd, pw, args, asProto);
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (args == null) {
+ dumpNormal(fd, pw, args);
+ return;
+ }
+
+ String priority = null;
+ for (int argIndex = 0; argIndex < args.length; argIndex++) {
+ if (args[argIndex].equals(PRIORITY_ARG) && argIndex + 1 < args.length) {
+ argIndex++;
+ priority = args[argIndex];
+ }
+ }
+
+ if (PRIORITY_ARG_HIGH.equals(priority)) {
+ dumpHigh(fd, pw);
+ } else if (PRIORITY_ARG_NORMAL.equals(priority)) {
+ dumpNormal(fd, pw, args);
+ } else {
+ // ConnectivityService publishes binder service using publishBinderService() with
+ // no priority assigned will be treated as NORMAL priority. Dumpsys does not send
+ // "--dump-priority" arguments to the service. Thus, dump both NORMAL and HIGH to
+ // align the legacy design.
+ // TODO: Integrate into signal dump.
+ dumpNormal(fd, pw, args);
+ pw.println();
+ pw.println("DUMP OF SERVICE HIGH connectivity");
+ pw.println();
+ dumpHigh(fd, pw);
+ }
}
- };
+ }
/**
* Keeps track of the number of requests made under different uids.
@@ -983,6 +1013,13 @@
}
/**
+ * Get the {@link ConnectivityResources} to use in ConnectivityService.
+ */
+ public ConnectivityResources getResources(@NonNull Context ctx) {
+ return new ConnectivityResources(ctx);
+ }
+
+ /**
* Create a HandlerThread to use in ConnectivityService.
*/
public HandlerThread makeHandlerThread() {
@@ -1035,19 +1072,19 @@
return new MultinetworkPolicyTracker(c, h, r);
}
- public IBatteryStats getBatteryStatsService() {
- return BatteryStatsService.getService();
- }
-
/**
* @see BatteryStatsManager
*/
public void reportNetworkInterfaceForTransports(Context context, String iface,
int[] transportTypes) {
- final BatteryStatsManager batteryStats =
+ final BatteryStatsManager batteryStats =
context.getSystemService(BatteryStatsManager.class);
batteryStats.reportNetworkInterfaceForTransports(iface, transportTypes);
}
+
+ public boolean getCellular464XlatEnabled() {
+ return NetworkProperties.isCellular464XlatEnabled().orElse(true);
+ }
}
public ConnectivityService(Context context) {
@@ -1064,6 +1101,7 @@
mSystemProperties = mDeps.getSystemProperties();
mNetIdManager = mDeps.makeNetIdManager();
mContext = Objects.requireNonNull(context, "missing Context");
+ mResources = deps.getResources(mContext);
mNetworkRequestCounter = new PerUidCounter(MAX_NETWORK_REQUESTS_PER_UID);
mMetricsLog = logger;
@@ -1124,8 +1162,6 @@
final PowerManager powerManager = (PowerManager) context.getSystemService(
Context.POWER_SERVICE);
mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
- mNetTransitionWakeLockTimeout = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_networkTransitionTimeout);
mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];
@@ -1192,10 +1228,6 @@
}
}
- mWolSupportedInterfaces = new ArraySet(
- mContext.getResources().getStringArray(
- com.android.internal.R.array.config_wakeonlan_supported_interfaces));
-
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
@@ -1246,8 +1278,7 @@
new NetworkInfo(TYPE_NONE, 0, "", ""),
new LinkProperties(), new NetworkCapabilities(), 0, mContext,
null, new NetworkAgentConfig(), this, null,
- null, 0, INVALID_UID,
- mQosCallbackTracker);
+ null, 0, INVALID_UID, mQosCallbackTracker, mDeps);
}
private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
@@ -1489,11 +1520,11 @@
// but only exists if an app asks about them or requests them. Ensure the requesting app
// gets the type it asks for.
filtered.setType(type);
- final DetailedState state = isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)
- ? DetailedState.BLOCKED
- : filtered.getDetailedState();
- filtered.setDetailedState(getLegacyLockdownState(state),
- "" /* reason */, null /* extraInfo */);
+ if (isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)) {
+ filtered.setDetailedState(DetailedState.BLOCKED, null /* reason */,
+ null /* extraInfo */);
+ }
+ filterForLegacyLockdown(filtered);
return filtered;
}
@@ -1569,8 +1600,8 @@
final DetailedState state = isNetworkWithCapabilitiesBlocked(nc, uid, false)
? DetailedState.BLOCKED
: DetailedState.DISCONNECTED;
- info.setDetailedState(getLegacyLockdownState(state),
- "" /* reason */, null /* extraInfo */);
+ info.setDetailedState(state, null /* reason */, null /* extraInfo */);
+ filterForLegacyLockdown(info);
return info;
}
@@ -2364,9 +2395,7 @@
mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService");
}
- // Public because it's used by mLockdownTracker.
- public void sendConnectedBroadcast(NetworkInfo info) {
- PermissionUtils.enforceNetworkStackPermission(mContext);
+ private void sendConnectedBroadcast(NetworkInfo info) {
sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
}
@@ -2603,7 +2632,7 @@
@Override
protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
@Nullable String[] args) {
- PriorityDump.dump(mPriorityDumper, fd, writer, args);
+ mPriorityDumper.dump(fd, writer, args);
}
private boolean checkDumpPermission(Context context, String tag, PrintWriter pw) {
@@ -2618,10 +2647,9 @@
}
}
- private void doDump(FileDescriptor fd, PrintWriter writer, String[] args, boolean asProto) {
+ private void doDump(FileDescriptor fd, PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
if (!checkDumpPermission(mContext, TAG, pw)) return;
- if (asProto) return;
if (CollectionUtils.contains(args, DIAG_ARG)) {
dumpNetworkDiagnostics(pw);
@@ -4597,7 +4625,9 @@
}
mWakelockLogs.log("ACQUIRE for " + forWhom);
Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
- mHandler.sendMessageDelayed(msg, mNetTransitionWakeLockTimeout);
+ final int lockTimeout = mResources.get().getInteger(
+ com.android.connectivity.resources.R.integer.config_networkTransitionTimeout);
+ mHandler.sendMessageDelayed(msg, lockTimeout);
}
// Called when we gain a new default network to release the network transition wakelock in a
@@ -5012,8 +5042,8 @@
// The legacy lockdown VPN always uses the default network.
// If the VPN's underlying network is no longer the current default network, it means that
// the default network has just switched, and the VPN is about to disconnect.
- // Report that the VPN is not connected, so when the state of NetworkInfo objects
- // overwritten by getLegacyLockdownState will be set to CONNECTING and not CONNECTED.
+ // Report that the VPN is not connected, so the state of NetworkInfo objects overwritten
+ // by filterForLegacyLockdown will be set to CONNECTING and not CONNECTED.
final NetworkAgentInfo defaultNetwork = getDefaultNetwork();
if (defaultNetwork == null || !defaultNetwork.network.equals(underlying[0])) {
return null;
@@ -5022,6 +5052,9 @@
return nai;
};
+ // TODO: move all callers to filterForLegacyLockdown and delete this method.
+ // This likely requires making sendLegacyNetworkBroadcast take a NetworkInfo object instead of
+ // just a DetailedState object.
private DetailedState getLegacyLockdownState(DetailedState origState) {
if (origState != DetailedState.CONNECTED) {
return origState;
@@ -5031,6 +5064,23 @@
: DetailedState.CONNECTED;
}
+ private void filterForLegacyLockdown(NetworkInfo ni) {
+ if (!mLockdownEnabled || !ni.isConnected()) return;
+ // The legacy lockdown VPN replaces the state of every network in CONNECTED state with the
+ // state of its VPN. This is to ensure that when an underlying network connects, apps will
+ // not see a CONNECTIVITY_ACTION broadcast for a network in state CONNECTED until the VPN
+ // comes up, at which point there is a new CONNECTIVITY_ACTION broadcast for the underlying
+ // network, this time with a state of CONNECTED.
+ //
+ // Now that the legacy lockdown code lives in ConnectivityService, and no longer has access
+ // to the internal state of the Vpn object, always replace the state with CONNECTING. This
+ // is not too far off the truth, since an always-on VPN, when not connected, is always
+ // trying to reconnect.
+ if (getLegacyLockdownNai() == null) {
+ ni.setDetailedState(DetailedState.CONNECTING, "", null);
+ }
+ }
+
@Override
public void setProvisioningNotificationVisible(boolean visible, int networkType,
String action) {
@@ -5501,6 +5551,8 @@
// request if the app changes network state. http://b/29964605
enforceMeteredApnPolicy(networkCapabilities);
break;
+ case TRACK_BEST:
+ throw new UnsupportedOperationException("Not implemented yet");
default:
throw new IllegalArgumentException("Unsupported request type " + reqType);
}
@@ -6106,7 +6158,7 @@
final NetworkAgentInfo nai = new NetworkAgentInfo(na,
new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
- this, mNetd, mDnsResolver, providerId, uid, mQosCallbackTracker);
+ this, mNetd, mDnsResolver, providerId, uid, mQosCallbackTracker, mDeps);
// Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
processCapabilitiesFromAgent(nai, nc);
@@ -6472,6 +6524,11 @@
}
private void updateWakeOnLan(@NonNull LinkProperties lp) {
+ if (mWolSupportedInterfaces == null) {
+ mWolSupportedInterfaces = new ArraySet<>(mResources.get().getStringArray(
+ com.android.connectivity.resources.R.array
+ .config_wakeonlan_supported_interfaces));
+ }
lp.setWakeOnLanSupported(mWolSupportedInterfaces.contains(lp.getInterfaceName()));
}
@@ -7914,6 +7971,7 @@
// and is still connected.
NetworkInfo info = new NetworkInfo(nai.networkInfo);
info.setType(type);
+ filterForLegacyLockdown(info);
if (state != DetailedState.DISCONNECTED) {
info.setDetailedState(state, null, info.getExtraInfo());
sendConnectedBroadcast(info);
@@ -8028,8 +8086,8 @@
@Override
public String getCaptivePortalServerUrl() {
enforceNetworkStackOrSettingsPermission();
- String settingUrl = mContext.getResources().getString(
- R.string.config_networkCaptivePortalServerUrl);
+ String settingUrl = mResources.get().getString(
+ com.android.connectivity.resources.R.string.config_networkCaptivePortalServerUrl);
if (!TextUtils.isEmpty(settingUrl)) {
return settingUrl;
diff --git a/services/core/java/com/android/server/ConnectivityServiceInitializer.java b/services/core/java/com/android/server/ConnectivityServiceInitializer.java
index b992208..2465479 100644
--- a/services/core/java/com/android/server/ConnectivityServiceInitializer.java
+++ b/services/core/java/com/android/server/ConnectivityServiceInitializer.java
@@ -16,9 +16,6 @@
package com.android.server;
-import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
-import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
-
import android.content.Context;
import android.util.Log;
@@ -42,6 +39,6 @@
public void onStart() {
Log.i(TAG, "Registering " + Context.CONNECTIVITY_SERVICE);
publishBinderService(Context.CONNECTIVITY_SERVICE, mConnectivity,
- /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
+ /* allowIsolated= */ false);
}
}
diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java
index f2782f6..18d47c6 100644
--- a/services/core/java/com/android/server/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/SensorPrivacyService.java
@@ -51,6 +51,7 @@
import android.hardware.ISensorPrivacyListener;
import android.hardware.ISensorPrivacyManager;
import android.hardware.SensorPrivacyManager;
+import android.hardware.SensorPrivacyManagerInternal;
import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
@@ -67,6 +68,7 @@
import android.service.SensorPrivacyUserProto;
import android.text.Html;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.IndentingPrintWriter;
import android.util.Log;
@@ -80,6 +82,7 @@
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.BackgroundThread;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FunctionalUtils;
import com.android.internal.util.XmlUtils;
@@ -137,6 +140,8 @@
private final ActivityManager mActivityManager;
private final ActivityTaskManager mActivityTaskManager;
+ private SensorPrivacyManagerInternalImpl mSensorPrivacyManagerInternal;
+
public SensorPrivacyService(Context context) {
super(context);
mUserManagerInternal = getLocalService(UserManagerInternal.class);
@@ -148,6 +153,9 @@
@Override
public void onStart() {
publishBinderService(Context.SENSOR_PRIVACY_SERVICE, mSensorPrivacyServiceImpl);
+ mSensorPrivacyManagerInternal = new SensorPrivacyManagerInternalImpl();
+ publishLocalService(SensorPrivacyManagerInternal.class,
+ mSensorPrivacyManagerInternal);
}
class SensorPrivacyServiceImpl extends ISensorPrivacyManager.Stub implements
@@ -1108,6 +1116,7 @@
}
public void handleSensorPrivacyChanged(int userId, int sensor, boolean enabled) {
+ mSensorPrivacyManagerInternal.dispatch(userId, sensor, enabled);
SparseArray<RemoteCallbackList<ISensorPrivacyListener>> listenersForUser =
mIndividualSensorListeners.get(userId);
if (listenersForUser == null) {
@@ -1168,4 +1177,87 @@
c.accept(userIds[i]);
}
}
+
+ private class SensorPrivacyManagerInternalImpl extends SensorPrivacyManagerInternal {
+
+ private ArrayMap<Integer, ArrayMap<Integer, ArraySet<OnSensorPrivacyChangedListener>>>
+ mListeners = new ArrayMap<>();
+ private ArrayMap<Integer, ArraySet<OnUserSensorPrivacyChangedListener>> mAllUserListeners =
+ new ArrayMap<>();
+
+ private final Object mLock = new Object();
+
+ private void dispatch(int userId, int sensor, boolean enabled) {
+ synchronized (mLock) {
+ ArraySet<OnUserSensorPrivacyChangedListener> allUserSensorListeners =
+ mAllUserListeners.get(sensor);
+ if (allUserSensorListeners != null) {
+ for (int i = 0; i < allUserSensorListeners.size(); i++) {
+ OnUserSensorPrivacyChangedListener listener =
+ allUserSensorListeners.valueAt(i);
+ BackgroundThread.getHandler().post(() ->
+ listener.onSensorPrivacyChanged(userId, enabled));
+ }
+ }
+
+ ArrayMap<Integer, ArraySet<OnSensorPrivacyChangedListener>> userSensorListeners =
+ mListeners.get(userId);
+ if (userSensorListeners != null) {
+ ArraySet<OnSensorPrivacyChangedListener> sensorListeners =
+ userSensorListeners.get(sensor);
+ if (sensorListeners != null) {
+ for (int i = 0; i < sensorListeners.size(); i++) {
+ OnSensorPrivacyChangedListener listener = sensorListeners.valueAt(i);
+ BackgroundThread.getHandler().post(() ->
+ listener.onSensorPrivacyChanged(enabled));
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean isSensorPrivacyEnabled(int userId, int sensor) {
+ return SensorPrivacyService.this
+ .mSensorPrivacyServiceImpl.isIndividualSensorPrivacyEnabled(userId, sensor);
+ }
+
+ @Override
+ public void addSensorPrivacyListener(int userId, int sensor,
+ OnSensorPrivacyChangedListener listener) {
+ synchronized (mLock) {
+ ArrayMap<Integer, ArraySet<OnSensorPrivacyChangedListener>> userSensorListeners =
+ mListeners.get(userId);
+ if (userSensorListeners == null) {
+ userSensorListeners = new ArrayMap<>();
+ mListeners.put(userId, userSensorListeners);
+ }
+
+ ArraySet<OnSensorPrivacyChangedListener> sensorListeners =
+ userSensorListeners.get(sensor);
+ if (sensorListeners == null) {
+ sensorListeners = new ArraySet<>();
+ userSensorListeners.put(sensor, sensorListeners);
+ }
+
+ sensorListeners.add(listener);
+ }
+ }
+
+ @Override
+ public void addSensorPrivacyListenerForAllUsers(int sensor,
+ OnUserSensorPrivacyChangedListener listener) {
+ synchronized (mLock) {
+ ArraySet<OnUserSensorPrivacyChangedListener> sensorListeners =
+ mAllUserListeners.get(sensor);
+ if (sensorListeners == null) {
+ sensorListeners = new ArraySet<>();
+ mAllUserListeners.put(sensor, sensorListeners);
+ }
+
+ sensorListeners.add(listener);
+ }
+ }
+ }
+
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 27b648e..740a1c1 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -4553,6 +4553,13 @@
private final List<StorageManagerInternal.ResetListener> mResetListeners =
new ArrayList<>();
+ @Override
+ public boolean isFuseMounted(int userId) {
+ synchronized (mLock) {
+ return mFuseMountedUser.contains(userId);
+ }
+ }
+
/**
* Check if fuse is running in target user, if it's running then setup its storage dirs.
* Return true if storage dirs are mounted.
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index 95af842..a09dbc7 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -21,7 +21,9 @@
}
],
"file_patterns": ["NotificationManagerService\\.java"]
- },
+ }
+ ],
+ "presubmit-large": [
{
"name": "CtsScopedStorageCoreHostTest",
"file_patterns": ["StorageManagerService\\.java"]
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 978bd64..a9904ba 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -964,10 +964,17 @@
remove(r.binder);
}
}
+ if (events.contains(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)) {
+ try {
+ r.callback.onLegacyCallStateChanged(mCallState[phoneId],
+ getCallIncomingNumber(r, phoneId));
+ } catch (RemoteException ex) {
+ remove(r.binder);
+ }
+ }
if (events.contains(TelephonyCallback.EVENT_CALL_STATE_CHANGED)) {
try {
- r.callback.onCallStateChanged(mCallState[phoneId],
- getCallIncomingNumber(r, phoneId));
+ r.callback.onCallStateChanged(mCallState[phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
@@ -1306,13 +1313,24 @@
synchronized (mRecords) {
for (Record r : mRecords) {
- if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED)
+ if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)
&& (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
try {
// Ensure the listener has read call log permission; if they do not return
// an empty phone number.
+ // This is ONLY for legacy onCallStateChanged in PhoneStateListener.
String phoneNumberOrEmpty = r.canReadCallLog() ? phoneNumber : "";
- r.callback.onCallStateChanged(state, phoneNumberOrEmpty);
+ r.callback.onLegacyCallStateChanged(state, phoneNumberOrEmpty);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
+
+ if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED)
+ && (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
+ try {
+ // The new callback does NOT provide the phone number.
+ r.callback.onCallStateChanged(state);
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
@@ -1341,12 +1359,25 @@
mCallState[phoneId] = state;
mCallIncomingNumber[phoneId] = incomingNumber;
for (Record r : mRecords) {
+ if (r.matchTelephonyCallbackEvent(
+ TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)
+ && (r.subId == subId)
+ && (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
+ try {
+ // Only the legacy PhoneStateListener receives the phone number.
+ String incomingNumberOrEmpty = getCallIncomingNumber(r, phoneId);
+ r.callback.onLegacyCallStateChanged(state, incomingNumberOrEmpty);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED)
&& (r.subId == subId)
&& (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
try {
- String incomingNumberOrEmpty = getCallIncomingNumber(r, phoneId);
- r.callback.onCallStateChanged(state, incomingNumberOrEmpty);
+ // The phone number is not included in the new call state changed
+ // listener.
+ r.callback.onCallStateChanged(state);
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index f768db1..68c4a73 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -20,7 +20,6 @@
import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND;
import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
import static android.app.ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
-import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT;
import static android.app.ActivityManager.PROCESS_STATE_RECEIVER;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -75,7 +74,6 @@
import android.app.ActivityThread;
import android.app.AppGlobals;
import android.app.AppOpsManager;
-import android.app.BroadcastOptions;
import android.app.ForegroundServiceStartNotAllowedException;
import android.app.IApplicationThread;
import android.app.IServiceConnection;
@@ -1217,7 +1215,18 @@
void killMisbehavingService(ServiceRecord r,
int appUid, int appPid, String localPackageName) {
synchronized (mAm) {
- stopServiceLocked(r, false);
+ if (!r.destroying) {
+ // This service is still alive, stop it.
+ stopServiceLocked(r, false);
+ } else {
+ // Check if there is another instance of it being started in parallel,
+ // if so, stop that too to avoid spamming the system.
+ final ServiceMap smap = getServiceMapLocked(r.userId);
+ final ServiceRecord found = smap.mServicesByInstanceName.remove(r.instanceName);
+ if (found != null) {
+ stopServiceLocked(found, false);
+ }
+ }
mAm.crashApplication(appUid, appPid, localPackageName, -1,
"Bad notification for startForeground", true /*force*/);
}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 38330fe..ed8d696 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2315,11 +2315,12 @@
StorageManagerInternal storageManagerInternal = LocalServices.getService(
StorageManagerInternal.class);
if (needsStorageDataIsolation(storageManagerInternal, app)) {
- bindMountAppStorageDirs = true;
- if (pkgDataInfoMap == null ||
- !storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(),
- app.processName)) {
- // Cannot prepare Android/app and Android/obb directory or inode == 0,
+ // We will run prepareStorageDirs() after we trigger zygote fork, so it won't
+ // slow down app starting speed as those dirs might not be cached.
+ if (pkgDataInfoMap != null && storageManagerInternal.isFuseMounted(userId)) {
+ bindMountAppStorageDirs = true;
+ } else {
+ // Fuse is not mounted or inode == 0,
// so we won't mount it in zygote, but resume the mount after unlocking device.
app.setBindMountPending(true);
bindMountAppStorageDirs = false;
@@ -2367,6 +2368,13 @@
allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
}
+ // This runs after Process.start() as this method may block app process starting time
+ // if dir is not cached. Running this method after Process.start() can make it
+ // cache the dir asynchronously, so zygote can use it without waiting for it.
+ if (bindMountAppStorageDirs) {
+ storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(),
+ app.processName);
+ }
checkSlow(startTime, "startProcess: returned from zygote!");
return startResult;
} finally {
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index caf2510..ec2020f 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -122,7 +122,6 @@
import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Consumer;
/**
* Helper class for {@link ActivityManagerService} responsible for multi-user functionality.
@@ -518,18 +517,12 @@
if (!mInjector.getUserManager().isPreCreated(userId)) {
mHandler.sendMessage(mHandler.obtainMessage(REPORT_LOCKED_BOOT_COMPLETE_MSG,
userId, 0));
- Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
- intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
- intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
- | Intent.FLAG_RECEIVER_OFFLOAD
- | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- mInjector.broadcastIntent(intent, null, resultTo, 0, null, null,
- new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
- AppOpsManager.OP_NONE,
- getTemporaryAppAllowlistBroadcastOptions(REASON_LOCKED_BOOT_COMPLETED)
- .toBundle(), true,
- false, MY_PID, SYSTEM_UID,
- Binder.getCallingUid(), Binder.getCallingPid(), userId);
+ // In case of headless system user mode, do not send boot complete broadcast for
+ // system user as it is sent by sendBootCompleted call.
+ if (!(UserManager.isHeadlessSystemUserMode() && uss.mHandle.isSystem())) {
+ // ACTION_LOCKED_BOOT_COMPLETED
+ sendLockedBootCompletedBroadcast(resultTo, userId);
+ }
}
}
@@ -552,6 +545,21 @@
}
}
+ private void sendLockedBootCompletedBroadcast(IIntentReceiver receiver, @UserIdInt int userId) {
+ final Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+ intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
+ | Intent.FLAG_RECEIVER_OFFLOAD
+ | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ mInjector.broadcastIntent(intent, null, receiver, 0, null, null,
+ new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
+ AppOpsManager.OP_NONE,
+ getTemporaryAppAllowlistBroadcastOptions(REASON_LOCKED_BOOT_COMPLETED)
+ .toBundle(), true,
+ false, MY_PID, SYSTEM_UID,
+ Binder.getCallingUid(), Binder.getCallingPid(), userId);
+ }
+
/**
* Step from {@link UserState#STATE_RUNNING_LOCKED} to
* {@link UserState#STATE_RUNNING_UNLOCKING}.
@@ -2167,26 +2175,22 @@
}
void sendBootCompleted(IIntentReceiver resultTo) {
- final boolean systemUserFinishedBooting;
-
// Get a copy of mStartedUsers to use outside of lock
SparseArray<UserState> startedUsers;
synchronized (mLock) {
- systemUserFinishedBooting = mCurrentUserId != UserHandle.USER_SYSTEM;
startedUsers = mStartedUsers.clone();
}
for (int i = 0; i < startedUsers.size(); i++) {
UserState uss = startedUsers.valueAt(i);
- if (systemUserFinishedBooting && uss.mHandle.isSystem()) {
- // On Automotive, at this point the system user has already been started and
- // unlocked, and some of the tasks we do here have already been done. So skip those
- // in that case.
- // TODO(b/132262830): this workdound shouldn't be necessary once we move the
- // headless-user start logic to UserManager-land
- Slog.d(TAG, "sendBootCompleted(): skipping on non-current system user");
- continue;
+ if (!UserManager.isHeadlessSystemUserMode()) {
+ finishUserBoot(uss, resultTo);
+ } else if (uss.mHandle.isSystem()) {
+ // In case of headless system user mode, send only locked boot complete broadcast
+ // for system user since finishUserBoot call will be made using other code path;
+ // for non-system user, do nothing since finishUserBoot will be called elsewhere.
+ sendLockedBootCompletedBroadcast(resultTo, uss.mHandle.getIdentifier());
+ return;
}
- finishUserBoot(uss, resultTo);
}
}
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index 050b28b..285f318 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -406,26 +406,49 @@
mBiometricService.getCurrentModality(
opPackageName, userId, callingUserId, authenticators);
+ final boolean isCredentialAllowed = Utils.isCredentialRequested(authenticators);
+
final String result;
switch (getCredentialBackupModality(modality)) {
case BiometricAuthenticator.TYPE_NONE:
result = null;
break;
+
case BiometricAuthenticator.TYPE_CREDENTIAL:
result = getContext().getString(
R.string.screen_lock_dialog_default_subtitle);
break;
+
case BiometricAuthenticator.TYPE_FINGERPRINT:
- result = getContext().getString(
- R.string.fingerprint_dialog_default_subtitle);
+ if (isCredentialAllowed) {
+ result = getContext().getString(
+ R.string.fingerprint_or_screen_lock_dialog_default_subtitle);
+ } else {
+ result = getContext().getString(
+ R.string.fingerprint_dialog_default_subtitle);
+ }
break;
+
case BiometricAuthenticator.TYPE_FACE:
- result = getContext().getString(R.string.face_dialog_default_subtitle);
+ if (isCredentialAllowed) {
+ result = getContext().getString(
+ R.string.face_or_screen_lock_dialog_default_subtitle);
+ } else {
+ result = getContext().getString(R.string.face_dialog_default_subtitle);
+ }
break;
+
default:
- result = getContext().getString(R.string.biometric_dialog_default_subtitle);
+ if (isCredentialAllowed) {
+ result = getContext().getString(
+ R.string.biometric_or_screen_lock_dialog_default_subtitle);
+ } else {
+ result = getContext().getString(
+ R.string.biometric_dialog_default_subtitle);
+ }
break;
}
+
return result;
} finally {
Binder.restoreCallingIdentity(identity);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java
index b4c9b29..4ca85d0 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java
@@ -139,8 +139,4 @@
}
};
}
-
- @Override
- public void reset() {
- }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java
index 8547a68..0b7f3ab 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java
@@ -140,9 +140,5 @@
}
};
}
-
- @Override
- public void reset() {
- }
}
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index 5020917..e0d1375 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -57,6 +57,7 @@
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.view.autofill.AutofillManagerInternal;
import android.widget.Toast;
@@ -274,6 +275,9 @@
/** Package of the app that set {@link #primaryClip}. */
String mPrimaryClipPackage;
+ /** Uids that have already triggered a toast notification for {@link #primaryClip} */
+ final SparseBooleanArray mNotifiedUids = new SparseBooleanArray();
+
final HashSet<String> activePermissionOwners
= new HashSet<String>();
@@ -649,6 +653,7 @@
return;
}
clipboard.primaryClip = clip;
+ clipboard.mNotifiedUids.clear();
if (clip != null) {
clipboard.primaryClipUid = uid;
clipboard.mPrimaryClipPackage = sourcePackage;
@@ -939,6 +944,11 @@
&& mAutofillInternal.isAugmentedAutofillServiceForUser(uid, userId)) {
return;
}
+ // Don't notify if already notified for this uid and clip.
+ if (clipboard.mNotifiedUids.get(uid)) {
+ return;
+ }
+ clipboard.mNotifiedUids.put(uid, true);
// Retrieve the app label of the source of the clip data
CharSequence sourceAppLabel = null;
diff --git a/services/core/java/com/android/server/connectivity/ConnectivityResources.java b/services/core/java/com/android/server/connectivity/ConnectivityResources.java
new file mode 100644
index 0000000..45cf21e
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/ConnectivityResources.java
@@ -0,0 +1,83 @@
+/*
+ * 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.connectivity;
+
+import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.util.Log;
+
+import com.android.server.ConnectivityService;
+
+import java.util.List;
+
+/**
+ * Utility to obtain the {@link ConnectivityService} {@link Resources}, in the
+ * ServiceConnectivityResources APK.
+ */
+public class ConnectivityResources {
+ private static final String RESOURCES_APK_INTENT =
+ "com.android.server.connectivity.intent.action.SERVICE_CONNECTIVITY_RESOURCES_APK";
+ private static final String RES_PKG_DIR = "/apex/com.android.tethering/";
+
+ @NonNull
+ private final Context mContext;
+
+ @Nullable
+ private Resources mResources = null;
+
+ public ConnectivityResources(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Get the {@link Resources} of the ServiceConnectivityResources APK.
+ */
+ public synchronized Resources get() {
+ if (mResources != null) {
+ return mResources;
+ }
+
+ final List<ResolveInfo> pkgs = mContext.getPackageManager()
+ .queryIntentActivities(new Intent(RESOURCES_APK_INTENT), MATCH_SYSTEM_ONLY);
+ pkgs.removeIf(pkg -> !pkg.activityInfo.applicationInfo.sourceDir.startsWith(RES_PKG_DIR));
+ if (pkgs.size() > 1) {
+ Log.wtf(ConnectivityResources.class.getSimpleName(),
+ "More than one package found: " + pkgs);
+ }
+ if (pkgs.isEmpty()) {
+ throw new IllegalStateException("No connectivity resource package found");
+ }
+
+ final Context pkgContext;
+ try {
+ pkgContext = mContext.createPackageContext(
+ pkgs.get(0).activityInfo.applicationInfo.packageName, 0 /* flags */);
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new IllegalStateException("Resolved package not found", e);
+ }
+
+ mResources = pkgContext.getResources();
+ return mResources;
+ }
+}
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index fa80b25..c66a280 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -16,6 +16,8 @@
package com.android.server.connectivity;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+
import static com.android.net.module.util.CollectionUtils.contains;
import android.annotation.NonNull;
@@ -35,6 +37,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.net.module.util.NetworkStackConstants;
+import com.android.server.ConnectivityService;
import java.net.Inet6Address;
import java.util.Objects;
@@ -94,12 +97,15 @@
private Inet6Address mIPv6Address;
private State mState = State.IDLE;
+ private boolean mEnableClatOnCellular;
private boolean mPrefixDiscoveryRunning;
- public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver) {
+ public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver,
+ ConnectivityService.Dependencies deps) {
mDnsResolver = dnsResolver;
mNetd = netd;
mNetwork = nai;
+ mEnableClatOnCellular = deps.getCellular464XlatEnabled();
}
/**
@@ -111,7 +117,7 @@
* @return true if the network requires clat, false otherwise.
*/
@VisibleForTesting
- protected static boolean requiresClat(NetworkAgentInfo nai) {
+ protected boolean requiresClat(NetworkAgentInfo nai) {
// TODO: migrate to NetworkCapabilities.TRANSPORT_*.
final boolean supported = contains(NETWORK_TYPES, nai.networkInfo.getType());
final boolean connected = contains(NETWORK_STATES, nai.networkInfo.getState());
@@ -126,7 +132,9 @@
final boolean skip464xlat = (nai.netAgentConfig() != null)
&& nai.netAgentConfig().skip464xlat;
- return supported && connected && isIpv6OnlyNetwork && !skip464xlat;
+ return supported && connected && isIpv6OnlyNetwork && !skip464xlat
+ && (nai.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)
+ ? isCellular464XlatEnabled() : true);
}
/**
@@ -137,7 +145,7 @@
* @return true if the network should start clat, false otherwise.
*/
@VisibleForTesting
- protected static boolean shouldStartClat(NetworkAgentInfo nai) {
+ protected boolean shouldStartClat(NetworkAgentInfo nai) {
LinkProperties lp = nai.linkProperties;
return requiresClat(nai) && lp != null && lp.getNat64Prefix() != null;
}
@@ -507,4 +515,9 @@
protected int getNetId() {
return mNetwork.network.getNetId();
}
+
+ @VisibleForTesting
+ protected boolean isCellular464XlatEnabled() {
+ return mEnableClatOnCellular;
+ }
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 1d0e115..803cc9d 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -341,7 +341,7 @@
@NonNull LinkProperties lp, @NonNull NetworkCapabilities nc, int score, Context context,
Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd,
IDnsResolver dnsResolver, int factorySerialNumber, int creatorUid,
- QosCallbackTracker qosCallbackTracker) {
+ QosCallbackTracker qosCallbackTracker, ConnectivityService.Dependencies deps) {
Objects.requireNonNull(net);
Objects.requireNonNull(info);
Objects.requireNonNull(lp);
@@ -355,7 +355,7 @@
linkProperties = lp;
networkCapabilities = nc;
mScore = score;
- clatd = new Nat464Xlat(this, netd, dnsResolver);
+ clatd = new Nat464Xlat(this, netd, dnsResolver, deps);
mConnService = connService;
mContext = context;
mHandler = handler;
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index d6826be..fcfa674 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -357,7 +357,7 @@
for (int i = mDisplayGroups.size() - 1; i >= 0; i--) {
final int groupId = mDisplayGroups.keyAt(i);
final DisplayGroup group = mDisplayGroups.valueAt(i);
- final boolean wasPreviouslyUpdated = mUpdatedDisplayGroups.indexOfKey(groupId) < 0;
+ final boolean wasPreviouslyUpdated = mUpdatedDisplayGroups.indexOfKey(groupId) > -1;
final int changeCount = group.getChangeCountLocked();
if (group.isEmptyLocked()) {
diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
index d2baaf22..0ba191c 100644
--- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
@@ -91,6 +91,10 @@
private boolean mPendingStatusChangeBroadcast;
+ private static final String[] RECEIVER_PERMISSIONS_FOR_BROADCAST = {
+ android.Manifest.permission.ACCESS_FINE_LOCATION,
+ };
+
// Called with SyncRoot lock held.
public WifiDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
Context context, Handler handler, Listener listener,
@@ -432,7 +436,8 @@
}
// Send protected broadcast about wifi display status to registered receivers.
- getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
+ getContext().createContextAsUser(UserHandle.ALL, 0)
+ .sendBroadcastWithMultiplePermissions(intent, RECEIVER_PERMISSIONS_FOR_BROADCAST);
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
diff --git a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
index 900ec90..06adce8 100644
--- a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
+++ b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
@@ -37,11 +37,11 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.graphics.fonts.IFontManager;
+import com.android.internal.security.VerityUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.SystemService;
-import com.android.server.security.VerityUtils;
import java.io.File;
import java.io.FileDescriptor;
diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
index 02b09b1..73ecbe0 100644
--- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
+++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
@@ -20,6 +20,7 @@
import android.hardware.hdmi.IHdmiControlCallback;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
/**
* Feature action that performs one touch play against TV/Display device. This action is initiated
@@ -40,13 +41,15 @@
// standby mode, and do not accept the command until their power status becomes 'ON'.
// For a workaround, we send <Give Device Power Status> commands periodically to make sure
// the device switches its status to 'ON'. Then we send additional <Active Source>.
- private static final int STATE_WAITING_FOR_REPORT_POWER_STATUS = 1;
+ @VisibleForTesting
+ static final int STATE_WAITING_FOR_REPORT_POWER_STATUS = 1;
// The maximum number of times we send <Give Device Power Status> before we give up.
// We wait up to RESPONSE_TIMEOUT_MS * LOOP_COUNTER_MAX = 20 seconds.
private static final int LOOP_COUNTER_MAX = 10;
private final int mTargetAddress;
+ private final boolean mIsCec20;
private int mPowerStatusCounter = 0;
@@ -65,8 +68,19 @@
private OneTouchPlayAction(HdmiCecLocalDevice localDevice, int targetAddress,
IHdmiControlCallback callback) {
+ this(localDevice, targetAddress, callback,
+ localDevice.getDeviceInfo().getCecVersion()
+ >= HdmiControlManager.HDMI_CEC_VERSION_2_0
+ && localDevice.mService.getHdmiCecNetwork().getCecDeviceInfo(
+ targetAddress).getCecVersion() >= HdmiControlManager.HDMI_CEC_VERSION_2_0);
+ }
+
+ @VisibleForTesting
+ OneTouchPlayAction(HdmiCecLocalDevice localDevice, int targetAddress,
+ IHdmiControlCallback callback, boolean isCec20) {
super(localDevice, callback);
mTargetAddress = targetAddress;
+ mIsCec20 = isCec20;
}
@Override
@@ -74,6 +88,9 @@
// Because only source device can create this action, it's safe to cast.
mSource = source();
sendCommand(HdmiCecMessageBuilder.buildTextViewOn(getSourceAddress(), mTargetAddress));
+ boolean targetOnBefore = localDevice().mService.getHdmiCecNetwork()
+ .getCecDeviceInfo(mTargetAddress).getDevicePowerStatus()
+ == HdmiControlManager.POWER_STATUS_ON;
broadcastActiveSource();
// If the device is not an audio system itself, request the connected audio system to
// turn on.
@@ -81,7 +98,20 @@
sendCommand(HdmiCecMessageBuilder.buildSystemAudioModeRequest(getSourceAddress(),
Constants.ADDR_AUDIO_SYSTEM, getSourcePath(), true));
}
- queryDevicePowerStatus();
+ int targetPowerStatus = localDevice().mService.getHdmiCecNetwork()
+ .getCecDeviceInfo(mTargetAddress).getDevicePowerStatus();
+ if (!mIsCec20 || targetPowerStatus == HdmiControlManager.POWER_STATUS_UNKNOWN) {
+ queryDevicePowerStatus();
+ } else if (targetPowerStatus == HdmiControlManager.POWER_STATUS_ON) {
+ if (!targetOnBefore) {
+ // Suppress 2nd <Active Source> message if the target device was already on when
+ // the 1st one was sent.
+ broadcastActiveSource();
+ }
+ finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
+ return true;
+ }
+ mState = STATE_WAITING_FOR_REPORT_POWER_STATUS;
addTimer(mState, HdmiConfig.TIMEOUT_MS);
return true;
}
@@ -101,7 +131,6 @@
}
private void queryDevicePowerStatus() {
- mState = STATE_WAITING_FOR_REPORT_POWER_STATUS;
sendCommand(HdmiCecMessageBuilder.buildGiveDevicePowerStatus(getSourceAddress(),
mTargetAddress));
}
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
index f7e871d..56e538b 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
@@ -17,6 +17,8 @@
package com.android.server.hdmi;
import android.hardware.tv.cec.V1_0.SendMessageResult;
+
+import com.android.internal.annotations.VisibleForTesting;
import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
/**
@@ -30,6 +32,14 @@
// <Give System Audio Mode Status> to AV Receiver.
private static final int STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS = 1;
+ @VisibleForTesting
+ static final int RETRIES_ON_TIMEOUT = 1;
+
+ // On some audio devices the <System Audio Mode Status> message can be delayed as the device
+ // is just waking up. Retry the <Give System Audio Mode Status> message to ensure we properly
+ // initialize system audio.
+ private int mRetriesOnTimeOut = RETRIES_ON_TIMEOUT;
+
SystemAudioAutoInitiationAction(HdmiCecLocalDevice source, int avrAddress) {
super(source);
mAvrAddress = avrAddress;
@@ -100,6 +110,13 @@
switch (mState) {
case STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS:
+ if (mRetriesOnTimeOut > 0) {
+ mRetriesOnTimeOut--;
+ addTimer(mState, HdmiConfig.TIMEOUT_MS);
+ sendGiveSystemAudioModeStatus();
+ return;
+ }
+
handleSystemAudioModeStatusTimeout();
break;
}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index edb5d97..7dc9a0b 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -586,18 +586,13 @@
private void setDisplayViewportsInternal(List<DisplayViewport> viewports) {
final DisplayViewport[] vArray = new DisplayViewport[viewports.size()];
if (ENABLE_PER_WINDOW_INPUT_ROTATION) {
- // Remove all viewport operations. They will be built-into the window transforms.
+ // Remove display projection information from DisplayViewport, leaving only the
+ // orientation. The display projection will be built-into the window transforms.
for (int i = viewports.size() - 1; i >= 0; --i) {
final DisplayViewport v = vArray[i] = viewports.get(i).makeCopy();
- // deviceWidth/Height are apparently in "rotated" space, so flip them if needed.
- if (v.orientation % 2 != 0) {
- final int dw = v.deviceWidth;
- v.deviceWidth = v.deviceHeight;
- v.deviceHeight = dw;
- }
+ // Note: the deviceWidth/Height are in rotated with the orientation.
v.logicalFrame.set(0, 0, v.deviceWidth, v.deviceHeight);
v.physicalFrame.set(0, 0, v.deviceWidth, v.deviceHeight);
- v.orientation = 0;
}
} else {
for (int i = viewports.size() - 1; i >= 0; --i) {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 8285e32..a89cb55 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2621,8 +2621,9 @@
}
if (DEBUG) Slog.v(TAG, "Initiating attach with token: " + mCurToken);
// Dispatch display id for InputMethodService to update context display.
- executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOO(
- MSG_INITIALIZE_IME, mCurTokenDisplayId, mCurMethod, mCurToken));
+ executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOOO(
+ MSG_INITIALIZE_IME, mCurTokenDisplayId, mCurMethod, mCurToken,
+ mMethodMap.get(mCurMethodId).getConfigChanges()));
scheduleNotifyImeUidToAudioService(mCurMethodUid);
if (mCurClient != null) {
clearClientSessionLocked(mCurClient);
@@ -4478,7 +4479,8 @@
}
final IBinder token = (IBinder) args.arg2;
((IInputMethod) args.arg1).initializeInternal(token, msg.arg1,
- new InputMethodPrivilegedOperationsImpl(this, token));
+ new InputMethodPrivilegedOperationsImpl(this, token),
+ (int) args.arg3);
} catch (RemoteException e) {
}
args.recycle();
diff --git a/services/core/java/com/android/server/location/geofence/GeofenceManager.java b/services/core/java/com/android/server/location/geofence/GeofenceManager.java
index 5a90fa7..7f47805 100644
--- a/services/core/java/com/android/server/location/geofence/GeofenceManager.java
+++ b/services/core/java/com/android/server/location/geofence/GeofenceManager.java
@@ -370,6 +370,7 @@
LocationStatsEnums.USAGE_ENDED,
LocationStatsEnums.API_REQUEST_GEOFENCE,
registration.getIdentity().getPackageName(),
+ registration.getIdentity().getAttributionTag(),
null,
/* LocationRequest= */ null,
/* hasListener= */ false,
@@ -383,6 +384,7 @@
LocationStatsEnums.USAGE_ENDED,
LocationStatsEnums.API_REQUEST_GEOFENCE,
registration.getIdentity().getPackageName(),
+ registration.getIdentity().getAttributionTag(),
null,
/* LocationRequest= */ null,
/* hasListener= */ false,
diff --git a/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java
index b3119d7..8460d67 100644
--- a/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java
@@ -189,6 +189,7 @@
LocationStatsEnums.USAGE_STARTED,
LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER,
registration.getIdentity().getPackageName(),
+ registration.getIdentity().getAttributionTag(),
null,
null,
true,
@@ -202,6 +203,7 @@
LocationStatsEnums.USAGE_ENDED,
LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER,
registration.getIdentity().getPackageName(),
+ registration.getIdentity().getAttributionTag(),
null,
null,
true,
diff --git a/services/core/java/com/android/server/location/gnss/GnssStatusProvider.java b/services/core/java/com/android/server/location/gnss/GnssStatusProvider.java
index 1eb1618..936283d 100644
--- a/services/core/java/com/android/server/location/gnss/GnssStatusProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssStatusProvider.java
@@ -83,6 +83,7 @@
LocationStatsEnums.USAGE_STARTED,
LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK,
registration.getIdentity().getPackageName(),
+ registration.getIdentity().getAttributionTag(),
null,
null,
true,
@@ -96,6 +97,7 @@
LocationStatsEnums.USAGE_ENDED,
LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK,
registration.getIdentity().getPackageName(),
+ registration.getIdentity().getAttributionTag(),
null,
null,
true,
diff --git a/services/core/java/com/android/server/location/injector/LocationUsageLogger.java b/services/core/java/com/android/server/location/injector/LocationUsageLogger.java
index 244a8e0..af21bcb 100644
--- a/services/core/java/com/android/server/location/injector/LocationUsageLogger.java
+++ b/services/core/java/com/android/server/location/injector/LocationUsageLogger.java
@@ -49,9 +49,9 @@
* Log a location API usage event.
*/
public void logLocationApiUsage(int usageType, int apiInUse,
- String packageName, String provider, LocationRequest locationRequest,
- boolean hasListener, boolean hasIntent,
- Geofence geofence, boolean foreground) {
+ String packageName, String attributionTag, String provider,
+ LocationRequest locationRequest, boolean hasListener,
+ boolean hasIntent, Geofence geofence, boolean foreground) {
try {
if (hitApiUsageLogCap()) {
return;
@@ -84,7 +84,8 @@
isGeofenceNull
? LocationStatsEnums.RADIUS_UNKNOWN
: bucketizeRadius(geofence.getRadius()),
- categorizeActivityImportance(foreground));
+ categorizeActivityImportance(foreground),
+ attributionTag);
} catch (Exception e) {
// Swallow exceptions to avoid crashing LMS.
Log.w(TAG, "Failed to log API usage to statsd.", e);
@@ -114,7 +115,8 @@
/* isListenerNull= */ true,
/* isIntentNull= */ true),
/* bucketizedRadius= */ 0,
- LocationStatsEnums.IMPORTANCE_UNKNOWN);
+ LocationStatsEnums.IMPORTANCE_UNKNOWN,
+ /* attribution_tag */ null);
} catch (Exception e) {
Log.w(TAG, "Failed to log API usage to statsd.", e);
}
diff --git a/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java b/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java
index dbd8dd9..aa3e579 100644
--- a/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java
+++ b/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java
@@ -82,7 +82,7 @@
TelephonyCallback.CallStateListener{
@Override
- public void onCallStateChanged(int state, String incomingNumber) {
+ public void onCallStateChanged(int state) {
if (state == TelephonyManager.CALL_STATE_IDLE) {
if (mIsInEmergencyCall) {
mEmergencyCallEndRealtimeMs = SystemClock.elapsedRealtime();
diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
index 2aa6f28..dc8b1d0 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
@@ -1854,6 +1854,7 @@
LocationStatsEnums.USAGE_STARTED,
LocationStatsEnums.API_REQUEST_LOCATION_UPDATES,
registration.getIdentity().getPackageName(),
+ registration.getIdentity().getAttributionTag(),
mName,
registration.getRequest(),
key instanceof PendingIntent,
@@ -1882,6 +1883,7 @@
LocationStatsEnums.USAGE_ENDED,
LocationStatsEnums.API_REQUEST_LOCATION_UPDATES,
registration.getIdentity().getPackageName(),
+ registration.getIdentity().getAttributionTag(),
mName,
registration.getRequest(),
key instanceof PendingIntent,
diff --git a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
index 82b0f9c..6d250ec 100644
--- a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
+++ b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
@@ -135,7 +135,11 @@
}
sensorIds.remove(sensorId);
- faceManager.revokeChallenge(sensorId);
+ // Challenge is only required for IBiometricsFace@1.0 (and not IFace AIDL). The
+ // IBiometricsFace@1.0 HAL does not require userId to revokeChallenge, so passing
+ // in 0 is OK.
+ final int userId = 0;
+ faceManager.revokeChallenge(sensorId, userId, challenge);
if (sensorIds.isEmpty()) {
Slog.d(TAG, "Done requesting resetLockout for all face sensors");
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
index 48382a9..6e99cba 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
@@ -64,6 +64,8 @@
@VisibleForTesting
public static final String REBOOT_ESCROW_ARMED_KEY = "reboot_escrow_armed_count";
+ static final String REBOOT_ESCROW_KEY_ARMED_TIMESTAMP = "reboot_escrow_key_stored_timestamp";
+
/**
* Number of boots until we consider the escrow data to be stale for the purposes of metrics.
* <p>
@@ -144,8 +146,7 @@
private RebootEscrowProviderInterface createRebootEscrowProvider() {
RebootEscrowProviderInterface rebootEscrowProvider;
- if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_OTA,
- "server_based_ror_enabled", false)) {
+ if (serverBasedResumeOnReboot()) {
Slog.i(TAG, "Using server based resume on reboot");
rebootEscrowProvider = new RebootEscrowProviderServerBasedImpl(mContext, mStorage);
} else {
@@ -166,6 +167,11 @@
handler.postDelayed(runnable, delayMillis);
}
+ public boolean serverBasedResumeOnReboot() {
+ return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_OTA,
+ "server_based_ror_enabled", false);
+ }
+
public Context getContext() {
return mContext;
}
@@ -204,10 +210,12 @@
DEFAULT_LOAD_ESCROW_DATA_RETRY_INTERVAL_SECONDS);
}
- public void reportMetric(boolean success) {
- // TODO(b/179105110) design error code; and report the true value for other fields.
- FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED, 0, 1, 1,
- -1, 0, -1);
+ public void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount,
+ int escrowDurationInSeconds, int vbmetaDigestStatus,
+ int durationSinceBootCompleteInSeconds) {
+ FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED, success,
+ errorCode, serviceType, attemptCount, escrowDurationInSeconds,
+ vbmetaDigestStatus, durationSinceBootCompleteInSeconds);
}
public RebootEscrowEventLog getEventLog() {
@@ -230,7 +238,7 @@
mKeyStoreManager = injector.getKeyStoreManager();
}
- private void onGetRebootEscrowKeyFailed(List<UserInfo> users) {
+ private void onGetRebootEscrowKeyFailed(List<UserInfo> users, int attemptCount) {
Slog.w(TAG, "Had reboot escrow data for users, but no key; removing escrow storage.");
for (UserInfo user : users) {
mStorage.removeRebootEscrow(user.id);
@@ -238,7 +246,7 @@
// Clear the old key in keystore.
mKeyStoreManager.clearKeyStoreEncryptionKey();
- onEscrowRestoreComplete(false);
+ onEscrowRestoreComplete(false, attemptCount);
}
void loadRebootEscrowDataIfAvailable(Handler retryHandler) {
@@ -251,6 +259,8 @@
}
if (rebootEscrowUsers.isEmpty()) {
+ Slog.i(TAG, "No reboot escrow data found for users,"
+ + " skipping loading escrow data");
return;
}
@@ -274,7 +284,7 @@
}
Slog.w(TAG, "Failed to load reboot escrow data after " + attemptNumber + " attempts");
- onGetRebootEscrowKeyFailed(users);
+ onGetRebootEscrowKeyFailed(users, attemptNumber);
}
void loadRebootEscrowDataWithRetry(Handler retryHandler, int attemptNumber,
@@ -297,7 +307,7 @@
}
if (escrowKey == null) {
- onGetRebootEscrowKeyFailed(users);
+ onGetRebootEscrowKeyFailed(users, attemptNumber + 1);
return;
}
@@ -311,16 +321,35 @@
// Clear the old key in keystore. A new key will be generated by new RoR requests.
mKeyStoreManager.clearKeyStoreEncryptionKey();
- onEscrowRestoreComplete(allUsersUnlocked);
+ onEscrowRestoreComplete(allUsersUnlocked, attemptNumber + 1);
}
- private void onEscrowRestoreComplete(boolean success) {
+ private void reportMetricOnRestoreComplete(boolean success, int attemptCount) {
+ int serviceType = mInjector.serverBasedResumeOnReboot()
+ ? FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED__TYPE__SERVER_BASED
+ : FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED__TYPE__HAL;
+
+ long armedTimestamp = mStorage.getLong(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, -1,
+ USER_SYSTEM);
+ mStorage.removeKey(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, USER_SYSTEM);
+ int escrowDurationInSeconds = armedTimestamp != -1
+ ? (int) (System.currentTimeMillis() - armedTimestamp) / 1000 : -1;
+
+ // TODO(b/179105110) design error code; and report the true value for other fields.
+ int vbmetaDigestStatus = FrameworkStatsLog
+ .REBOOT_ESCROW_RECOVERY_REPORTED__VBMETA_DIGEST_STATUS__MATCH_EXPECTED_SLOT;
+
+ mInjector.reportMetric(success, 0 /* error code */, serviceType, attemptCount,
+ escrowDurationInSeconds, vbmetaDigestStatus, -1);
+ }
+
+ private void onEscrowRestoreComplete(boolean success, int attemptCount) {
int previousBootCount = mStorage.getInt(REBOOT_ESCROW_ARMED_KEY, -1, USER_SYSTEM);
mStorage.removeKey(REBOOT_ESCROW_ARMED_KEY, USER_SYSTEM);
int bootCountDelta = mInjector.getBootCount() - previousBootCount;
if (success || (previousBootCount != -1 && bootCountDelta <= BOOT_COUNT_TOLERANCE)) {
- mInjector.reportMetric(success);
+ reportMetricOnRestoreComplete(success, attemptCount);
}
}
@@ -476,6 +505,8 @@
boolean armedRebootEscrow = rebootEscrowProvider.storeRebootEscrowKey(escrowKey, kk);
if (armedRebootEscrow) {
mStorage.setInt(REBOOT_ESCROW_ARMED_KEY, mInjector.getBootCount(), USER_SYSTEM);
+ mStorage.setLong(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, System.currentTimeMillis(),
+ USER_SYSTEM);
mEventLog.addEntry(RebootEscrowEvent.SET_ARMED_STATUS);
}
diff --git a/services/core/java/com/android/server/locksettings/TEST_MAPPING b/services/core/java/com/android/server/locksettings/TEST_MAPPING
index c1cba5f..4a216ca 100644
--- a/services/core/java/com/android/server/locksettings/TEST_MAPPING
+++ b/services/core/java/com/android/server/locksettings/TEST_MAPPING
@@ -10,6 +10,17 @@
"exclude-annotation": "android.platform.test.annotations.FlakyTest"
}
]
+ },
+ {
+ "name": "FrameworksServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.locksettings."
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+ }
+ ]
}
]
}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformDecryptionKey.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformDecryptionKey.java
index 35571f1..e75aae1 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformDecryptionKey.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformDecryptionKey.java
@@ -16,7 +16,7 @@
package com.android.server.locksettings.recoverablekeystore;
-import android.security.keystore.AndroidKeyStoreSecretKey;
+import javax.crypto.SecretKey;
/**
* Used to unwrap recoverable keys before syncing them with remote storage.
@@ -30,7 +30,7 @@
public class PlatformDecryptionKey {
private final int mGenerationId;
- private final AndroidKeyStoreSecretKey mKey;
+ private final SecretKey mKey;
/**
* A new instance.
@@ -40,7 +40,7 @@
*
* @hide
*/
- public PlatformDecryptionKey(int generationId, AndroidKeyStoreSecretKey key) {
+ public PlatformDecryptionKey(int generationId, SecretKey key) {
mGenerationId = generationId;
mKey = key;
}
@@ -59,7 +59,7 @@
*
* @hide
*/
- public AndroidKeyStoreSecretKey getKey() {
+ public SecretKey getKey() {
return mKey;
}
}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java
index 38f5b45..ee33446 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java
@@ -16,7 +16,7 @@
package com.android.server.locksettings.recoverablekeystore;
-import android.security.keystore.AndroidKeyStoreSecretKey;
+import javax.crypto.SecretKey;
/**
* Private key stored in AndroidKeyStore. Used to wrap recoverable keys before writing them to disk.
@@ -33,7 +33,7 @@
public class PlatformEncryptionKey {
private final int mGenerationId;
- private final AndroidKeyStoreSecretKey mKey;
+ private final SecretKey mKey;
/**
* A new instance.
@@ -41,7 +41,7 @@
* @param generationId The generation ID of the key.
* @param key The secret key handle. Can be used to encrypt WITHOUT requiring screen unlock.
*/
- public PlatformEncryptionKey(int generationId, AndroidKeyStoreSecretKey key) {
+ public PlatformEncryptionKey(int generationId, SecretKey key) {
mGenerationId = generationId;
mKey = key;
}
@@ -56,7 +56,7 @@
/**
* Returns the actual key, which can only be used to encrypt.
*/
- public AndroidKeyStoreSecretKey getKey() {
+ public SecretKey getKey() {
return mKey;
}
}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
index f448a6e..f32af54 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
@@ -21,7 +21,6 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.security.GateKeeper;
-import android.security.keystore.AndroidKeyStoreSecretKey;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
@@ -237,7 +236,7 @@
if (!isKeyLoaded(userId, generationId)) {
throw new UnrecoverableKeyException("KeyStore doesn't contain key " + alias);
}
- AndroidKeyStoreSecretKey key = (AndroidKeyStoreSecretKey) mKeyStore.getKey(
+ SecretKey key = (SecretKey) mKeyStore.getKey(
alias, /*password=*/ null);
return new PlatformEncryptionKey(generationId, key);
}
@@ -289,7 +288,7 @@
if (!isKeyLoaded(userId, generationId)) {
throw new UnrecoverableKeyException("KeyStore doesn't contain key " + alias);
}
- AndroidKeyStoreSecretKey key = (AndroidKeyStoreSecretKey) mKeyStore.getKey(
+ SecretKey key = (SecretKey) mKeyStore.getKey(
alias, /*password=*/ null);
return new PlatformDecryptionKey(generationId, key);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 6f39fea..0cc9f9e 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -134,7 +134,6 @@
import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.AutomaticZenRule;
-import android.app.BroadcastOptions;
import android.app.IActivityManager;
import android.app.INotificationManager;
import android.app.ITransientNotification;
@@ -6082,6 +6081,17 @@
}
}
+ // Ensure CallStyle has all the correct actions
+ if ("android.app.Notification$CallStyle".equals(
+ notification.extras.getString(Notification.EXTRA_TEMPLATE))) {
+ Notification.Builder builder =
+ Notification.Builder.recoverBuilder(getContext(), notification);
+ Notification.CallStyle style = (Notification.CallStyle) builder.getStyle();
+ List<Notification.Action> actions = style.getActionsListWithSystemActions();
+ notification.actions = new Notification.Action[actions.size()];
+ actions.toArray(notification.actions);
+ }
+
// Remote views? Are they too big?
checkRemoteViews(pkg, tag, id, notification);
}
diff --git a/services/core/java/com/android/server/pm/ApkChecksums.java b/services/core/java/com/android/server/pm/ApkChecksums.java
index 66ea554..afce23f 100644
--- a/services/core/java/com/android/server/pm/ApkChecksums.java
+++ b/services/core/java/com/android/server/pm/ApkChecksums.java
@@ -59,8 +59,8 @@
import android.util.apk.VerityBuilder;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.security.VerityUtils;
import com.android.server.pm.parsing.pkg.AndroidPackage;
-import com.android.server.security.VerityUtils;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index d3a56c6..044e186 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -70,6 +70,7 @@
import android.os.Handler;
import android.os.IInterface;
import android.os.ParcelFileDescriptor;
+import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -114,6 +115,7 @@
@Override
public void onStart() {
publishBinderService(Context.LAUNCHER_APPS_SERVICE, mLauncherAppsImpl);
+ mLauncherAppsImpl.registerLoadingProgressForIncrementalApps();
}
static class BroadcastCookie {
@@ -1184,6 +1186,30 @@
mCallbackHandler.post(r);
}
+ /**
+ * Check all installed apps and if a package is installed via Incremental and not fully
+ * loaded, register loading progress listener.
+ */
+ void registerLoadingProgressForIncrementalApps() {
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
+ final List<UserHandle> users = mUm.getUserProfiles();
+ if (users == null) {
+ return;
+ }
+ for (UserHandle user : users) {
+ pmInt.forEachInstalledPackage(pkg -> {
+ final String packageName = pkg.getPackageName();
+ if (pmInt.getIncrementalStatesInfo(packageName, Process.myUid(),
+ user.getIdentifier()).isLoading()) {
+ pmInt.registerInstalledLoadingProgressCallback(packageName,
+ new PackageLoadingProgressCallback(packageName, user),
+ user.getIdentifier());
+ }
+ }, user.getIdentifier());
+ }
+ }
+
public static class ShortcutChangeHandler implements LauncherApps.ShortcutChangeCallback {
private final UserManagerInternal mUserManagerInternal;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 903652a..82b12aa 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -138,6 +138,7 @@
import com.android.internal.content.PackageHelper;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.os.SomeArgs;
+import com.android.internal.security.VerityUtils;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
@@ -146,7 +147,6 @@
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.parsing.pkg.AndroidPackage;
-import com.android.server.security.VerityUtils;
import libcore.io.IoUtils;
import libcore.util.EmptyArray;
@@ -3060,7 +3060,7 @@
// Also stage .dm.fsv_sig. .dm may be required to install with fs-verity signature on
// supported on older devices.
maybeStageFsveritySignatureLocked(dexMetadataFile, targetDexMetadataFile,
- VerityUtils.isFsVeritySupported() && DexMetadataHelper.isFsVerityRequired());
+ DexMetadataHelper.isFsVerityRequired());
}
private void storeBytesToInstallationFile(final String localPath, final String absolutePath,
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a1da241..f828a11 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -349,6 +349,7 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.SomeArgs;
import com.android.internal.policy.AttributeCache;
+import com.android.internal.security.VerityUtils;
import com.android.internal.telephony.CarrierAppUtils;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;
@@ -401,7 +402,6 @@
import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyV1;
import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyV2;
import com.android.server.rollback.RollbackManagerInternal;
-import com.android.server.security.VerityUtils;
import com.android.server.storage.DeviceStorageMonitorInternal;
import com.android.server.uri.UriGrantsManagerInternal;
import com.android.server.utils.TimingsTraceAndSlog;
@@ -1979,6 +1979,8 @@
@Nullable ComponentName component, @ComponentType int componentType, int userId);
boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
int userId);
+ boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus, int callingUid,
+ int userId);
int bestDomainVerificationStatus(int status1, int status2);
int checkUidPermission(String permName, int uid);
int getPackageUidInternal(String packageName, int flags, int userId, int callingUid);
@@ -4143,6 +4145,19 @@
}
/**
+ * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
+ */
+ public boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus, int callingUid,
+ int userId) {
+ boolean filterApp = true;
+ for (int index = sus.packages.size() - 1; index >= 0 && filterApp; index--) {
+ filterApp &= shouldFilterApplicationLocked(sus.packages.valueAt(index),
+ callingUid, /* component */ null, TYPE_UNKNOWN, userId);
+ }
+ return filterApp;
+ }
+
+ /**
* Verification statuses are ordered from the worse to the best, except for
* INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
*/
@@ -7904,6 +7919,15 @@
ps, callingUid, userId);
}
+ /**
+ * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
+ */
+ @GuardedBy("mLock")
+ private boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus, int callingUid,
+ int userId) {
+ return liveComputer().shouldFilterApplicationLocked(sus, callingUid, userId);
+ }
+
@GuardedBy("mLock")
private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
int flags) {
@@ -8970,7 +8994,6 @@
public int checkUidSignatures(int uid1, int uid2) {
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
- final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
// Map to base uids.
final int appId1 = UserHandle.getAppId(uid1);
final int appId2 = UserHandle.getAppId(uid2);
@@ -8981,10 +9004,11 @@
Object obj = mSettings.getSettingLPr(appId1);
if (obj != null) {
if (obj instanceof SharedUserSetting) {
- if (isCallerInstantApp) {
+ final SharedUserSetting sus = (SharedUserSetting) obj;
+ if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
- p1SigningDetails = ((SharedUserSetting) obj).signatures.mSigningDetails;
+ p1SigningDetails = sus.signatures.mSigningDetails;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
@@ -9000,10 +9024,11 @@
obj = mSettings.getSettingLPr(appId2);
if (obj != null) {
if (obj instanceof SharedUserSetting) {
- if (isCallerInstantApp) {
+ final SharedUserSetting sus = (SharedUserSetting) obj;
+ if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
- p2SigningDetails = ((SharedUserSetting) obj).signatures.mSigningDetails;
+ p2SigningDetails = sus.signatures.mSigningDetails;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
@@ -9092,11 +9117,11 @@
final Object obj = mSettings.getSettingLPr(appId);
if (obj != null) {
if (obj instanceof SharedUserSetting) {
- final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
- if (isCallerInstantApp) {
+ final SharedUserSetting sus = (SharedUserSetting) obj;
+ if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
return false;
}
- signingDetails = ((SharedUserSetting)obj).signatures.mSigningDetails;
+ signingDetails = sus.signatures.mSigningDetails;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
@@ -9221,16 +9246,19 @@
if (getInstantAppPackageName(callingUid) != null) {
return null;
}
+ final int callingUserId = UserHandle.getUserId(callingUid);
final int appId = UserHandle.getAppId(uid);
synchronized (mLock) {
final Object obj = mSettings.getSettingLPr(appId);
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
+ if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
+ return null;
+ }
return sus.name + ":" + sus.userId;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplicationLocked(
- ps, callingUid, UserHandle.getUserId(callingUid))) {
+ if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
return null;
}
return ps.name;
@@ -9248,6 +9276,7 @@
if (getInstantAppPackageName(callingUid) != null) {
return null;
}
+ final int callingUserId = UserHandle.getUserId(callingUid);
final String[] names = new String[uids.length];
synchronized (mLock) {
for (int i = uids.length - 1; i >= 0; i--) {
@@ -9255,11 +9284,14 @@
final Object obj = mSettings.getSettingLPr(appId);
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
- names[i] = "shared:" + sus.name;
+ if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
+ names[i] = null;
+ } else {
+ names[i] = "shared:" + sus.name;
+ }
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplicationLocked(
- ps, callingUid, UserHandle.getUserId(callingUid))) {
+ if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
names[i] = null;
} else {
names[i] = ps.name;
@@ -9301,16 +9333,19 @@
if (getInstantAppPackageName(callingUid) != null) {
return 0;
}
+ final int callingUserId = UserHandle.getUserId(callingUid);
final int appId = UserHandle.getAppId(uid);
synchronized (mLock) {
final Object obj = mSettings.getSettingLPr(appId);
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
+ if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
+ return 0;
+ }
return sus.pkgFlags;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplicationLocked(
- ps, callingUid, UserHandle.getUserId(callingUid))) {
+ if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
return 0;
}
return ps.pkgFlags;
@@ -9325,16 +9360,19 @@
if (getInstantAppPackageName(callingUid) != null) {
return 0;
}
+ final int callingUserId = UserHandle.getUserId(callingUid);
final int appId = UserHandle.getAppId(uid);
synchronized (mLock) {
final Object obj = mSettings.getSettingLPr(appId);
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
+ if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
+ return 0;
+ }
return sus.pkgPrivateFlags;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplicationLocked(
- ps, callingUid, UserHandle.getUserId(callingUid))) {
+ if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
return 0;
}
return ps.pkgPrivateFlags;
@@ -27765,13 +27803,23 @@
}
private static String getDefaultTimeouts() {
- return DeviceConfig.getString(DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE,
- PROPERTY_INCFS_DEFAULT_TIMEOUTS, "");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return DeviceConfig.getString(NAMESPACE_PACKAGE_MANAGER_SERVICE,
+ PROPERTY_INCFS_DEFAULT_TIMEOUTS, "");
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
private static String getKnownDigestersList() {
- return DeviceConfig.getString(DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE,
- PROPERTY_KNOWN_DIGESTERS_LIST, "");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return DeviceConfig.getString(NAMESPACE_PACKAGE_MANAGER_SERVICE,
+ PROPERTY_KNOWN_DIGESTERS_LIST, "");
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
/**
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index d1cf55d..38cba4c 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -1889,231 +1889,248 @@
@Override
public void setDynamicShortcuts(String packageName, ParceledListSlice shortcutInfoList,
@UserIdInt int userId, @NonNull AndroidFuture callback) {
- verifyCaller(packageName, userId);
+ try {
+ verifyCaller(packageName, userId);
- final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
- verifyShortcutInfoPackages(packageName, newShortcuts);
- final int size = newShortcuts.size();
+ final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
+ verifyShortcutInfoPackages(packageName, newShortcuts);
+ final int size = newShortcuts.size();
- final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
- injectBinderCallingPid(), injectBinderCallingUid());
+ final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
+ injectBinderCallingPid(), injectBinderCallingUid());
- List<ShortcutInfo> changedShortcuts = null;
- List<ShortcutInfo> removedShortcuts = null;
+ List<ShortcutInfo> changedShortcuts = null;
+ List<ShortcutInfo> removedShortcuts = null;
- synchronized (mLock) {
- throwIfUserLockedL(userId);
+ synchronized (mLock) {
+ throwIfUserLockedL(userId);
- final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
+ final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName,
+ userId);
- ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
- ps.ensureNoBitmapIconIfShortcutIsLongLived(newShortcuts);
+ ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
+ ps.ensureNoBitmapIconIfShortcutIsLongLived(newShortcuts);
- fillInDefaultActivity(newShortcuts);
+ fillInDefaultActivity(newShortcuts);
- ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_SET);
+ ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_SET);
- // Throttling.
- if (!ps.tryApiCall(unlimited)) {
- callback.complete(false);
+ // Throttling.
+ if (!ps.tryApiCall(unlimited)) {
+ callback.complete(false);
+ return;
+ }
+
+ // Initialize the implicit ranks for ShortcutPackage.adjustRanks().
+ ps.clearAllImplicitRanks();
+ assignImplicitRanks(newShortcuts);
+
+ for (int i = 0; i < size; i++) {
+ fixUpIncomingShortcutInfo(newShortcuts.get(i), /* forUpdate= */ false);
+ }
+
+ ArrayList<ShortcutInfo> cachedOrPinned = new ArrayList<>();
+ ps.findAll(cachedOrPinned, (ShortcutInfo si) -> si.isVisibleToPublisher()
+ && si.isDynamic() && (si.isCached() || si.isPinned()),
+ ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
+
+ // First, remove all un-pinned and non-cached; dynamic shortcuts
+ removedShortcuts = ps.deleteAllDynamicShortcuts(/*ignoreInvisible=*/ true);
+
+ // Then, add/update all. We need to make sure to take over "pinned" flag.
+ for (int i = 0; i < size; i++) {
+ final ShortcutInfo newShortcut = newShortcuts.get(i);
+ ps.addOrReplaceDynamicShortcut(newShortcut);
+ }
+
+ // Lastly, adjust the ranks.
+ ps.adjustRanks();
+
+ changedShortcuts = prepareChangedShortcuts(
+ cachedOrPinned, newShortcuts, removedShortcuts, ps);
}
- // Initialize the implicit ranks for ShortcutPackage.adjustRanks().
- ps.clearAllImplicitRanks();
- assignImplicitRanks(newShortcuts);
+ packageShortcutsChanged(packageName, userId, changedShortcuts, removedShortcuts);
- for (int i = 0; i < size; i++) {
- fixUpIncomingShortcutInfo(newShortcuts.get(i), /* forUpdate= */ false);
- }
+ verifyStates();
- ArrayList<ShortcutInfo> cachedOrPinned = new ArrayList<>();
- ps.findAll(cachedOrPinned, (ShortcutInfo si) -> si.isVisibleToPublisher()
- && si.isDynamic() && (si.isCached() || si.isPinned()),
- ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
-
- // First, remove all un-pinned and non-cached; dynamic shortcuts
- removedShortcuts = ps.deleteAllDynamicShortcuts(/*ignoreInvisible=*/ true);
-
- // Then, add/update all. We need to make sure to take over "pinned" flag.
- for (int i = 0; i < size; i++) {
- final ShortcutInfo newShortcut = newShortcuts.get(i);
- ps.addOrReplaceDynamicShortcut(newShortcut);
- }
-
- // Lastly, adjust the ranks.
- ps.adjustRanks();
-
- changedShortcuts = prepareChangedShortcuts(
- cachedOrPinned, newShortcuts, removedShortcuts, ps);
+ callback.complete(true);
+ } catch (Exception e) {
+ callback.completeExceptionally(e);
}
-
- packageShortcutsChanged(packageName, userId, changedShortcuts, removedShortcuts);
-
- verifyStates();
-
- callback.complete(true);
}
@Override
public void updateShortcuts(String packageName, ParceledListSlice shortcutInfoList,
@UserIdInt int userId, AndroidFuture callback) {
- verifyCaller(packageName, userId);
+ try {
+ verifyCaller(packageName, userId);
- final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
- verifyShortcutInfoPackages(packageName, newShortcuts);
- final int size = newShortcuts.size();
+ final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
+ verifyShortcutInfoPackages(packageName, newShortcuts);
+ final int size = newShortcuts.size();
- final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
- injectBinderCallingPid(), injectBinderCallingUid());
+ final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
+ injectBinderCallingPid(), injectBinderCallingUid());
- final List<ShortcutInfo> changedShortcuts = new ArrayList<>(1);
+ final List<ShortcutInfo> changedShortcuts = new ArrayList<>(1);
- synchronized (mLock) {
- throwIfUserLockedL(userId);
+ synchronized (mLock) {
+ throwIfUserLockedL(userId);
- final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
+ final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName,
+ userId);
- ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
- ps.ensureNoBitmapIconIfShortcutIsLongLived(newShortcuts);
+ ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
+ ps.ensureNoBitmapIconIfShortcutIsLongLived(newShortcuts);
- // For update, don't fill in the default activity. Having null activity means
- // "don't update the activity" here.
+ // For update, don't fill in the default activity. Having null activity means
+ // "don't update the activity" here.
- ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_UPDATE);
+ ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_UPDATE);
- // Throttling.
- if (!ps.tryApiCall(unlimited)) {
- callback.complete(false);
- return;
+ // Throttling.
+ if (!ps.tryApiCall(unlimited)) {
+ callback.complete(false);
+ return;
+ }
+
+ // Initialize the implicit ranks for ShortcutPackage.adjustRanks().
+ ps.clearAllImplicitRanks();
+ assignImplicitRanks(newShortcuts);
+
+ for (int i = 0; i < size; i++) {
+ final ShortcutInfo source = newShortcuts.get(i);
+ fixUpIncomingShortcutInfo(source, /* forUpdate= */ true);
+
+ ps.mutateShortcut(source.getId(), null, target -> {
+ // Invisible shortcuts can't be updated.
+ if (target == null || !target.isVisibleToPublisher()) {
+ return;
+ }
+
+ if (target.isEnabled() != source.isEnabled()) {
+ Slog.w(TAG, "ShortcutInfo.enabled cannot be changed with"
+ + " updateShortcuts()");
+ }
+
+ if (target.isLongLived() != source.isLongLived()) {
+ Slog.w(TAG,
+ "ShortcutInfo.longLived cannot be changed with"
+ + " updateShortcuts()");
+ }
+
+ // When updating the rank, we need to insert between existing ranks, so set
+ // this setRankChanged, and also copy the implicit rank fo adjustRanks().
+ if (source.hasRank()) {
+ target.setRankChanged();
+ target.setImplicitRank(source.getImplicitRank());
+ }
+
+ final boolean replacingIcon = (source.getIcon() != null);
+ if (replacingIcon) {
+ removeIconLocked(target);
+ }
+
+ // Note copyNonNullFieldsFrom() does the "updatable with?" check too.
+ target.copyNonNullFieldsFrom(source);
+ target.setTimestamp(injectCurrentTimeMillis());
+
+ if (replacingIcon) {
+ saveIconAndFixUpShortcutLocked(target);
+ }
+
+ // When we're updating any resource related fields, re-extract the res
+ // names and the values.
+ if (replacingIcon || source.hasStringResources()) {
+ fixUpShortcutResourceNamesAndValues(target);
+ }
+
+ changedShortcuts.add(target);
+ });
+ }
+
+ // Lastly, adjust the ranks.
+ ps.adjustRanks();
}
+ packageShortcutsChanged(packageName, userId,
+ changedShortcuts.isEmpty() ? null : changedShortcuts, null);
- // Initialize the implicit ranks for ShortcutPackage.adjustRanks().
- ps.clearAllImplicitRanks();
- assignImplicitRanks(newShortcuts);
+ verifyStates();
- for (int i = 0; i < size; i++) {
- final ShortcutInfo source = newShortcuts.get(i);
- fixUpIncomingShortcutInfo(source, /* forUpdate= */ true);
-
- ps.mutateShortcut(source.getId(), null, target -> {
- // Invisible shortcuts can't be updated.
- if (target == null || !target.isVisibleToPublisher()) {
- return;
- }
-
- if (target.isEnabled() != source.isEnabled()) {
- Slog.w(TAG,
- "ShortcutInfo.enabled cannot be changed with updateShortcuts()");
- }
-
- if (target.isLongLived() != source.isLongLived()) {
- Slog.w(TAG,
- "ShortcutInfo.longLived cannot be changed with updateShortcuts()");
- }
-
- // When updating the rank, we need to insert between existing ranks, so set
- // this setRankChanged, and also copy the implicit rank fo adjustRanks().
- if (source.hasRank()) {
- target.setRankChanged();
- target.setImplicitRank(source.getImplicitRank());
- }
-
- final boolean replacingIcon = (source.getIcon() != null);
- if (replacingIcon) {
- removeIconLocked(target);
- }
-
- // Note copyNonNullFieldsFrom() does the "updatable with?" check too.
- target.copyNonNullFieldsFrom(source);
- target.setTimestamp(injectCurrentTimeMillis());
-
- if (replacingIcon) {
- saveIconAndFixUpShortcutLocked(target);
- }
-
- // When we're updating any resource related fields, re-extract the res names and
- // the values.
- if (replacingIcon || source.hasStringResources()) {
- fixUpShortcutResourceNamesAndValues(target);
- }
-
- changedShortcuts.add(target);
- });
- }
-
- // Lastly, adjust the ranks.
- ps.adjustRanks();
+ callback.complete(true);
+ } catch (Exception e) {
+ callback.completeExceptionally(e);
}
- packageShortcutsChanged(packageName, userId,
- changedShortcuts.isEmpty() ? null : changedShortcuts, null);
-
- verifyStates();
-
- callback.complete(true);
}
@Override
public void addDynamicShortcuts(String packageName, ParceledListSlice shortcutInfoList,
@UserIdInt int userId, AndroidFuture callback) {
- verifyCaller(packageName, userId);
+ try {
+ verifyCaller(packageName, userId);
- final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
- verifyShortcutInfoPackages(packageName, newShortcuts);
- final int size = newShortcuts.size();
+ final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
+ verifyShortcutInfoPackages(packageName, newShortcuts);
+ final int size = newShortcuts.size();
- final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
- injectBinderCallingPid(), injectBinderCallingUid());
+ final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
+ injectBinderCallingPid(), injectBinderCallingUid());
- List<ShortcutInfo> changedShortcuts = null;
+ List<ShortcutInfo> changedShortcuts = null;
- synchronized (mLock) {
- throwIfUserLockedL(userId);
+ synchronized (mLock) {
+ throwIfUserLockedL(userId);
- final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
+ final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName,
+ userId);
- ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
- ps.ensureNoBitmapIconIfShortcutIsLongLived(newShortcuts);
+ ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
+ ps.ensureNoBitmapIconIfShortcutIsLongLived(newShortcuts);
- fillInDefaultActivity(newShortcuts);
+ fillInDefaultActivity(newShortcuts);
- ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_ADD);
+ ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_ADD);
- // Initialize the implicit ranks for ShortcutPackage.adjustRanks().
- ps.clearAllImplicitRanks();
- assignImplicitRanks(newShortcuts);
+ // Initialize the implicit ranks for ShortcutPackage.adjustRanks().
+ ps.clearAllImplicitRanks();
+ assignImplicitRanks(newShortcuts);
- // Throttling.
- if (!ps.tryApiCall(unlimited)) {
- callback.complete(false);
- return;
- }
- for (int i = 0; i < size; i++) {
- final ShortcutInfo newShortcut = newShortcuts.get(i);
-
- // Validate the shortcut.
- fixUpIncomingShortcutInfo(newShortcut, /* forUpdate= */ false);
-
- // When ranks are changing, we need to insert between ranks, so set the
- // "rank changed" flag.
- newShortcut.setRankChanged();
-
- // Add it.
- ps.addOrReplaceDynamicShortcut(newShortcut);
-
- if (changedShortcuts == null) {
- changedShortcuts = new ArrayList<>(1);
+ // Throttling.
+ if (!ps.tryApiCall(unlimited)) {
+ callback.complete(false);
+ return;
}
- changedShortcuts.add(newShortcut);
+ for (int i = 0; i < size; i++) {
+ final ShortcutInfo newShortcut = newShortcuts.get(i);
+
+ // Validate the shortcut.
+ fixUpIncomingShortcutInfo(newShortcut, /* forUpdate= */ false);
+
+ // When ranks are changing, we need to insert between ranks, so set the
+ // "rank changed" flag.
+ newShortcut.setRankChanged();
+
+ // Add it.
+ ps.addOrReplaceDynamicShortcut(newShortcut);
+
+ if (changedShortcuts == null) {
+ changedShortcuts = new ArrayList<>(1);
+ }
+ changedShortcuts.add(newShortcut);
+ }
+
+ // Lastly, adjust the ranks.
+ ps.adjustRanks();
}
+ packageShortcutsChanged(packageName, userId, changedShortcuts, null);
- // Lastly, adjust the ranks.
- ps.adjustRanks();
+ verifyStates();
+
+ callback.complete(true);
+ } catch (Exception e) {
+ callback.completeExceptionally(e);
}
- packageShortcutsChanged(packageName, userId, changedShortcuts, null);
-
- verifyStates();
-
- callback.complete(true);
}
@Override
@@ -2180,31 +2197,40 @@
@Override
public void requestPinShortcut(String packageName, ShortcutInfo shortcut,
IntentSender resultIntent, int userId, AndroidFuture callback) {
- Objects.requireNonNull(shortcut);
- Objects.requireNonNull(callback);
- Preconditions.checkArgument(shortcut.isEnabled(), "Shortcut must be enabled");
- callback.complete(requestPinItem(packageName, userId, shortcut, null, null, resultIntent));
+ try {
+ Objects.requireNonNull(shortcut);
+ Objects.requireNonNull(callback);
+ Preconditions.checkArgument(shortcut.isEnabled(), "Shortcut must be enabled");
+ callback.complete(
+ requestPinItem(packageName, userId, shortcut, null, null, resultIntent));
+ } catch (Exception e) {
+ callback.completeExceptionally(e);
+ }
}
@Override
public void createShortcutResultIntent(String packageName, ShortcutInfo shortcut, int userId,
AndroidFuture callback)
throws RemoteException {
- Objects.requireNonNull(shortcut);
- Preconditions.checkArgument(shortcut.isEnabled(), "Shortcut must be enabled");
- verifyCaller(packageName, userId);
- verifyShortcutInfoPackage(packageName, shortcut);
+ try {
+ Objects.requireNonNull(shortcut);
+ Preconditions.checkArgument(shortcut.isEnabled(), "Shortcut must be enabled");
+ verifyCaller(packageName, userId);
+ verifyShortcutInfoPackage(packageName, shortcut);
- final Intent ret;
- synchronized (mLock) {
- throwIfUserLockedL(userId);
+ final Intent ret;
+ synchronized (mLock) {
+ throwIfUserLockedL(userId);
- // Send request to the launcher, if supported.
- ret = mShortcutRequestPinProcessor.createShortcutResultIntent(shortcut, userId);
+ // Send request to the launcher, if supported.
+ ret = mShortcutRequestPinProcessor.createShortcutResultIntent(shortcut, userId);
+ }
+
+ verifyStates();
+ callback.complete(ret);
+ } catch (Exception e) {
+ callback.completeExceptionally(e);
}
-
- verifyStates();
- callback.complete(ret);
}
/**
@@ -2464,47 +2490,57 @@
public void getShortcuts(String packageName,
@ShortcutManager.ShortcutMatchFlags int matchFlags, @UserIdInt int userId,
AndroidFuture<ParceledListSlice<ShortcutInfo>> callback) {
- verifyCaller(packageName, userId);
+ try {
+ verifyCaller(packageName, userId);
- synchronized (mLock) {
- throwIfUserLockedL(userId);
+ synchronized (mLock) {
+ throwIfUserLockedL(userId);
- final boolean matchDynamic = (matchFlags & ShortcutManager.FLAG_MATCH_DYNAMIC) != 0;
- final boolean matchPinned = (matchFlags & ShortcutManager.FLAG_MATCH_PINNED) != 0;
- final boolean matchManifest = (matchFlags & ShortcutManager.FLAG_MATCH_MANIFEST) != 0;
- final boolean matchCached = (matchFlags & ShortcutManager.FLAG_MATCH_CACHED) != 0;
+ final boolean matchDynamic = (matchFlags & ShortcutManager.FLAG_MATCH_DYNAMIC) != 0;
+ final boolean matchPinned = (matchFlags & ShortcutManager.FLAG_MATCH_PINNED) != 0;
+ final boolean matchManifest =
+ (matchFlags & ShortcutManager.FLAG_MATCH_MANIFEST) != 0;
+ final boolean matchCached = (matchFlags & ShortcutManager.FLAG_MATCH_CACHED) != 0;
- final int shortcutFlags = (matchDynamic ? ShortcutInfo.FLAG_DYNAMIC : 0)
- | (matchPinned ? ShortcutInfo.FLAG_PINNED : 0)
- | (matchManifest ? ShortcutInfo.FLAG_MANIFEST : 0)
- | (matchCached ? ShortcutInfo.FLAG_CACHED_ALL : 0);
+ final int shortcutFlags = (matchDynamic ? ShortcutInfo.FLAG_DYNAMIC : 0)
+ | (matchPinned ? ShortcutInfo.FLAG_PINNED : 0)
+ | (matchManifest ? ShortcutInfo.FLAG_MANIFEST : 0)
+ | (matchCached ? ShortcutInfo.FLAG_CACHED_ALL : 0);
- callback.complete(getShortcutsWithQueryLocked(
- packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
- (ShortcutInfo si) ->
- si.isVisibleToPublisher() && (si.getFlags() & shortcutFlags) != 0));
+ callback.complete(getShortcutsWithQueryLocked(
+ packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
+ (ShortcutInfo si) ->
+ si.isVisibleToPublisher() && (si.getFlags() & shortcutFlags) != 0));
+ }
+ } catch (Exception e) {
+ callback.completeExceptionally(e);
}
}
@Override
public void getShareTargets(String packageName, IntentFilter filter, @UserIdInt int userId,
AndroidFuture<ParceledListSlice> callback) {
- Preconditions.checkStringNotEmpty(packageName, "packageName");
- Objects.requireNonNull(filter, "intentFilter");
+ try {
+ Preconditions.checkStringNotEmpty(packageName, "packageName");
+ Objects.requireNonNull(filter, "intentFilter");
- verifyCaller(packageName, userId);
- enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_APP_PREDICTIONS,
- "getShareTargets");
+ verifyCaller(packageName, userId);
+ enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_APP_PREDICTIONS,
+ "getShareTargets");
- synchronized (mLock) {
- throwIfUserLockedL(userId);
+ synchronized (mLock) {
+ throwIfUserLockedL(userId);
- final List<ShortcutManager.ShareShortcutInfo> shortcutInfoList = new ArrayList<>();
+ final List<ShortcutManager.ShareShortcutInfo> shortcutInfoList = new ArrayList<>();
- final ShortcutUser user = getUserShortcutsLocked(userId);
- user.forAllPackages(p -> shortcutInfoList.addAll(p.getMatchingShareTargets(filter)));
+ final ShortcutUser user = getUserShortcutsLocked(userId);
+ user.forAllPackages(
+ p -> shortcutInfoList.addAll(p.getMatchingShareTargets(filter)));
- callback.complete(new ParceledListSlice<>(shortcutInfoList));
+ callback.complete(new ParceledListSlice<>(shortcutInfoList));
+ }
+ } catch (Exception e) {
+ callback.completeExceptionally(e);
}
}
diff --git a/services/core/java/com/android/server/power/FaceDownDetector.java b/services/core/java/com/android/server/power/FaceDownDetector.java
index 2442079..676181d 100644
--- a/services/core/java/com/android/server/power/FaceDownDetector.java
+++ b/services/core/java/com/android/server/power/FaceDownDetector.java
@@ -30,6 +30,7 @@
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.Looper;
+import android.os.PowerManager;
import android.os.SystemClock;
import android.provider.DeviceConfig;
import android.util.Slog;
@@ -66,7 +67,7 @@
private static final float MOVING_AVERAGE_WEIGHT = 0.5f;
/** DeviceConfig flag name, if {@code true}, enables Face Down features. */
- private static final String KEY_FEATURE_ENABLED = "enable_flip_to_screen_off";
+ static final String KEY_FEATURE_ENABLED = "enable_flip_to_screen_off";
/** Default value in absence of {@link DeviceConfig} override. */
private static final boolean DEFAULT_FEATURE_ENABLED = true;
@@ -139,6 +140,7 @@
new ExponentialMovingAverage(MOVING_AVERAGE_WEIGHT);
private boolean mFaceDown = false;
+ private boolean mInteractive = false;
private boolean mActive = false;
private float mPrevAcceleration = 0;
@@ -149,62 +151,64 @@
private final Handler mHandler;
private final Runnable mUserActivityRunnable;
+ private final BroadcastReceiver mScreenReceiver;
+
+ private Context mContext;
public FaceDownDetector(@NonNull Consumer<Boolean> onFlip) {
mOnFlip = Objects.requireNonNull(onFlip);
mHandler = new Handler(Looper.getMainLooper());
+ mScreenReceiver = new ScreenStateReceiver();
mUserActivityRunnable = () -> {
if (mFaceDown) {
exitFaceDown(USER_INTERACTION, SystemClock.uptimeMillis() - mLastFlipTime);
- checkAndUpdateActiveState(false);
+ updateActiveState();
}
};
}
/** Initializes the FaceDownDetector and all necessary listeners. */
public void systemReady(Context context) {
+ mContext = context;
mSensorManager = context.getSystemService(SensorManager.class);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
readValuesFromDeviceConfig();
- checkAndUpdateActiveState(true);
DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_ATTENTION_MANAGER_SERVICE,
ActivityThread.currentApplication().getMainExecutor(),
(properties) -> onDeviceConfigChange(properties.getKeyset()));
+ updateActiveState();
+ }
+
+ private void registerScreenReceiver(Context context) {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
- context.registerReceiver(new ScreenStateReceiver(), intentFilter);
+ context.registerReceiver(mScreenReceiver, intentFilter);
}
/**
* Sets the active state of the detector. If false, we will not process accelerometer changes.
*/
- private void checkAndUpdateActiveState(boolean active) {
- if (mIsEnabled && mActive != active) {
- final long currentTime = SystemClock.uptimeMillis();
- // Don't make active if there was recently a user interaction while face down.
- if (active && mPreviousResultType == USER_INTERACTION
- && currentTime - mPreviousResultTime < mUserInteractionBackoffMillis) {
- return;
- }
- if (DEBUG) Slog.d(TAG, "Update active - " + active);
- mActive = active;
- if (!active) {
- if (mFaceDown && mPreviousResultTime != USER_INTERACTION) {
- mPreviousResultType = SCREEN_OFF_RESULT;
- mPreviousResultTime = currentTime;
- }
- mSensorManager.unregisterListener(this);
- mFaceDown = false;
- mOnFlip.accept(false);
- } else {
+ private void updateActiveState() {
+ final long currentTime = SystemClock.uptimeMillis();
+ final boolean sawRecentInteraction = mPreviousResultType == USER_INTERACTION
+ && currentTime - mPreviousResultTime < mUserInteractionBackoffMillis;
+ final boolean shouldBeActive = mInteractive && mIsEnabled && !sawRecentInteraction;
+ if (mActive != shouldBeActive) {
+ if (shouldBeActive) {
+ mSensorManager.registerListener(
+ this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
if (mPreviousResultType == SCREEN_OFF_RESULT) {
logScreenOff();
}
- mSensorManager.registerListener(
- this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
+ } else {
+ mSensorManager.unregisterListener(this);
+ mFaceDown = false;
+ mOnFlip.accept(false);
}
+ mActive = shouldBeActive;
+ if (DEBUG) Slog.d(TAG, "Update active - " + shouldBeActive);
}
}
@@ -287,8 +291,10 @@
* The user interacted with the screen while face down, indicated the phone is in use.
* We log this event and temporarily make this detector inactive.
*/
- public void userActivity() {
- mHandler.post(mUserActivityRunnable);
+ public void userActivity(int event) {
+ if (event != PowerManager.USER_ACTIVITY_EVENT_FACE_DOWN) {
+ mHandler.post(mUserActivityRunnable);
+ }
}
private void exitFaceDown(int resultType, long millisSinceFlip) {
@@ -389,6 +395,7 @@
case KEY_TIME_THRESHOLD_MILLIS:
case KEY_FEATURE_ENABLED:
readValuesFromDeviceConfig();
+ updateActiveState();
return;
default:
Slog.i(TAG, "Ignoring change on " + key);
@@ -401,8 +408,18 @@
mZAccelerationThreshold = getZAccelerationThreshold();
mZAccelerationThresholdLenient = mZAccelerationThreshold + 1.0f;
mTimeThreshold = getTimeThreshold();
- mIsEnabled = isEnabled();
mUserInteractionBackoffMillis = getUserInteractionBackoffMillis();
+ final boolean oldEnabled = mIsEnabled;
+ mIsEnabled = isEnabled();
+ if (oldEnabled != mIsEnabled) {
+ if (!mIsEnabled) {
+ mContext.unregisterReceiver(mScreenReceiver);
+ mInteractive = false;
+ } else {
+ registerScreenReceiver(mContext);
+ mInteractive = mContext.getSystemService(PowerManager.class).isInteractive();
+ }
+ }
Slog.i(TAG, "readValuesFromDeviceConfig():"
+ "\nmAccelerationThreshold=" + mAccelerationThreshold
@@ -423,9 +440,11 @@
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
- checkAndUpdateActiveState(false);
+ mInteractive = false;
+ updateActiveState();
} else if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
- checkAndUpdateActiveState(true);
+ mInteractive = true;
+ updateActiveState();
}
}
}
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index f49e2f1..7555a7f 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -549,6 +549,7 @@
if (!mUserActivityPending) {
mUserActivityPending = true;
Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY);
+ msg.arg1 = event;
msg.setAsynchronous(true);
mHandler.sendMessage(msg);
}
@@ -647,7 +648,7 @@
mSuspendBlocker.release();
}
- private void sendUserActivity() {
+ private void sendUserActivity(int event) {
synchronized (mLock) {
if (!mUserActivityPending) {
return;
@@ -657,7 +658,7 @@
TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
tm.notifyUserActivity();
mPolicy.userActivity();
- mFaceDownDetector.userActivity();
+ mFaceDownDetector.userActivity(event);
}
void postEnhancedDischargePredictionBroadcast(long delayMs) {
@@ -833,7 +834,7 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_USER_ACTIVITY:
- sendUserActivity();
+ sendUserActivity(msg.arg1);
break;
case MSG_BROADCAST:
sendNextBroadcast();
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 29adde3..d2a4cd6 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -180,8 +180,6 @@
private static final int DIRTY_VR_MODE_CHANGED = 1 << 13;
// Dirty bit: attentive timer may have timed out
private static final int DIRTY_ATTENTIVE = 1 << 14;
- // Dirty bit: phone flipped to face down
- private static final int DIRTY_FACE_DOWN = 1 << 15;
// Dirty bit: display group power state has changed
private static final int DIRTY_DISPLAY_GROUP_POWER_UPDATED = 1 << 16;
@@ -1069,8 +1067,9 @@
final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout, -1L);
millisUntilNormalTimeout =
mLastUserActivityTime + screenOffTimeout - mClock.uptimeMillis();
- mDirty |= DIRTY_FACE_DOWN;
- updatePowerStateLocked();
+ userActivityInternal(mClock.uptimeMillis(),
+ PowerManager.USER_ACTIVITY_EVENT_FACE_DOWN, /* flags= */0,
+ Process.SYSTEM_UID);
}
}
if (isFaceDown) {
diff --git a/services/core/java/com/android/server/power/PreRebootLogger.java b/services/core/java/com/android/server/power/PreRebootLogger.java
index 2e4b054..c9e81ed 100644
--- a/services/core/java/com/android/server/power/PreRebootLogger.java
+++ b/services/core/java/com/android/server/power/PreRebootLogger.java
@@ -19,7 +19,6 @@
import android.annotation.DurationMillisLong;
import android.annotation.NonNull;
import android.content.Context;
-import android.os.Binder;
import android.os.Environment;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
@@ -147,7 +146,6 @@
return;
}
- final long token = Binder.clearCallingIdentity();
try {
final File dumpFile = new File(dumpDir, serviceName);
final ParcelFileDescriptor fd = ParcelFileDescriptor.open(dumpFile,
@@ -156,8 +154,6 @@
binder.dump(fd.getFileDescriptor(), ArrayUtils.emptyArray(String.class));
} catch (FileNotFoundException | RemoteException e) {
Slog.e(TAG, String.format("Failed to dump %s service before reboot", serviceName), e);
- } finally {
- Binder.restoreCallingIdentity(token);
}
}
}
diff --git a/services/core/java/com/android/server/rotationresolver/RemoteRotationResolverService.java b/services/core/java/com/android/server/rotationresolver/RemoteRotationResolverService.java
index cfb4c27..189f47f 100644
--- a/services/core/java/com/android/server/rotationresolver/RemoteRotationResolverService.java
+++ b/services/core/java/com/android/server/rotationresolver/RemoteRotationResolverService.java
@@ -77,9 +77,7 @@
@GuardedBy("mLock")
public void resolveRotationLocked(RotationRequest request) {
- final RotationResolutionRequest remoteRequest = new RotationResolutionRequest(
- request.mProposedRotation, request.mCurrentRotation, request.mPackageName,
- request.mTimeoutMillis);
+ final RotationResolutionRequest remoteRequest = request.mRemoteRequest;
post(service -> service.resolveRotation(request.mIRotationResolverCallback, remoteRequest));
// schedule a timeout.
@@ -91,7 +89,7 @@
request.cancelInternal();
}
}
- }, request.mTimeoutMillis);
+ }, request.mRemoteRequest.getTimeoutMillis());
}
@VisibleForTesting
@@ -109,28 +107,18 @@
@GuardedBy("mLock")
boolean mIsFulfilled;
- private final long mTimeoutMillis;
-
@VisibleForTesting
- final int mProposedRotation;
-
- private final int mCurrentRotation;
- private final String mPackageName;
+ final RotationResolutionRequest mRemoteRequest;
boolean mIsDispatched;
private final Object mLock = new Object();
private final long mRequestStartTimeMillis;
RotationRequest(
- @NonNull RotationResolverInternal.RotationResolverCallbackInternal
- callbackInternal, int proposedRotation, int currentRotation,
- String packageName, long timeoutMillis,
- @NonNull CancellationSignal cancellationSignal) {
- mTimeoutMillis = timeoutMillis;
+ @NonNull RotationResolverInternal.RotationResolverCallbackInternal callbackInternal,
+ RotationResolutionRequest request, @NonNull CancellationSignal cancellationSignal) {
mCallbackInternal = callbackInternal;
- mProposedRotation = proposedRotation;
- mCurrentRotation = currentRotation;
- mPackageName = packageName;
+ mRemoteRequest = request;
mIRotationResolverCallback = new RotationResolverCallback(this);
mCancellationSignalInternal = cancellationSignal;
mRequestStartTimeMillis = SystemClock.elapsedRealtime();
@@ -185,8 +173,8 @@
request.mCallbackInternal.onSuccess(rotation);
final long timeToCalculate =
SystemClock.elapsedRealtime() - request.mRequestStartTimeMillis;
- logRotationStats(request.mProposedRotation, request.mCurrentRotation, rotation,
- timeToCalculate);
+ logRotationStats(request.mRemoteRequest.getProposedRotation(),
+ request.mRemoteRequest.getCurrentRotation(), rotation, timeToCalculate);
Slog.d(TAG, "onSuccess:" + rotation);
Slog.d(TAG, "timeToCalculate:" + timeToCalculate);
}
@@ -204,8 +192,9 @@
request.mCallbackInternal.onFailure(error);
final long timeToCalculate =
SystemClock.elapsedRealtime() - request.mRequestStartTimeMillis;
- logRotationStats(request.mProposedRotation, request.mCurrentRotation,
- RESOLUTION_FAILURE, timeToCalculate);
+ logRotationStats(request.mRemoteRequest.getProposedRotation(),
+ request.mRemoteRequest.getCurrentRotation(), RESOLUTION_FAILURE,
+ timeToCalculate);
Slog.d(TAG, "onFailure:" + error);
Slog.d(TAG, "timeToCalculate:" + timeToCalculate);
}
diff --git a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java
index 13f8d61..1dbe3e4 100644
--- a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java
+++ b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java
@@ -34,11 +34,11 @@
import android.content.pm.ServiceInfo;
import android.os.CancellationSignal;
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;
-import android.view.Surface;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -95,14 +95,14 @@
@VisibleForTesting
void resolveRotationLocked(
@NonNull RotationResolverInternal.RotationResolverCallbackInternal callbackInternal,
- @Surface.Rotation int proposedRotation, @Surface.Rotation int currentRotation,
- String packageName, long timeoutMillis,
+ @NonNull RotationResolutionRequest request,
@NonNull CancellationSignal cancellationSignalInternal) {
if (!isServiceAvailableLocked()) {
Slog.w(TAG, "Service is not available at this moment.");
callbackInternal.onFailure(ROTATION_RESULT_FAILURE_CANCELLED);
- logRotationStats(proposedRotation, currentRotation, RESOLUTION_UNAVAILABLE);
+ logRotationStats(request.getProposedRotation(), request.getCurrentRotation(),
+ RESOLUTION_UNAVAILABLE);
return;
}
@@ -114,8 +114,7 @@
}
mCurrentRequest = new RemoteRotationResolverService.RotationRequest(callbackInternal,
- proposedRotation, currentRotation, packageName, timeoutMillis,
- cancellationSignalInternal);
+ request, cancellationSignalInternal);
cancellationSignalInternal.setOnCancelListener(() -> {
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java
index e57d4ce..a7f3cdb 100644
--- a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java
+++ b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java
@@ -35,6 +35,7 @@
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.rotationresolver.RotationResolverInternal;
+import android.service.rotationresolver.RotationResolutionRequest;
import android.text.TextUtils;
import android.util.IndentingPrintWriter;
import android.util.Slog;
@@ -158,8 +159,9 @@
if (mIsServiceEnabled) {
final RotationResolverManagerPerUserService service = getServiceForUserLocked(
UserHandle.getCallingUserId());
- service.resolveRotationLocked(callbackInternal, proposedRotation,
- currentRotation, /* packageName */ "", timeout,
+ final RotationResolutionRequest request = new RotationResolutionRequest("",
+ currentRotation, proposedRotation, true, timeout);
+ service.resolveRotationLocked(callbackInternal, request,
cancellationSignalInternal);
} else {
Slog.w(TAG, "Rotation Resolver service is disabled.");
diff --git a/services/core/java/com/android/server/rotationresolver/RotationResolverShellCommand.java b/services/core/java/com/android/server/rotationresolver/RotationResolverShellCommand.java
index e5088c0..a0e04ee 100644
--- a/services/core/java/com/android/server/rotationresolver/RotationResolverShellCommand.java
+++ b/services/core/java/com/android/server/rotationresolver/RotationResolverShellCommand.java
@@ -22,6 +22,7 @@
import android.os.CancellationSignal;
import android.os.ShellCommand;
import android.rotationresolver.RotationResolverInternal.RotationResolverCallbackInternal;
+import android.service.rotationresolver.RotationResolutionRequest;
import android.text.TextUtils;
import android.view.Surface;
@@ -107,8 +108,10 @@
}
private int runResolveRotation() {
- mService.resolveRotationLocked(sTestableRotationCallbackInternal, Surface.ROTATION_0,
- Surface.ROTATION_0, "", 2000L, new CancellationSignal());
+ final RotationResolutionRequest request = new RotationResolutionRequest("",
+ Surface.ROTATION_0, Surface.ROTATION_0, true, 2000L);
+ mService.resolveRotationLocked(sTestableRotationCallbackInternal, request,
+ new CancellationSignal());
return 0;
}
diff --git a/services/core/java/com/android/server/security/FileIntegrityService.java b/services/core/java/com/android/server/security/FileIntegrityService.java
index 74bb993..466ac74 100644
--- a/services/core/java/com/android/server/security/FileIntegrityService.java
+++ b/services/core/java/com/android/server/security/FileIntegrityService.java
@@ -29,6 +29,7 @@
import android.security.IFileIntegrityService;
import android.util.Slog;
+import com.android.internal.security.VerityUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
diff --git a/services/core/java/com/android/server/security/OWNERS b/services/core/java/com/android/server/security/OWNERS
index 91b240b..e6f5826 100644
--- a/services/core/java/com/android/server/security/OWNERS
+++ b/services/core/java/com/android/server/security/OWNERS
@@ -1,4 +1,3 @@
# Bug component: 36824
per-file FileIntegrityService.java = victorhsieh@google.com
-per-file VerityUtils.java = victorhsieh@google.com
diff --git a/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java b/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java
index dbe7354..52c1467b 100644
--- a/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java
+++ b/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java
@@ -16,6 +16,8 @@
package com.android.server.speech;
+import static android.Manifest.permission.MANAGE_SPEECH_RECOGNITION;
+
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.content.ComponentName;
@@ -24,6 +26,7 @@
import android.os.UserHandle;
import android.speech.IRecognitionServiceManager;
import android.speech.IRecognitionServiceManagerCallback;
+import android.util.Slog;
import com.android.internal.R;
import com.android.server.infra.AbstractMasterSystemService;
@@ -42,6 +45,8 @@
SpeechRecognitionManagerServiceImpl> {
private static final String TAG = SpeechRecognitionManagerService.class.getSimpleName();
+ private static final int MAX_TEMP_SERVICE_SUBSTITUTION_DURATION_MS = 60_000;
+
public SpeechRecognitionManagerService(@NonNull Context context) {
super(context,
// TODO(b/176578753): think if we want to favor the particular service here.
@@ -58,6 +63,16 @@
}
@Override
+ protected void enforceCallingPermissionForManagement() {
+ getContext().enforceCallingPermission(MANAGE_SPEECH_RECOGNITION, TAG);
+ }
+
+ @Override
+ protected int getMaximumTemporaryServiceDurationMs() {
+ return MAX_TEMP_SERVICE_SUBSTITUTION_DURATION_MS;
+ }
+
+ @Override
protected SpeechRecognitionManagerServiceImpl newServiceLocked(
@UserIdInt int resolvedUserId, boolean disabled) {
return new SpeechRecognitionManagerServiceImpl(this, mLock, resolvedUserId, disabled);
@@ -77,5 +92,21 @@
service.createSessionLocked(componentName, clientToken, onDevice, callback);
}
}
+
+ @Override
+ public void setTemporaryComponent(ComponentName componentName) {
+ int userId = UserHandle.getCallingUserId();
+ if (componentName == null) {
+ resetTemporaryService(userId);
+ Slog.i(TAG, "Reset temporary service for user " + userId);
+ return;
+ }
+ setTemporaryService(
+ userId,
+ componentName.flattenToString(),
+ MAX_TEMP_SERVICE_SUBSTITUTION_DURATION_MS);
+ Slog.i(TAG, "SpeechRecognition temporarily set to " + componentName + " for "
+ + MAX_TEMP_SERVICE_SUBSTITUTION_DURATION_MS + "ms");
+ }
}
}
diff --git a/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java b/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
index 2656a3d..769e049 100644
--- a/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
@@ -100,6 +100,9 @@
}
if (serviceComponent == null) {
+ if (mMaster.debug) {
+ Slog.i(TAG, "Service component is undefined, responding with error.");
+ }
tryRespondWithError(callback, SpeechRecognizer.ERROR_CLIENT);
return;
}
@@ -213,6 +216,10 @@
@Nullable
private ComponentName getOnDeviceComponentNameLocked() {
final String serviceName = getComponentNameLocked();
+ if (mMaster.debug) {
+ Slog.i(TAG, "Resolved component name: " + serviceName);
+ }
+
if (serviceName == null) {
if (mMaster.verbose) {
Slog.v(TAG, "ensureRemoteServiceLocked(): no service component name.");
@@ -241,6 +248,11 @@
service.getServiceComponentName().equals(serviceComponent))
.findFirst();
if (existingService.isPresent()) {
+
+ if (mMaster.debug) {
+ Slog.i(TAG, "Reused existing connection to " + serviceComponent);
+ }
+
return existingService.get();
}
}
@@ -253,6 +265,10 @@
mRemoteServicesByUid.computeIfAbsent(callingUid, key -> new HashSet<>());
valuesByCaller.add(service);
+ if (mMaster.debug) {
+ Slog.i(TAG, "Creating a new connection to " + serviceComponent);
+ }
+
return service;
}
}
diff --git a/services/core/java/com/android/server/stats/OWNERS b/services/core/java/com/android/server/stats/OWNERS
index fc7fd22..174ad3a 100644
--- a/services/core/java/com/android/server/stats/OWNERS
+++ b/services/core/java/com/android/server/stats/OWNERS
@@ -1,7 +1,10 @@
jeffreyhuang@google.com
joeo@google.com
+jtnguyen@google.com
muhammadq@google.com
+rslawik@google.com
ruchirr@google.com
+sharaienko@google.com
singhtejinder@google.com
tsaichristine@google.com
yaochen@google.com
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 7ed7a59..8023fd4 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -148,11 +148,13 @@
import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader;
import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader;
import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader;
+import com.android.internal.os.KernelSingleProcessCpuThreadReader.ProcessCpuUsage;
import com.android.internal.os.KernelWakelockReader;
import com.android.internal.os.KernelWakelockStats;
import com.android.internal.os.LooperStats;
import com.android.internal.os.PowerProfile;
import com.android.internal.os.ProcessCpuTracker;
+import com.android.internal.os.SelectedProcessCpuThreadReader;
import com.android.internal.os.StoragedUidIoStatsReader;
import com.android.internal.os.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes;
import com.android.internal.util.CollectionUtils;
@@ -351,6 +353,8 @@
@GuardedBy("mDataBytesTransferLock")
private final ArrayList<SubInfo> mHistoricalSubs = new ArrayList<>();
+ private SelectedProcessCpuThreadReader mSurfaceFlingerProcessCpuThreadReader;
+
// Puller locks
private final Object mDataBytesTransferLock = new Object();
private final Object mBluetoothBytesTransferLock = new Object();
@@ -753,6 +757,9 @@
}
}
}
+
+ mSurfaceFlingerProcessCpuThreadReader =
+ new SelectedProcessCpuThreadReader("/system/bin/surfaceflinger");
}
void registerEventListeners() {
@@ -1479,7 +1486,7 @@
}
for (int freqIndex = 0; freqIndex < timesMs.length; ++freqIndex) {
int cluster = freqsClusters[freqIndex];
- long freq = freqs[freqIndex];
+ int freq = (int) freqs[freqIndex];
long timeMs = timesMs[freqIndex];
pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, cluster, freq, timeMs));
}
@@ -1678,6 +1685,18 @@
FrameworkStatsLog.CPU_CYCLES_PER_THREAD_GROUP_CLUSTER__THREAD_GROUP__SYSTEM_SERVER_BINDER,
times.binderThreadCpuTimesUs);
+ ProcessCpuUsage surfaceFlingerTimes = mSurfaceFlingerProcessCpuThreadReader.readAbsolute();
+ if (surfaceFlingerTimes != null && surfaceFlingerTimes.threadCpuTimesMillis != null) {
+ long[] surfaceFlingerTimesUs =
+ new long[surfaceFlingerTimes.threadCpuTimesMillis.length];
+ for (int i = 0; i < surfaceFlingerTimesUs.length; ++i) {
+ surfaceFlingerTimesUs[i] = surfaceFlingerTimes.threadCpuTimesMillis[i] * 1_000;
+ }
+ addCpuCyclesPerThreadGroupClusterAtoms(atomTag, pulledData,
+ FrameworkStatsLog.CPU_CYCLES_PER_THREAD_GROUP_CLUSTER__THREAD_GROUP__SURFACE_FLINGER,
+ surfaceFlingerTimesUs);
+ }
+
return StatsManager.PULL_SUCCESS;
}
diff --git a/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java
index 3ae9d64..ee78a4e 100644
--- a/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java
+++ b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java
@@ -28,8 +28,6 @@
import android.app.time.TimeZoneConfiguration;
import android.os.UserHandle;
-import com.android.internal.util.Preconditions;
-
import java.util.Objects;
/**
@@ -39,7 +37,7 @@
*/
public final class ConfigurationInternal {
- private final boolean mAutoDetectionSupported;
+ private final boolean mTelephonyDetectionSupported;
private final boolean mGeoDetectionSupported;
private final boolean mAutoDetectionEnabled;
private final @UserIdInt int mUserId;
@@ -48,7 +46,7 @@
private final boolean mGeoDetectionEnabled;
private ConfigurationInternal(Builder builder) {
- mAutoDetectionSupported = builder.mAutoDetectionSupported;
+ mTelephonyDetectionSupported = builder.mTelephonyDetectionSupported;
mGeoDetectionSupported = builder.mGeoDetectionSupported;
mAutoDetectionEnabled = builder.mAutoDetectionEnabled;
@@ -56,14 +54,16 @@
mUserConfigAllowed = builder.mUserConfigAllowed;
mLocationEnabled = builder.mLocationEnabled;
mGeoDetectionEnabled = builder.mGeoDetectionEnabled;
- // if mGeoDetectionSupported then mAutoDetectionSupported, i.e. mGeoDetectionSupported
- // cannot be true if mAutoDetectionSupported == false
- Preconditions.checkState(mAutoDetectionSupported || !mGeoDetectionSupported);
}
/** Returns true if the device supports any form of auto time zone detection. */
public boolean isAutoDetectionSupported() {
- return mAutoDetectionSupported;
+ return mTelephonyDetectionSupported || mGeoDetectionSupported;
+ }
+
+ /** Returns true if the device supports telephony time zone detection. */
+ public boolean isTelephonyDetectionSupported() {
+ return mTelephonyDetectionSupported;
}
/** Returns true if the device supports geolocation time zone detection. */
@@ -78,9 +78,10 @@
/**
* Returns true if auto time zone detection behavior is actually enabled, which can be distinct
- * from the raw setting value. */
+ * from the raw setting value.
+ */
public boolean getAutoDetectionEnabledBehavior() {
- return mAutoDetectionSupported && mAutoDetectionEnabled;
+ return isAutoDetectionSupported() && mAutoDetectionEnabled;
}
/** Returns the ID of the user this configuration is associated with. */
@@ -212,7 +213,7 @@
ConfigurationInternal that = (ConfigurationInternal) o;
return mUserId == that.mUserId
&& mUserConfigAllowed == that.mUserConfigAllowed
- && mAutoDetectionSupported == that.mAutoDetectionSupported
+ && mTelephonyDetectionSupported == that.mTelephonyDetectionSupported
&& mGeoDetectionSupported == that.mGeoDetectionSupported
&& mAutoDetectionEnabled == that.mAutoDetectionEnabled
&& mLocationEnabled == that.mLocationEnabled
@@ -221,7 +222,7 @@
@Override
public int hashCode() {
- return Objects.hash(mUserId, mUserConfigAllowed, mAutoDetectionSupported,
+ return Objects.hash(mUserId, mUserConfigAllowed, mTelephonyDetectionSupported,
mGeoDetectionSupported, mAutoDetectionEnabled, mLocationEnabled,
mGeoDetectionEnabled);
}
@@ -231,7 +232,7 @@
return "ConfigurationInternal{"
+ "mUserId=" + mUserId
+ ", mUserConfigAllowed=" + mUserConfigAllowed
- + ", mAutoDetectionSupported=" + mAutoDetectionSupported
+ + ", mTelephonyDetectionSupported=" + mTelephonyDetectionSupported
+ ", mGeoDetectionSupported=" + mGeoDetectionSupported
+ ", mAutoDetectionEnabled=" + mAutoDetectionEnabled
+ ", mLocationEnabled=" + mLocationEnabled
@@ -247,7 +248,7 @@
private final @UserIdInt int mUserId;
private boolean mUserConfigAllowed;
- private boolean mAutoDetectionSupported;
+ private boolean mTelephonyDetectionSupported;
private boolean mGeoDetectionSupported;
private boolean mAutoDetectionEnabled;
private boolean mLocationEnabled;
@@ -266,7 +267,7 @@
public Builder(ConfigurationInternal toCopy) {
this.mUserId = toCopy.mUserId;
this.mUserConfigAllowed = toCopy.mUserConfigAllowed;
- this.mAutoDetectionSupported = toCopy.mAutoDetectionSupported;
+ this.mTelephonyDetectionSupported = toCopy.mTelephonyDetectionSupported;
this.mGeoDetectionSupported = toCopy.mGeoDetectionSupported;
this.mAutoDetectionEnabled = toCopy.mAutoDetectionEnabled;
this.mLocationEnabled = toCopy.mLocationEnabled;
@@ -282,10 +283,10 @@
}
/**
- * Sets whether any form of automatic time zone detection is supported on this device.
+ * Sets whether telephony time zone detection is supported on this device.
*/
- public Builder setAutoDetectionFeatureSupported(boolean supported) {
- mAutoDetectionSupported = supported;
+ public Builder setTelephonyDetectionFeatureSupported(boolean supported) {
+ mTelephonyDetectionSupported = supported;
return this;
}
diff --git a/services/core/java/com/android/server/timezonedetector/EnvironmentImpl.java b/services/core/java/com/android/server/timezonedetector/EnvironmentImpl.java
index e3caae94..0e5f3bf 100644
--- a/services/core/java/com/android/server/timezonedetector/EnvironmentImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/EnvironmentImpl.java
@@ -128,8 +128,8 @@
@Override
public ConfigurationInternal getConfigurationInternal(@UserIdInt int userId) {
return new ConfigurationInternal.Builder(userId)
- .setAutoDetectionFeatureSupported(
- mServiceConfigAccessor.isAutoDetectionFeatureSupported())
+ .setTelephonyDetectionFeatureSupported(
+ mServiceConfigAccessor.isTelephonyTimeZoneDetectionFeatureSupported())
.setGeoDetectionFeatureSupported(
mServiceConfigAccessor.isGeoTimeZoneDetectionFeatureSupported())
.setAutoDetectionEnabled(isAutoDetectionEnabled())
diff --git a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
index 86c32f8..2452c8d 100644
--- a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
+++ b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
@@ -115,10 +115,15 @@
/** Returns {@code true} if any form of automatic time zone detection is supported. */
public boolean isAutoDetectionFeatureSupported() {
- return deviceHasTelephonyNetwork() || isGeoTimeZoneDetectionFeatureSupported();
+ return isTelephonyTimeZoneDetectionFeatureSupported()
+ || isGeoTimeZoneDetectionFeatureSupported();
}
- private boolean deviceHasTelephonyNetwork() {
+ /**
+ * Returns {@code true} if the telephony-based time zone detection feature is supported on the
+ * device.
+ */
+ public boolean isTelephonyTimeZoneDetectionFeatureSupported() {
// TODO b/150583524 Avoid the use of a deprecated API.
return mContext.getSystemService(ConnectivityManager.class)
.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java
index 2d5dacd..7ba20ee 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java
@@ -86,7 +86,7 @@
@NonNull GeolocationTimeZoneSuggestion timeZoneSuggestion) {
Objects.requireNonNull(timeZoneSuggestion);
- // All strategy calls must take place on the mHandler thread.
+ // This call can take place on the mHandler thread because there is no return value.
mHandler.post(
() -> mTimeZoneDetectorStrategy.suggestGeolocationTimeZone(timeZoneSuggestion));
}
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
index d163a0e..2e96a10 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
@@ -195,6 +195,13 @@
private ReferenceWithHistory<GeolocationTimeZoneSuggestion> mLatestGeoLocationSuggestion =
new ReferenceWithHistory<>(KEEP_SUGGESTION_HISTORY_SIZE);
+ /**
+ * The latest manual suggestion received.
+ */
+ @GuardedBy("this")
+ private ReferenceWithHistory<ManualTimeZoneSuggestion> mLatestManualSuggestion =
+ new ReferenceWithHistory<>(KEEP_SUGGESTION_HISTORY_SIZE);
+
@GuardedBy("this")
private final List<Dumpable> mDumpables = new ArrayList<>();
@@ -286,6 +293,7 @@
if (currentUserConfig.getGeoDetectionEnabledBehavior()) {
// Only store a geolocation suggestion if geolocation detection is currently enabled.
+ // See also clearGeolocationSuggestionIfNeeded().
mLatestGeoLocationSuggestion.set(suggestion);
// Now perform auto time zone detection. The new suggestion may be used to modify the
@@ -324,6 +332,12 @@
return false;
}
+ // Record the manual suggestion for debugging / metrics (but only if manual detection is
+ // currently enabled).
+ // Note: This is not used to set the device back to a previous manual suggestion if the user
+ // later disables automatic time zone detection.
+ mLatestManualSuggestion.set(suggestion);
+
setDeviceTimeZoneIfRequired(timeZoneId, cause);
return true;
}
@@ -619,6 +633,11 @@
mTimeZoneChangesLog.dump(ipw);
ipw.decreaseIndent(); // level 2
+ ipw.println("Manual suggestion history:");
+ ipw.increaseIndent(); // level 2
+ mLatestManualSuggestion.dump(ipw);
+ ipw.decreaseIndent(); // level 2
+
ipw.println("Geolocation suggestion history:");
ipw.increaseIndent(); // level 2
mLatestGeoLocationSuggestion.dump(ipw);
@@ -639,6 +658,14 @@
* A method used to inspect strategy state during tests. Not intended for general use.
*/
@VisibleForTesting
+ public synchronized ManualTimeZoneSuggestion getLatestManualSuggestion() {
+ return mLatestManualSuggestion.get();
+ }
+
+ /**
+ * A method used to inspect strategy state during tests. Not intended for general use.
+ */
+ @VisibleForTesting
public synchronized QualifiedTelephonyTimeZoneSuggestion getLatestTelephonySuggestion(
int slotIndex) {
return mTelephonySuggestionsBySlotIndex.get(slotIndex);
diff --git a/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java b/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java
index c0c9e6d..417a636 100644
--- a/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java
+++ b/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java
@@ -39,15 +39,13 @@
*/
class BinderLocationTimeZoneProvider extends LocationTimeZoneProvider {
- private static final String TAG = LocationTimeZoneManagerService.TAG;
-
@NonNull private final LocationTimeZoneProviderProxy mProxy;
BinderLocationTimeZoneProvider(
@NonNull ThreadingDomain threadingDomain,
@NonNull String providerName,
@NonNull LocationTimeZoneProviderProxy proxy) {
- super(threadingDomain, providerName);
+ super(threadingDomain, providerName, new ZoneInfoDbTimeZoneIdValidator());
mProxy = Objects.requireNonNull(proxy);
}
diff --git a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerService.java b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerService.java
index 0d1692a..5883821 100644
--- a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerService.java
+++ b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerService.java
@@ -520,6 +520,12 @@
}
}
+ static void infoLog(String msg) {
+ if (Log.isLoggable(TAG, Log.INFO)) {
+ Slog.i(TAG, msg);
+ }
+ }
+
static void warnLog(String msg) {
warnLog(msg, null);
}
diff --git a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java
index ef2f357..b97c838 100644
--- a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java
+++ b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java
@@ -20,6 +20,7 @@
import static android.service.timezone.TimeZoneProviderService.TEST_COMMAND_RESULT_SUCCESS_KEY;
import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.debugLog;
+import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.infoLog;
import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.warnLog;
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_DESTROYED;
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_PERM_FAILED;
@@ -85,6 +86,18 @@
}
/**
+ * Used by {@link LocationTimeZoneProvider} to check if time zone IDs are understood
+ * by the platform.
+ */
+ interface TimeZoneIdValidator {
+
+ /**
+ * Returns whether {@code timeZoneId} is supported by the platform or not.
+ */
+ boolean isValid(@NonNull String timeZoneId);
+ }
+
+ /**
* Information about the provider's current state.
*/
static class ProviderState {
@@ -364,13 +377,17 @@
// Non-null and effectively final after initialize() is called.
ProviderListener mProviderListener;
+ @NonNull private TimeZoneIdValidator mTimeZoneIdValidator;
+
/** Creates the instance. */
LocationTimeZoneProvider(@NonNull ThreadingDomain threadingDomain,
- @NonNull String providerName) {
+ @NonNull String providerName,
+ @NonNull TimeZoneIdValidator timeZoneIdValidator) {
mThreadingDomain = Objects.requireNonNull(threadingDomain);
mInitializationTimeoutQueue = threadingDomain.createSingleRunnableQueue();
mSharedLock = threadingDomain.getLockObject();
mProviderName = Objects.requireNonNull(providerName);
+ mTimeZoneIdValidator = Objects.requireNonNull(timeZoneIdValidator);
}
/**
@@ -610,6 +627,25 @@
mThreadingDomain.assertCurrentThread();
Objects.requireNonNull(timeZoneProviderEvent);
+ // If the provider has made a suggestion with unknown time zone IDs it cannot be used to set
+ // the device's time zone. This logic prevents bad time zone IDs entering the time zone
+ // detection logic from third party code.
+ //
+ // An event containing an unknown time zone ID could occur if the provider is using a
+ // different TZDB version than the device. Provider developers are expected to take steps to
+ // avoid version skew problem, e.g. by ensuring atomic updates with the platform time zone
+ // rules, or providing IDs based on the device's TZDB version, so this is not considered a
+ // common case.
+ //
+ // Treating a suggestion containing unknown time zone IDs as "uncertain" in the primary
+ // enables immediate failover to a secondary provider, one that might provide valid IDs for
+ // the same location, which should provide better behavior than just ignoring the event.
+ if (hasInvalidTimeZones(timeZoneProviderEvent)) {
+ infoLog("event=" + timeZoneProviderEvent + " has unsupported time zones. "
+ + "Replacing it with uncertain event.");
+ timeZoneProviderEvent = TimeZoneProviderEvent.createUncertainEvent();
+ }
+
synchronized (mSharedLock) {
debugLog("handleTimeZoneProviderEvent: mProviderName=" + mProviderName
+ ", timeZoneProviderEvent=" + timeZoneProviderEvent);
@@ -707,6 +743,20 @@
}
}
+ private boolean hasInvalidTimeZones(@NonNull TimeZoneProviderEvent event) {
+ if (event.getSuggestion() == null) {
+ return false;
+ }
+
+ for (String timeZone : event.getSuggestion().getTimeZoneIds()) {
+ if (!mTimeZoneIdValidator.isValid(timeZone)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
@GuardedBy("mSharedLock")
private void assertIsStarted() {
ProviderState currentState = mCurrentState.get();
diff --git a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java b/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
new file mode 100644
index 0000000..cab5ad2
--- /dev/null
+++ b/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
@@ -0,0 +1,30 @@
+/*
+ * 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.timezonedetector.location;
+
+import android.annotation.NonNull;
+
+import com.android.i18n.timezone.ZoneInfoDb;
+
+class ZoneInfoDbTimeZoneIdValidator implements
+ LocationTimeZoneProvider.TimeZoneIdValidator {
+
+ @Override
+ public boolean isValid(@NonNull String timeZoneId) {
+ return ZoneInfoDb.getInstance().hasTimeZone(timeZoneId);
+ }
+}
diff --git a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
index b2db9f5..8dcc547 100644
--- a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
+++ b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
@@ -23,7 +23,6 @@
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
-import android.net.NetworkCapabilities.NetCapability;
import android.net.NetworkRequest;
import android.net.TelephonyNetworkSpecifier;
import android.os.Handler;
@@ -115,33 +114,61 @@
getWifiNetworkRequest(), mHandler, mWifiBringupCallback);
updateSubIdsAndCellularRequests();
- // register Network-selection request used to decide selected underlying Network
+ // Register Network-selection request used to decide selected underlying Network. All
+ // underlying networks must be VCN managed in order to be used.
mConnectivityManager.requestBackgroundNetwork(
- getNetworkRequestBase().build(), mHandler, mRouteSelectionCallback);
+ getBaseNetworkRequest(true /* requireVcnManaged */).build(),
+ mHandler,
+ mRouteSelectionCallback);
}
private NetworkRequest getWifiNetworkRequest() {
- return getNetworkRequestBase().addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build();
+ // Request exclusively VCN managed networks to ensure that we only ever keep carrier wifi
+ // alive.
+ return getBaseNetworkRequest(true /* requireVcnManaged */)
+ .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+ .build();
}
private NetworkRequest getCellNetworkRequestForSubId(int subId) {
- return getNetworkRequestBase()
+ // Do not request NOT_VCN_MANAGED to ensure that the TelephonyNetworkFactory has a
+ // fulfillable request to bring up underlying cellular Networks even if the VCN is already
+ // connected.
+ return getBaseNetworkRequest(false /* requireVcnManaged */)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId))
.build();
}
- private NetworkRequest.Builder getNetworkRequestBase() {
- NetworkRequest.Builder requestBase = new NetworkRequest.Builder();
- for (@NetCapability int capability : mRequiredUnderlyingNetworkCapabilities) {
+ /**
+ * Builds and returns a NetworkRequest builder common to all Underlying Network requests
+ *
+ * <p>A NetworkRequest may either (1) Require the presence of a capability by using
+ * addCapability(), (2) require the absence of a capability using unwanted capabilities, or (3)
+ * allow any state. Underlying networks are never desired to have the NOT_VCN_MANAGED
+ * capability, and only cases (2) and (3) are used.
+ *
+ * @param requireVcnManaged whether the underlying network is required to be VCN managed to
+ * match this request. If {@code true}, the NOT_VCN_MANAGED capability will be set as
+ * unwanted. Else, the NOT_VCN_MANAGED capability will be removed, and any state is
+ * acceptable.
+ */
+ private NetworkRequest.Builder getBaseNetworkRequest(boolean requireVcnManaged) {
+ NetworkRequest.Builder requestBase =
+ new NetworkRequest.Builder()
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+
+ for (int capability : mRequiredUnderlyingNetworkCapabilities) {
requestBase.addCapability(capability);
}
- return requestBase
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
- .addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ if (requireVcnManaged) {
+ requestBase.addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ }
+
+ return requestBase;
}
/**
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java
index c55913e..3f74938 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -299,9 +299,7 @@
for (VcnGatewayConnectionConfig gatewayConnectionConfig :
mConfig.getGatewayConnectionConfigs()) {
if (isRequestSatisfiedByGatewayConnectionConfig(request, gatewayConnectionConfig)) {
- Slog.v(
- getLogTag(),
- "Bringing up new VcnGatewayConnection for request " + request.requestId);
+ Slog.v(getLogTag(), "Bringing up new VcnGatewayConnection for request " + request);
final VcnGatewayConnection vcnGatewayConnection =
mDeps.newVcnGatewayConnection(
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 15429f4..69a153f 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -20,6 +20,7 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.vcn.VcnManager.VCN_ERROR_CODE_CONFIG_ERROR;
@@ -59,6 +60,7 @@
import android.net.ipsec.ike.exceptions.IkeException;
import android.net.ipsec.ike.exceptions.IkeInternalException;
import android.net.ipsec.ike.exceptions.IkeProtocolException;
+import android.net.vcn.VcnControlPlaneIkeConfig;
import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnTransportInfo;
import android.net.wifi.WifiInfo;
@@ -1348,7 +1350,7 @@
mIkeSession = null;
}
- mIkeSession = buildIkeSession();
+ mIkeSession = buildIkeSession(mUnderlying.network);
}
@Override
@@ -1726,6 +1728,7 @@
final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
builder.addTransportType(TRANSPORT_CELLULAR);
+ builder.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
builder.addCapability(NET_CAPABILITY_NOT_CONGESTED);
builder.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
@@ -1939,23 +1942,29 @@
new EventDisconnectRequestedInfo(reason, shouldQuit));
}
- private IkeSessionParams buildIkeParams() {
- // TODO: Implement this once IkeSessionParams is persisted
- return null;
+ private IkeSessionParams buildIkeParams(@NonNull Network network) {
+ final VcnControlPlaneIkeConfig controlPlaneConfig =
+ (VcnControlPlaneIkeConfig) mConnectionConfig.getControlPlaneConfig();
+ final IkeSessionParams.Builder builder =
+ new IkeSessionParams.Builder(controlPlaneConfig.getIkeSessionParams());
+ builder.setConfiguredNetwork(network);
+
+ return builder.build();
}
private ChildSessionParams buildChildParams() {
- // TODO: Implement this once IkeSessionParams is persisted
- return null;
+ final VcnControlPlaneIkeConfig controlPlaneConfig =
+ (VcnControlPlaneIkeConfig) mConnectionConfig.getControlPlaneConfig();
+ return controlPlaneConfig.getChildSessionParams();
}
@VisibleForTesting(visibility = Visibility.PRIVATE)
- VcnIkeSession buildIkeSession() {
+ VcnIkeSession buildIkeSession(@NonNull Network network) {
final int token = ++mCurrentToken;
return mDeps.newIkeSession(
mVcnContext,
- buildIkeParams(),
+ buildIkeParams(network),
buildChildParams(),
new IkeSessionCallbackImpl(token),
new VcnChildSessionCallback(token));
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 5446a39..aeeabe2 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
@@ -84,8 +85,12 @@
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.content.pm.ActivityInfo.SIZE_CHANGES_SUPPORTED_METADATA;
+import static android.content.pm.ActivityInfo.SIZE_CHANGES_SUPPORTED_OVERRIDE;
+import static android.content.pm.ActivityInfo.SIZE_CHANGES_UNSUPPORTED_OVERRIDE;
import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.res.Configuration.EMPTY;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
@@ -205,6 +210,7 @@
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowContainerChildProto.ACTIVITY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
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;
@@ -278,6 +284,7 @@
import android.os.Trace;
import android.os.UserHandle;
import android.os.storage.StorageManager;
+import android.permission.PermissionManager;
import android.service.dreams.DreamActivity;
import android.service.dreams.DreamManagerInternal;
import android.service.voice.IVoiceInteractionSession;
@@ -6815,8 +6822,14 @@
* aspect ratio.
*/
boolean shouldCreateCompatDisplayInsets() {
- if (info.supportsSizeChanges() != ActivityInfo.SIZE_CHANGES_UNSUPPORTED) {
- return false;
+ switch (info.supportsSizeChanges()) {
+ case SIZE_CHANGES_SUPPORTED_METADATA:
+ case SIZE_CHANGES_SUPPORTED_OVERRIDE:
+ return false;
+ case SIZE_CHANGES_UNSUPPORTED_OVERRIDE:
+ return true;
+ default:
+ // Fall through
}
if (inMultiWindowMode() || getWindowConfiguration().hasWindowDecorCaption()) {
final ActivityRecord root = task != null ? task.getRootActivity() : null;
@@ -6955,6 +6968,20 @@
// layout traversals.
mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
getResolvedOverrideConfiguration().seq = mConfigurationSeq;
+
+ // Sandbox max bounds by setting it to the app bounds, if activity is letterboxed or in
+ // size compat mode.
+ if (providesMaxBounds()) {
+ if (DEBUG_CONFIGURATION) {
+ ProtoLog.d(WM_DEBUG_CONFIGURATION, "Sandbox max bounds for uid %s to bounds %s "
+ + "due to letterboxing from mismatch with parent bounds? %s size compat "
+ + "mode %s", getUid(),
+ resolvedConfig.windowConfiguration.getBounds(), !matchParentBounds(),
+ inSizeCompatMode());
+ }
+ resolvedConfig.windowConfiguration
+ .setMaxBounds(resolvedConfig.windowConfiguration.getBounds());
+ }
}
/**
@@ -7296,6 +7323,20 @@
return super.getBounds();
}
+ @Override
+ public boolean providesMaxBounds() {
+ // System and SystemUI should always be able to access the physical display bounds,
+ // so do not provide it with the overridden maximum bounds.
+ // TODO(b/179179513) check WindowState#mOwnerCanAddInternalSystemWindow instead
+ if (getUid() == SYSTEM_UID || PermissionManager.checkPermission(INTERNAL_SYSTEM_WINDOW,
+ getPid(), info.applicationInfo.uid) == PERMISSION_GRANTED) {
+ return false;
+ }
+ // Max bounds should be sandboxed where an activity is letterboxed (activity bounds will be
+ // smaller than task bounds) or put in size compat mode.
+ return !matchParentBounds() || inSizeCompatMode();
+ }
+
@VisibleForTesting
@Override
Rect getAnimationBounds(int appRootTaskClipMode) {
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index 62a0080..8fbe177 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -367,8 +367,7 @@
* Returns {@code true} if this {@link ConfigurationContainer} provides the maximum bounds to
* its child {@link ConfigurationContainer}s. Returns {@code false}, otherwise.
* <p>
- * The maximum bounds is how large a window can be expanded. Currently only
- * {@link DisplayContent} and {@link DisplayArea} effect this property.
+ * The maximum bounds is how large a window can be expanded.
* </p>
*/
protected boolean providesMaxBounds() {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 1d45c6e..426e631 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -131,7 +131,6 @@
import static com.android.server.wm.WindowManagerService.H.REPORT_HARD_KEYBOARD_STATUS_CHANGE;
import static com.android.server.wm.WindowManagerService.H.WINDOW_HIDE_TIMEOUT;
import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
-import static com.android.server.wm.WindowManagerService.SEAMLESS_ROTATION_TIMEOUT_DURATION;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_REMOVING_FOCUS;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_ASSIGN_LAYERS;
@@ -1811,11 +1810,6 @@
w.mReportOrientationChanged = true;
}, true /* traverseTopToBottom */);
- if (rotateSeamlessly) {
- mWmService.mH.sendNewMessageDelayed(WindowManagerService.H.SEAMLESS_ROTATION_TIMEOUT,
- this, SEAMLESS_ROTATION_TIMEOUT_DURATION);
- }
-
for (int i = mWmService.mRotationWatchers.size() - 1; i >= 0; i--) {
final WindowManagerService.RotationWatcher rotationWatcher
= mWmService.mRotationWatchers.get(i);
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 63cb38a..5df1355 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -567,7 +567,7 @@
}
mDisplayContent.forAllWindows(w -> {
if (w.mSeamlesslyRotated) {
- w.finishSeamlessRotation(false /* timeout */);
+ w.cancelSeamlessRotation();
w.mSeamlesslyRotated = false;
}
}, true /* traverseTopToBottom */);
@@ -670,24 +670,6 @@
}
}
- void onSeamlessRotationTimeout() {
- final boolean[] isLayoutNeeded = { false };
-
- mDisplayContent.forAllWindows(w -> {
- if (!w.mSeamlesslyRotated) {
- return;
- }
- isLayoutNeeded[0] = true;
- w.setDisplayLayoutNeeded();
- w.finishSeamlessRotation(true /* timeout */);
- markForSeamlessRotation(w, false /* seamlesslyRotated */);
- }, true /* traverseTopToBottom */);
-
- if (isLayoutNeeded[0]) {
- mService.mWindowPlacerLocked.performSurfacePlacement();
- }
- }
-
/**
* Returns the animation to run for a rotation transition based on the top fullscreen windows
* {@link android.view.WindowManager.LayoutParams#rotationAnimation} and whether it is currently
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index c6c7fe0..45c4233 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -93,7 +93,6 @@
private boolean mServerVisible;
private boolean mSeamlessRotating;
- private long mFinishSeamlessRotateFrameNumber = -1;
private final boolean mControllable;
@@ -342,15 +341,6 @@
mIsLeashReadyForDispatching = false;
final SurfaceControl leash = mAdapter.mCapturedLeash;
- final long frameNumber = mFinishSeamlessRotateFrameNumber;
- mFinishSeamlessRotateFrameNumber = -1;
- if (mWin.mHasSurface && leash != null) {
- // We just finished the seamless rotation. We don't want to change the position or the
- // window crop of the surface controls (including the leash) until the client finishes
- // drawing the new frame of the new orientation. Although we cannot defer the reparent
- // operation, it is fine, because reparent won't cause any visual effect.
- deferTransactionUntil(t, leash, frameNumber);
- }
mControlTarget = target;
updateVisibility();
mControl = new InsetsSourceControl(mSource.getType(), leash, surfacePosition);
@@ -359,19 +349,14 @@
}
void startSeamlessRotation() {
- if (!mSeamlessRotating) {
- mSeamlessRotating = true;
-
- // This will revoke the leash and clear the control target.
- mWin.cancelAnimation();
- }
+ if (!mSeamlessRotating) {
+ mSeamlessRotating = true;
+ mWin.cancelAnimation();
+ }
}
- void finishSeamlessRotation(boolean timeout) {
- if (mSeamlessRotating) {
- mSeamlessRotating = false;
- mFinishSeamlessRotateFrameNumber = timeout ? -1 : mWin.getFrameNumber();
- }
+ void finishSeamlessRotation() {
+ mSeamlessRotating = false;
}
boolean updateClientVisibility(InsetsControlTarget caller) {
@@ -529,7 +514,6 @@
proto.write(CLIENT_VISIBLE, mClientVisible);
proto.write(SERVER_VISIBLE, mServerVisible);
proto.write(SEAMLESS_ROTATING, mSeamlessRotating);
- proto.write(FINISH_SEAMLESS_ROTATE_FRAME_NUMBER, mFinishSeamlessRotateFrameNumber);
proto.write(CONTROLLABLE, mControllable);
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 42cb96f..6fc585e 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -104,11 +104,11 @@
*/
void goodToGo(@WindowManager.TransitionOldType int transit) {
ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "goodToGo()");
- if (mPendingAnimations.isEmpty() || mCanceled) {
+ if (mCanceled) {
ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS,
- "goodToGo(): Animation finished already, canceled=%s mPendingAnimations=%d",
- mCanceled, mPendingAnimations.size());
+ "goodToGo(): Animation canceled already");
onAnimationFinished();
+ invokeAnimationCancelled();
return;
}
@@ -120,8 +120,11 @@
// Create the app targets
final RemoteAnimationTarget[] appTargets = createAppAnimations();
if (appTargets.length == 0) {
- ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "goodToGo(): No apps to animate");
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS,
+ "goodToGo(): No apps to animate, mPendingAnimations=%d",
+ mPendingAnimations.size());
onAnimationFinished();
+ invokeAnimationCancelled();
return;
}
diff --git a/services/core/java/com/android/server/wm/SeamlessRotator.java b/services/core/java/com/android/server/wm/SeamlessRotator.java
index 3d305e4..1e8b8a5 100644
--- a/services/core/java/com/android/server/wm/SeamlessRotator.java
+++ b/services/core/java/com/android/server/wm/SeamlessRotator.java
@@ -35,9 +35,6 @@
* Helper class for seamless rotation.
*
* Works by transforming the {@link WindowState} back into the old display rotation.
- *
- * Uses {@link Transaction#deferTransactionUntil(SurfaceControl, IBinder, long)} instead of
- * latching on the buffer size to allow for seamless 180 degree rotations.
*/
public class SeamlessRotator {
@@ -103,22 +100,7 @@
* Removing the transform and the result of the {@link WindowState} layout are both tied to the
* {@link WindowState} next frame, such that they apply at the same time the client draws the
* window in the new orientation.
- *
- * In the case of a rotation timeout, we want to remove the transform immediately and not defer
- * it.
*/
- public void finish(WindowState win, boolean timeout) {
- final Transaction t = win.getPendingTransaction();
- finish(t, win);
- if (win.mWinAnimator.mSurfaceController != null && !timeout) {
- t.deferTransactionUntil(win.mSurfaceControl,
- win.getClientViewRootSurface(), win.getFrameNumber());
- t.deferTransactionUntil(win.mWinAnimator.mSurfaceController.mSurfaceControl,
- win.getClientViewRootSurface(), win.getFrameNumber());
- }
- }
-
- /** Removes the transform and restore to the original last position. */
void finish(Transaction t, WindowContainer win) {
mTransform.reset();
t.setMatrix(win.mSurfaceControl, mTransform, mFloat9);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index d992a45..04a254c 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -5245,17 +5245,29 @@
if (mForceHiddenFlags == newFlags) {
return false;
}
+
final boolean wasHidden = isForceHidden();
+ final boolean wasVisible = isVisible();
mForceHiddenFlags = newFlags;
- if (wasHidden != isForceHidden() && isTopActivityFocusable()) {
- // The change in force-hidden state will change visibility without triggering a root
- // task order change, so we should reset the preferred top focusable root task to ensure
- // it's not used if a new activity is started from this task.
- getDisplayArea().resetPreferredTopFocusableRootTaskIfNeeded(this);
+ final boolean nowHidden = isForceHidden();
+ if (wasHidden != nowHidden) {
+ final String reason = "setForceHidden";
+ if (wasVisible && nowHidden) {
+ // Move this visible task to back when the task is forced hidden
+ moveToBack(reason, null);
+ } else if (isAlwaysOnTop()) {
+ // Move this always-on-top task to front when no longer hidden
+ moveToFront(reason);
+ }
}
return true;
}
+ @Override
+ public boolean isAlwaysOnTop() {
+ return !isForceHidden() && super.isAlwaysOnTop();
+ }
+
/**
* Returns whether this task is currently forced to be hidden for any reason.
*/
@@ -7482,17 +7494,22 @@
}
public void setAlwaysOnTop(boolean alwaysOnTop) {
- if (isAlwaysOnTop() == alwaysOnTop) {
+ // {@link #isAwaysonTop} overrides the original behavior which also evaluates if this
+ // task is force hidden, so super.isAlwaysOnTop() is used here to see whether the
+ // alwaysOnTop attributes should be updated.
+ if (super.isAlwaysOnTop() == alwaysOnTop) {
return;
}
super.setAlwaysOnTop(alwaysOnTop);
- final TaskDisplayArea taskDisplayArea = getDisplayArea();
// positionChildAtTop() must be called even when always on top gets turned off because we
// need to make sure that the root task is moved from among always on top windows to
// below other always on top windows. Since the position the root task should be inserted
// into is calculated properly in {@link DisplayContent#getTopInsertPosition()} in both
// cases, we can just request that the root task is put at top here.
- taskDisplayArea.positionChildAt(POSITION_TOP, this, false /* includingParents */);
+ // Don't bother moving task to top if this task is force hidden and invisible to user.
+ if (!isForceHidden()) {
+ getDisplayArea().positionChildAt(POSITION_TOP, this, false /* includingParents */);
+ }
}
void dismissPip() {
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index ed92fd0..91aa48e 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -393,7 +393,7 @@
final boolean moveToBottom = position <= 0;
final int oldPosition = mChildren.indexOf(child);
- if (child.getWindowConfiguration().isAlwaysOnTop() && !moveToTop) {
+ if (child.isAlwaysOnTop() && !moveToTop) {
// This root task is always-on-top, override the default behavior.
Slog.w(TAG_WM, "Ignoring move of always-on-top root task=" + this + " to bottom");
@@ -974,14 +974,6 @@
onRootTaskOrderChanged(rootTask);
}
- /** Reset the mPreferredTopFocusableRootTask if it is or below the given task. */
- void resetPreferredTopFocusableRootTaskIfNeeded(Task task) {
- if (mPreferredTopFocusableRootTask != null
- && mPreferredTopFocusableRootTask.compareTo(task) <= 0) {
- mPreferredTopFocusableRootTask = null;
- }
- }
-
/**
* Moves/reparents `task` to the back of whatever container the root home task is in. This is
* for when we just want to move a task to "the back" vs. a specific place. The primary use-case
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 6f853c7..0a75924 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -273,7 +273,6 @@
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.os.BackgroundThread;
import com.android.internal.os.IResultReceiver;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
@@ -367,9 +366,6 @@
/** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */
static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;
- /** Amount of time (in milliseconds) to delay before declaring a seamless rotation timeout. */
- static final int SEAMLESS_ROTATION_TIMEOUT_DURATION = 2000;
-
/** Amount of time (in milliseconds) to delay before declaring a window replacement timeout. */
static final int WINDOW_REPLACEMENT_TIMEOUT_DURATION = 2000;
@@ -529,14 +525,6 @@
@Override
public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
boolean asProto) {
- // Bugreport dumps the trace 2x, 1x as proto and 1x as text. Save file to disk only 1x.
- if (asProto && mWindowTracing.isEnabled()) {
- mWindowTracing.stopTrace(null, false /* writeToFile */);
- BackgroundThread.getHandler().post(() -> {
- mWindowTracing.writeTraceToFile();
- mWindowTracing.startTrace(null);
- });
- }
doDump(fd, pw, new String[] {"-a"}, asProto);
}
@@ -2245,9 +2233,6 @@
win.setFrameNumber(frameNumber);
final DisplayContent dc = win.getDisplayContent();
- if (!dc.mWaitingForConfig) {
- win.finishSeamlessRotation(false /* timeout */);
- }
if (win.mPendingPositionChanged != null) {
win.mPendingPositionChanged.updateLeashPosition(frameNumber);
@@ -2255,6 +2240,7 @@
}
if (mUseBLASTSync && win.useBLASTSync() && viewVisibility != View.GONE) {
+ win.prepareDrawHandlers();
result |= RELAYOUT_RES_BLAST_SYNC;
}
@@ -5095,7 +5081,6 @@
public static final int UPDATE_ANIMATION_SCALE = 51;
public static final int WINDOW_HIDE_TIMEOUT = 52;
- public static final int SEAMLESS_ROTATION_TIMEOUT = 54;
public static final int RESTORE_POINTER_ICON = 55;
public static final int SET_HAS_OVERLAY_UI = 58;
public static final int ANIMATION_FAILSAFE = 60;
@@ -5378,13 +5363,6 @@
}
break;
}
- case SEAMLESS_ROTATION_TIMEOUT: {
- final DisplayContent displayContent = (DisplayContent) msg.obj;
- synchronized (mGlobalLock) {
- displayContent.getDisplayRotation().onSeamlessRotationTimeout();
- }
- break;
- }
case SET_HAS_OVERLAY_UI: {
mAmInternal.setHasOverlayUi(msg.arg1, msg.arg2 == 1);
break;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index d9b879f..eaa3b23 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -261,6 +261,7 @@
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
+import java.util.function.Consumer;
import java.util.function.Predicate;
/** A window in the window manager. */
@@ -749,6 +750,31 @@
private final WindowProcessController mWpcForDisplayAreaConfigChanges;
/**
+ * We split the draw handlers in to a "pending" and "ready" list, in order to solve
+ * sequencing problems. Think of it this way, let's say I update a windows orientation
+ * (in configuration), and then I call applyWithNextDraw. What I'm hoping for is to
+ * apply with the draw that contains the orientation change. However, since the client
+ * can call finishDrawing at any time, it could be about to call a previous call to
+ * finishDrawing (or maybe its already called it, we just haven't handled it). Since this
+ * frame was already completed it had no time to include the orientation change we made.
+ * To solve this problem we accumulate draw handlers in mPendingDrawHandlers, and then force
+ * the client to call relayout. Only the frame post relayout will contain the configuration
+ * change since the window has to relayout), and so in relayout we drain mPendingDrawHandlers
+ * into mReadyDrawHandlers. Finally once we get to finishDrawing we know everything in
+ * mReadyDrawHandlers corresponds to state which was observed by the client and we can
+ * invoke the consumers.
+ */
+ private final List<Consumer<SurfaceControl.Transaction>> mPendingDrawHandlers
+ = new ArrayList<>();
+ private final List<Consumer<SurfaceControl.Transaction>> mReadyDrawHandlers
+ = new ArrayList<>();
+
+ private final Consumer<SurfaceControl.Transaction> mSeamlessRotationFinishedConsumer = t -> {
+ finishSeamlessRotation(t);
+ updateSurfacePosition(t);
+ };
+
+ /**
* Returns the visibility of the given {@link InternalInsetsType type} requested by the client.
*
* @param type the given {@link InternalInsetsType type}.
@@ -831,19 +857,27 @@
mPendingSeamlessRotate.unrotate(transaction, this);
getDisplayContent().getDisplayRotation().markForSeamlessRotation(this,
true /* seamlesslyRotated */);
+ applyWithNextDraw(mSeamlessRotationFinishedConsumer);
}
}
- void finishSeamlessRotation(boolean timeout) {
- if (mPendingSeamlessRotate != null) {
- mPendingSeamlessRotate.finish(this, timeout);
- mFinishSeamlessRotateFrameNumber = getFrameNumber();
- mPendingSeamlessRotate = null;
- getDisplayContent().getDisplayRotation().markForSeamlessRotation(this,
- false /* seamlesslyRotated */);
- if (mControllableInsetProvider != null) {
- mControllableInsetProvider.finishSeamlessRotation(timeout);
- }
+ void cancelSeamlessRotation() {
+ finishSeamlessRotation(getPendingTransaction());
+ }
+
+ void finishSeamlessRotation(SurfaceControl.Transaction t) {
+ if (mPendingSeamlessRotate == null) {
+ return;
+ }
+
+ mPendingSeamlessRotate.finish(t, this);
+ mFinishSeamlessRotateFrameNumber = getFrameNumber();
+ mPendingSeamlessRotate = null;
+
+ getDisplayContent().getDisplayRotation().markForSeamlessRotation(this,
+ false /* seamlesslyRotated */);
+ if (mControllableInsetProvider != null) {
+ mControllableInsetProvider.finishSeamlessRotation();
}
}
@@ -5684,6 +5718,8 @@
Slog.i(TAG, "finishDrawing of relaunch: " + this + " " + duration + "ms");
mActivityRecord.mRelaunchStartTime = 0;
}
+
+ executeDrawHandlers(postDrawTransaction);
if (!onSyncFinishedDrawing()) {
return mWinAnimator.finishDrawingLocked(postDrawTransaction);
}
@@ -5698,6 +5734,7 @@
}
void immediatelyNotifyBlastSync() {
+ prepareDrawHandlers();
finishDrawing(null);
mWmService.mH.removeMessages(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this);
if (!useBLASTSync()) return;
@@ -5777,4 +5814,66 @@
outSize.inset(-attrs.surfaceInsets.left, -attrs.surfaceInsets.top,
-attrs.surfaceInsets.right, -attrs.surfaceInsets.bottom);
}
+
+ /**
+ * This method is used to control whether we return the BLAST_SYNC flag
+ * from relayoutWindow calls on this window (triggering the client to redirect
+ * it's next draw in to a transaction). If we have pending draw handlers, we are
+ * looking for the client to sync.
+ *
+ * See {@link WindowState#mPendingDrawHandlers}
+ */
+ @Override
+ boolean useBLASTSync() {
+ return super.useBLASTSync() || (mPendingDrawHandlers.size() != 0);
+ }
+
+ /**
+ * Apply the transaction with the next window redraw. A full relayout/finishDrawing
+ * cycle must occur before completion. This means if you call the function while
+ * "in relayout", the results may be undefined but at all other times the function
+ * should sort of transparently work like this:
+ * 1. Make changes to WM hierarchy (say change app configuration)
+ * 2. Call apply with next draw.
+ * 3. After finishDrawing, our consumer will be passed the Transaction
+ * containing the buffer, and we can merge in additional operations.
+ * See {@link WindowState#mPendingDrawHandlers}
+ */
+ void applyWithNextDraw(Consumer<SurfaceControl.Transaction> consumer) {
+ mPendingDrawHandlers.add(consumer);
+ requestRedrawForSync();
+
+ mWmService.mH.sendNewMessageDelayed(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this,
+ BLAST_TIMEOUT_DURATION);
+ }
+
+ /**
+ * Called from relayout, to indicate the next "finishDrawing" will contain
+ * all changes applied by the time mPendingDrawHandlers was populated.
+ *
+ * See {@link WindowState#mPendingDrawHandlers}
+ */
+ void prepareDrawHandlers() {
+ mReadyDrawHandlers.addAll(mPendingDrawHandlers);
+ mPendingDrawHandlers.clear();
+ }
+
+ /**
+ * Drain the draw handlers, called from finishDrawing()
+ * See {@link WindowState#mPendingDrawHandlers}
+ */
+ boolean executeDrawHandlers(SurfaceControl.Transaction t) {
+ if (t == null) t = mTmpTransaction;
+ boolean hadHandlers = false;
+ for (int i = 0; i < mReadyDrawHandlers.size(); i++) {
+ mReadyDrawHandlers.get(i).accept(t);
+ hadHandlers = true;
+ }
+ mReadyDrawHandlers.clear();
+ mWmService.mH.removeMessages(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this);
+
+ t.apply();
+
+ return hadHandlers;
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowTracing.java b/services/core/java/com/android/server/wm/WindowTracing.java
index e8b8bfc..0bb97f5 100644
--- a/services/core/java/com/android/server/wm/WindowTracing.java
+++ b/services/core/java/com/android/server/wm/WindowTracing.java
@@ -114,15 +114,6 @@
* @param pw Print writer
*/
void stopTrace(@Nullable PrintWriter pw) {
- stopTrace(pw, true /* writeToFile */);
- }
-
- /**
- * Stops the trace
- * @param pw Print writer
- * @param writeToFile If the current buffer should be written to disk or not
- */
- void stopTrace(@Nullable PrintWriter pw, boolean writeToFile) {
if (IS_USER) {
logAndPrintln(pw, "Error: Tracing is not supported on user builds.");
return;
@@ -135,12 +126,35 @@
logAndPrintln(pw, "ERROR: tracing was re-enabled while waiting for flush.");
throw new IllegalStateException("tracing enabled while waiting for flush.");
}
- if (writeToFile) {
- writeTraceToFileLocked();
- logAndPrintln(pw, "Trace written to " + mTraceFile + ".");
- }
+ writeTraceToFileLocked();
+ logAndPrintln(pw, "Trace written to " + mTraceFile + ".");
}
- ProtoLogImpl.getSingleInstance().stopProtoLog(pw, writeToFile);
+ ProtoLogImpl.getSingleInstance().stopProtoLog(pw, true);
+ }
+
+ /**
+ * Stops the trace and write the current buffer to disk then restart, if it's already running.
+ * @param pw Print writer
+ */
+ void saveForBugreport(@Nullable PrintWriter pw) {
+ if (IS_USER) {
+ logAndPrintln(pw, "Error: Tracing is not supported on user builds.");
+ return;
+ }
+ synchronized (mEnabledLock) {
+ if (!mEnabled) {
+ return;
+ }
+ mEnabled = mEnabledLockFree = false;
+ logAndPrintln(pw, "Stop tracing to " + mTraceFile + ". Waiting for traces to flush.");
+ writeTraceToFileLocked();
+ logAndPrintln(pw, "Trace written to " + mTraceFile + ".");
+ ProtoLogImpl.getSingleInstance().stopProtoLog(pw, true);
+ logAndPrintln(pw, "Start tracing to " + mTraceFile + ".");
+ mBuffer.resetBuffer();
+ mEnabled = mEnabledLockFree = true;
+ ProtoLogImpl.getSingleInstance().startProtoLog(pw);
+ }
}
private void setLogLevel(@WindowTraceLogLevel int logLevel, PrintWriter pw) {
@@ -188,6 +202,9 @@
case "stop":
stopTrace(pw);
return 0;
+ case "save-for-bugreport":
+ saveForBugreport(pw);
+ return 0;
case "status":
logAndPrintln(pw, getStatus());
return 0;
@@ -230,6 +247,7 @@
pw.println("Window manager trace options:");
pw.println(" start: Start logging");
pw.println(" stop: Stop logging");
+ pw.println(" save-for-bugreport: Save logging data to file if it's running.");
pw.println(" frame: Log trace once per frame");
pw.println(" transaction: Log each transaction");
pw.println(" size: Set the maximum log size (in KB)");
@@ -316,19 +334,6 @@
}
}
- /**
- * Writes the trace buffer to new file for the bugreport.
- *
- * This method is synchronized with {@code #startTrace(PrintWriter)} and
- * {@link #stopTrace(PrintWriter)}.
- */
- void writeTraceToFile() {
- synchronized (mEnabledLock) {
- writeTraceToFileLocked();
- }
- ProtoLogImpl.getSingleInstance().writeProtoLogToFile();
- }
-
private void logAndPrintln(@Nullable PrintWriter pw, String msg) {
Log.i(TAG, msg);
if (pw != null) {
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 29bce79..0a02a86 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -49,7 +49,6 @@
"com_android_server_net_NetworkStatsService.cpp",
"com_android_server_power_PowerManagerService.cpp",
"com_android_server_powerstats_PowerStatsService.cpp",
- "com_android_server_security_VerityUtils.cpp",
"com_android_server_SerialService.cpp",
"com_android_server_soundtrigger_middleware_AudioSessionProviderImpl.cpp",
"com_android_server_soundtrigger_middleware_ExternalCaptureStateTracker.cpp",
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 1815f0c..03a0152 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -52,7 +52,6 @@
int register_android_hardware_display_DisplayViewport(JNIEnv* env);
int register_android_server_net_NetworkStatsFactory(JNIEnv* env);
int register_android_server_net_NetworkStatsService(JNIEnv* env);
-int register_android_server_security_VerityUtils(JNIEnv* env);
int register_android_server_am_CachedAppOptimizer(JNIEnv* env);
int register_android_server_am_LowMemDetector(JNIEnv* env);
int register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(JNIEnv* env);
@@ -106,7 +105,6 @@
register_android_hardware_display_DisplayViewport(env);
register_android_server_net_NetworkStatsFactory(env);
register_android_server_net_NetworkStatsService(env);
- register_android_server_security_VerityUtils(env);
register_android_server_am_CachedAppOptimizer(env);
register_android_server_am_LowMemDetector(env);
register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(env);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index a3dadd8..1590ef1 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -473,7 +473,7 @@
// to decide whether an existing policy in the {@link #DEVICE_POLICIES_XML} needs to
// be upgraded. See {@link PolicyVersionUpgrader} on instructions how to add an upgrade
// step.
- static final int DPMS_VERSION = 1;
+ static final int DPMS_VERSION = 2;
static {
SECURE_SETTINGS_ALLOWLIST = new ArraySet<>();
@@ -2969,8 +2969,9 @@
private class DpmsUpgradeDataProvider implements PolicyUpgraderDataProvider {
@Override
- public boolean isUserDeviceOwner(int userId) {
- return mOwners.isDeviceOwnerUserId(userId);
+ public boolean isUserDeviceOwner(int userId, ComponentName who) {
+ return mOwners.isDeviceOwnerUserId(userId)
+ && mOwners.getDeviceOwnerComponent().equals(who);
}
@Override
@@ -9329,6 +9330,8 @@
dumpResources(pw, mContext, "vendor_cross_profile_apps", R.array.vendor_cross_profile_apps);
dumpResources(pw, mContext, "config_packagesExemptFromSuspension",
R.array.config_packagesExemptFromSuspension);
+ dumpResources(pw, mContext, "policy_exempt_apps", R.array.policy_exempt_apps);
+ dumpResources(pw, mContext, "vendor_policy_exempt_apps", R.array.vendor_policy_exempt_apps);
pw.decreaseIndent();
pw.println();
}
@@ -14214,10 +14217,6 @@
hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
enforceCallerSystemUserHandle();
- // no effect if it's called from user build
- if (!mInjector.isBuildDebuggable()) {
- return;
- }
final int userId = UserHandle.USER_SYSTEM;
boolean isUserCompleted = mInjector.settingsSecureGetIntForUser(
Settings.Secure.USER_SETUP_COMPLETE, 0, userId) != 0;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyUpgraderDataProvider.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyUpgraderDataProvider.java
index b6420f8..c20d0f5 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyUpgraderDataProvider.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyUpgraderDataProvider.java
@@ -33,7 +33,7 @@
* Returns true if the provided {@code userId} is a device owner. May affect some policy
* defaults.
*/
- boolean isUserDeviceOwner(int userId);
+ boolean isUserDeviceOwner(int userId, ComponentName who);
/**
* Returns true if the storage manager indicates file-based encryption is enabled.
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java
index cea0863..2ab4b66 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java
@@ -83,6 +83,27 @@
currentVersion = 1;
}
+ if (currentVersion == 1) {
+ Slog.i(LOG_TAG, String.format("Upgrading from version %d", currentVersion));
+ // This upgrade step is for Device Owner scenario only: For devices upgrading to S,
+ // if there is a device owner, it retains the ability to control sensors-related
+ // permission grants.
+ for (int userId : allUsers) {
+ DevicePolicyData userData = allUsersData.get(userId);
+ if (userData == null) {
+ continue;
+ }
+ for (ActiveAdmin admin : userData.mAdminList) {
+ if (mProvider.isUserDeviceOwner(userId, admin.info.getComponent())) {
+ Slog.i(LOG_TAG, String.format(
+ "Marking Device Owner in user %d for permission grant ", userId));
+ admin.mAdminCanGrantSensorsPermissions = true;
+ }
+ }
+ }
+ currentVersion = 2;
+ }
+
writePoliciesAndVersion(allUsers, allUsersData, currentVersion);
}
diff --git a/services/incremental/Android.bp b/services/incremental/Android.bp
index 5ffbd77..5140b9f 100644
--- a/services/incremental/Android.bp
+++ b/services/incremental/Android.bp
@@ -68,6 +68,7 @@
"libutils",
"libvold_binder",
"libc++fs",
+ "libziparchive_for_incfs",
],
shared_libs: [
"libandroidfw",
@@ -77,7 +78,6 @@
"libincfs",
"liblog",
"libz",
- "libziparchive",
],
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/power/FaceDownDetectorTest.java b/services/tests/mockingservicestests/src/com/android/server/power/FaceDownDetectorTest.java
new file mode 100644
index 0000000..8ecb071
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/power/FaceDownDetectorTest.java
@@ -0,0 +1,255 @@
+/*
+ * 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.power;
+
+import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE;
+
+import static com.android.server.power.FaceDownDetector.KEY_FEATURE_ENABLED;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorManager;
+import android.os.PowerManager;
+import android.provider.DeviceConfig;
+import android.testing.TestableContext;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.server.testables.TestableDeviceConfig;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.time.Duration;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class FaceDownDetectorTest {
+ @ClassRule
+ public static final TestableContext sContext = new TestableContext(
+ InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
+ @Rule
+ public TestableDeviceConfig.TestableDeviceConfigRule
+ mDeviceConfigRule = new TestableDeviceConfig.TestableDeviceConfigRule();
+
+ private final FaceDownDetector mFaceDownDetector = new FaceDownDetector(this::onFlip);
+
+ @Mock private SensorManager mSensorManager;
+ @Mock private PowerManager mPowerManager;
+
+ private Duration mCurrentTime;
+ private int mOnFaceDownCalls;
+ private int mOnFaceDownExitCalls;
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ sContext.addMockSystemService(SensorManager.class, mSensorManager);
+ sContext.addMockSystemService(PowerManager.class, mPowerManager);
+ doReturn(true).when(mPowerManager).isInteractive();
+ DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
+ KEY_FEATURE_ENABLED, "true", false);
+ mCurrentTime = Duration.ZERO;
+ mOnFaceDownCalls = 0;
+ mOnFaceDownExitCalls = 0;
+ }
+
+ @Test
+ public void faceDownFor2Seconds_triggersFaceDown() throws Exception {
+ mFaceDownDetector.systemReady(sContext);
+
+ triggerFaceDown();
+
+ assertThat(mOnFaceDownCalls).isEqualTo(1);
+ assertThat(mOnFaceDownExitCalls).isEqualTo(0);
+ }
+
+ @Test
+ public void faceDownFor2Seconds_withMotion_DoesNotTriggerFaceDown() throws Exception {
+ mFaceDownDetector.systemReady(sContext);
+
+ // Face up
+ mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, 10.0f));
+
+ for (int i = 0; i < 100; i++) {
+ advanceTime(Duration.ofMillis(20));
+ //Move along x direction
+ mFaceDownDetector.onSensorChanged(createTestEvent(0.5f * i, 0.0f, -10.0f));
+ }
+
+ assertThat(mOnFaceDownCalls).isEqualTo(0);
+ assertThat(mOnFaceDownExitCalls).isEqualTo(0);
+ }
+
+ @Test
+ public void faceDownForHalfSecond_DoesNotTriggerFaceDown() throws Exception {
+ mFaceDownDetector.systemReady(sContext);
+
+ // Face up
+ mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, 10.0f));
+
+ for (int i = 0; i < 100; i++) {
+ advanceTime(Duration.ofMillis(5));
+ mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, -10.0f));
+ }
+
+ assertThat(mOnFaceDownCalls).isEqualTo(0);
+ assertThat(mOnFaceDownExitCalls).isEqualTo(0);
+ }
+
+ @Test
+ public void faceDownFor2Seconds_followedByFaceUp_triggersFaceDownExit() throws Exception {
+ mFaceDownDetector.systemReady(sContext);
+
+ triggerFaceDown();
+
+ // Phone flips
+ for (int i = 0; i < 10; i++) {
+ advanceTime(Duration.ofMillis(5));
+ mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 1.0f, 0.0f));
+ }
+
+ assertThat(mOnFaceDownCalls).isEqualTo(1);
+ assertThat(mOnFaceDownExitCalls).isEqualTo(1);
+ }
+
+ @Test
+ public void notInteractive_doesNotTriggerFaceDown() throws Exception {
+ doReturn(false).when(mPowerManager).isInteractive();
+ mFaceDownDetector.systemReady(sContext);
+
+ triggerFaceDown();
+
+ assertThat(mOnFaceDownCalls).isEqualTo(0);
+ assertThat(mOnFaceDownExitCalls).isEqualTo(0);
+ }
+
+ @Test
+ public void afterDisablingFeature_doesNotTriggerFaceDown() throws Exception {
+ mFaceDownDetector.systemReady(sContext);
+ setEnabled(false);
+
+ triggerFaceDown();
+
+ assertThat(mOnFaceDownCalls).isEqualTo(0);
+ }
+
+ @Test
+ public void afterReenablingWhileNonInteractive_doesNotTriggerFaceDown() throws Exception {
+ mFaceDownDetector.systemReady(sContext);
+ setEnabled(false);
+
+ doReturn(false).when(mPowerManager).isInteractive();
+ setEnabled(true);
+
+ triggerFaceDown();
+
+ assertThat(mOnFaceDownCalls).isEqualTo(0);
+ }
+
+ @Test
+ public void afterReenablingWhileInteractive_doesTriggerFaceDown() throws Exception {
+ mFaceDownDetector.systemReady(sContext);
+ setEnabled(false);
+
+ setEnabled(true);
+
+ triggerFaceDown();
+
+ assertThat(mOnFaceDownCalls).isEqualTo(1);
+ }
+
+ private void triggerFaceDown() throws Exception {
+ // Face up
+ // Using 0.5 on x to simulate constant acceleration, such as a sloped surface.
+ mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, 10.0f));
+
+ for (int i = 0; i < 200; i++) {
+ advanceTime(Duration.ofMillis(20));
+ mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, -10.0f));
+ }
+ }
+
+ private void setEnabled(Boolean enabled) throws Exception {
+ DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
+ KEY_FEATURE_ENABLED, enabled.toString(), false);
+ waitForListenerToHandle();
+ }
+
+ private void advanceTime(Duration duration) {
+ mCurrentTime = mCurrentTime.plus(duration);
+ }
+
+ /**
+ * Create a test event to replicate an accelerometer sensor event.
+ * @param x Acceleration along the x dimension.
+ * @param y Acceleration along the y dimension.
+ * @param gravity Acceleration along the Z dimension. Relates to
+ */
+ private SensorEvent createTestEvent(float x, float y, float gravity) throws Exception {
+ final Constructor<SensorEvent> constructor =
+ SensorEvent.class.getDeclaredConstructor(int.class);
+ constructor.setAccessible(true);
+ final SensorEvent event = constructor.newInstance(3);
+ event.sensor = createSensor(Sensor.TYPE_ACCELEROMETER, Sensor.STRING_TYPE_ACCELEROMETER);
+ event.values[0] = x;
+ event.values[1] = y;
+ event.values[2] = gravity;
+ event.timestamp = mCurrentTime.toNanos();
+ return event;
+ }
+
+ private void onFlip(boolean isFaceDown) {
+ if (isFaceDown) {
+ mOnFaceDownCalls++;
+ } else {
+ mOnFaceDownExitCalls++;
+ }
+ }
+
+ private Sensor createSensor(int type, String strType) throws Exception {
+ Constructor<Sensor> constr = Sensor.class.getDeclaredConstructor();
+ constr.setAccessible(true);
+ Sensor sensor = constr.newInstance();
+ Method setter = Sensor.class.getDeclaredMethod("setType", Integer.TYPE);
+ setter.setAccessible(true);
+ setter.invoke(sensor, type);
+ if (strType != null) {
+ Field f = sensor.getClass().getDeclaredField("mStringType");
+ f.setAccessible(true);
+ f.set(sensor, strType);
+ }
+ return sensor;
+ }
+
+ private void waitForListenerToHandle() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ sContext.getMainExecutor().execute(latch::countDown);
+ assertThat(latch.await(5, TimeUnit.SECONDS)).isTrue();
+ }
+}
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 07f6732..1c96838 100644
--- a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
@@ -40,9 +40,11 @@
import android.net.Uri;
import android.os.RemoteException;
import android.os.UserManager;
+import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
+import com.android.server.LocalServices;
import com.android.server.SystemService;
import org.junit.Before;
@@ -60,6 +62,7 @@
* Tests for {@link com.android.server.apphibernation.AppHibernationService}
*/
@SmallTest
+@Presubmit
public final class AppHibernationServiceTest {
private static final String PACKAGE_SCHEME = "package";
private static final String PACKAGE_NAME_1 = "package1";
@@ -91,6 +94,7 @@
MockitoAnnotations.initMocks(this);
doReturn(mContext).when(mContext).createContextAsUser(any(), anyInt());
+ LocalServices.removeServiceForTest(AppHibernationManagerInternal.class);
mAppHibernationService = new AppHibernationService(new MockInjector(mContext));
verify(mContext).registerReceiver(mReceiverCaptor.capture(), any());
diff --git a/services/tests/servicestests/src/com/android/server/apphibernation/HibernationStateDiskStoreTest.java b/services/tests/servicestests/src/com/android/server/apphibernation/HibernationStateDiskStoreTest.java
index 59f3c35..2237c84 100644
--- a/services/tests/servicestests/src/com/android/server/apphibernation/HibernationStateDiskStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/apphibernation/HibernationStateDiskStoreTest.java
@@ -19,6 +19,7 @@
import static org.junit.Assert.assertEquals;
import android.os.FileUtils;
+import android.platform.test.annotations.Presubmit;
import android.util.proto.ProtoInputStream;
import android.util.proto.ProtoOutputStream;
@@ -48,6 +49,7 @@
@SmallTest
+@Presubmit
public class HibernationStateDiskStoreTest {
private static final String STATES_FILE_NAME = "states";
private final MockScheduledExecutorService mMockScheduledExecutorService =
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 87100a6..89435e9 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -3875,7 +3875,7 @@
}
@Test
- public void testForceUpdateUserSetupComplete_userbuild() {
+ public void testForceUpdateUserSetupComplete_forcesUpdate() {
mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
@@ -3888,34 +3888,6 @@
userData.mUserSetupComplete = true;
dpms.mUserData.put(UserHandle.USER_SYSTEM, userData);
- // GIVEN it's user build
- getServices().buildMock.isDebuggable = false;
-
- assertThat(dpms.hasUserSetupCompleted()).isTrue();
-
- dpm.forceUpdateUserSetupComplete();
-
- // THEN the state in dpms is not changed
- assertThat(dpms.hasUserSetupCompleted()).isTrue();
- }
-
- @Test
- public void testForceUpdateUserSetupComplete_userDebugbuild() {
- mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
- mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
-
- final int userId = UserHandle.USER_SYSTEM;
- // GIVEN userComplete is false in SettingsProvider
- setUserSetupCompleteForUser(false, userId);
-
- // GIVEN userComplete is true in DPM
- DevicePolicyData userData = new DevicePolicyData(userId);
- userData.mUserSetupComplete = true;
- dpms.mUserData.put(UserHandle.USER_SYSTEM, userData);
-
- // GIVEN it's userdebug build
- getServices().buildMock.isDebuggable = true;
-
assertThat(dpms.hasUserSetupCompleted()).isTrue();
dpm.forceUpdateUserSetupComplete();
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java
index f94b800a..2fe47d3 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java
@@ -21,6 +21,11 @@
import android.app.admin.DeviceAdminInfo;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.os.Parcel;
+import android.util.TypedXmlPullParser;
+import android.util.Xml;
import androidx.test.InstrumentationRegistry;
@@ -32,9 +37,14 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
import java.io.IOException;
+import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
@@ -44,18 +54,21 @@
public class PolicyVersionUpgraderTest {
// NOTE: Only change this value if the corresponding CL also adds a test to test the upgrade
// to the new version.
- private static final int LATEST_TESTED_VERSION = 1;
+ private static final int LATEST_TESTED_VERSION = 2;
+ public static final String PERMISSIONS_TAG = "admin-can-grant-sensors-permissions";
+ private ComponentName mFakeAdmin;
private static class FakePolicyUpgraderDataProvider implements PolicyUpgraderDataProvider {
int mDeviceOwnerUserId;
+ ComponentName mDeviceOwnerComponent = new ComponentName("", "");
boolean mIsFileBasedEncryptionEnabled;
Map<Integer, ComponentName> mUserToComponent = new HashMap<>();
- Map<ComponentName, DeviceAdminInfo> mComponentToDeviceAdminInfo;
+ Map<ComponentName, DeviceAdminInfo> mComponentToDeviceAdminInfo = new HashMap<>();
File mDataDir;
@Override
- public boolean isUserDeviceOwner(int userId) {
- return userId == mDeviceOwnerUserId;
+ public boolean isUserDeviceOwner(int userId, ComponentName who) {
+ return userId == mDeviceOwnerUserId && mDeviceOwnerComponent.equals(who);
}
@Override
@@ -105,7 +118,14 @@
mUpgrader = new PolicyVersionUpgrader(mProvider);
mDataDir = new File(mRealTestContext.getCacheDir(), "test-data");
mDataDir.getParentFile().mkdirs();
+ // Prepare provider.
mProvider.mDataDir = mDataDir;
+ mFakeAdmin = new ComponentName(
+ "com.android.frameworks.servicestests",
+ "com.android.server.devicepolicy.DummyDeviceAdmins$Admin1");
+ ActivityInfo activityInfo = createActivityInfo(mFakeAdmin);
+ DeviceAdminInfo dai = createDeviceAdminInfo(activityInfo);
+ mProvider.mComponentToDeviceAdminInfo.put(mFakeAdmin, dai);
}
@Test
@@ -122,21 +142,43 @@
}
@Test
- public void testUpgrade0To1RemovesPasswordMetrics() throws IOException {
+ public void testUpgrade0To1RemovesPasswordMetrics() throws IOException, XmlPullParserException {
+ final String activePasswordTag = "active-password";
int[] users = new int[] {0, 10};
writeVersionToXml(0);
for (int userId : users) {
preparePoliciesFile(userId);
}
-
- String oldContents = readPoliciesFile(0);
- assertThat(oldContents).contains("active-password");
+ // Validate test set-up.
+ assertThat(isTagPresent(readPoliciesFileToStream(0), activePasswordTag)).isTrue();
mUpgrader.upgradePolicy(users, 1);
- assertThat(readVersionFromXml()).isEqualTo(1);
- assertThat(readPoliciesFile(users[0])).doesNotContain("active-password");
- assertThat(readPoliciesFile(users[1])).doesNotContain("active-password");
+ assertThat(readVersionFromXml()).isGreaterThan(1);
+ for (int user: users) {
+ assertThat(isTagPresent(readPoliciesFileToStream(user), activePasswordTag)).isFalse();
+ }
+ }
+
+ @Test
+ public void testUpgrade1To2MarksDoForPermissionControl()
+ throws IOException, XmlPullParserException {
+ int[] users = new int[] {0, 10};
+ writeVersionToXml(1);
+ for (int userId : users) {
+ preparePoliciesFile(userId);
+ }
+ mProvider.mDeviceOwnerUserId = 10;
+ mProvider.mDeviceOwnerComponent = mFakeAdmin;
+ mProvider.mUserToComponent.put(10, mFakeAdmin);
+
+ mUpgrader.upgradePolicy(users, 2);
+
+ assertThat(readVersionFromXml()).isEqualTo(2);
+ assertThat(getBooleanValueTag(readPoliciesFileToStream(users[0]),
+ PERMISSIONS_TAG)).isFalse();
+ assertThat(getBooleanValueTag(readPoliciesFileToStream(users[1]),
+ PERMISSIONS_TAG)).isTrue();
}
@Test
@@ -169,6 +211,70 @@
private String readPoliciesFile(int userId) throws IOException {
File policiesFile = mProvider.makeDevicePoliciesJournaledFile(userId).chooseForRead();
- return new String(Files.asByteSource(policiesFile).read());
+ FileReader reader = new FileReader(policiesFile);
+ return new String(Files.asByteSource(policiesFile).read(), Charset.defaultCharset());
+ }
+
+ private InputStream readPoliciesFileToStream(int userId) throws IOException {
+ File policiesFile = mProvider.makeDevicePoliciesJournaledFile(userId).chooseForRead();
+ return new FileInputStream(policiesFile);
+ }
+
+ private boolean getBooleanValueTag(InputStream inputXml, String tagName)
+ throws IOException, XmlPullParserException {
+ TypedXmlPullParser parser = Xml.resolvePullParser(inputXml);
+
+ int eventType = parser.getEventType();
+ while (eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG) {
+ String tag = parser.getName();
+ if (tagName.equals(tag)) {
+ String res = parser.getAttributeValue(null, "value");
+ return Boolean.parseBoolean(res);
+ }
+ }
+ eventType = parser.next();
+ }
+
+ throw new IllegalStateException("Could not find " + tagName);
+ }
+
+ private boolean isTagPresent(InputStream inputXml, String tagName)
+ throws IOException, XmlPullParserException {
+ TypedXmlPullParser parser = Xml.resolvePullParser(inputXml);
+
+ int eventType = parser.getEventType();
+ while (eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG) {
+ String tag = parser.getName();
+ if (tagName.equals(tag)) {
+ return true;
+ }
+ }
+ eventType = parser.next();
+ }
+
+ return false;
+ }
+
+ private ActivityInfo createActivityInfo(ComponentName admin) {
+ ActivityInfo ai = new ActivityInfo();
+ ApplicationInfo applicationInfo = new ApplicationInfo();
+ applicationInfo.className = admin.getClassName();
+ applicationInfo.uid = 2222;
+ ai.applicationInfo = applicationInfo;
+ ai.name = admin.getClassName();
+ ai.packageName = admin.getPackageName();
+ return ai;
+ }
+
+ private DeviceAdminInfo createDeviceAdminInfo(ActivityInfo activityInfo) {
+ Parcel parcel = Parcel.obtain();
+ activityInfo.writeToParcel(parcel, 0);
+ parcel.writeInt(0);
+ parcel.writeBoolean(true);
+ parcel.setDataPosition(0);
+
+ return DeviceAdminInfo.CREATOR.createFromParcel(parcel);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index 915392e..1a6bad8 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -61,6 +61,12 @@
/** Tests for {@link HdmiCecLocalDevicePlayback} class. */
public class HdmiCecLocalDevicePlaybackTest {
+ private static final int PORT_1 = 1;
+ private static final HdmiDeviceInfo INFO_TV = new HdmiDeviceInfo(
+ ADDR_TV, 0x0000, PORT_1, HdmiDeviceInfo.DEVICE_TV,
+ 0x1234, "TV",
+ HdmiControlManager.POWER_STATUS_ON, HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
+
private HdmiControlService mHdmiControlService;
private HdmiCecController mHdmiCecController;
private HdmiCecLocalDevicePlayback mHdmiCecLocalDevicePlayback;
@@ -159,6 +165,7 @@
mNativeWrapper.setPhysicalAddress(mPlaybackPhysicalAddress);
mTestLooper.dispatchAll();
mPlaybackLogicalAddress = mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress();
+ mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
mNativeWrapper.clearResultMessages();
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
new file mode 100644
index 0000000..907cf3e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
@@ -0,0 +1,420 @@
+/*
+ * 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.hdmi;
+
+import static com.android.server.hdmi.Constants.ADDR_TV;
+import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
+import static com.android.server.hdmi.OneTouchPlayAction.STATE_WAITING_FOR_REPORT_POWER_STATUS;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.hardware.hdmi.HdmiControlManager;
+import android.hardware.hdmi.HdmiDeviceInfo;
+import android.hardware.hdmi.IHdmiControlCallback;
+import android.media.AudioManager;
+import android.os.Handler;
+import android.os.IPowerManager;
+import android.os.IThermalService;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.test.TestLooper;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import com.android.server.hdmi.HdmiCecFeatureAction.ActionTimer;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+/** Tests for {@link OneTouchPlayAction} */
+@SmallTest
+@RunWith(JUnit4.class)
+public class OneTouchPlayActionTest {
+ private static final byte[] POWER_ON = new byte[]{HdmiControlManager.POWER_STATUS_ON};
+ private static final byte[] POWER_TRANSIENT_TO_ON =
+ new byte[]{HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON};
+
+ private static final int PORT_1 = 1;
+ private static final HdmiDeviceInfo INFO_TV = new HdmiDeviceInfo(
+ ADDR_TV, 0x0000, PORT_1, HdmiDeviceInfo.DEVICE_TV,
+ 0x1234, "TV",
+ HdmiControlManager.POWER_STATUS_ON, HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
+
+ private Context mContextSpy;
+ private HdmiControlService mHdmiControlService;
+ private FakeNativeWrapper mNativeWrapper;
+
+ private TestLooper mTestLooper = new TestLooper();
+ private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
+ private int mPhysicalAddress;
+
+ @Mock
+ private IPowerManager mIPowerManagerMock;
+ @Mock
+ private IThermalService mIThermalServiceMock;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
+
+ PowerManager powerManager = new PowerManager(mContextSpy, mIPowerManagerMock,
+ mIThermalServiceMock, new Handler(mTestLooper.getLooper()));
+ when(mContextSpy.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager);
+ when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
+ when(mIPowerManagerMock.isInteractive()).thenReturn(true);
+
+ mHdmiControlService = new HdmiControlService(mContextSpy) {
+ @Override
+ AudioManager getAudioManager() {
+ return new AudioManager() {
+ @Override
+ public void setWiredDeviceConnectionState(
+ int type, int state, String address, String name) {
+ // Do nothing.
+ }
+ };
+ }
+
+ @Override
+ void wakeUp() {
+ }
+
+ @Override
+ boolean isPowerStandby() {
+ return false;
+ }
+
+ @Override
+ protected PowerManager getPowerManager() {
+ return powerManager;
+ }
+
+ @Override
+ protected void writeStringSystemProperty(String key, String value) {
+ // do nothing
+ }
+ };
+
+ Looper looper = mTestLooper.getLooper();
+ mHdmiControlService.setIoLooper(looper);
+ mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy));
+ mNativeWrapper = new FakeNativeWrapper();
+ HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
+ this.mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
+ mHdmiControlService.setCecController(hdmiCecController);
+ mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
+ mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService));
+ mHdmiControlService.initService();
+ mPhysicalAddress = 0x2000;
+ mNativeWrapper.setPhysicalAddress(mPhysicalAddress);
+ mTestLooper.dispatchAll();
+ mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
+ }
+
+ private OneTouchPlayAction createOneTouchPlayAction(HdmiCecLocalDevicePlayback device,
+ TestActionTimer actionTimer, TestCallback callback, boolean isCec20) {
+ OneTouchPlayAction action = new OneTouchPlayAction(device, ADDR_TV, callback, isCec20);
+ action.setActionTimer(actionTimer);
+ return action;
+ }
+
+ @Test
+ public void succeedAfterGettingPowerStatusOn_Cec14b() {
+ HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
+ mHdmiControlService);
+ playbackDevice.init();
+ mLocalDevices.add(playbackDevice);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mTestLooper.dispatchAll();
+
+ TestActionTimer actionTimer = new TestActionTimer();
+ TestCallback callback = new TestCallback();
+ OneTouchPlayAction action = createOneTouchPlayAction(playbackDevice, actionTimer, callback,
+ false);
+ playbackDevice.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
+ playbackDevice.mAddress, mPhysicalAddress);
+ HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(playbackDevice.mAddress,
+ ADDR_TV);
+ HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder
+ .buildGiveDevicePowerStatus(playbackDevice.mAddress, ADDR_TV);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
+ mNativeWrapper.clearResultMessages();
+ assertThat(actionTimer.getState()).isEqualTo(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ HdmiCecMessage reportPowerStatusOn = new HdmiCecMessage(
+ ADDR_TV, playbackDevice.mAddress, Constants.MESSAGE_REPORT_POWER_STATUS, POWER_ON);
+ action.processCommand(reportPowerStatusOn);
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus);
+ assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
+ }
+
+ @Test
+ public void succeedAfterGettingTransientPowerStatus_Cec14b() {
+ HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
+ mHdmiControlService);
+ playbackDevice.init();
+ mLocalDevices.add(playbackDevice);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mTestLooper.dispatchAll();
+
+ TestActionTimer actionTimer = new TestActionTimer();
+ TestCallback callback = new TestCallback();
+ OneTouchPlayAction action = createOneTouchPlayAction(playbackDevice, actionTimer, callback,
+ false);
+ playbackDevice.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
+ playbackDevice.mAddress, mPhysicalAddress);
+ HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(playbackDevice.mAddress,
+ ADDR_TV);
+ HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder
+ .buildGiveDevicePowerStatus(playbackDevice.mAddress, ADDR_TV);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
+ mNativeWrapper.clearResultMessages();
+ assertThat(actionTimer.getState()).isEqualTo(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ HdmiCecMessage reportPowerStatusTransientToOn = new HdmiCecMessage(
+ ADDR_TV, playbackDevice.mAddress, Constants.MESSAGE_REPORT_POWER_STATUS,
+ POWER_TRANSIENT_TO_ON);
+ action.processCommand(reportPowerStatusTransientToOn);
+ action.handleTimerEvent(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
+ mNativeWrapper.clearResultMessages();
+
+ HdmiCecMessage reportPowerStatusOn = new HdmiCecMessage(
+ ADDR_TV, playbackDevice.mAddress, Constants.MESSAGE_REPORT_POWER_STATUS, POWER_ON);
+ action.processCommand(reportPowerStatusOn);
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus);
+ assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
+ }
+
+ @Test
+ public void timeOut_Cec14b() {
+ HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
+ mHdmiControlService);
+ playbackDevice.init();
+ mLocalDevices.add(playbackDevice);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mTestLooper.dispatchAll();
+
+ TestActionTimer actionTimer = new TestActionTimer();
+ TestCallback callback = new TestCallback();
+ OneTouchPlayAction action = createOneTouchPlayAction(playbackDevice, actionTimer, callback,
+ false);
+ playbackDevice.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
+ playbackDevice.mAddress, mPhysicalAddress);
+ HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(playbackDevice.mAddress,
+ ADDR_TV);
+ HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder
+ .buildGiveDevicePowerStatus(playbackDevice.mAddress, ADDR_TV);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
+ mNativeWrapper.clearResultMessages();
+ assertThat(actionTimer.getState()).isEqualTo(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ for (int i = 0; i < 10; ++i) {
+ action.handleTimerEvent(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ mTestLooper.dispatchAll();
+ }
+
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
+ action.handleTimerEvent(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TIMEOUT);
+ }
+
+ @Test
+ public void succeedIfPowerStatusOn_Cec20() {
+ HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
+ mHdmiControlService);
+ playbackDevice.init();
+ mLocalDevices.add(playbackDevice);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mHdmiControlService.getHdmiCecNetwork().updateDevicePowerStatus(ADDR_TV,
+ HdmiControlManager.POWER_STATUS_ON);
+ mTestLooper.dispatchAll();
+
+ TestActionTimer actionTimer = new TestActionTimer();
+ TestCallback callback = new TestCallback();
+ OneTouchPlayAction action = createOneTouchPlayAction(playbackDevice, actionTimer, callback,
+ true);
+ playbackDevice.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
+ playbackDevice.mAddress, mPhysicalAddress);
+ HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(playbackDevice.mAddress,
+ ADDR_TV);
+ HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder
+ .buildGiveDevicePowerStatus(playbackDevice.mAddress, ADDR_TV);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus);
+ assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
+ }
+
+ @Test
+ public void succeedIfPowerStatusUnknown_Cec20() {
+ HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
+ mHdmiControlService);
+ playbackDevice.init();
+ mLocalDevices.add(playbackDevice);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mHdmiControlService.getHdmiCecNetwork().updateDevicePowerStatus(ADDR_TV,
+ HdmiControlManager.POWER_STATUS_UNKNOWN);
+ mTestLooper.dispatchAll();
+
+ TestActionTimer actionTimer = new TestActionTimer();
+ TestCallback callback = new TestCallback();
+ OneTouchPlayAction action = createOneTouchPlayAction(playbackDevice, actionTimer, callback,
+ true);
+ playbackDevice.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
+ playbackDevice.mAddress, mPhysicalAddress);
+ HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(playbackDevice.mAddress,
+ ADDR_TV);
+ HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder
+ .buildGiveDevicePowerStatus(playbackDevice.mAddress, ADDR_TV);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
+ mNativeWrapper.clearResultMessages();
+ assertThat(actionTimer.getState()).isEqualTo(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ HdmiCecMessage reportPowerStatusOn = new HdmiCecMessage(
+ ADDR_TV, playbackDevice.mAddress, Constants.MESSAGE_REPORT_POWER_STATUS, POWER_ON);
+ action.processCommand(reportPowerStatusOn);
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus);
+ assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
+ }
+
+ @Test
+ public void succeedIfPowerStatusStandby_Cec20() {
+ HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
+ mHdmiControlService);
+ playbackDevice.init();
+ mLocalDevices.add(playbackDevice);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mHdmiControlService.getHdmiCecNetwork().updateDevicePowerStatus(ADDR_TV,
+ HdmiControlManager.POWER_STATUS_STANDBY);
+ mTestLooper.dispatchAll();
+
+ TestActionTimer actionTimer = new TestActionTimer();
+ TestCallback callback = new TestCallback();
+ OneTouchPlayAction action = createOneTouchPlayAction(playbackDevice, actionTimer, callback,
+ true);
+ playbackDevice.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
+ playbackDevice.mAddress, mPhysicalAddress);
+ HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(playbackDevice.mAddress,
+ ADDR_TV);
+ HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder
+ .buildGiveDevicePowerStatus(playbackDevice.mAddress, ADDR_TV);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus);
+ mNativeWrapper.clearResultMessages();
+ assertThat(actionTimer.getState()).isEqualTo(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ HdmiCecMessage reportPowerStatusOn = new HdmiCecMessage(
+ ADDR_TV, playbackDevice.mAddress, Constants.MESSAGE_REPORT_POWER_STATUS, POWER_ON);
+ action.processCommand(reportPowerStatusOn);
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus);
+ assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
+ }
+
+ private static class TestActionTimer implements ActionTimer {
+ private int mState;
+
+ @Override
+ public void sendTimerMessage(int state, long delayMillis) {
+ mState = state;
+ }
+
+ @Override
+ public void clearTimerMessage() {
+ }
+
+ private int getState() {
+ return mState;
+ }
+ }
+
+ private static class TestCallback extends IHdmiControlCallback.Stub {
+ private final ArrayList<Integer> mCallbackResult = new ArrayList<Integer>();
+
+ @Override
+ public void onComplete(int result) {
+ mCallbackResult.add(result);
+ }
+
+ private int getResult() {
+ assertThat(mCallbackResult.size()).isEqualTo(1);
+ return mCallbackResult.get(0);
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java
new file mode 100644
index 0000000..865eb7a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java
@@ -0,0 +1,343 @@
+/*
+ * 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.hdmi;
+
+
+import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
+import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
+import static com.android.server.hdmi.SystemAudioAutoInitiationAction.RETRIES_ON_TIMEOUT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.hardware.hdmi.HdmiPortInfo;
+import android.media.AudioManager;
+import android.os.Handler;
+import android.os.IPowerManager;
+import android.os.IThermalService;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.test.TestLooper;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+/**
+ * Test for {@link SystemAudioAutoInitiationAction}.
+ */
+@SmallTest
+@RunWith(JUnit4.class)
+public class SystemAudioAutoInitiationActionTest {
+
+ private Context mContextSpy;
+ private HdmiControlService mHdmiControlService;
+ private FakeNativeWrapper mNativeWrapper;
+
+ private HdmiCecLocalDeviceTv mHdmiCecLocalDeviceTv;
+
+ private TestLooper mTestLooper = new TestLooper();
+ private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
+ private int mPhysicalAddress;
+
+ @Mock
+ private IPowerManager mIPowerManagerMock;
+ @Mock
+ private IThermalService mIThermalServiceMock;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
+
+ Looper myLooper = mTestLooper.getLooper();
+ PowerManager powerManager = new PowerManager(mContextSpy, mIPowerManagerMock,
+ mIThermalServiceMock, new Handler(myLooper));
+ when(mContextSpy.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager);
+ when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
+ when(mIPowerManagerMock.isInteractive()).thenReturn(true);
+
+ mHdmiControlService = new HdmiControlService(mContextSpy) {
+ @Override
+ AudioManager getAudioManager() {
+ return new AudioManager() {
+ @Override
+ public void setWiredDeviceConnectionState(
+ int type, int state, String address, String name) {
+ // Do nothing.
+ }
+ };
+ }
+
+ @Override
+ void wakeUp() {
+ }
+
+ @Override
+ boolean isPowerStandby() {
+ return false;
+ }
+
+ @Override
+ protected PowerManager getPowerManager() {
+ return powerManager;
+ }
+
+ @Override
+ protected void writeStringSystemProperty(String key, String value) {
+ // do nothing
+ }
+ };
+
+ mHdmiCecLocalDeviceTv = new HdmiCecLocalDeviceTv(mHdmiControlService);
+ mHdmiCecLocalDeviceTv.init();
+ mHdmiControlService.setIoLooper(myLooper);
+ mNativeWrapper = new FakeNativeWrapper();
+ HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
+ mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
+ mHdmiControlService.setCecController(hdmiCecController);
+ mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
+ mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService));
+ mLocalDevices.add(mHdmiCecLocalDeviceTv);
+ HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[2];
+ hdmiPortInfos[0] =
+ new HdmiPortInfo(1, HdmiPortInfo.PORT_INPUT, 0x1000, true, false, false);
+ hdmiPortInfos[1] =
+ new HdmiPortInfo(2, HdmiPortInfo.PORT_INPUT, 0x2000, true, false, true);
+ mNativeWrapper.setPortInfo(hdmiPortInfos);
+ mHdmiControlService.initService();
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mPhysicalAddress = 0x0000;
+ mNativeWrapper.setPhysicalAddress(mPhysicalAddress);
+ mTestLooper.dispatchAll();
+ mPhysicalAddress = mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress();
+ mNativeWrapper.clearResultMessages();
+ }
+
+ private void setSystemAudioSetting(boolean on) {
+ mHdmiCecLocalDeviceTv.setSystemAudioControlFeatureEnabled(on);
+ }
+
+ private void setTvHasSystemAudioChangeAction() {
+ mHdmiCecLocalDeviceTv.addAndStartAction(
+ new SystemAudioActionFromTv(mHdmiCecLocalDeviceTv, Constants.ADDR_AUDIO_SYSTEM,
+ true, null));
+ }
+
+ @Test
+ public void testReceiveSystemAudioMode_systemAudioOn() {
+ // Record that previous system audio mode is on.
+ setSystemAudioSetting(true);
+
+ HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv,
+ ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceTv.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage giveSystemAudioModeStatus =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mHdmiCecLocalDeviceTv.mAddress, ADDR_AUDIO_SYSTEM);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+
+ HdmiCecMessage reportSystemAudioMode = HdmiCecMessageBuilder.buildReportSystemAudioMode(
+ ADDR_AUDIO_SYSTEM, mHdmiCecLocalDeviceTv.mAddress, true);
+ mHdmiControlService.handleCecCommand(reportSystemAudioMode);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiControlService.isSystemAudioActivated()).isTrue();
+ }
+
+ @Test
+ public void testReceiveSystemAudioMode_systemAudioOnAndImpossibleToChangeSystemAudio() {
+ // Turn on system audio.
+ setSystemAudioSetting(true);
+ // Impossible to change system audio mode while SystemAudioActionFromTv is in progress.
+ setTvHasSystemAudioChangeAction();
+
+ HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv,
+ ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceTv.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage giveSystemAudioModeStatus =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mHdmiCecLocalDeviceTv.mAddress, ADDR_AUDIO_SYSTEM);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+
+ HdmiCecMessage reportSystemAudioMode = HdmiCecMessageBuilder.buildReportSystemAudioMode(
+ ADDR_AUDIO_SYSTEM, mHdmiCecLocalDeviceTv.mAddress, true);
+ mHdmiControlService.handleCecCommand(reportSystemAudioMode);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiControlService.isSystemAudioActivated()).isFalse();
+ }
+
+ @Test
+ public void testReceiveSystemAudioMode_systemAudioOnAndResponseOff() {
+ // Record that previous system audio mode is on.
+ setSystemAudioSetting(true);
+
+ HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv,
+ ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceTv.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage giveSystemAudioModeStatus =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mHdmiCecLocalDeviceTv.mAddress, ADDR_AUDIO_SYSTEM);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+
+ HdmiCecMessage reportSystemAudioMode = HdmiCecMessageBuilder.buildReportSystemAudioMode(
+ ADDR_AUDIO_SYSTEM, mHdmiCecLocalDeviceTv.mAddress, false);
+ mHdmiControlService.handleCecCommand(reportSystemAudioMode);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiCecLocalDeviceTv.getActions(SystemAudioActionFromTv.class)).isNotEmpty();
+ SystemAudioActionFromTv resultingAction = mHdmiCecLocalDeviceTv.getActions(
+ SystemAudioActionFromTv.class).get(0);
+ assertThat(resultingAction.mTargetAudioStatus).isTrue();
+ }
+
+ @Test
+ public void testReceiveSystemAudioMode_settingOffAndResponseOn() {
+ // Turn off system audio.
+ setSystemAudioSetting(false);
+
+ HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv,
+ ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceTv.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage giveSystemAudioModeStatus =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mHdmiCecLocalDeviceTv.mAddress, ADDR_AUDIO_SYSTEM);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+
+ HdmiCecMessage reportSystemAudioMode = HdmiCecMessageBuilder.buildReportSystemAudioMode(
+ ADDR_AUDIO_SYSTEM, mHdmiCecLocalDeviceTv.mAddress, true);
+ mHdmiControlService.handleCecCommand(reportSystemAudioMode);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiCecLocalDeviceTv.getActions(SystemAudioActionFromTv.class)).isNotEmpty();
+ SystemAudioActionFromTv resultingAction = mHdmiCecLocalDeviceTv.getActions(
+ SystemAudioActionFromTv.class).get(0);
+ assertThat(resultingAction.mTargetAudioStatus).isFalse();
+ }
+
+ @Test
+ public void testReceiveSystemAudioMode_settingOffAndResponseOff() {
+ // Turn off system audio.
+ setSystemAudioSetting(false);
+
+ HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv,
+ ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceTv.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage giveSystemAudioModeStatus =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mHdmiCecLocalDeviceTv.mAddress, ADDR_AUDIO_SYSTEM);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+
+ HdmiCecMessage reportSystemAudioMode = HdmiCecMessageBuilder.buildReportSystemAudioMode(
+ ADDR_AUDIO_SYSTEM, mHdmiCecLocalDeviceTv.mAddress, false);
+ mHdmiControlService.handleCecCommand(reportSystemAudioMode);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiCecLocalDeviceTv.getActions(SystemAudioActionFromTv.class)).isEmpty();
+ assertThat(mHdmiControlService.isSystemAudioActivated()).isFalse();
+ }
+
+ @Test
+ public void testTimeout_systemAudioOn_retries() {
+ // Turn on system audio.
+ setSystemAudioSetting(true);
+
+ HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv,
+ ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceTv.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage giveSystemAudioModeStatus =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mHdmiCecLocalDeviceTv.mAddress, ADDR_AUDIO_SYSTEM);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+ mNativeWrapper.clearResultMessages();
+
+ mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
+ mTestLooper.dispatchAll();
+
+ // Retry sends <Give System Audio Mode Status> again
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+ }
+
+ @Test
+ public void testTimeout_systemAudioOn_allRetriesFail() {
+ boolean targetStatus = true;
+ // Turn on system audio.
+ setSystemAudioSetting(targetStatus);
+
+ HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv,
+ ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceTv.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage giveSystemAudioModeStatus =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mHdmiCecLocalDeviceTv.mAddress, ADDR_AUDIO_SYSTEM);
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+
+ for (int i = 0; i < RETRIES_ON_TIMEOUT; i++) {
+ mNativeWrapper.clearResultMessages();
+
+ // Target device doesn't respond within timeout
+ mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
+ mTestLooper.dispatchAll();
+
+ // Retry sends <Give System Audio Mode Status> again
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+ }
+
+ // Target device doesn't respond within timeouts
+ mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiCecLocalDeviceTv.getActions(SystemAudioActionFromTv.class)).isNotEmpty();
+ SystemAudioActionFromTv resultingAction = mHdmiCecLocalDeviceTv.getActions(
+ SystemAudioActionFromTv.class).get(0);
+ assertThat(resultingAction.mTargetAudioStatus).isEqualTo(targetStatus);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java
index 1db5544..d07831d 100644
--- a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java
@@ -11,15 +11,15 @@
* 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
+ * limitations under the License.
*/
package com.android.server.inputmethod;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
-import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
index 6ab48e5..9092ec3 100644
--- a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
@@ -177,10 +177,10 @@
private void assertRotationOrder(final ControllerImpl controller,
final boolean onlyCurrentIme,
final ImeSubtypeListItem... expectedRotationOrderOfImeSubtypeList) {
- final int N = expectedRotationOrderOfImeSubtypeList.length;
- for (int i = 0; i < N; i++) {
+ final int numItems = expectedRotationOrderOfImeSubtypeList.length;
+ for (int i = 0; i < numItems; i++) {
final int currentIndex = i;
- final int nextIndex = (currentIndex + 1) % N;
+ final int nextIndex = (currentIndex + 1) % numItems;
final ImeSubtypeListItem currentItem =
expectedRotationOrderOfImeSubtypeList[currentIndex];
final ImeSubtypeListItem nextItem = expectedRotationOrderOfImeSubtypeList[nextIndex];
@@ -200,47 +200,47 @@
@Test
public void testControllerImpl() throws Exception {
final List<ImeSubtypeListItem> disabledItems = createDisabledImeSubtypes();
- final ImeSubtypeListItem disabledIme_en_US = disabledItems.get(0);
+ final ImeSubtypeListItem disabledIme_en_us = disabledItems.get(0);
final ImeSubtypeListItem disabledIme_hi = disabledItems.get(1);
final ImeSubtypeListItem disabledSwitchingUnawareIme = disabledItems.get(2);
final ImeSubtypeListItem disabledSubtypeUnawareIme = disabledItems.get(3);
final List<ImeSubtypeListItem> enabledItems = createEnabledImeSubtypes();
- final ImeSubtypeListItem latinIme_en_US = enabledItems.get(0);
+ final ImeSubtypeListItem latinIme_en_us = enabledItems.get(0);
final ImeSubtypeListItem latinIme_fr = enabledItems.get(1);
- final ImeSubtypeListItem switchingUnawarelatinIme_en_UK = enabledItems.get(2);
- final ImeSubtypeListItem switchingUnawarelatinIme_hi = enabledItems.get(3);
+ final ImeSubtypeListItem switchingUnawareLatinIme_en_uk = enabledItems.get(2);
+ final ImeSubtypeListItem switchingUnawareLatinIme_hi = enabledItems.get(3);
final ImeSubtypeListItem subtypeUnawareIme = enabledItems.get(4);
- final ImeSubtypeListItem japaneseIme_ja_JP = enabledItems.get(5);
- final ImeSubtypeListItem switchUnawareJapaneseIme_ja_JP = enabledItems.get(6);
+ final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(5);
+ final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(6);
final ControllerImpl controller = ControllerImpl.createFrom(
null /* currentInstance */, enabledItems);
// switching-aware loop
assertRotationOrder(controller, false /* onlyCurrentIme */,
- latinIme_en_US, latinIme_fr, japaneseIme_ja_JP);
+ latinIme_en_us, latinIme_fr, japaneseIme_ja_jp);
// switching-unaware loop
assertRotationOrder(controller, false /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi, subtypeUnawareIme,
- switchUnawareJapaneseIme_ja_JP);
+ switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi, subtypeUnawareIme,
+ switchUnawareJapaneseIme_ja_jp);
// test onlyCurrentIme == true
assertRotationOrder(controller, true /* onlyCurrentIme */,
- latinIme_en_US, latinIme_fr);
+ latinIme_en_us, latinIme_fr);
assertRotationOrder(controller, true /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi);
+ switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
subtypeUnawareIme, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- japaneseIme_ja_JP, null);
+ japaneseIme_ja_jp, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- switchUnawareJapaneseIme_ja_JP, null);
+ switchUnawareJapaneseIme_ja_jp, null);
// Make sure that disabled IMEs are not accepted.
assertNextInputMethod(controller, false /* onlyCurrentIme */,
- disabledIme_en_US, null);
+ disabledIme_en_us, null);
assertNextInputMethod(controller, false /* onlyCurrentIme */,
disabledIme_hi, null);
assertNextInputMethod(controller, false /* onlyCurrentIme */,
@@ -248,7 +248,7 @@
assertNextInputMethod(controller, false /* onlyCurrentIme */,
disabledSubtypeUnawareIme, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- disabledIme_en_US, null);
+ disabledIme_en_us, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
disabledIme_hi, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
@@ -260,82 +260,82 @@
@Test
public void testControllerImplWithUserAction() throws Exception {
final List<ImeSubtypeListItem> enabledItems = createEnabledImeSubtypes();
- final ImeSubtypeListItem latinIme_en_US = enabledItems.get(0);
+ final ImeSubtypeListItem latinIme_en_us = enabledItems.get(0);
final ImeSubtypeListItem latinIme_fr = enabledItems.get(1);
- final ImeSubtypeListItem switchingUnawarelatinIme_en_UK = enabledItems.get(2);
+ final ImeSubtypeListItem switchingUnawarelatinIme_en_uk = enabledItems.get(2);
final ImeSubtypeListItem switchingUnawarelatinIme_hi = enabledItems.get(3);
final ImeSubtypeListItem subtypeUnawareIme = enabledItems.get(4);
- final ImeSubtypeListItem japaneseIme_ja_JP = enabledItems.get(5);
- final ImeSubtypeListItem switchUnawareJapaneseIme_ja_JP = enabledItems.get(6);
+ final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(5);
+ final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(6);
final ControllerImpl controller = ControllerImpl.createFrom(
null /* currentInstance */, enabledItems);
// === switching-aware loop ===
assertRotationOrder(controller, false /* onlyCurrentIme */,
- latinIme_en_US, latinIme_fr, japaneseIme_ja_JP);
+ latinIme_en_us, latinIme_fr, japaneseIme_ja_jp);
// Then notify that a user did something for latinIme_fr.
onUserAction(controller, latinIme_fr);
assertRotationOrder(controller, false /* onlyCurrentIme */,
- latinIme_fr, latinIme_en_US, japaneseIme_ja_JP);
+ latinIme_fr, latinIme_en_us, japaneseIme_ja_jp);
// Then notify that a user did something for latinIme_fr again.
onUserAction(controller, latinIme_fr);
assertRotationOrder(controller, false /* onlyCurrentIme */,
- latinIme_fr, latinIme_en_US, japaneseIme_ja_JP);
+ latinIme_fr, latinIme_en_us, japaneseIme_ja_jp);
// Then notify that a user did something for japaneseIme_ja_JP.
onUserAction(controller, latinIme_fr);
assertRotationOrder(controller, false /* onlyCurrentIme */,
- japaneseIme_ja_JP, latinIme_fr, latinIme_en_US);
+ japaneseIme_ja_jp, latinIme_fr, latinIme_en_us);
// Check onlyCurrentIme == true.
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- japaneseIme_ja_JP, null);
+ japaneseIme_ja_jp, null);
assertRotationOrder(controller, true /* onlyCurrentIme */,
- latinIme_fr, latinIme_en_US);
+ latinIme_fr, latinIme_en_us);
assertRotationOrder(controller, true /* onlyCurrentIme */,
- latinIme_en_US, latinIme_fr);
+ latinIme_en_us, latinIme_fr);
// === switching-unaware loop ===
assertRotationOrder(controller, false /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi, subtypeUnawareIme,
- switchUnawareJapaneseIme_ja_JP);
+ switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
+ switchUnawareJapaneseIme_ja_jp);
// User action should be ignored for switching unaware IMEs.
onUserAction(controller, switchingUnawarelatinIme_hi);
assertRotationOrder(controller, false /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi, subtypeUnawareIme,
- switchUnawareJapaneseIme_ja_JP);
+ switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
+ switchUnawareJapaneseIme_ja_jp);
// User action should be ignored for switching unaware IMEs.
- onUserAction(controller, switchUnawareJapaneseIme_ja_JP);
+ onUserAction(controller, switchUnawareJapaneseIme_ja_jp);
assertRotationOrder(controller, false /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi, subtypeUnawareIme,
- switchUnawareJapaneseIme_ja_JP);
+ switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
+ switchUnawareJapaneseIme_ja_jp);
// Check onlyCurrentIme == true.
assertRotationOrder(controller, true /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi);
+ switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
subtypeUnawareIme, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- switchUnawareJapaneseIme_ja_JP, null);
+ switchUnawareJapaneseIme_ja_jp, null);
// Rotation order should be preserved when created with the same subtype list.
final List<ImeSubtypeListItem> sameEnabledItems = createEnabledImeSubtypes();
final ControllerImpl newController = ControllerImpl.createFrom(controller,
sameEnabledItems);
assertRotationOrder(newController, false /* onlyCurrentIme */,
- japaneseIme_ja_JP, latinIme_fr, latinIme_en_US);
+ japaneseIme_ja_jp, latinIme_fr, latinIme_en_us);
assertRotationOrder(newController, false /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi, subtypeUnawareIme,
- switchUnawareJapaneseIme_ja_JP);
+ switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
+ switchUnawareJapaneseIme_ja_jp);
// Rotation order should be initialized when created with a different subtype list.
final List<ImeSubtypeListItem> differentEnabledItems = Arrays.asList(
- latinIme_en_US, latinIme_fr, switchingUnawarelatinIme_en_UK,
- switchUnawareJapaneseIme_ja_JP);
+ latinIme_en_us, latinIme_fr, switchingUnawarelatinIme_en_uk,
+ switchUnawareJapaneseIme_ja_jp);
final ControllerImpl anotherController = ControllerImpl.createFrom(controller,
differentEnabledItems);
assertRotationOrder(anotherController, false /* onlyCurrentIme */,
- latinIme_en_US, latinIme_fr);
+ latinIme_en_us, latinIme_fr);
assertRotationOrder(anotherController, false /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchUnawareJapaneseIme_ja_JP);
+ switchingUnawarelatinIme_en_uk, switchUnawareJapaneseIme_ja_jp);
}
@Test
@@ -344,27 +344,27 @@
addDummyImeSubtypeListItems(items, "LatinIme", "LatinIme",
Arrays.asList("en_US", "fr", "en", "en_uk", "enn", "e", "EN_US"),
true /* supportsSwitchingToNextInputMethod*/);
- final ImeSubtypeListItem item_en_US = items.get(0);
+ final ImeSubtypeListItem item_en_us = items.get(0);
final ImeSubtypeListItem item_fr = items.get(1);
final ImeSubtypeListItem item_en = items.get(2);
final ImeSubtypeListItem item_enn = items.get(3);
final ImeSubtypeListItem item_e = items.get(4);
- final ImeSubtypeListItem item_EN_US = items.get(5);
+ final ImeSubtypeListItem item_en_us_allcaps = items.get(5);
- assertTrue(item_en_US.mIsSystemLocale);
+ assertTrue(item_en_us.mIsSystemLocale);
assertFalse(item_fr.mIsSystemLocale);
assertFalse(item_en.mIsSystemLocale);
assertFalse(item_en.mIsSystemLocale);
assertFalse(item_enn.mIsSystemLocale);
assertFalse(item_e.mIsSystemLocale);
- assertFalse(item_EN_US.mIsSystemLocale);
+ assertFalse(item_en_us_allcaps.mIsSystemLocale);
- assertTrue(item_en_US.mIsSystemLanguage);
+ assertTrue(item_en_us.mIsSystemLanguage);
assertFalse(item_fr.mIsSystemLanguage);
assertTrue(item_en.mIsSystemLanguage);
assertFalse(item_enn.mIsSystemLocale);
assertFalse(item_e.mIsSystemLocale);
- assertFalse(item_EN_US.mIsSystemLocale);
+ assertFalse(item_en_us_allcaps.mIsSystemLocale);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
index 1d914ec..eebc25a 100644
--- a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
@@ -60,6 +60,7 @@
private static final boolean IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE = true;
private static final boolean IS_ASCII_CAPABLE = true;
private static final boolean IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE = true;
+ private static final boolean CHECK_COUNTRY = true;
private static final Locale LOCALE_EN = new Locale("en");
private static final Locale LOCALE_EN_US = new Locale("en", "US");
private static final Locale LOCALE_EN_GB = new Locale("en", "GB");
@@ -668,8 +669,6 @@
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final boolean CHECK_COUNTRY = true;
-
{
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
subtypes.add(nonAutoEnUS);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
index b51f4df..91342ce 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
@@ -26,6 +26,7 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
@@ -109,7 +110,8 @@
public interface MockableRebootEscrowInjected {
int getBootCount();
- void reportMetric(boolean success);
+ void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount,
+ int escrowDurationInSeconds, int vbmetaDigestStatus, int durationSinceBootComplete);
}
static class MockInjector extends RebootEscrowManager.Injector {
@@ -119,6 +121,7 @@
private final UserManager mUserManager;
private final MockableRebootEscrowInjected mInjected;
private final RebootEscrowKeyStoreManager mKeyStoreManager;
+ private final boolean mServerBased;
MockInjector(Context context, UserManager userManager,
IRebootEscrow rebootEscrow,
@@ -128,6 +131,7 @@
super(context, storage);
mRebootEscrow = rebootEscrow;
mServiceConnection = null;
+ mServerBased = false;
RebootEscrowProviderHalImpl.Injector halInjector =
new RebootEscrowProviderHalImpl.Injector() {
@Override
@@ -149,6 +153,7 @@
super(context, storage);
mServiceConnection = serviceConnection;
mRebootEscrow = null;
+ mServerBased = true;
RebootEscrowProviderServerBasedImpl.Injector injector =
new RebootEscrowProviderServerBasedImpl.Injector(serviceConnection);
mRebootEscrowProvider = new RebootEscrowProviderServerBasedImpl(storage, injector);
@@ -168,6 +173,11 @@
}
@Override
+ public boolean serverBasedResumeOnReboot() {
+ return mServerBased;
+ }
+
+ @Override
public RebootEscrowProviderInterface getRebootEscrowProvider() {
return mRebootEscrowProvider;
}
@@ -195,8 +205,11 @@
}
@Override
- public void reportMetric(boolean success) {
- mInjected.reportMetric(success);
+ public void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount,
+ int escrowDurationInSeconds, int vbmetaDigestStatus,
+ int durationSinceBootComplete) {
+ mInjected.reportMetric(success, errorCode, serviceType, attemptCount,
+ escrowDurationInSeconds, vbmetaDigestStatus, durationSinceBootComplete);
}
}
@@ -418,7 +431,9 @@
when(mInjected.getBootCount()).thenReturn(1);
ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
- doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture());
+ doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
+ eq(0) /* error code */, eq(1) /* HAL based */, eq(1) /* attempt count */,
+ anyInt(), anyInt(), anyInt());
when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> keyByteCaptor.getValue());
mService.loadRebootEscrowDataIfAvailable(null);
@@ -451,7 +466,9 @@
// pretend reboot happens here
when(mInjected.getBootCount()).thenReturn(1);
ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
- doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture());
+ doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
+ eq(0) /* error code */, eq(2) /* Server based */, eq(1) /* attempt count */,
+ anyInt(), anyInt(), anyInt());
when(mServiceConnection.unwrap(any(), anyLong()))
.thenAnswer(invocation -> invocation.getArgument(0));
@@ -485,7 +502,8 @@
// pretend reboot happens here
when(mInjected.getBootCount()).thenReturn(1);
ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
- doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture());
+ doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
+ anyInt(), anyInt(), eq(2) /* attempt count */, anyInt(), anyInt(), anyInt());
when(mServiceConnection.unwrap(any(), anyLong()))
.thenThrow(new IOException())
@@ -528,7 +546,8 @@
mService.loadRebootEscrowDataIfAvailable(null);
verify(mRebootEscrow).retrieveKey();
- verify(mInjected, never()).reportMetric(anyBoolean());
+ verify(mInjected, never()).reportMetric(anyBoolean(), anyInt(), anyInt(), anyInt(),
+ anyInt(), anyInt(), anyInt());
}
@Test
@@ -554,7 +573,8 @@
when(mRebootEscrow.retrieveKey()).thenReturn(new byte[32]);
mService.loadRebootEscrowDataIfAvailable(null);
- verify(mInjected, never()).reportMetric(anyBoolean());
+ verify(mInjected, never()).reportMetric(anyBoolean(), anyInt(), anyInt(), anyInt(),
+ anyInt(), anyInt(), anyInt());
}
@Test
@@ -588,7 +608,8 @@
when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> keyByteCaptor.getValue());
mService.loadRebootEscrowDataIfAvailable(null);
- verify(mInjected).reportMetric(eq(true));
+ verify(mInjected).reportMetric(eq(true), eq(0) /* error code */, eq(1) /* HAL based */,
+ eq(1) /* attempt count */, anyInt(), anyInt(), anyInt());
}
@Test
@@ -615,7 +636,9 @@
when(mInjected.getBootCount()).thenReturn(1);
ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
- doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture());
+ doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
+ anyInt() /* error code */, eq(1) /* HAL based */, eq(1) /* attempt count */,
+ anyInt(), anyInt(), anyInt());
when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> new byte[32]);
mService.loadRebootEscrowDataIfAvailable(null);
verify(mRebootEscrow).retrieveKey();
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
index dd3054f..3fd2c97 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
@@ -32,7 +32,6 @@
import android.content.Context;
import android.os.RemoteException;
import android.security.GateKeeper;
-import android.security.keystore.AndroidKeyStoreSecretKey;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
@@ -59,6 +58,7 @@
import java.util.List;
import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -575,7 +575,7 @@
return (KeyProtection) mProtectionParameterCaptor.getValue();
}
- private AndroidKeyStoreSecretKey generateAndroidKeyStoreKey() throws Exception {
+ private SecretKey generateAndroidKeyStoreKey() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance(
KEY_ALGORITHM,
ANDROID_KEY_STORE_PROVIDER);
@@ -584,7 +584,7 @@
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build());
- return (AndroidKeyStoreSecretKey) keyGenerator.generateKey();
+ return keyGenerator.generateKey();
}
class PlatformKeyManagerTestable extends PlatformKeyManager {
diff --git a/services/tests/servicestests/src/com/android/server/power/FaceDownDetectorTest.java b/services/tests/servicestests/src/com/android/server/power/FaceDownDetectorTest.java
deleted file mode 100644
index ef20ee7..0000000
--- a/services/tests/servicestests/src/com/android/server/power/FaceDownDetectorTest.java
+++ /dev/null
@@ -1,165 +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.power;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorManager;
-import android.testing.TestableContext;
-
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.server.display.TestUtils;
-
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.lang.reflect.Constructor;
-import java.time.Duration;
-
-public class FaceDownDetectorTest {
- @ClassRule
- public static final TestableContext sContext = new TestableContext(
- InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
-
- private final FaceDownDetector mFaceDownDetector =
- new FaceDownDetector(this::onFlip);
-
- @Mock private SensorManager mSensorManager;
-
- private long mCurrentTime;
- private int mOnFaceDownCalls = 0;
- private int mOnFaceDownExitCalls = 0;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- sContext.addMockSystemService(SensorManager.class, mSensorManager);
- mCurrentTime = 0;
- }
-
- @Test
- public void faceDownFor2Seconds_triggersFaceDown() throws Exception {
- mFaceDownDetector.systemReady(sContext);
-
- // Face up
- // Using 0.5 on x to simulate constant acceleration, such as a sloped surface.
- mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, 10.0f));
-
- for (int i = 0; i < 200; i++) {
- advanceTime(Duration.ofMillis(20));
- mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, -10.0f));
- }
-
- assertThat(mOnFaceDownCalls).isEqualTo(1);
- assertThat(mOnFaceDownExitCalls).isEqualTo(0);
- }
-
- @Test
- public void faceDownFor2Seconds_withMotion_DoesNotTriggerFaceDown() throws Exception {
- mFaceDownDetector.systemReady(sContext);
-
- // Face up
- mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, 10.0f));
-
- for (int i = 0; i < 100; i++) {
- advanceTime(Duration.ofMillis(20));
- //Move along x direction
- mFaceDownDetector.onSensorChanged(createTestEvent(0.5f * i, 0.0f, -10.0f));
- }
-
- assertThat(mOnFaceDownCalls).isEqualTo(0);
- assertThat(mOnFaceDownExitCalls).isEqualTo(0);
- }
-
- @Test
- public void faceDownForHalfSecond_DoesNotTriggerFaceDown() throws Exception {
- mFaceDownDetector.systemReady(sContext);
-
- // Face up
- mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, 10.0f));
-
- for (int i = 0; i < 100; i++) {
- advanceTime(Duration.ofMillis(5));
- mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, -10.0f));
- }
-
- assertThat(mOnFaceDownCalls).isEqualTo(0);
- assertThat(mOnFaceDownExitCalls).isEqualTo(0);
- }
-
- @Test
- public void faceDownFor2Seconds_followedByFaceUp_triggersFaceDownExit() throws Exception {
- mFaceDownDetector.systemReady(sContext);
-
- // Face up
- // Using 0.5 on x to simulate constant acceleration, such as a sloped surface.
- mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, 10.0f));
-
- // Trigger face down
- for (int i = 0; i < 100; i++) {
- advanceTime(Duration.ofMillis(20));
- mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, -10.0f));
- }
-
- // Phone flips
- for (int i = 0; i < 10; i++) {
- advanceTime(Duration.ofMillis(5));
- mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 1.0f, 0.0f));
- }
-
- assertThat(mOnFaceDownCalls).isEqualTo(1);
- assertThat(mOnFaceDownExitCalls).isEqualTo(1);
- }
-
- private void advanceTime(Duration duration) {
- mCurrentTime += duration.toNanos();
- }
-
- /**
- * Create a test event to replicate an accelerometer sensor event.
- * @param x Acceleration along the x dimension.
- * @param y Acceleration along the y dimension.
- * @param gravity Acceleration along the Z dimension. Relates to
- */
- private SensorEvent createTestEvent(float x, float y, float gravity) throws Exception {
- final Constructor<SensorEvent> constructor =
- SensorEvent.class.getDeclaredConstructor(int.class);
- constructor.setAccessible(true);
- final SensorEvent event = constructor.newInstance(3);
- event.sensor =
- TestUtils.createSensor(Sensor.TYPE_ACCELEROMETER, Sensor.STRING_TYPE_ACCELEROMETER);
- event.values[0] = x;
- event.values[1] = y;
- event.values[2] = gravity;
- event.timestamp = mCurrentTime;
- return event;
- }
-
- private void onFlip(boolean isFaceDown) {
- if (isFaceDown) {
- mOnFaceDownCalls++;
- } else {
- mOnFaceDownExitCalls++;
- }
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/rotationresolver/RotationResolverManagerPerUserServiceTest.java b/services/tests/servicestests/src/com/android/server/rotationresolver/RotationResolverManagerPerUserServiceTest.java
index 22c38c1..fa2123c 100644
--- a/services/tests/servicestests/src/com/android/server/rotationresolver/RotationResolverManagerPerUserServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/rotationresolver/RotationResolverManagerPerUserServiceTest.java
@@ -31,6 +31,7 @@
import android.os.CancellationSignal;
import android.os.RemoteException;
import android.rotationresolver.RotationResolverInternal;
+import android.service.rotationresolver.RotationResolutionRequest;
import android.view.Surface;
import androidx.test.core.app.ApplicationProvider;
@@ -58,6 +59,7 @@
private Context mContext;
private CancellationSignal mCancellationSignal;
private RotationResolverManagerPerUserService mService;
+ private RotationResolutionRequest mRequest;
@Before
public void setUp() throws RemoteException {
@@ -79,9 +81,10 @@
mCancellationSignal = new CancellationSignal();
+ mRequest = new RotationResolutionRequest("", Surface.ROTATION_0, Surface.ROTATION_0,
+ true, 1000L);
this.mService.mCurrentRequest = new RemoteRotationResolverService.RotationRequest(
- mMockCallbackInternal, Surface.ROTATION_0, Surface.ROTATION_0, "", 1000L,
- mCancellationSignal);
+ mMockCallbackInternal, mRequest, mCancellationSignal);
this.mService.getMaster().mIsServiceEnabled = true;
@@ -99,8 +102,7 @@
RotationResolverInternal.RotationResolverCallbackInternal callbackInternal =
Mockito.mock(RotationResolverInternal.RotationResolverCallbackInternal.class);
- mService.resolveRotationLocked(callbackInternal, Surface.ROTATION_0, Surface.ROTATION_0,
- "", 1000L, mCancellationSignal);
+ mService.resolveRotationLocked(callbackInternal, mRequest, mCancellationSignal);
verify(callbackInternal).onSuccess(anyInt());
}
@@ -110,8 +112,7 @@
Mockito.mock(RotationResolverInternal.RotationResolverCallbackInternal.class);
final CancellationSignal cancellationSignal = new CancellationSignal();
- mService.resolveRotationLocked(callbackInternal, Surface.ROTATION_0, Surface.ROTATION_0,
- "", 1000L, cancellationSignal);
+ mService.resolveRotationLocked(callbackInternal, mRequest, cancellationSignal);
cancellationSignal.cancel();
}
@@ -132,7 +133,7 @@
@Override
public void resolveRotationLocked(RotationRequest request) {
- request.mCallbackInternal.onSuccess(request.mProposedRotation);
+ request.mCallbackInternal.onSuccess(request.mRemoteRequest.getProposedRotation());
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
index 5f86d28..bbf11fd 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
@@ -209,7 +209,7 @@
@Test(expected = SecurityException.class)
public void testSuggestExternalTime_withoutPermission() {
doThrow(new SecurityException("Mock"))
- .when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
+ .when(mMockContext).enforceCallingPermission(anyString(), any());
ExternalTimeSuggestion externalTimeSuggestion = createExternalTimeSuggestion();
try {
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java
index 5d27552..0036982 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java
@@ -46,7 +46,7 @@
public void test_unrestricted() {
ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
.setUserConfigAllowed(true)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setAutoDetectionEnabled(true)
.setLocationEnabled(true)
@@ -108,7 +108,7 @@
public void test_restricted() {
ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
.setUserConfigAllowed(false)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setAutoDetectionEnabled(true)
.setLocationEnabled(true)
@@ -170,7 +170,7 @@
public void test_autoDetectNotSupported() {
ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
.setUserConfigAllowed(true)
- .setAutoDetectionFeatureSupported(false)
+ .setTelephonyDetectionFeatureSupported(false)
.setGeoDetectionFeatureSupported(false)
.setAutoDetectionEnabled(true)
.setLocationEnabled(true)
@@ -232,7 +232,7 @@
public void test_geoDetectNotSupported() {
ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
.setUserConfigAllowed(true)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(false)
.setAutoDetectionEnabled(true)
.setLocationEnabled(true)
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
index 14e0bbd..8af2c4d 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
@@ -364,7 +364,7 @@
// the tests.
final boolean geoDetectionEnabled = autoDetectionEnabled;
return new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setUserConfigAllowed(true)
.setAutoDetectionEnabled(autoDetectionEnabled)
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
index f1f8b2f..b0341d7 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
@@ -90,7 +90,7 @@
private static final ConfigurationInternal CONFIG_INT_USER_RESTRICTED_AUTO_DISABLED =
new ConfigurationInternal.Builder(USER_ID)
.setUserConfigAllowed(false)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setAutoDetectionEnabled(false)
.setLocationEnabled(true)
@@ -100,7 +100,7 @@
private static final ConfigurationInternal CONFIG_INT_USER_RESTRICTED_AUTO_ENABLED =
new ConfigurationInternal.Builder(USER_ID)
.setUserConfigAllowed(false)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setAutoDetectionEnabled(true)
.setLocationEnabled(true)
@@ -110,17 +110,17 @@
private static final ConfigurationInternal CONFIG_INT_AUTO_DETECT_NOT_SUPPORTED =
new ConfigurationInternal.Builder(USER_ID)
.setUserConfigAllowed(true)
- .setAutoDetectionFeatureSupported(false)
+ .setTelephonyDetectionFeatureSupported(false)
.setGeoDetectionFeatureSupported(false)
.setAutoDetectionEnabled(false)
.setLocationEnabled(true)
.setGeoDetectionEnabled(false)
.build();
- private static final ConfigurationInternal CONFIG_INT_AUTO_SUPPORTED_GEO_NOT_SUPPORTED =
+ private static final ConfigurationInternal CONFIG_INT_TELEPHONY_SUPPORTED_GEO_NOT_SUPPORTED =
new ConfigurationInternal.Builder(USER_ID)
.setUserConfigAllowed(true)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(false)
.setAutoDetectionEnabled(true)
.setLocationEnabled(true)
@@ -130,7 +130,7 @@
private static final ConfigurationInternal CONFIG_INT_AUTO_DISABLED_GEO_DISABLED =
new ConfigurationInternal.Builder(USER_ID)
.setUserConfigAllowed(true)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setAutoDetectionEnabled(false)
.setLocationEnabled(true)
@@ -139,7 +139,7 @@
private static final ConfigurationInternal CONFIG_INT_AUTO_ENABLED_GEO_DISABLED =
new ConfigurationInternal.Builder(USER_ID)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setUserConfigAllowed(true)
.setAutoDetectionEnabled(true)
@@ -149,7 +149,7 @@
private static final ConfigurationInternal CONFIG_INT_AUTO_ENABLED_GEO_ENABLED =
new ConfigurationInternal.Builder(USER_ID)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setUserConfigAllowed(true)
.setAutoDetectionEnabled(true)
@@ -266,7 +266,8 @@
@Test
public void testUpdateConfiguration_autoDetectSupportedGeoNotSupported() {
- Script script = new Script().initializeConfig(CONFIG_INT_AUTO_SUPPORTED_GEO_NOT_SUPPORTED);
+ Script script = new Script().initializeConfig(
+ CONFIG_INT_TELEPHONY_SUPPORTED_GEO_NOT_SUPPORTED);
// Update the configuration with auto detection disabled.
script.simulateUpdateConfiguration(
@@ -274,7 +275,7 @@
// The settings should have been changed and the StrategyListener onChange() called.
ConfigurationInternal expectedConfig =
- new ConfigurationInternal.Builder(CONFIG_INT_AUTO_SUPPORTED_GEO_NOT_SUPPORTED)
+ new ConfigurationInternal.Builder(CONFIG_INT_TELEPHONY_SUPPORTED_GEO_NOT_SUPPORTED)
.setAutoDetectionEnabled(false)
.build();
script.verifyConfigurationChangedAndReset(expectedConfig);
@@ -675,6 +676,8 @@
script.simulateManualTimeZoneSuggestion(
USER_ID, createManualSuggestion("Europe/Paris"), false /* expectedResult */)
.verifyTimeZoneNotChanged();
+
+ assertNull(mTimeZoneDetectorStrategy.getLatestManualSuggestion());
}
@Test
@@ -687,6 +690,8 @@
script.simulateManualTimeZoneSuggestion(
USER_ID, createManualSuggestion("Europe/Paris"), false /* expectedResult */)
.verifyTimeZoneNotChanged();
+
+ assertNull(mTimeZoneDetectorStrategy.getLatestManualSuggestion());
}
@Test
@@ -700,6 +705,8 @@
script.simulateManualTimeZoneSuggestion(
USER_ID, manualSuggestion, true /* expectedResult */)
.verifyTimeZoneChangedAndReset(manualSuggestion);
+
+ assertEquals(manualSuggestion, mTimeZoneDetectorStrategy.getLatestManualSuggestion());
}
@Test
@@ -713,6 +720,8 @@
script.simulateManualTimeZoneSuggestion(
USER_ID, manualSuggestion, false /* expectedResult */)
.verifyTimeZoneNotChanged();
+
+ assertNull(mTimeZoneDetectorStrategy.getLatestManualSuggestion());
}
@Test
@@ -726,6 +735,8 @@
script.simulateManualTimeZoneSuggestion(
USER_ID, manualSuggestion, true /* expectedResult */)
.verifyTimeZoneChangedAndReset(manualSuggestion);
+
+ assertEquals(manualSuggestion, mTimeZoneDetectorStrategy.getLatestManualSuggestion());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/location/ControllerImplTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/location/ControllerImplTest.java
index 4284240..3daa7f0 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/location/ControllerImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/location/ControllerImplTest.java
@@ -72,6 +72,7 @@
private TestCallback mTestCallback;
private TestLocationTimeZoneProvider mTestPrimaryLocationTimeZoneProvider;
private TestLocationTimeZoneProvider mTestSecondaryLocationTimeZoneProvider;
+ private FakeTimeZoneIdValidator mTimeZoneAvailabilityChecker;
@Before
public void setUp() {
@@ -80,10 +81,13 @@
// will never get a chance to execute.
mTestThreadingDomain = new TestThreadingDomain();
mTestCallback = new TestCallback(mTestThreadingDomain);
+ mTimeZoneAvailabilityChecker = new FakeTimeZoneIdValidator();
mTestPrimaryLocationTimeZoneProvider =
- new TestLocationTimeZoneProvider(mTestThreadingDomain, "primary");
+ new TestLocationTimeZoneProvider(
+ mTestThreadingDomain, "primary", mTimeZoneAvailabilityChecker);
mTestSecondaryLocationTimeZoneProvider =
- new TestLocationTimeZoneProvider(mTestThreadingDomain, "secondary");
+ new TestLocationTimeZoneProvider(
+ mTestThreadingDomain, "secondary", mTimeZoneAvailabilityChecker);
}
@Test
@@ -1177,8 +1181,10 @@
/**
* Creates the instance.
*/
- TestLocationTimeZoneProvider(ThreadingDomain threadingDomain, String providerName) {
- super(threadingDomain, providerName);
+ TestLocationTimeZoneProvider(ThreadingDomain threadingDomain,
+ String providerName,
+ TimeZoneIdValidator timeZoneIdValidator) {
+ super(threadingDomain, providerName, timeZoneIdValidator);
}
public void setFailDuringInitialization(boolean failInitialization) {
@@ -1311,4 +1317,14 @@
mTestProviderState.commitLatest();
}
}
+
+ private static final class FakeTimeZoneIdValidator
+ implements LocationTimeZoneProvider.TimeZoneIdValidator {
+
+ @Override
+ public boolean isValid(@NonNull String timeZoneId) {
+ return true;
+ }
+
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderTest.java
index 095c868..278fdaf 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderTest.java
@@ -32,6 +32,8 @@
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import static java.util.Arrays.asList;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Bundle;
@@ -50,7 +52,9 @@
import java.time.Duration;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
/**
@@ -62,20 +66,25 @@
private static final long ARBITRARY_ELAPSED_REALTIME_MILLIS = 123456789L;
private TestThreadingDomain mTestThreadingDomain;
-
private TestProviderListener mProviderListener;
+ private FakeTimeZoneIdValidator mTimeZoneAvailabilityChecker;
@Before
public void setUp() {
mTestThreadingDomain = new TestThreadingDomain();
mProviderListener = new TestProviderListener();
+ mTimeZoneAvailabilityChecker = new FakeTimeZoneIdValidator();
}
@Test
public void lifecycle() {
String providerName = "arbitrary";
TestLocationTimeZoneProvider provider =
- new TestLocationTimeZoneProvider(mTestThreadingDomain, providerName);
+ new TestLocationTimeZoneProvider(
+ mTestThreadingDomain,
+ providerName,
+ mTimeZoneAvailabilityChecker);
+ mTimeZoneAvailabilityChecker.validIds("Europe/London");
// initialize()
provider.initialize(mProviderListener);
@@ -163,7 +172,10 @@
public void defaultHandleTestCommandImpl() {
String providerName = "primary";
TestLocationTimeZoneProvider provider =
- new TestLocationTimeZoneProvider(mTestThreadingDomain, providerName);
+ new TestLocationTimeZoneProvider(
+ mTestThreadingDomain,
+ providerName,
+ mTimeZoneAvailabilityChecker);
TestCommand testCommand = TestCommand.createForTests("test", new Bundle());
AtomicReference<Bundle> resultReference = new AtomicReference<>();
@@ -180,8 +192,12 @@
public void stateRecording() {
String providerName = "primary";
TestLocationTimeZoneProvider provider =
- new TestLocationTimeZoneProvider(mTestThreadingDomain, providerName);
+ new TestLocationTimeZoneProvider(
+ mTestThreadingDomain,
+ providerName,
+ mTimeZoneAvailabilityChecker);
provider.setStateChangeRecordingEnabled(true);
+ mTimeZoneAvailabilityChecker.validIds("Europe/London");
// initialize()
provider.initialize(mProviderListener);
@@ -218,6 +234,34 @@
provider.assertLatestRecordedState(PROVIDER_STATE_DESTROYED);
}
+ @Test
+ public void considerSuggestionWithInvalidTimeZoneIdsAsUncertain() {
+ String providerName = "primary";
+ TestLocationTimeZoneProvider provider =
+ new TestLocationTimeZoneProvider(
+ mTestThreadingDomain,
+ providerName,
+ mTimeZoneAvailabilityChecker);
+ provider.setStateChangeRecordingEnabled(true);
+ provider.initialize(mProviderListener);
+
+ ConfigurationInternal config = USER1_CONFIG_GEO_DETECTION_ENABLED;
+ Duration arbitraryInitializationTimeout = Duration.ofMinutes(5);
+ Duration arbitraryInitializationTimeoutFuzz = Duration.ofMinutes(2);
+ provider.startUpdates(config, arbitraryInitializationTimeout,
+ arbitraryInitializationTimeoutFuzz);
+
+ List<String> invalidTimeZoneIds = asList("Atlantic/Atlantis");
+ TimeZoneProviderSuggestion invalidIdSuggestion = new TimeZoneProviderSuggestion.Builder()
+ .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS)
+ .setTimeZoneIds(invalidTimeZoneIds)
+ .build();
+ TimeZoneProviderEvent event =
+ TimeZoneProviderEvent.createSuggestionEvent(invalidIdSuggestion);
+ provider.simulateProviderEventReceived(event);
+ provider.assertLatestRecordedState(PROVIDER_STATE_STARTED_UNCERTAIN);
+ }
+
/** A test stand-in for the real {@link LocationTimeZoneProviderController}'s listener. */
private static class TestProviderListener implements ProviderListener {
@@ -251,8 +295,9 @@
/** Creates the instance. */
TestLocationTimeZoneProvider(@NonNull ThreadingDomain threadingDomain,
- @NonNull String providerName) {
- super(threadingDomain, providerName);
+ @NonNull String providerName,
+ @NonNull TimeZoneIdValidator timeZoneIdValidator) {
+ super(threadingDomain, providerName, timeZoneIdValidator);
}
@Override
@@ -308,4 +353,19 @@
recordedStates.get(recordedStates.size() - 1).stateEnum);
}
}
+
+ private static final class FakeTimeZoneIdValidator
+ implements LocationTimeZoneProvider.TimeZoneIdValidator {
+ private final Set<String> mValidTimeZoneIds = new HashSet<>();
+
+ @Override
+ public boolean isValid(@NonNull String timeZoneId) {
+ return mValidTimeZoneIds.contains(timeZoneId);
+ }
+
+ public void validIds(String... timeZoneIdss) {
+ mValidTimeZoneIds.addAll(asList(timeZoneIdss));
+ }
+
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/location/TestSupport.java b/services/tests/servicestests/src/com/android/server/timezonedetector/location/TestSupport.java
index 8280cdc..16ac1d6 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/location/TestSupport.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/location/TestSupport.java
@@ -44,7 +44,7 @@
@UserIdInt int userId, boolean geoDetectionEnabled) {
return new ConfigurationInternal.Builder(userId)
.setUserConfigAllowed(true)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setAutoDetectionEnabled(true)
.setLocationEnabled(true)
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidatorTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidatorTest.java
new file mode 100644
index 0000000..5561b2c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidatorTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.timezonedetector.location;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.TimeZone;
+
+@Presubmit
+public class ZoneInfoDbTimeZoneIdValidatorTest {
+ private final LocationTimeZoneProvider.TimeZoneIdValidator mTzChecker =
+ new ZoneInfoDbTimeZoneIdValidator();
+
+ @Test
+ public void timeZoneIdsFromZoneInfoDbAreValid() {
+ for (String timeZone : TimeZone.getAvailableIDs()) {
+ assertWithMessage("Time zone %s should be supported", timeZone)
+ .that(mTzChecker.isValid(timeZone)).isTrue();
+ }
+ }
+
+ @Test
+ public void nonExistingZones_areNotSupported() {
+ List<String> nonExistingTimeZones = Arrays.asList(
+ "SystemV/HST10", "Atlantic/Atlantis", "EUROPE/LONDON", "Etc/GMT-5:30"
+ );
+
+ for (String timeZone : nonExistingTimeZones) {
+ assertWithMessage(timeZone + " is not a valid time zone")
+ .that(mTzChecker.isValid(timeZone))
+ .isFalse();
+ }
+ }
+}
diff --git a/services/tests/servicestests/test-apps/SimpleServiceTestApp/OWNERS b/services/tests/servicestests/test-apps/SimpleServiceTestApp/OWNERS
new file mode 100644
index 0000000..72c0a9e
--- /dev/null
+++ b/services/tests/servicestests/test-apps/SimpleServiceTestApp/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/am/OWNERS
diff --git a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index 5182b3b..b921838 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -243,10 +243,18 @@
final UserHandle user = getParentUser(context);
List<String> roleHolders = callWithShellPermissionIdentity(
() -> roleManager.getRoleHoldersAsUser(RoleManager.ROLE_HOME, user));
- if (roleHolders.size() == 1) {
+ int size = roleHolders.size();
+ if (size == 1) {
return roleHolders.get(0);
}
- fail("Failed to get the default launcher for user " + context.getUserId());
+
+ if (size > 1) {
+ fail("Too many launchers for user " + user.getIdentifier() + " using role "
+ + RoleManager.ROLE_HOME + ": " + roleHolders);
+ } else {
+ fail("No default launcher for user " + user.getIdentifier() + " using role "
+ + RoleManager.ROLE_HOME);
+ }
return null;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index 9830631..c483ae9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -141,7 +141,7 @@
assertNull(mProvider.getControlTarget());
// We can have the control and the control target after seamless rotation.
- mProvider.finishSeamlessRotation(false /* timeout */);
+ mProvider.finishSeamlessRotation();
mProvider.updateControlForTarget(target, false /* force */);
assertNotNull(mProvider.getControl(target));
assertNotNull(mProvider.getControlTarget());
diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
index 2fdd63e..c98e013 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -36,6 +36,8 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
@@ -208,18 +210,20 @@
}
@Test
- public void testZeroAnimations() {
+ public void testZeroAnimations() throws Exception {
mController.goodToGo(TRANSIT_OLD_NONE);
- verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
+ verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any());
+ verify(mMockRunner).onAnimationCancelled();
}
@Test
- public void testNotReallyStarted() {
+ public void testNotReallyStarted() throws Exception {
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
mController.createRemoteAnimationRecord(win.mActivityRecord,
new Point(50, 100), null, new Rect(50, 100, 150, 150), null);
mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
- verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
+ verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any());
+ verify(mMockRunner).onAnimationCancelled();
}
@Test
@@ -250,7 +254,7 @@
}
@Test
- public void testRemovedBeforeStarted() {
+ public void testRemovedBeforeStarted() throws Exception {
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord,
new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter;
@@ -258,7 +262,8 @@
mFinishedCallback);
win.mActivityRecord.removeImmediately();
mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
- verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
+ verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any());
+ verify(mMockRunner).onAnimationCancelled();
verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION),
eq(adapter));
}
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 2f1d7eb..36cf9c9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -40,6 +40,8 @@
import static com.android.server.wm.Task.ActivityState.STOPPED;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
@@ -117,18 +119,19 @@
@Test
public void testKeepBoundsWhenChangingFromFreeformToFullscreen() {
removeGlobalMinSizeRestriction();
- // create freeform display and a freeform app
+ // Create landscape freeform display and a freeform app.
DisplayContent display = new TestDisplayContent.Builder(mAtm, 2000, 1000)
.setCanRotate(false)
.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM).build();
setUpApp(display);
- // Put app window into freeform and then make it a compat app.
+ // Put app window into portrait freeform and then make it a compat app.
final Rect bounds = new Rect(100, 100, 400, 600);
mTask.setBounds(bounds);
-
prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
assertEquals(bounds, mActivity.getBounds());
+ // Activity is not yet in size compat mode; it is filling the freeform window.
+ assertMaxBoundsInheritDisplayAreaBounds();
// The activity should be able to accept negative x position [-150, 100 - 150, 600].
final int dx = bounds.left + bounds.width() / 2;
@@ -137,7 +140,7 @@
final int density = mActivity.getConfiguration().densityDpi;
- // change display configuration to fullscreen
+ // Change display configuration to fullscreen.
Configuration c = new Configuration(display.getRequestedOverrideConfiguration());
c.windowConfiguration.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
display.onRequestedOverrideConfigurationChanged(c);
@@ -147,6 +150,8 @@
assertEquals(bounds.width(), mActivity.getBounds().width());
assertEquals(bounds.height(), mActivity.getBounds().height());
assertEquals(density, mActivity.getConfiguration().densityDpi);
+ // Size compat mode is sandboxed at the activity level.
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -172,6 +177,12 @@
assertEquals(appBounds.height(), appBounds.width() * aspectRatio, 0.5f /* delta */);
// The decor height should be a part of the effective bounds.
assertEquals(mActivity.getBounds().height(), appBounds.height() + notchHeight);
+ // Activity max bounds should be sandboxed; activity is letterboxed due to aspect ratio.
+ assertActivityMaxBoundsSandboxed();
+ // Activity max bounds ignore notch, since an app can be shown past the notch (although app
+ // is currently limited by the notch).
+ assertThat(mActivity.getWindowConfiguration().getMaxBounds().height())
+ .isEqualTo(displayBounds.height());
mActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
assertFitted();
@@ -181,9 +192,17 @@
assertEquals(appBounds.width(), appBounds.height() * aspectRatio, 0.5f /* delta */);
// The notch is no longer on top.
assertEquals(appBounds, mActivity.getBounds());
+ // Activity max bounds are sandboxed.
+ assertActivityMaxBoundsSandboxed();
mActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
assertFitted();
+ // Activity max bounds should be sandboxed; activity is letterboxed due to aspect ratio.
+ assertActivityMaxBoundsSandboxed();
+ // Activity max bounds ignore notch, since an app can be shown past the notch (although app
+ // is currently limited by the notch).
+ assertThat(mActivity.getWindowConfiguration().getMaxBounds().height())
+ .isEqualTo(displayBounds.height());
}
@Test
@@ -206,6 +225,9 @@
assertEquals(originalBounds.width(), mActivity.getBounds().width());
assertEquals(originalBounds.height(), mActivity.getBounds().height());
assertEquals(originalDpi, mActivity.getConfiguration().densityDpi);
+ // Activity is sandboxed; it is in size compat mode since it is not resizable and has a
+ // max aspect ratio.
+ assertActivityMaxBoundsSandboxed();
assertScaled();
}
@@ -213,11 +235,13 @@
public void testFixedScreenBoundsWhenDisplaySizeChanged() {
setUpDisplaySizeWithApp(1000, 2500);
prepareUnresizable(mActivity, -1f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+ final DisplayContent display = mActivity.mDisplayContent;
assertFitted();
+ // Activity inherits bounds from TaskDisplayArea, since not sandboxed.
+ assertMaxBoundsInheritDisplayAreaBounds();
final Rect origBounds = new Rect(mActivity.getBounds());
final Rect currentBounds = mActivity.getWindowConfiguration().getBounds();
- final DisplayContent display = mActivity.mDisplayContent;
// Change the size of current display.
resizeDisplay(display, 1000, 2000);
@@ -234,6 +258,8 @@
// The position of configuration bounds should be the same as compat bounds.
assertEquals(mActivity.getBounds().left, currentBounds.left);
assertEquals(mActivity.getBounds().top, currentBounds.top);
+ // Activity is sandboxed to the offset size compat bounds.
+ assertActivityMaxBoundsSandboxed();
// Change display size to a different orientation
resizeDisplay(display, 2000, 1000);
@@ -242,6 +268,8 @@
assertEquals(origBounds.height(), currentBounds.height());
assertEquals(ORIENTATION_LANDSCAPE, display.getConfiguration().orientation);
assertEquals(Configuration.ORIENTATION_PORTRAIT, mActivity.getConfiguration().orientation);
+ // Activity is sandboxed to the offset size compat bounds.
+ assertActivityMaxBoundsSandboxed();
// The previous resize operation doesn't consider the rotation change after size changed.
// These setups apply the requested orientation to rotation as real case that the top fixed
@@ -261,6 +289,8 @@
assertEquals(origBounds.height(), currentBounds.height());
assertEquals(offsetX, currentBounds.left);
assertScaled();
+ // Activity is sandboxed due to size compat mode.
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -276,6 +306,8 @@
assertEquals(bounds.width(), bounds.height() * maxAspect, 0.0001f /* delta */);
// The position should be horizontal centered.
assertEquals((displayWidth - bounds.width()) / 2, bounds.left);
+ // Activity max bounds should be sandboxed since it is letterboxed.
+ assertActivityMaxBoundsSandboxed();
mActivity.mDisplayContent.setImeLayeringTarget(addWindowToActivity(mActivity));
// Make sure IME cannot attach to the app, otherwise IME window will also be shifted.
@@ -287,6 +319,8 @@
// It should keep non-attachable because the resolved bounds will be computed according to
// the aspect ratio that won't match its parent bounds.
assertFalse(mActivity.mDisplayContent.isImeAttachedToApp());
+ // Activity max bounds should be sandboxed since it is letterboxed.
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -312,14 +346,13 @@
}
@Test
- public void testMoveToDifferentOrientDisplay() {
+ public void testMoveToDifferentOrientationDisplay() {
setUpDisplaySizeWithApp(1000, 2500);
prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
assertFitted();
- final Rect configBounds = mActivity.getWindowConfiguration().getBounds();
- final int origWidth = configBounds.width();
- final int origHeight = configBounds.height();
+ final Rect currentBounds = mActivity.getWindowConfiguration().getBounds();
+ final Rect originalBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
final int notchHeight = 100;
final DisplayContent newDisplay = new TestDisplayContent.Builder(mAtm, 2000, 1000)
@@ -328,37 +361,45 @@
// Move the non-resizable activity to the new display.
mTask.reparent(newDisplay.getDefaultTaskDisplayArea(), true /* onTop */);
// The configuration bounds [820, 0 - 1820, 2500] should keep the same.
- assertEquals(origWidth, configBounds.width());
- assertEquals(origHeight, configBounds.height());
+ assertEquals(originalBounds.width(), currentBounds.width());
+ assertEquals(originalBounds.height(), currentBounds.height());
assertScaled();
+ // Activity max bounds are sandboxed due to size compat mode on the new display.
+ assertActivityMaxBoundsSandboxed();
final Rect newDisplayBounds = newDisplay.getWindowConfiguration().getBounds();
// The scaled bounds should exclude notch area (1000 - 100 == 360 * 2500 / 1000 = 900).
assertEquals(newDisplayBounds.height() - notchHeight,
- (int) ((float) mActivity.getBounds().width() * origHeight / origWidth));
+ (int) ((float) mActivity.getBounds().width() * originalBounds.height()
+ / originalBounds.width()));
// Recompute the natural configuration in the new display.
mActivity.clearSizeCompatMode();
mActivity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
// Because the display cannot rotate, the portrait activity will fit the short side of
// display with keeping portrait bounds [200, 0 - 700, 1000] in center.
- assertEquals(newDisplayBounds.height(), configBounds.height());
- assertEquals(configBounds.height() * newDisplayBounds.height() / newDisplayBounds.width(),
- configBounds.width());
+ assertEquals(newDisplayBounds.height(), currentBounds.height());
+ assertEquals(currentBounds.height() * newDisplayBounds.height() / newDisplayBounds.width(),
+ currentBounds.width());
assertFitted();
// The appBounds should be [200, 100 - 700, 1000].
final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds();
- assertEquals(configBounds.width(), appBounds.width());
- assertEquals(configBounds.height() - notchHeight, appBounds.height());
+ assertEquals(currentBounds.width(), appBounds.width());
+ assertEquals(currentBounds.height() - notchHeight, appBounds.height());
+ // Activity max bounds are sandboxed due to letterboxing from orientation mismatch with
+ // display.
+ assertActivityMaxBoundsSandboxed();
}
@Test
- public void testFixedOrientRotateCutoutDisplay() {
+ public void testFixedOrientationRotateCutoutDisplay() {
// Create a display with a notch/cutout
final int notchHeight = 60;
- setUpApp(new TestDisplayContent.Builder(mAtm, 1000, 2500)
+ final int width = 1000;
+ setUpApp(new TestDisplayContent.Builder(mAtm, width, 2500)
.setNotch(notchHeight).build());
- // Bounds=[0, 0 - 1000, 1460], AppBounds=[0, 60 - 1000, 1460].
+ // Bounds=[0, 0 - 1000, 1400], AppBounds=[0, 60 - 1000, 1460].
+ final float maxAspect = 1.4f;
prepareUnresizable(mActivity, 1.4f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
final Rect currentBounds = mActivity.getWindowConfiguration().getBounds();
@@ -366,6 +407,11 @@
final Rect origBounds = new Rect(currentBounds);
final Rect origAppBounds = new Rect(appBounds);
+ // Activity is sandboxed, and bounds include the area consumed by the notch.
+ assertActivityMaxBoundsSandboxed();
+ assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds().height())
+ .isEqualTo(Math.round(width * maxAspect) + notchHeight);
+
// Although the activity is fixed orientation, force rotate the display.
rotateDisplay(mActivity.mDisplayContent, ROTATION_270);
assertEquals(ROTATION_270, mTask.getWindowConfiguration().getRotation());
@@ -381,10 +427,13 @@
// The position in configuration should be global coordinates.
assertEquals(mActivity.getBounds().left, currentBounds.left);
assertEquals(mActivity.getBounds().top, currentBounds.top);
+
+ // Activity max bounds are sandboxed due to size compat mode.
+ assertActivityMaxBoundsSandboxed();
}
@Test
- public void testFixedAspOrientChangeOrient() {
+ public void testFixedAspectRatioOrientationChangeOrientation() {
setUpDisplaySizeWithApp(1000, 2500);
final float maxAspect = 1.4f;
@@ -396,6 +445,8 @@
final Rect originalAppBounds = new Rect(mActivity.getWindowConfiguration().getAppBounds());
assertEquals((int) (originalBounds.width() * maxAspect), originalBounds.height());
+ // Activity is sandboxed due to fixed aspect ratio.
+ assertActivityMaxBoundsSandboxed();
// Change the fixed orientation.
mActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
@@ -407,6 +458,8 @@
mActivity.getWindowConfiguration().getAppBounds().height());
assertEquals(originalAppBounds.height(),
mActivity.getWindowConfiguration().getAppBounds().width());
+ // Activity is sandboxed due to fixed aspect ratio.
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -455,6 +508,8 @@
// restarted and the override configuration won't be cleared.
verify(mActivity, never()).restartProcessIfVisible();
assertScaled();
+ // Activity max bounds are sandboxed due to size compat mode, even if is not visible.
+ assertActivityMaxBoundsSandboxed();
// Change display density
display.mBaseDisplayDensity = (int) (0.7f * display.mBaseDisplayDensity);
@@ -550,13 +605,13 @@
}
@Test
- public void testShouldUseSizeCompatModeOnResizableTask() {
+ public void testShouldCreateCompatDisplayInsetsOnResizeableTask() {
setUpDisplaySizeWithApp(1000, 2500);
// Make the task root resizable.
mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
- // Create a size compat activity on the same task.
+ // Create an activity on the same task.
final ActivityRecord activity = new ActivityBuilder(mAtm)
.setTask(mTask)
.setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
@@ -568,26 +623,30 @@
// in multi-window mode.
mTask.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
assertFalse(activity.shouldCreateCompatDisplayInsets());
+ // Activity should not be sandboxed.
+ assertMaxBoundsInheritDisplayAreaBounds();
// The non-resizable activity should not be size compat because the display support
// changing windowing mode from fullscreen to freeform.
mTask.mDisplayContent.setDisplayWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
mTask.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
assertFalse(activity.shouldCreateCompatDisplayInsets());
+ // Activity should not be sandboxed.
+ assertMaxBoundsInheritDisplayAreaBounds();
}
@Test
- @EnableCompatChanges({ActivityInfo.FORCE_RESIZE_APP})
- public void testNoSizeCompatWhenPerAppOverrideSet() {
+ public void testShouldCreateCompatDisplayInsetsWhenUnresizeableAndSupportsSizeChangesTrue() {
setUpDisplaySizeWithApp(1000, 2500);
// Make the task root resizable.
mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
- // Create a size compat activity on the same task.
+ // Create an activity on the same task.
final ActivityRecord activity = new ActivityBuilder(mAtm)
.setTask(mTask)
.setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
+ .setSupportsSizeChanges(true)
.setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
.setComponent(ComponentName.createRelative(mContext,
SizeCompatTests.class.getName()))
@@ -597,6 +656,130 @@
}
@Test
+ public void testShouldCreateCompatDisplayInsetsWhenUnresizeableAndSupportsSizeChangesFalse() {
+ setUpDisplaySizeWithApp(1000, 2500);
+
+ // Make the task root resizable.
+ mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
+
+ // Create an activity on the same task.
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setTask(mTask)
+ .setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
+ .setSupportsSizeChanges(false)
+ .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+ .setComponent(ComponentName.createRelative(mContext,
+ SizeCompatTests.class.getName()))
+ .setUid(android.os.Process.myUid())
+ .build();
+ assertTrue(activity.shouldCreateCompatDisplayInsets());
+ }
+
+ @Test
+ public void testShouldCreateCompatDisplayInsetsWhenResizeableAndSupportsSizeChangesFalse() {
+ setUpDisplaySizeWithApp(1000, 2500);
+
+ // Make the task root resizable.
+ mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
+
+ // Create an activity on the same task.
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setTask(mTask)
+ .setResizeMode(ActivityInfo.RESIZE_MODE_RESIZEABLE)
+ .setSupportsSizeChanges(false)
+ .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+ .setComponent(ComponentName.createRelative(mContext,
+ SizeCompatTests.class.getName()))
+ .setUid(android.os.Process.myUid())
+ .build();
+ assertFalse(activity.shouldCreateCompatDisplayInsets());
+ }
+
+ @Test
+ public void
+ testShouldCreateCompatDisplayInsetsWhenUnfixedOrientationSupportsSizeChangesFalse() {
+ setUpDisplaySizeWithApp(1000, 2500);
+
+ // Make the task root resizable.
+ mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
+
+ // Create an activity on the same task.
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setTask(mTask)
+ .setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
+ .setSupportsSizeChanges(false)
+ .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
+ .setComponent(ComponentName.createRelative(mContext,
+ SizeCompatTests.class.getName()))
+ .setUid(android.os.Process.myUid())
+ .build();
+ assertFalse(activity.shouldCreateCompatDisplayInsets());
+ }
+
+ @Test
+ @EnableCompatChanges({ActivityInfo.FORCE_RESIZE_APP})
+ public void testShouldCreateCompatDisplayInsetsWhenForceResizeAppOverrideSet() {
+ setUpDisplaySizeWithApp(1000, 2500);
+
+ // Make the task root resizable.
+ mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
+
+ // Create an activity on the same task.
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setTask(mTask)
+ .setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
+ .setSupportsSizeChanges(false)
+ .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+ .setComponent(ComponentName.createRelative(mContext,
+ SizeCompatTests.class.getName()))
+ .setUid(android.os.Process.myUid())
+ .build();
+ assertFalse(activity.shouldCreateCompatDisplayInsets());
+ }
+
+ @Test
+ @EnableCompatChanges({ActivityInfo.FORCE_NON_RESIZE_APP})
+ public void testShouldCreateCompatDisplayInsetsWhenForceNonResizeOverrideSet() {
+ setUpDisplaySizeWithApp(1000, 2500);
+
+ // Make the task root resizable.
+ mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
+
+ // Create an activity on the same task.
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setTask(mTask)
+ .setResizeMode(ActivityInfo.RESIZE_MODE_RESIZEABLE)
+ .setSupportsSizeChanges(true)
+ .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+ .setComponent(ComponentName.createRelative(mContext,
+ SizeCompatTests.class.getName()))
+ .setUid(android.os.Process.myUid())
+ .build();
+ assertTrue(activity.shouldCreateCompatDisplayInsets());
+ }
+
+ @Test
+ @EnableCompatChanges({ActivityInfo.FORCE_NON_RESIZE_APP})
+ public void testShouldCreateCompatDisplayInsetsWhenForceNonResizeSetAndUnfixedOrientation() {
+ setUpDisplaySizeWithApp(1000, 2500);
+
+ // Make the task root resizable.
+ mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
+
+ // Create an activity on the same task.
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setTask(mTask)
+ .setResizeMode(ActivityInfo.RESIZE_MODE_RESIZEABLE)
+ .setSupportsSizeChanges(true)
+ .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
+ .setComponent(ComponentName.createRelative(mContext,
+ SizeCompatTests.class.getName()))
+ .setUid(android.os.Process.myUid())
+ .build();
+ assertTrue(activity.shouldCreateCompatDisplayInsets());
+ }
+
+ @Test
public void testLaunchWithFixedRotationTransform() {
final int dw = 1000;
final int dh = 2500;
@@ -637,6 +820,9 @@
// be transparent.
assertFalse(displayPolicy.isFullyTransparentAllowed(w, TYPE_STATUS_BAR));
+ // Activity is sandboxed.
+ assertActivityMaxBoundsSandboxed();
+
// Make the activity fill the display.
prepareUnresizable(mActivity, 10 /* maxAspect */, SCREEN_ORIENTATION_LANDSCAPE);
w.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
@@ -646,6 +832,7 @@
// The letterbox should only cover the notch area, so status bar can be transparent.
assertEquals(new Rect(notchHeight, 0, 0, 0), mActivity.getLetterboxInsets());
assertTrue(displayPolicy.isFullyTransparentAllowed(w, TYPE_STATUS_BAR));
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -668,6 +855,7 @@
// App should launch in fixed orientation letterbox.
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
+ assertActivityMaxBoundsSandboxed();
// Activity bounds should be 700x1400 with the ratio as the display.
assertEquals(displayBounds.height(), activityBounds.height());
@@ -789,6 +977,7 @@
assertScaled();
assertEquals(activityBounds.width(), newActivityBounds.width());
assertEquals(activityBounds.height(), newActivityBounds.height());
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -800,29 +989,29 @@
// Portrait fixed app without max aspect.
prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
- Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
- Rect activityBounds = new Rect(mActivity.getBounds());
-
// App should launch in fullscreen.
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
- assertEquals(displayBounds, activityBounds);
+ // Activity inherits max bounds from TaskDisplayArea.
+ assertMaxBoundsInheritDisplayAreaBounds();
// Rotate display to landscape.
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
- displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
- activityBounds = new Rect(mActivity.getBounds());
- assertTrue(displayBounds.width() > displayBounds.height());
+ final Rect rotatedDisplayBounds = new Rect(mActivity.mDisplayContent.getBounds());
+ final Rect rotatedActivityBounds = new Rect(mActivity.getBounds());
+ assertTrue(rotatedDisplayBounds.width() > rotatedDisplayBounds.height());
// App should be in size compat.
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertScaled();
+ assertThat(mActivity.inSizeCompatMode()).isTrue();
+ assertActivityMaxBoundsSandboxed();
// App bounds should be 700x1400 with the ratio as the display.
- assertEquals(displayBounds.height(), activityBounds.height());
- assertEquals(displayBounds.height() * displayBounds.height() / displayBounds.width(),
- activityBounds.width());
+ assertEquals(rotatedDisplayBounds.height(), rotatedActivityBounds.height());
+ assertEquals(rotatedDisplayBounds.height() * rotatedDisplayBounds.height()
+ / rotatedDisplayBounds.width(), rotatedActivityBounds.width());
}
@Test
@@ -859,6 +1048,7 @@
// has 700x1400 bounds with the ratio as the display.
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(newActivity.inSizeCompatMode());
+ assertActivityMaxBoundsSandboxed();
assertEquals(taskBounds, displayBounds);
assertEquals(displayBounds.height(), newActivityBounds.height());
assertEquals(displayBounds.height() * displayBounds.height() / displayBounds.width(),
@@ -899,6 +1089,11 @@
// Task bounds should fill parent bounds.
assertEquals(displayBounds, taskBounds);
+ // Prior and new activity max bounds are sandboxed due to letterbox.
+ assertThat(newActivity.getConfiguration().windowConfiguration.getMaxBounds())
+ .isEqualTo(newActivityBounds);
+ assertActivityMaxBoundsSandboxed();
+
// Activity bounds should be (1400 / 1.3 = 1076)x1400 with the app requested ratio.
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(newActivity.inSizeCompatMode());
@@ -927,6 +1122,9 @@
// App should be in size compat.
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertScaled();
+ assertThat(mActivity.inSizeCompatMode()).isTrue();
+ // Activity max bounds are sandboxed due to size compat mode.
+ assertActivityMaxBoundsSandboxed();
final Rect activityBounds = new Rect(mActivity.getBounds());
mTask.resumeTopActivityUncheckedLocked(null /* prev */, null /* options */);
@@ -936,6 +1134,8 @@
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertScaled();
assertEquals(activityBounds, mActivity.getBounds());
+ // Activity max bounds are sandboxed due to size compat.
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -951,6 +1151,7 @@
// In fixed orientation letterbox
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
+ assertActivityMaxBoundsSandboxed();
// Rotate display to portrait.
rotateDisplay(display, ROTATION_90);
@@ -958,13 +1159,15 @@
// App should be in size compat.
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertScaled();
+ assertActivityMaxBoundsSandboxed();
// Rotate display to landscape.
rotateDisplay(display, ROTATION_180);
- // In Task letterbox
+ // In activity letterbox
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -982,20 +1185,23 @@
// In fixed orientation letterbox
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
+ assertActivityMaxBoundsSandboxed();
- // Rotate display to portrait.
+ // Rotate display to landscape.
rotateDisplay(display, ROTATION_90);
// App should be in size compat.
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertScaled();
+ assertActivityMaxBoundsSandboxed();
- // Rotate display to landscape.
+ // Rotate display to portrait.
rotateDisplay(display, ROTATION_180);
// In fixed orientation letterbox
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -1012,12 +1218,18 @@
assertEquals(ORIENTATION_LANDSCAPE, display.getConfiguration().orientation);
assertEquals(2800, displayBounds.width());
assertEquals(1400, displayBounds.height());
- taskDisplayArea.setBounds(0, 0, 2400, 1000);
+ Rect displayAreaBounds = new Rect(0, 0, 2400, 1000);
+ taskDisplayArea.setBounds(displayAreaBounds);
final Rect activityBounds = new Rect(mActivity.getBounds());
assertFalse(mActivity.inSizeCompatMode());
assertEquals(2400, activityBounds.width());
assertEquals(1000, activityBounds.height());
+ // Task and activity maximum bounds inherit from TaskDisplayArea bounds.
+ assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds())
+ .isEqualTo(displayAreaBounds);
+ assertThat(mTask.getConfiguration().windowConfiguration.getMaxBounds())
+ .isEqualTo(displayAreaBounds);
}
@Test
@@ -1042,6 +1254,7 @@
assertScaled();
assertEquals(originalBounds,
mActivity.getConfiguration().windowConfiguration.getBounds());
+ assertActivityMaxBoundsSandboxed();
// Recompute the natural configuration of the non-resizable activity and the split screen.
mActivity.clearSizeCompatMode();
@@ -1053,12 +1266,13 @@
addWindowToActivity(mActivity);
mActivity.mRootWindowContainer.performSurfacePlacement();
- // Split screen is also in portrait [1000,1400], so activty should be in fixed orientation
+ // Split screen is also in portrait [1000,1400], so activity should be in fixed orientation
// letterbox.
assertEquals(ORIENTATION_PORTRAIT, mTask.getConfiguration().orientation);
assertEquals(ORIENTATION_LANDSCAPE, mActivity.getConfiguration().orientation);
assertFitted();
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertActivityMaxBoundsSandboxed();
// Letterbox should fill the gap between the split screen and the letterboxed activity.
final Rect primarySplitBounds = new Rect(organizer.mPrimary.getBounds());
@@ -1165,6 +1379,22 @@
assertFalse(mActivity.hasSizeCompatBounds());
}
+ /** Asserts the activity max bounds inherit from the TaskDisplayArea. */
+ private void assertMaxBoundsInheritDisplayAreaBounds() {
+ assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds())
+ .isEqualTo(mTask.getDisplayArea().getBounds());
+ }
+
+ /**
+ * Asserts activity-level letterbox or size compat mode size compat mode, so activity max
+ * bounds are sandboxed.
+ */
+ private void assertActivityMaxBoundsSandboxed() {
+ // Activity max bounds are sandboxed due to size compat mode.
+ assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds())
+ .isEqualTo(mActivity.getWindowConfiguration().getBounds());
+ }
+
static Configuration rotateDisplay(DisplayContent display, int rotation) {
final Configuration c = new Configuration();
display.getDisplayRotation().setRotation(rotation);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index ecb8b60..dca6b08 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -26,6 +26,7 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
import static com.google.common.truth.Truth.assertThat;
@@ -277,4 +278,15 @@
// Orientation request from standard activity in multi window will not be handled.
assertFalse(leafTask2.handlesOrientationChangeFromDescendant());
}
+
+ @Test
+ public void testAlwaysOnTop() {
+ final Task task = createTaskStackOnDisplay(mDisplayContent);
+ task.setAlwaysOnTop(true);
+ task.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ assertTrue(task.isAlwaysOnTop());
+
+ task.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, true /* set */);
+ assertFalse(task.isAlwaysOnTop());
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
index ae85ceb..cac6965 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
@@ -136,6 +136,7 @@
final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
mInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
final TestDisplayContent newDisplay = createInternal(display);
+
// disable the normal system decorations
final DisplayPolicy displayPolicy = newDisplay.getDisplayPolicy();
spyOn(displayPolicy);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 51aec65..5b5b1da 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -521,7 +521,7 @@
matrix.mapPoints(curSurfacePos);
verify(t).setPosition(eq(app.mSurfaceControl), eq(curSurfacePos[0]), eq(curSurfacePos[1]));
- app.finishSeamlessRotation(false /* timeout */);
+ app.finishSeamlessRotation(t);
assertFalse(app.mSeamlesslyRotated);
assertNull(app.mPendingSeamlessRotate);
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 8d50a77..827ff6c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -176,6 +176,11 @@
} else {
mDisplayContent = mDefaultDisplay;
}
+
+ // 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);
}
private void createTestDisplay(UseTestDisplay annotation) {
@@ -704,6 +709,7 @@
private int mLaunchMode;
private int mResizeMode = RESIZE_MODE_RESIZEABLE;
private float mMaxAspectRatio;
+ private boolean mSupportsSizeChanges;
private int mScreenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
private boolean mLaunchTaskBehind = false;
private int mConfigChanges;
@@ -782,6 +788,11 @@
return this;
}
+ ActivityBuilder setSupportsSizeChanges(boolean supportsSizeChanges) {
+ mSupportsSizeChanges = supportsSizeChanges;
+ return this;
+ }
+
ActivityBuilder setScreenOrientation(int screenOrientation) {
mScreenOrientation = screenOrientation;
return this;
@@ -869,6 +880,7 @@
aInfo.launchMode = mLaunchMode;
aInfo.resizeMode = mResizeMode;
aInfo.maxAspectRatio = mMaxAspectRatio;
+ aInfo.supportsSizeChanges = mSupportsSizeChanges;
aInfo.screenOrientation = mScreenOrientation;
aInfo.configChanges |= mConfigChanges;
aInfo.taskAffinity = mAffinity;
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index ed71d17..e089995a 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -17,6 +17,7 @@
package com.android.server.voiceinteraction;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -25,8 +26,10 @@
import android.media.AudioAttributes;
import android.media.AudioRecord;
import android.media.MediaRecorder;
+import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
+import android.os.SharedMemory;
import android.service.voice.AlwaysOnHotwordDetector;
import android.service.voice.HotwordDetectionService;
import android.service.voice.IDspHotwordDetectionCallback;
@@ -74,7 +77,8 @@
boolean mBound;
HotwordDetectionConnection(Object lock, Context context, ComponentName serviceName,
- int userId, boolean bindInstantServiceAllowed) {
+ int userId, boolean bindInstantServiceAllowed, @Nullable Bundle options,
+ @Nullable SharedMemory sharedMemory) {
mLock = lock;
mContext = context;
mDetectionComponentName = serviceName;
@@ -90,6 +94,14 @@
boolean connected) {
synchronized (mLock) {
mBound = connected;
+ if (connected) {
+ try {
+ service.setConfig(options, sharedMemory);
+ } catch (RemoteException e) {
+ // TODO: (b/181842909) Report an error to voice interactor
+ Slog.w(TAG, "Failed to setConfig for HotwordDetectionService", e);
+ }
+ }
}
}
@@ -117,6 +129,11 @@
}
}
+ void setConfigLocked(Bundle options, SharedMemory sharedMemory) {
+ mRemoteHotwordDetectionService.run(
+ service -> service.setConfig(options, sharedMemory));
+ }
+
private void detectFromDspSource(SoundTrigger.KeyphraseRecognitionEvent recognitionEvent,
IHotwordRecognitionStatusCallback externalCallback) {
if (DEBUG) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index dce63eb..2626bfd 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -60,6 +60,7 @@
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
+import android.os.SharedMemory;
import android.os.ShellCallback;
import android.os.Trace;
import android.os.UserHandle;
@@ -982,23 +983,46 @@
}
@Override
- public int setHotwordDetectionConfig(Bundle options) {
+ public void setHotwordDetectionServiceConfig(@Nullable Bundle options,
+ @Nullable SharedMemory sharedMemory) {
synchronized (this) {
enforceIsCurrentVoiceInteractionService();
if (mImpl == null) {
Slog.w(TAG,
- "setHotwordDetectionConfig without running voice interaction service");
- return VoiceInteractionService.HOTWORD_CONFIG_FAILURE;
+ "setHotwordDetectionServiceConfig without running voice"
+ + " interaction service");
+ return;
}
final long caller = Binder.clearCallingIdentity();
try {
- return mImpl.setHotwordDetectionConfigLocked(options);
+ mImpl.setHotwordDetectionServiceConfigLocked(options, sharedMemory);
} finally {
Binder.restoreCallingIdentity(caller);
}
}
}
+
+ @Override
+ public void shutdownHotwordDetectionService() {
+ synchronized (this) {
+ enforceIsCurrentVoiceInteractionService();
+
+ if (mImpl == null) {
+ Slog.w(TAG,
+ "shutdownHotwordDetectionService without running voice"
+ + " interaction service");
+ return;
+ }
+ final long caller = Binder.clearCallingIdentity();
+ try {
+ mImpl.shutdownHotwordDetectionServiceLocked();
+ } finally {
+ Binder.restoreCallingIdentity(caller);
+ }
+ }
+ }
+
//----------------- Model management APIs --------------------------------//
@Override
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 04dea3f..5861610 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -43,11 +43,13 @@
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SharedMemory;
import android.os.UserHandle;
import android.service.voice.IVoiceInteractionService;
import android.service.voice.IVoiceInteractionSession;
import android.service.voice.VoiceInteractionService;
import android.service.voice.VoiceInteractionServiceInfo;
+import android.system.OsConstants;
import android.util.PrintWriterPrinter;
import android.util.Slog;
import android.view.IWindowManager;
@@ -389,25 +391,48 @@
return mInfo.getSupportsLocalInteraction();
}
- public int setHotwordDetectionConfigLocked(Bundle options) {
+ public void setHotwordDetectionServiceConfigLocked(@Nullable Bundle options,
+ @Nullable SharedMemory sharedMemory) {
if (DEBUG) {
- Slog.d(TAG, "setHotwordDetectionConfigLocked");
+ Slog.d(TAG, "setHotwordDetectionServiceConfigLocked");
}
if (mHotwordDetectionComponentName == null) {
- Slog.e(TAG, "Calling setHotwordDetectionConfigLocked, but hotword detection service"
- + " name not found");
- return VoiceInteractionService.HOTWORD_CONFIG_FAILURE;
+ Slog.w(TAG, "Hotword detection service name not found");
+ throw new IllegalStateException("Hotword detection service name not found");
}
if (!isIsolatedProcessLocked(mHotwordDetectionComponentName)) {
- return VoiceInteractionService.HOTWORD_CONFIG_FAILURE;
+ Slog.w(TAG, "Hotword detection service not in isolated process");
+ throw new IllegalStateException("Hotword detection service not in isolated process");
}
// TODO : Need to check related permissions for hotword detection service
// TODO : Sanitize for bundle
- mHotwordDetectionConnection = new HotwordDetectionConnection(mServiceStub, mContext,
- mHotwordDetectionComponentName, mUser, /* bindInstantServiceAllowed= */ false);
+ if (sharedMemory != null && !sharedMemory.setProtect(OsConstants.PROT_READ)) {
+ Slog.w(TAG, "Can't set sharedMemory to be read-only");
+ throw new IllegalStateException("Can't set sharedMemory to be read-only");
+ }
- return VoiceInteractionService.HOTWORD_CONFIG_SUCCESS;
+ if (mHotwordDetectionConnection == null) {
+ mHotwordDetectionConnection = new HotwordDetectionConnection(mServiceStub, mContext,
+ mHotwordDetectionComponentName, mUser, /* bindInstantServiceAllowed= */ false,
+ options, sharedMemory);
+ } else {
+ mHotwordDetectionConnection.setConfigLocked(options, sharedMemory);
+ }
+ }
+
+ public void shutdownHotwordDetectionServiceLocked() {
+ if (DEBUG) {
+ Slog.d(TAG, "shutdownHotwordDetectionServiceLocked");
+ }
+
+ if (mHotwordDetectionConnection == null) {
+ Slog.w(TAG, "shutdown, but no hotword detection connection");
+ return;
+ }
+
+ mHotwordDetectionConnection.cancelLocked();
+ mHotwordDetectionConnection = null;
}
public IRecognitionStatusCallback createSoundTriggerCallbackLocked(
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index dc2fb94..f84dd7b 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -338,7 +338,7 @@
*
* @param videoState The video state in which to answer the connection.
*/
- public void onAnswer(int videoState) {}
+ public void onAnswer(@VideoProfile.VideoState int videoState) {}
/**
* Notifies this Conference, which is in {@code STATE_RINGING}, of
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index c189b19..d8bd6a5 100755
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -20,6 +20,7 @@
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
@@ -1919,6 +1920,7 @@
/** {@inheritDoc} */
@Override
public final IBinder onBind(Intent intent) {
+ onBindClient(intent);
return mBinder;
}
@@ -1929,6 +1931,13 @@
return super.onUnbind(intent);
}
+ /**
+ * Used for testing to let the test suite know when the connection service has been bound.
+ * @hide
+ */
+ @TestApi
+ public void onBindClient(@Nullable Intent intent) {
+ }
/**
* This can be used by telecom to either create a new outgoing conference call or attach
@@ -2585,9 +2594,9 @@
* @return The {@code Connection} object to satisfy this call, or {@code null} to
* not handle the call.
*/
- public final RemoteConnection createRemoteIncomingConnection(
- PhoneAccountHandle connectionManagerPhoneAccount,
- ConnectionRequest request) {
+ public final @Nullable RemoteConnection createRemoteIncomingConnection(
+ @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+ @NonNull ConnectionRequest request) {
return mRemoteConnectionManager.createRemoteConnection(
connectionManagerPhoneAccount, request, true);
}
@@ -2604,9 +2613,9 @@
* @return The {@code Connection} object to satisfy this call, or {@code null} to
* not handle the call.
*/
- public final RemoteConnection createRemoteOutgoingConnection(
- PhoneAccountHandle connectionManagerPhoneAccount,
- ConnectionRequest request) {
+ public final @Nullable RemoteConnection createRemoteOutgoingConnection(
+ @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+ @NonNull ConnectionRequest request) {
return mRemoteConnectionManager.createRemoteConnection(
connectionManagerPhoneAccount, request, false);
}
@@ -2846,12 +2855,14 @@
* @param connectionManagerPhoneAccount See description at
* {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
* @param request Details about the incoming conference call.
- * @return The {@code Conference} object to satisfy this call, or {@code null} to
- * not handle the call.
+ * @return The {@code Conference} object to satisfy this call. If the conference attempt is
+ * failed, the return value will be a result of an invocation of
+ * {@link Connection#createFailedConnection(DisconnectCause)}.
+ * Return {@code null} if the {@link ConnectionService} cannot handle the call.
*/
public @Nullable Conference onCreateIncomingConference(
- @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
- @Nullable ConnectionRequest request) {
+ @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+ @NonNull ConnectionRequest request) {
return null;
}
@@ -2954,8 +2965,8 @@
* @param request The outgoing connection request.
*/
public void onCreateOutgoingConferenceFailed(
- @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
- @Nullable ConnectionRequest request) {
+ @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+ @NonNull ConnectionRequest request) {
}
@@ -3019,12 +3030,14 @@
* a {@code PhoneAccount} registered by this {@code ConnectionService} to use for
* making the connection.
* @param request Details about the outgoing call.
- * @return The {@code Conference} object to satisfy this call, or the result of an invocation
- * of {@link Connection#createFailedConnection(DisconnectCause)} to not handle the call.
+ * @return The {@code Conference} object to satisfy this call. If the conference attempt is
+ * failed, the return value will be a result of an invocation of
+ * {@link Connection#createFailedConnection(DisconnectCause)}.
+ * Return {@code null} if the {@link ConnectionService} cannot handle the call.
*/
public @Nullable Conference onCreateOutgoingConference(
- @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
- @Nullable ConnectionRequest request) {
+ @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+ @NonNull ConnectionRequest request) {
return null;
}
diff --git a/telephony/java/android/telephony/CarrierBandwidth.java b/telephony/java/android/telephony/CarrierBandwidth.java
index b153fef..9e1dee0 100644
--- a/telephony/java/android/telephony/CarrierBandwidth.java
+++ b/telephony/java/android/telephony/CarrierBandwidth.java
@@ -101,7 +101,7 @@
}
/**
- * Retrieves the upstream bandwidth for the primary network in Kbps. This always only refers to
+ * Retrieves the upstream bandwidth for the primary network in kbps. This always only refers to
* the estimated first hop transport bandwidth.
* This will be {@link #INVALID} if the network is not connected
*
@@ -112,7 +112,7 @@
}
/**
- * Retrieves the downstream bandwidth for the primary network in Kbps. This always only refers
+ * Retrieves the downstream bandwidth for the primary network in kbps. This always only refers
* to the estimated first hop transport bandwidth.
* This will be {@link #INVALID} if the network is not connected
*
@@ -123,7 +123,7 @@
}
/**
- * Retrieves the upstream bandwidth for the secondary network in Kbps. This always only refers
+ * Retrieves the upstream bandwidth for the secondary network in kbps. This always only refers
* to the estimated first hop transport bandwidth.
* <p/>
* This will be {@link #INVALID} if either are the case:
@@ -143,7 +143,7 @@
}
/**
- * Retrieves the downstream bandwidth for the secondary network in Kbps. This always only
+ * Retrieves the downstream bandwidth for the secondary network in kbps. This always only
* refers to the estimated first hop transport bandwidth.
* <p/>
* This will be {@link #INVALID} if either are the case:
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index b52f4919..705e93f 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -35,7 +35,6 @@
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsRegistrationAttributes;
import android.telephony.ims.ImsSsData;
-import android.telephony.ims.SipDelegateManager;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.feature.RcsFeature;
@@ -1341,6 +1340,38 @@
"support_ims_conference_event_package_on_peer_bool";
/**
+ * Indicates whether the carrier supports the use of RFC8285 compliant RTP header extensions for
+ * the purpose of device to device communication while in a call.
+ * <p>
+ * See also {@link #KEY_SUPPORTS_SDP_NEGOTIATION_OF_D2D_RTP_HEADER_EXTENSIONS_BOOL}.
+ */
+ public static final String KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL =
+ "supports_device_to_device_communication_using_rtp_bool";
+
+ /**
+ * Indicates whether the carrier supports the negotiations of RFC8285 compliant RTP header
+ * extensions supported on a call during the Session Description Protocol (SDP). This option
+ * is only used when {@link #KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL} is
+ * {@code true}.
+ * <p>
+ * When {@code true}, the RTP header extensions the platform uses for device to device
+ * communication will be offered to the remote end during the SDP negotiation process.
+ * When {@code false}, the RTP header extensions will not be negotiated during the SDP
+ * negotiation process and the platform will send RTP header extensions without prior
+ * negotiation if {@link #KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL} is
+ * {@code true}.
+ */
+ public static final String KEY_SUPPORTS_SDP_NEGOTIATION_OF_D2D_RTP_HEADER_EXTENSIONS_BOOL =
+ "supports_sdp_negotiation_of_d2d_rtp_header_extensions_bool";
+
+ /**
+ * Indicates whether the carrier supports the use of DTMF digits A-D for the purpose of device
+ * to device communication while in a call.
+ */
+ public static final String KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_DTMF_BOOL =
+ "supports_device_to_device_communication_using_dtmf_bool";
+
+ /**
* Determines whether High Definition audio property is displayed in the dialer UI.
* If {@code false}, remove the HD audio property from the connection so that HD audio related
* UI is not displayed. If {@code true}, keep HD audio property as it is configured.
@@ -1537,15 +1568,13 @@
"wfc_carrier_name_override_by_pnn_bool";
/**
- * Value for {#CROSS_SIM_SPN_FORMAT_CARRIER_NAME_WITH_BRANDING} cnfig.
- * specifies SPN format of displaying carrier name only.
+ * Specifies SPN format of displaying carrier name only.
*
*/
public static final int CROSS_SIM_SPN_FORMAT_CARRIER_NAME_ONLY = 0;
/**
- * Value for {#CROSS_SIM_SPN_FORMAT_CARRIER_NAME_WITH_BRANDING} cnfig.
- * specifies SPN format of displaying carrier name along with "Cross-SIM calling".
+ * Specifies SPN format of displaying carrier name along with "Cross-SIM calling".
*/
public static final int CROSS_SIM_SPN_FORMAT_CARRIER_NAME_WITH_BRANDING = 1;
@@ -1554,8 +1583,8 @@
*
* <p>Available options are:
* <ul>
- * <li> {#CROSS_SIM_SPN_FORMAT_CARRIER_NAME_ONLY}: %s</li>
- * <li> {#CROSS_SIM_SPN_FORMAT_CARRIER_NAME_WITH_BRANDING}: %s Cross-SIM Calling</li>
+ * <li> {@link #CROSS_SIM_SPN_FORMAT_CARRIER_NAME_ONLY}: %s</li>
+ * <li> {@link #CROSS_SIM_SPN_FORMAT_CARRIER_NAME_WITH_BRANDING}: %s Cross-SIM Calling</li>
* </ul>
* %s will be filled with carrier name
*/
@@ -5011,6 +5040,9 @@
sDefaults.putBoolean(KEY_SUPPORT_MANAGE_IMS_CONFERENCE_CALL_BOOL, true);
sDefaults.putBoolean(KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL, true);
sDefaults.putBoolean(KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_ON_PEER_BOOL, true);
+ sDefaults.putBoolean(KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL, false);
+ sDefaults.putBoolean(KEY_SUPPORTS_SDP_NEGOTIATION_OF_D2D_RTP_HEADER_EXTENSIONS_BOOL, false);
+ sDefaults.putBoolean(KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_DTMF_BOOL, false);
sDefaults.putBoolean(KEY_SUPPORT_VIDEO_CONFERENCE_CALL_BOOL, false);
sDefaults.putBoolean(KEY_IS_IMS_CONFERENCE_SIZE_ENFORCED_BOOL, false);
sDefaults.putInt(KEY_IMS_CONFERENCE_SIZE_LIMIT_INT, 5);
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index cf4e677..2d5f5fb 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -416,7 +416,7 @@
* <p>
* Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
* subscription cross sim calling enabled
- * {@link ImsMmTelManager#isCrossSimCallingEnabledByUser()}
+ * {@link ImsMmTelManager#isCrossSimCallingEnabled()}
* while your app is running. You can also use a {@link android.app.job.JobService}
* to ensure your app
* is notified of changes to the {@link Uri} even when it is not running.
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c48bd21..3cb72b5 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -14618,12 +14618,11 @@
* {@link #NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE}
* </ol>
* @return operation result.
- * <p>Requires Permission:
- * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
* @throws IllegalStateException if the Telephony process is not currently available.
* @hide
*/
@SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public @EnableNrDualConnectivityResult int setNrDualConnectivityState(
@NrDualConnectivityState int nrDualConnectivityState) {
try {
diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java
index ca1f861..363e47a 100644
--- a/telephony/java/android/telephony/data/DataServiceCallback.java
+++ b/telephony/java/android/telephony/data/DataServiceCallback.java
@@ -254,15 +254,15 @@
}
/**
- * The APN is throttled for the duration specified in
- * {@link DataCallResponse#getRetryDurationMillis}. Calling this method unthrottles that
- * APN.
+ * Unthrottles the APN on the current transport. There is no matching "APN throttle" method.
+ * Instead, the APN is throttled for the time specified in
+ * {@link DataCallResponse#getRetryDurationMillis}.
* <p/>
* see: {@link DataCallResponse#getRetryDurationMillis}
*
* @param apn Access Point Name defined by the carrier.
*/
- public void onApnUnthrottled(@NonNull String apn) {
+ public void onApnUnthrottled(final @NonNull String apn) {
if (mCallback != null) {
try {
if (DBG) Rlog.d(TAG, "onApnUnthrottled");
diff --git a/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java b/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java
index 041edc0..406c38b 100644
--- a/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java
+++ b/telephony/java/android/telephony/data/EpsBearerQosSessionAttributes.java
@@ -184,16 +184,6 @@
mRemoteAddresses = Collections.unmodifiableList(remoteAddresses);
}
- /**
- * Creates attributes based off of a parcel
- * @param in the parcel
- * @return the attributes
- */
- @NonNull
- public static EpsBearerQosSessionAttributes create(@NonNull final Parcel in) {
- return new EpsBearerQosSessionAttributes(in);
- }
-
@Override
public int describeContents() {
return 0;
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index fcb4782..4b28296 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -1018,7 +1018,7 @@
@RequiresPermission(anyOf = {
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
android.Manifest.permission.READ_PRECISE_PHONE_STATE})
- public boolean isCrossSimCallingEnabledByUser() throws ImsException {
+ public boolean isCrossSimCallingEnabled() throws ImsException {
ITelephony iTelephony = getITelephony();
if (iTelephony == null) {
throw new ImsException("Could not find Telephony Service.",
@@ -1058,7 +1058,7 @@
* the IMS service is not available.
* @param isEnabled true if the user's setting for Voice over Cross SIM is enabled,
* false otherwise
- * @see #isCrossSimCallingEnabledByUser()
+ * @see #isCrossSimCallingEnabled()
* @hide
*/
@SystemApi
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index 20e4b88..6985b36 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -17,25 +17,12 @@
package com.android.server.wm.flicker.rotation
import android.platform.test.annotations.Presubmit
-import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
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.dsl.FlickerBuilder
-import com.android.server.wm.flicker.endRotation
-import com.android.server.wm.flicker.focusDoesNotChange
import com.android.server.wm.flicker.helpers.SimpleAppHelper
-import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
-import com.android.server.wm.flicker.noUncoveredRegions
-import com.android.server.wm.flicker.startRotation
-import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
-import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
-import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -66,24 +53,6 @@
@Presubmit
@Test
- fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsAlwaysVisible()
-
- @Presubmit
- @Test
- fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible()
-
- @Presubmit
- @Test
- fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
- testSpec.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
- @Presubmit
- @Test
- fun noUncoveredRegions() = testSpec.noUncoveredRegions(testSpec.config.startRotation,
- testSpec.config.endRotation, allStates = false)
-
- @Presubmit
- @Test
fun screenshotLayerBecomesInvisible() {
testSpec.assertLayers {
this.isVisible(testApp.getPackage())
@@ -94,49 +63,6 @@
}
}
- @FlakyTest(bugId = 140855415)
- @Test
- fun navBarLayerIsAlwaysVisible() = testSpec.navBarLayerIsAlwaysVisible()
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsAlwaysVisible()
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales(
- testSpec.config.startRotation, testSpec.config.endRotation)
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales(
- testSpec.config.startRotation, testSpec.config.endRotation)
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun visibleLayersShownMoreThanOneConsecutiveEntry() =
- testSpec.visibleLayersShownMoreThanOneConsecutiveEntry()
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun appLayerRotates_StartingPos() {
- testSpec.assertLayersStart {
- this.coversExactly(startingPos, testApp.getPackage())
- }
- }
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun appLayerRotates_EndingPos() {
- testSpec.assertLayersEnd {
- this.coversExactly(endingPos, testApp.getPackage())
- }
- }
-
- @FlakyTest(bugId = 151179149)
- @Test
- fun focusDoesNotChange() = testSpec.focusDoesNotChange()
-
companion object {
private const val SCREENSHOT_LAYER = "RotationLayer"
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
index c391112..9d78eb8 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
@@ -17,17 +17,30 @@
package com.android.server.wm.flicker.rotation
import android.app.Instrumentation
+import android.platform.test.annotations.Presubmit
+import androidx.test.filters.FlakyTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.FlickerBuilderProvider
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.endRotation
+import com.android.server.wm.flicker.focusDoesNotChange
import com.android.server.wm.flicker.helpers.StandardAppHelper
import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
import com.android.server.wm.flicker.repetitions
import com.android.server.wm.flicker.startRotation
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
+import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
+import org.junit.Test
abstract class RotationTransition(protected val testSpec: FlickerTestParameter) {
protected abstract val testApp: StandardAppHelper
@@ -63,4 +76,82 @@
transition(testSpec.config)
}
}
+
+ @Presubmit
+ @Test
+ open fun navBarWindowIsAlwaysVisible() {
+ testSpec.navBarWindowIsAlwaysVisible()
+ }
+
+ @FlakyTest(bugId = 140855415)
+ @Test
+ open fun navBarLayerIsAlwaysVisible() {
+ testSpec.navBarLayerIsAlwaysVisible()
+ }
+
+ @FlakyTest(bugId = 140855415)
+ @Test
+ open fun navBarLayerRotatesAndScales() {
+ testSpec.navBarLayerRotatesAndScales(
+ testSpec.config.startRotation, testSpec.config.endRotation)
+ }
+
+ @Presubmit
+ @Test
+ open fun statusBarWindowIsAlwaysVisible() {
+ testSpec.statusBarWindowIsAlwaysVisible()
+ }
+
+ @FlakyTest(bugId = 140855415)
+ @Test
+ open fun statusBarLayerIsAlwaysVisible() {
+ testSpec.statusBarLayerIsAlwaysVisible()
+ }
+
+ @FlakyTest(bugId = 140855415)
+ @Test
+ open fun statusBarLayerRotatesScales() {
+ testSpec.statusBarLayerRotatesScales(
+ testSpec.config.startRotation, testSpec.config.endRotation)
+ }
+
+ @FlakyTest(bugId = 140855415)
+ @Test
+ open fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ testSpec.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ @Presubmit
+ @Test
+ open fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
+ testSpec.visibleWindowsShownMoreThanOneConsecutiveEntry()
+ }
+
+ @Presubmit
+ @Test
+ open fun noUncoveredRegions() {
+ testSpec.noUncoveredRegions(testSpec.config.startRotation,
+ testSpec.config.endRotation, allStates = false)
+ }
+
+ @FlakyTest(bugId = 151179149)
+ @Test
+ open fun focusDoesNotChange() {
+ testSpec.focusDoesNotChange()
+ }
+
+ @FlakyTest(bugId = 140855415)
+ @Test
+ open fun appLayerRotates_StartingPos() {
+ testSpec.assertLayersStart {
+ this.coversExactly(startingPos, testApp.getPackage())
+ }
+ }
+
+ @FlakyTest(bugId = 140855415)
+ @Test
+ open fun appLayerRotates_EndingPos() {
+ testSpec.assertLayersEnd {
+ this.coversExactly(endingPos, testApp.getPackage())
+ }
+ }
}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index fc5bcc7..45d3006 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -24,21 +24,9 @@
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.appWindowAlwaysVisibleOnTop
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.endRotation
-import com.android.server.wm.flicker.focusDoesNotChange
import com.android.server.wm.flicker.helpers.SeamlessRotationAppHelper
import com.android.server.wm.flicker.layerAlwaysVisible
-import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
-import com.android.server.wm.flicker.noUncoveredRegions
-import com.android.server.wm.flicker.startRotation
-import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
-import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -71,10 +59,17 @@
}
}
- @Presubmit
+ @FlakyTest(bugId = 140855415)
@Test
- fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
- testSpec.visibleWindowsShownMoreThanOneConsecutiveEntry()
+ override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+ @FlakyTest(bugId = 140855415)
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+ @FlakyTest(bugId = 147659548)
+ @Test
+ override fun noUncoveredRegions() = super.noUncoveredRegions()
@Presubmit
@Test
@@ -84,42 +79,6 @@
@Test
fun layerAlwaysVisible() = testSpec.layerAlwaysVisible(testApp.`package`)
- @FlakyTest(bugId = 140855415)
- @Test
- fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsAlwaysVisible()
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible()
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun navBarLayerIsAlwaysVisible() = testSpec.navBarLayerIsAlwaysVisible()
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsAlwaysVisible()
-
- @FlakyTest(bugId = 147659548)
- @Test
- fun noUncoveredRegions() = testSpec.noUncoveredRegions(testSpec.config.startRotation,
- testSpec.config.endRotation, allStates = false)
-
- @FlakyTest
- @Test
- fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales(
- testSpec.config.startRotation, testSpec.config.endRotation)
-
- @FlakyTest
- @Test
- fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales(
- testSpec.config.startRotation, testSpec.config.endRotation)
-
- @FlakyTest
- @Test
- fun visibleLayersShownMoreThanOneConsecutiveEntry() =
- testSpec.visibleLayersShownMoreThanOneConsecutiveEntry()
-
@FlakyTest(bugId = 147659548)
@Test
fun appLayerRotates() {
@@ -128,10 +87,6 @@
}
}
- @FlakyTest(bugId = 151179149)
- @Test
- fun focusDoesNotChange() = testSpec.focusDoesNotChange()
-
companion object {
private val testFactory = FlickerTestParameterFactory.getInstance()
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index 7f0318a..e1a424f 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -79,6 +79,7 @@
"android.test.runner",
"android.test.base",
"android.test.mock",
+ "ServiceConnectivityResources",
],
jni_libs: [
"libservice-connectivity",
diff --git a/tests/net/TEST_MAPPING b/tests/net/TEST_MAPPING
index 89fc6ea..d659688 100644
--- a/tests/net/TEST_MAPPING
+++ b/tests/net/TEST_MAPPING
@@ -9,6 +9,23 @@
"name": "FrameworksNetDeflakeTest"
}
],
+ "auto-postsubmit": [
+ // Test tag for automotive targets. These are only running in postsubmit so as to harden the
+ // automotive targets to avoid introducing additional test flake and build time. The plan for
+ // presubmit testing for auto is to augment the existing tests to cover auto use cases as well.
+ // Additionally, this tag is used in targeted test suites to limit resource usage on the test
+ // infra during the hardening phase.
+ // TODO: this tag to be removed once the above is no longer an issue.
+ {
+ "name": "FrameworksNetTests"
+ },
+ {
+ "name": "FrameworksNetIntegrationTests"
+ },
+ {
+ "name": "FrameworksNetDeflakeTest"
+ }
+ ],
"imports": [
{
"path": "cts/tests/tests/net"
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index ddc31bf..e84b992 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -68,6 +68,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.modules.utils.build.SdkLevel;
+import com.android.testutils.CompatUtil;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
@@ -211,7 +212,7 @@
nc1 = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI);
nc2 = new NetworkCapabilities()
.addTransportType(TRANSPORT_WIFI)
- .setNetworkSpecifier(new EthernetNetworkSpecifier("eth42"));
+ .setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier("eth42"));
assertNotEquals("", nc1.describeImmutableDifferences(nc2));
assertEquals("", nc1.describeImmutableDifferences(nc1));
}
@@ -671,7 +672,7 @@
NetworkCapabilities nc1 = new NetworkCapabilities();
nc1.addTransportType(TRANSPORT_CELLULAR).addTransportType(TRANSPORT_WIFI);
try {
- nc1.setNetworkSpecifier(new EthernetNetworkSpecifier("eth0"));
+ nc1.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier("eth0"));
fail("Cannot set NetworkSpecifier on a NetworkCapability with multiple transports!");
} catch (IllegalStateException expected) {
// empty
@@ -680,7 +681,7 @@
// Sequence 2: Transport + NetworkSpecifier + Transport
NetworkCapabilities nc2 = new NetworkCapabilities();
nc2.addTransportType(TRANSPORT_CELLULAR).setNetworkSpecifier(
- new EthernetNetworkSpecifier("testtap3"));
+ CompatUtil.makeEthernetNetworkSpecifier("testtap3"));
try {
nc2.addTransportType(TRANSPORT_WIFI);
fail("Cannot set a second TransportType of a network which has a NetworkSpecifier!");
diff --git a/tests/net/common/java/android/net/NetworkProviderTest.kt b/tests/net/common/java/android/net/NetworkProviderTest.kt
index 71a7a7c..340e6f9 100644
--- a/tests/net/common/java/android/net/NetworkProviderTest.kt
+++ b/tests/net/common/java/android/net/NetworkProviderTest.kt
@@ -27,6 +27,7 @@
import android.os.Looper
import androidx.test.InstrumentationRegistry
import com.android.net.module.util.ArrayTrackRecord
+import com.android.testutils.CompatUtil
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.DevSdkIgnoreRunner
import com.android.testutils.isDevSdkInRange
@@ -102,7 +103,8 @@
mCm.registerNetworkProvider(provider)
assertNotEquals(provider.getProviderId(), NetworkProvider.ID_NONE)
- val specifier = EthernetNetworkSpecifier(UUID.randomUUID().toString())
+ val specifier = CompatUtil.makeTestNetworkSpecifier(
+ UUID.randomUUID().toString())
val nr: NetworkRequest = NetworkRequest.Builder()
.addTransportType(TRANSPORT_TEST)
.setNetworkSpecifier(specifier)
@@ -183,7 +185,8 @@
mCm.registerNetworkProvider(provider)
- val specifier = EthernetNetworkSpecifier(UUID.randomUUID().toString())
+ val specifier = CompatUtil.makeTestNetworkSpecifier(
+ UUID.randomUUID().toString())
val nr: NetworkRequest = NetworkRequest.Builder()
.addTransportType(TRANSPORT_TEST)
.setNetworkSpecifier(specifier)
diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
index e1da3d0..01d8186 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -64,6 +64,7 @@
private final HandlerThread mHandlerThread;
private final Context mContext;
private final String mLogTag;
+ private final NetworkAgentConfig mNetworkAgentConfig;
private final ConditionVariable mDisconnected = new ConditionVariable();
private final ConditionVariable mPreventReconnectReceived = new ConditionVariable();
@@ -115,13 +116,19 @@
mHandlerThread = new HandlerThread(mLogTag);
mHandlerThread.start();
- mNetworkAgent = makeNetworkAgent(linkProperties, type, typeName);
+ // extraInfo is set to "" by default in NetworkAgentConfig.
+ final String extraInfo = (transport == TRANSPORT_CELLULAR) ? "internet.apn" : "";
+ mNetworkAgentConfig = new NetworkAgentConfig.Builder()
+ .setLegacyType(type)
+ .setLegacyTypeName(typeName)
+ .setLegacyExtraInfo(extraInfo)
+ .build();
+ mNetworkAgent = makeNetworkAgent(linkProperties, mNetworkAgentConfig);
}
protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties,
- final int type, final String typeName)
- throws Exception {
- return new InstrumentedNetworkAgent(this, linkProperties, type, typeName);
+ final NetworkAgentConfig nac) throws Exception {
+ return new InstrumentedNetworkAgent(this, linkProperties, nac);
}
public static class InstrumentedNetworkAgent extends NetworkAgent {
@@ -129,11 +136,9 @@
private static final String PROVIDER_NAME = "InstrumentedNetworkAgentProvider";
public InstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp,
- final int type, final String typeName) {
+ NetworkAgentConfig nac) {
super(wrapper.mContext, wrapper.mHandlerThread.getLooper(), wrapper.mLogTag,
- wrapper.mNetworkCapabilities, lp, wrapper.mScore,
- new NetworkAgentConfig.Builder()
- .setLegacyType(type).setLegacyTypeName(typeName).build(),
+ wrapper.mNetworkCapabilities, lp, wrapper.mScore, nac,
new NetworkProvider(wrapper.mContext, wrapper.mHandlerThread.getLooper(),
PROVIDER_NAME));
mWrapper = wrapper;
@@ -301,6 +306,14 @@
return mNetworkCapabilities;
}
+ public int getLegacyType() {
+ return mNetworkAgentConfig.getLegacyType();
+ }
+
+ public String getExtraInfo() {
+ return mNetworkAgentConfig.getLegacyExtraInfo();
+ }
+
public @NonNull ArrayTrackRecord<CallbackType>.ReadHead getCallbackHistory() {
return mCallbackHistory;
}
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
index 6a09b02..098b029 100644
--- a/tests/net/java/android/net/ConnectivityManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -376,13 +376,13 @@
eq(testPkgName), eq(testAttributionTag));
reset(mService);
- manager.requestBackgroundNetwork(request, null, callback);
+ Handler handler = new Handler(ConnectivityThread.getInstanceLooper());
+ manager.requestBackgroundNetwork(request, handler, callback);
verify(mService).requestNetwork(eq(request.networkCapabilities),
eq(BACKGROUND_REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
eq(testPkgName), eq(testAttributionTag));
reset(mService);
- Handler handler = new Handler(ConnectivityThread.getInstanceLooper());
manager.registerSystemDefaultNetworkCallback(callback, handler);
verify(mService).requestNetwork(eq(null),
eq(TRACK_SYSTEM_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 2c6a21a..9db5854 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -266,7 +266,6 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.internal.app.IBatteryStats;
import com.android.internal.net.VpnConfig;
import com.android.internal.net.VpnProfile;
import com.android.internal.util.ArrayUtils;
@@ -276,6 +275,7 @@
import com.android.net.module.util.ArrayTrackRecord;
import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInfo;
import com.android.server.connectivity.ConnectivityConstants;
+import com.android.server.connectivity.ConnectivityResources;
import com.android.server.connectivity.MockableSystemProperties;
import com.android.server.connectivity.Nat464Xlat;
import com.android.server.connectivity.NetworkAgentInfo;
@@ -428,7 +428,6 @@
@Mock DeviceIdleInternal mDeviceIdleInternal;
@Mock INetworkManagementService mNetworkManagementService;
@Mock NetworkStatsManager mStatsManager;
- @Mock IBatteryStats mBatteryStatsService;
@Mock IDnsResolver mMockDnsResolver;
@Mock INetd mMockNetd;
@Mock NetworkStackClient mNetworkStack;
@@ -446,6 +445,7 @@
@Mock NetworkPolicyManager mNetworkPolicyManager;
@Mock VpnProfileStore mVpnProfileStore;
@Mock SystemConfigManager mSystemConfigManager;
+ @Mock Resources mResources;
private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor =
ArgumentCaptor.forClass(ResolverParamsParcel.class);
@@ -473,7 +473,7 @@
private class MockContext extends BroadcastInterceptingContext {
private final MockContentResolver mContentResolver;
- @Spy private Resources mResources;
+ @Spy private Resources mInternalResources;
private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>();
// Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant
@@ -482,21 +482,15 @@
MockContext(Context base, ContentProvider settingsProvider) {
super(base);
- mResources = spy(base.getResources());
- when(mResources.getStringArray(com.android.internal.R.array.networkAttributes)).
- thenReturn(new String[] {
+ mInternalResources = spy(base.getResources());
+ when(mInternalResources.getStringArray(com.android.internal.R.array.networkAttributes))
+ .thenReturn(new String[] {
"wifi,1,1,1,-1,true",
"mobile,0,0,0,-1,true",
"mobile_mms,2,0,2,60000,true",
"mobile_supl,3,0,2,60000,true",
});
- when(mResources.getStringArray(
- com.android.internal.R.array.config_wakeonlan_supported_interfaces))
- .thenReturn(new String[]{
- WIFI_WOL_IFNAME,
- });
-
mContentResolver = new MockContentResolver();
mContentResolver.addProvider(Settings.AUTHORITY, settingsProvider);
}
@@ -561,7 +555,7 @@
@Override
public Resources getResources() {
- return mResources;
+ return mInternalResources;
}
@Override
@@ -720,7 +714,7 @@
@Override
protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties,
- final int type, final String typeName) throws Exception {
+ NetworkAgentConfig nac) throws Exception {
mNetworkMonitor = mock(INetworkMonitor.class);
final Answer validateAnswer = inv -> {
@@ -739,8 +733,8 @@
any() /* name */,
nmCbCaptor.capture());
- final InstrumentedNetworkAgent na = new InstrumentedNetworkAgent(this, linkProperties,
- type, typeName) {
+ final InstrumentedNetworkAgent na =
+ new InstrumentedNetworkAgent(this, linkProperties, nac) {
@Override
public void networkStatus(int status, String redirectUrl) {
mRedirectUrl = redirectUrl;
@@ -1527,12 +1521,23 @@
doReturn(mSystemProperties).when(deps).getSystemProperties();
doReturn(mock(ProxyTracker.class)).when(deps).makeProxyTracker(any(), any());
doReturn(true).when(deps).queryUserAccess(anyInt(), anyInt());
- doReturn(mBatteryStatsService).when(deps).getBatteryStatsService();
doAnswer(inv -> {
mPolicyTracker = new WrappedMultinetworkPolicyTracker(
inv.getArgument(0), inv.getArgument(1), inv.getArgument(2));
return mPolicyTracker;
}).when(deps).makeMultinetworkPolicyTracker(any(), any(), any());
+ doReturn(true).when(deps).getCellular464XlatEnabled();
+
+ doReturn(60000).when(mResources).getInteger(
+ com.android.connectivity.resources.R.integer.config_networkTransitionTimeout);
+ doReturn("").when(mResources).getString(
+ com.android.connectivity.resources.R.string.config_networkCaptivePortalServerUrl);
+ doReturn(new String[]{ WIFI_WOL_IFNAME }).when(mResources).getStringArray(
+ com.android.connectivity.resources.R.array.config_wakeonlan_supported_interfaces);
+ final com.android.server.connectivity.ConnectivityResources connRes = mock(
+ ConnectivityResources.class);
+ doReturn(mResources).when(connRes).get();
+ doReturn(connRes).when(deps).getResources(any());
return deps;
}
@@ -1743,11 +1748,29 @@
return expected;
}
+ private boolean extraInfoInBroadcastHasExpectedNullness(NetworkInfo ni) {
+ final DetailedState state = ni.getDetailedState();
+ if (state == DetailedState.CONNECTED && ni.getExtraInfo() == null) return false;
+ // Expect a null extraInfo if the network is CONNECTING, because a CONNECTIVITY_ACTION
+ // broadcast with a state of CONNECTING only happens due to legacy VPN lockdown, which also
+ // nulls out extraInfo.
+ if (state == DetailedState.CONNECTING && ni.getExtraInfo() != null) return false;
+ // Can't make any assertions about DISCONNECTED broadcasts. When a network actually
+ // disconnects, disconnectAndDestroyNetwork sets its state to DISCONNECTED and its extraInfo
+ // to null. But if the DISCONNECTED broadcast is just simulated by LegacyTypeTracker due to
+ // a network switch, extraInfo will likely be populated.
+ // This is likely a bug in CS, but likely not one we can fix without impacting apps.
+ return true;
+ }
+
private ExpectedBroadcast expectConnectivityAction(int type, NetworkInfo.DetailedState state) {
- return registerConnectivityBroadcastThat(1, intent ->
- type == intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) && state.equals(
- ((NetworkInfo) intent.getParcelableExtra(EXTRA_NETWORK_INFO))
- .getDetailedState()));
+ return registerConnectivityBroadcastThat(1, intent -> {
+ final int actualType = intent.getIntExtra(EXTRA_NETWORK_TYPE, -1);
+ final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO);
+ return type == actualType
+ && state == ni.getDetailedState()
+ && extraInfoInBroadcastHasExpectedNullness(ni);
+ });
}
@Test
@@ -4011,7 +4034,8 @@
grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid());
final TestNetworkCallback cellBgCallback = new TestNetworkCallback();
mCm.requestBackgroundNetwork(new NetworkRequest.Builder()
- .addTransportType(TRANSPORT_CELLULAR).build(), null, cellBgCallback);
+ .addTransportType(TRANSPORT_CELLULAR).build(),
+ mCsHandlerThread.getThreadHandler(), cellBgCallback);
// Make callbacks for monitoring.
final NetworkRequest request = new NetworkRequest.Builder().build();
@@ -7185,12 +7209,14 @@
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mCellNetworkAgent);
setUidRulesChanged(RULE_REJECT_ALL);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
assertNull(mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+ assertExtraInfoFromCmBlocked(mCellNetworkAgent);
// ConnectivityService should cache it not to invoke the callback again.
setUidRulesChanged(RULE_REJECT_METERED);
@@ -7201,12 +7227,14 @@
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mCellNetworkAgent);
setUidRulesChanged(RULE_REJECT_METERED);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
assertNull(mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+ assertExtraInfoFromCmBlocked(mCellNetworkAgent);
// Restrict the network based on UID rule and NOT_METERED capability change.
mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
@@ -7215,6 +7243,7 @@
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mCellNetworkAgent);
mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED,
@@ -7223,12 +7252,14 @@
assertNull(mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+ assertExtraInfoFromCmBlocked(mCellNetworkAgent);
setUidRulesChanged(RULE_ALLOW_METERED);
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mCellNetworkAgent);
setUidRulesChanged(RULE_NONE);
cellNetworkCallback.assertNoCallback();
@@ -7239,6 +7270,7 @@
assertNull(mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+ assertExtraInfoFromCmBlocked(mCellNetworkAgent);
setRestrictBackgroundChanged(true);
cellNetworkCallback.assertNoCallback();
@@ -7246,12 +7278,14 @@
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mCellNetworkAgent);
setRestrictBackgroundChanged(false);
cellNetworkCallback.assertNoCallback();
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mCellNetworkAgent);
mCm.unregisterNetworkCallback(cellNetworkCallback);
}
@@ -7310,6 +7344,15 @@
assertNotNull(ni);
assertEquals(type, ni.getType());
assertEquals(ConnectivityManager.getNetworkTypeName(type), state, ni.getDetailedState());
+ if (state == DetailedState.CONNECTED || state == DetailedState.SUSPENDED) {
+ assertNotNull(ni.getExtraInfo());
+ } else {
+ // Technically speaking, a network that's in CONNECTING state will generally have a
+ // non-null extraInfo. This doesn't actually happen in this test because it never calls
+ // a legacy API while a network is connecting. When a network is in CONNECTING state
+ // because of legacy lockdown VPN, its extraInfo is always null.
+ assertNull(ni.getExtraInfo());
+ }
}
private void assertActiveNetworkInfo(int type, DetailedState state) {
@@ -7319,6 +7362,26 @@
checkNetworkInfo(mCm.getNetworkInfo(type), type, state);
}
+ private void assertExtraInfoFromCm(TestNetworkAgentWrapper network, boolean present) {
+ final NetworkInfo niForNetwork = mCm.getNetworkInfo(network.getNetwork());
+ final NetworkInfo niForType = mCm.getNetworkInfo(network.getLegacyType());
+ if (present) {
+ assertEquals(network.getExtraInfo(), niForNetwork.getExtraInfo());
+ assertEquals(network.getExtraInfo(), niForType.getExtraInfo());
+ } else {
+ assertNull(niForNetwork.getExtraInfo());
+ assertNull(niForType.getExtraInfo());
+ }
+ }
+
+ private void assertExtraInfoFromCmBlocked(TestNetworkAgentWrapper network) {
+ assertExtraInfoFromCm(network, false);
+ }
+
+ private void assertExtraInfoFromCmPresent(TestNetworkAgentWrapper network) {
+ assertExtraInfoFromCm(network, true);
+ }
+
// Checks that each of the |agents| receive a blocked status change callback with the specified
// |blocked| value, in any order. This is needed because when an event affects multiple
// networks, ConnectivityService does not guarantee the order in which callbacks are fired.
@@ -7633,6 +7696,7 @@
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED);
+ assertExtraInfoFromCmBlocked(mCellNetworkAgent);
// TODO: it would be nice if we could simply rely on the production code here, and have
// LockdownVpnTracker start the VPN, have the VPN code register its NetworkAgent with
@@ -7661,6 +7725,7 @@
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED);
assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mCellNetworkAgent);
assertTrue(vpnNc.hasTransport(TRANSPORT_VPN));
assertTrue(vpnNc.hasTransport(TRANSPORT_CELLULAR));
assertFalse(vpnNc.hasTransport(TRANSPORT_WIFI));
@@ -7703,6 +7768,7 @@
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED);
+ assertExtraInfoFromCmBlocked(mWiFiNetworkAgent);
// The VPN comes up again on wifi.
b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED);
@@ -7717,6 +7783,7 @@
assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED);
assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mWiFiNetworkAgent);
vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
assertTrue(vpnNc.hasTransport(TRANSPORT_VPN));
assertTrue(vpnNc.hasTransport(TRANSPORT_WIFI));
@@ -7733,6 +7800,7 @@
assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED);
assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mWiFiNetworkAgent);
b1 = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED);
mWiFiNetworkAgent.disconnect();
@@ -7812,7 +7880,6 @@
verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext,
cellLp.getInterfaceName(),
new int[] { TRANSPORT_CELLULAR });
- reset(mBatteryStatsService);
final LinkProperties wifiLp = new LinkProperties();
wifiLp.setInterfaceName("wifi0");
@@ -7822,7 +7889,6 @@
verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext,
wifiLp.getInterfaceName(),
new int[] { TRANSPORT_WIFI });
- reset(mBatteryStatsService);
mCellNetworkAgent.disconnect();
mWiFiNetworkAgent.disconnect();
@@ -7905,7 +7971,6 @@
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
reset(mMockDnsResolver);
reset(mMockNetd);
- reset(mBatteryStatsService);
// Connect with ipv6 link properties. Expect prefix discovery to be started.
mCellNetworkAgent.connect(true);
@@ -8268,6 +8333,45 @@
}
@Test
+ public void testWith464XlatDisable() throws Exception {
+ doReturn(false).when(mDeps).getCellular464XlatEnabled();
+
+ final TestNetworkCallback callback = new TestNetworkCallback();
+ final TestNetworkCallback defaultCallback = new TestNetworkCallback();
+ final NetworkRequest networkRequest = new NetworkRequest.Builder()
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .build();
+ mCm.registerNetworkCallback(networkRequest, callback);
+ mCm.registerDefaultNetworkCallback(defaultCallback);
+
+ // Bring up validated cell.
+ final LinkProperties cellLp = new LinkProperties();
+ cellLp.setInterfaceName(MOBILE_IFNAME);
+ cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64"));
+ cellLp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, MOBILE_IFNAME));
+ mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+
+ mCellNetworkAgent.sendLinkProperties(cellLp);
+ mCellNetworkAgent.connect(true);
+ callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+ defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+ final int cellNetId = mCellNetworkAgent.getNetwork().netId;
+ waitForIdle();
+
+ verify(mMockDnsResolver, never()).startPrefix64Discovery(cellNetId);
+ Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent);
+ assertTrue("Nat464Xlat was not IDLE", !clat.isStarted());
+
+ // This cannot happen because prefix discovery cannot succeed if it is never started.
+ mService.mResolverUnsolEventCallback.onNat64PrefixEvent(
+ makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, "64:ff9b::", 96));
+
+ // ... but still, check that even if it did, clatd would not be started.
+ verify(mMockNetd, never()).clatdStart(anyString(), anyString());
+ assertTrue("Nat464Xlat was not IDLE", !clat.isStarted());
+ }
+
+ @Test
public void testDataActivityTracking() throws Exception {
final TestNetworkCallback networkCallback = new TestNetworkCallback();
final NetworkRequest networkRequest = new NetworkRequest.Builder()
@@ -8973,7 +9077,7 @@
TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE));
return new NetworkAgentInfo(null, new Network(NET_ID), info, new LinkProperties(),
nc, 0, mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0,
- INVALID_UID, mQosCallbackTracker);
+ INVALID_UID, mQosCallbackTracker, new ConnectivityService.Dependencies());
}
@Test
@@ -10930,4 +11034,12 @@
verifyNoNetwork();
mCm.unregisterNetworkCallback(cellCb);
}
+
+ @Test
+ public void testRegisterBestMatchingNetworkCallback() throws Exception {
+ final NetworkRequest request = new NetworkRequest.Builder().build();
+ assertThrows(UnsupportedOperationException.class,
+ () -> mCm.registerBestMatchingNetworkCallback(request, new NetworkCallback(),
+ mCsHandlerThread.getThreadHandler()));
+ }
}
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index a913673..1c0ba4f 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -357,7 +357,7 @@
NetworkAgentInfo nai = new NetworkAgentInfo(null, new Network(netId), info,
new LinkProperties(), caps, 50, mCtx, null, new NetworkAgentConfig() /* config */,
mConnService, mNetd, mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(),
- mQosCallbackTracker);
+ mQosCallbackTracker, new ConnectivityService.Dependencies());
nai.everValidated = true;
return nai;
}
diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
index 5f56e25..9b2a638 100644
--- a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
+++ b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
@@ -16,11 +16,15 @@
package com.android.server.connectivity;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -34,6 +38,7 @@
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.NetworkAgentConfig;
+import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.test.TestLooper;
@@ -72,11 +77,15 @@
Handler mHandler;
NetworkAgentConfig mAgentConfig = new NetworkAgentConfig();
- Nat464Xlat makeNat464Xlat() {
- return new Nat464Xlat(mNai, mNetd, mDnsResolver) {
+ Nat464Xlat makeNat464Xlat(boolean isCellular464XlatEnabled) {
+ return new Nat464Xlat(mNai, mNetd, mDnsResolver, new ConnectivityService.Dependencies()) {
@Override protected int getNetId() {
return NETID;
}
+
+ @Override protected boolean isCellular464XlatEnabled() {
+ return isCellular464XlatEnabled;
+ }
};
}
@@ -99,6 +108,7 @@
mNai.linkProperties.setInterfaceName(BASE_IFACE);
mNai.networkInfo = new NetworkInfo(null);
mNai.networkInfo.setType(ConnectivityManager.TYPE_WIFI);
+ mNai.networkCapabilities = new NetworkCapabilities();
markNetworkConnected();
when(mNai.connService()).thenReturn(mConnectivity);
when(mNai.netAgentConfig()).thenReturn(mAgentConfig);
@@ -110,21 +120,23 @@
}
private void assertRequiresClat(boolean expected, NetworkAgentInfo nai) {
+ Nat464Xlat nat = makeNat464Xlat(true);
String msg = String.format("requiresClat expected %b for type=%d state=%s skip=%b "
+ "nat64Prefix=%s addresses=%s", expected, nai.networkInfo.getType(),
nai.networkInfo.getDetailedState(),
mAgentConfig.skip464xlat, nai.linkProperties.getNat64Prefix(),
nai.linkProperties.getLinkAddresses());
- assertEquals(msg, expected, Nat464Xlat.requiresClat(nai));
+ assertEquals(msg, expected, nat.requiresClat(nai));
}
private void assertShouldStartClat(boolean expected, NetworkAgentInfo nai) {
+ Nat464Xlat nat = makeNat464Xlat(true);
String msg = String.format("shouldStartClat expected %b for type=%d state=%s skip=%b "
+ "nat64Prefix=%s addresses=%s", expected, nai.networkInfo.getType(),
nai.networkInfo.getDetailedState(),
mAgentConfig.skip464xlat, nai.linkProperties.getNat64Prefix(),
nai.linkProperties.getLinkAddresses());
- assertEquals(msg, expected, Nat464Xlat.shouldStartClat(nai));
+ assertEquals(msg, expected, nat.shouldStartClat(nai));
}
@Test
@@ -194,7 +206,7 @@
}
private void checkNormalStartAndStop(boolean dueToDisconnect) throws Exception {
- Nat464Xlat nat = makeNat464Xlat();
+ Nat464Xlat nat = makeNat464Xlat(true);
ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class);
mNai.linkProperties.addLinkAddress(V6ADDR);
@@ -245,7 +257,7 @@
}
private void checkStartStopStart(boolean interfaceRemovedFirst) throws Exception {
- Nat464Xlat nat = makeNat464Xlat();
+ Nat464Xlat nat = makeNat464Xlat(true);
ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class);
InOrder inOrder = inOrder(mNetd, mConnectivity);
@@ -335,7 +347,7 @@
@Test
public void testClatdCrashWhileRunning() throws Exception {
- Nat464Xlat nat = makeNat464Xlat();
+ Nat464Xlat nat = makeNat464Xlat(true);
ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class);
nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX));
@@ -372,7 +384,7 @@
}
private void checkStopBeforeClatdStarts(boolean dueToDisconnect) throws Exception {
- Nat464Xlat nat = makeNat464Xlat();
+ Nat464Xlat nat = makeNat464Xlat(true);
mNai.linkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64"));
@@ -414,7 +426,7 @@
}
private void checkStopAndClatdNeverStarts(boolean dueToDisconnect) throws Exception {
- Nat464Xlat nat = makeNat464Xlat();
+ Nat464Xlat nat = makeNat464Xlat(true);
mNai.linkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64"));
@@ -450,7 +462,7 @@
final IpPrefix prefixFromDns = new IpPrefix(NAT64_PREFIX);
final IpPrefix prefixFromRa = new IpPrefix(OTHER_NAT64_PREFIX);
- Nat464Xlat nat = makeNat464Xlat();
+ Nat464Xlat nat = makeNat464Xlat(true);
final LinkProperties emptyLp = new LinkProperties();
LinkProperties fixedupLp;
@@ -486,10 +498,57 @@
assertEquals(null, fixedupLp.getNat64Prefix());
}
+ private void checkClatDisabledOnCellular(boolean onCellular) throws Exception {
+ // Disable 464xlat on cellular networks.
+ Nat464Xlat nat = makeNat464Xlat(false);
+ mNai.linkProperties.addLinkAddress(V6ADDR);
+ mNai.networkCapabilities.setTransportType(TRANSPORT_CELLULAR, onCellular);
+ nat.update();
+
+ final IpPrefix nat64Prefix = new IpPrefix(NAT64_PREFIX);
+ if (onCellular) {
+ // Prefix discovery is never started.
+ verify(mDnsResolver, never()).startPrefix64Discovery(eq(NETID));
+ assertIdle(nat);
+
+ // If a NAT64 prefix comes in from an RA, clat is not started either.
+ mNai.linkProperties.setNat64Prefix(nat64Prefix);
+ nat.setNat64PrefixFromRa(nat64Prefix);
+ nat.update();
+ verify(mNetd, never()).clatdStart(anyString(), anyString());
+ assertIdle(nat);
+ } else {
+ // Prefix discovery is started.
+ verify(mDnsResolver).startPrefix64Discovery(eq(NETID));
+ assertIdle(nat);
+
+ // If a NAT64 prefix comes in from an RA, clat is started.
+ mNai.linkProperties.setNat64Prefix(nat64Prefix);
+ nat.setNat64PrefixFromRa(nat64Prefix);
+ nat.update();
+ verify(mNetd).clatdStart(BASE_IFACE, NAT64_PREFIX);
+ assertStarting(nat);
+ }
+ }
+
+ @Test
+ public void testClatDisabledOnCellular() throws Exception {
+ checkClatDisabledOnCellular(true);
+ }
+
+ @Test
+ public void testClatDisabledOnNonCellular() throws Exception {
+ checkClatDisabledOnCellular(false);
+ }
+
static void assertIdle(Nat464Xlat nat) {
assertTrue("Nat464Xlat was not IDLE", !nat.isStarted());
}
+ static void assertStarting(Nat464Xlat nat) {
+ assertTrue("Nat464Xlat was not STARTING", nat.isStarting());
+ }
+
static void assertRunning(Nat464Xlat nat) {
assertTrue("Nat464Xlat was not RUNNING", nat.isRunning());
}
diff --git a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
index 1d459a3..1ef1a61 100644
--- a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
@@ -194,29 +194,35 @@
}
private NetworkRequest getWifiRequest() {
- return getExpectedRequestBase()
+ return getExpectedRequestBase(true)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.build();
}
private NetworkRequest getCellRequestForSubId(int subId) {
- return getExpectedRequestBase()
+ return getExpectedRequestBase(false)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId))
.build();
}
private NetworkRequest getRouteSelectionRequest() {
- return getExpectedRequestBase().build();
+ return getExpectedRequestBase(true).build();
}
- private NetworkRequest.Builder getExpectedRequestBase() {
- return new NetworkRequest.Builder()
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
- .addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ private NetworkRequest.Builder getExpectedRequestBase(boolean requireVcnManaged) {
+ final NetworkRequest.Builder builder =
+ new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+
+ if (requireVcnManaged) {
+ builder.addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ }
+
+ return builder;
}
@Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 4bf8491..0e5f5e4 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -73,7 +73,7 @@
mGatewayConnection.setUnderlyingNetwork(TEST_UNDERLYING_NETWORK_RECORD_1);
- mIkeSession = mGatewayConnection.buildIkeSession();
+ mIkeSession = mGatewayConnection.buildIkeSession(TEST_UNDERLYING_NETWORK_RECORD_1.network);
mGatewayConnection.setIkeSession(mIkeSession);
mGatewayConnection.transitionTo(mGatewayConnection.mConnectedState);
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
index d07d2cf..7afa449 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
@@ -25,12 +25,15 @@
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import android.net.ipsec.ike.IkeSessionParams;
+
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.ArgumentCaptor;
/** Tests for VcnGatewayConnection.ConnectingState */
@RunWith(AndroidJUnit4.class)
@@ -51,7 +54,12 @@
@Test
public void testEnterStateCreatesNewIkeSession() throws Exception {
- verify(mDeps).newIkeSession(any(), any(), any(), any(), any());
+ final ArgumentCaptor<IkeSessionParams> paramsCaptor =
+ ArgumentCaptor.forClass(IkeSessionParams.class);
+ verify(mDeps).newIkeSession(any(), paramsCaptor.capture(), any(), any(), any());
+ assertEquals(
+ TEST_UNDERLYING_NETWORK_RECORD_1.network,
+ paramsCaptor.getValue().getConfiguredNetwork());
}
@Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
index 661e03a..99feffd 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
@@ -38,7 +38,8 @@
public void setUp() throws Exception {
super.setUp();
- mGatewayConnection.setIkeSession(mGatewayConnection.buildIkeSession());
+ mGatewayConnection.setIkeSession(
+ mGatewayConnection.buildIkeSession(TEST_UNDERLYING_NETWORK_RECORD_2.network));
// ensure that mGatewayConnection has an underlying Network before entering
// DisconnectingState
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
index 748c792..d08af9d 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
@@ -18,6 +18,7 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
@@ -87,6 +88,7 @@
private void verifyBuildNetworkCapabilitiesCommon(int transportType) {
final NetworkCapabilities underlyingCaps = new NetworkCapabilities();
underlyingCaps.addTransportType(transportType);
+ underlyingCaps.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
underlyingCaps.addCapability(NET_CAPABILITY_NOT_METERED);
underlyingCaps.addCapability(NET_CAPABILITY_NOT_ROAMING);