diff options
851 files changed, 14937 insertions, 8033 deletions
diff --git a/apex/appsearch/framework/Android.bp b/apex/appsearch/framework/Android.bp index b8fce4f10cd0..cd9be9bb8be7 100644 --- a/apex/appsearch/framework/Android.bp +++ b/apex/appsearch/framework/Android.bp @@ -65,5 +65,8 @@ java_sdk_library { }, jarjar_rules: "jarjar-rules.txt", apex_available: ["com.android.appsearch"], + impl_library_visibility: [ + "//frameworks/base/apex/appsearch/service", + ], unsafe_ignore_missing_latest_api: true, // TODO(b/146218515) should be removed } diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java index 0b24c0d9f5c5..b5e366255180 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java +++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java @@ -90,6 +90,7 @@ public final class AppSearchSession implements Closeable { @NonNull Consumer<AppSearchResult<AppSearchSession>> callback) { try { mService.initialize( + mPackageName, mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), new IAppSearchResultCallback.Stub() { @@ -685,7 +686,9 @@ public final class AppSearchSession implements Closeable { if (mIsMutated && !mIsClosed) { try { mService.persistToDisk( - mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime()); + mPackageName, + mUserHandle, + /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime()); mIsClosed = true; } catch (RemoteException e) { Log.e(TAG, "Unable to close the AppSearchSession", e); diff --git a/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java index 247eb08d698a..130e442c0000 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java +++ b/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java @@ -73,6 +73,7 @@ public class GlobalSearchSession implements Closeable { @NonNull Consumer<AppSearchResult<GlobalSearchSession>> callback) { try { mService.initialize( + mPackageName, mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime(), new IAppSearchResultCallback.Stub() { @@ -187,7 +188,9 @@ public class GlobalSearchSession implements Closeable { if (mIsMutated && !mIsClosed) { try { mService.persistToDisk( - mUserHandle, /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime()); + mPackageName, + mUserHandle, + /*binderCallStartTimeMillis=*/ SystemClock.elapsedRealtime()); mIsClosed = true; } catch (RemoteException e) { Log.e(TAG, "Unable to close the GlobalSearchSession", e); diff --git a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java b/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java index eb5d22eaaea0..6dfa01f6e680 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java +++ b/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java @@ -124,7 +124,8 @@ public class SearchResults implements Closeable { wrapCallback(executor, callback)); } } else { - mService.getNextPage(mNextPageToken, mUserHandle, wrapCallback(executor, callback)); + mService.getNextPage(mPackageName, mNextPageToken, mUserHandle, + wrapCallback(executor, callback)); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -135,7 +136,7 @@ public class SearchResults implements Closeable { public void close() { if (!mIsClosed) { try { - mService.invalidateNextPageToken(mNextPageToken, mUserHandle); + mService.invalidateNextPageToken(mPackageName, mNextPageToken, mUserHandle); mIsClosed = true; } catch (RemoteException e) { Log.e(TAG, "Unable to close the SearchResults", e); diff --git a/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl index c639ef604de8..a2f545f791fd 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl +++ b/apex/appsearch/framework/java/android/app/appsearch/aidl/IAppSearchManager.aidl @@ -181,21 +181,30 @@ interface IAppSearchManager { * Fetches the next page of results of a previously executed query. Results can be empty if * next-page token is invalid or all pages have been returned. * + * @param packageName The name of the package to persist to disk for. * @param nextPageToken The token of pre-loaded results of previously executed query. * @param userHandle Handle of the calling user * @param callback {@link AppSearchResult}<{@link Bundle}> of performing this * operation. */ - void getNextPage(in long nextPageToken, in UserHandle userHandle, in IAppSearchResultCallback callback); + void getNextPage( + in String packageName, + in long nextPageToken, + in UserHandle userHandle, + in IAppSearchResultCallback callback); /** * Invalidates the next-page token so that no more results of the related query can be returned. * + * @param packageName The name of the package to persist to disk for. * @param nextPageToken The token of pre-loaded results of previously executed query to be * Invalidated. * @param userHandle Handle of the calling user */ - void invalidateNextPageToken(in long nextPageToken, in UserHandle userHandle); + void invalidateNextPageToken( + in String packageName, + in long nextPageToken, + in UserHandle userHandle); /** * Searches a document based on a given specifications. @@ -336,20 +345,26 @@ interface IAppSearchManager { /** * Persists all update/delete requests to the disk. * + * @param packageName The name of the package to persist to disk for. * @param userHandle Handle of the calling user * @param binderCallStartTimeMillis start timestamp of binder call in Millis */ - void persistToDisk(in UserHandle userHandle, in long binderCallStartTimeMillis); + void persistToDisk( + in String packageName, + in UserHandle userHandle, + in long binderCallStartTimeMillis); /** * Creates and initializes AppSearchImpl for the calling app. * + * @param packageName The name of the package to initialize for. * @param userHandle Handle of the calling user * @param binderCallStartTimeMillis start timestamp of binder call in Millis * @param callback {@link IAppSearchResultCallback#onResult} will be called with an * {@link AppSearchResult}<{@link Void}>. */ void initialize( + in String packageName, in UserHandle userHandle, in long binderCallStartTimeMillis, in IAppSearchResultCallback callback); diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchBatchResult.java b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchBatchResult.java index 272e12db0124..d493a1c28a3a 100644 --- a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchBatchResult.java +++ b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchBatchResult.java @@ -96,17 +96,6 @@ public final class AppSearchBatchResult<KeyType, ValueType> { return Collections.unmodifiableMap(mAll); } - /** - * Asserts that this {@link AppSearchBatchResult} has no failures. - * - * @hide - */ - public void checkSuccess() { - if (!isSuccess()) { - throw new IllegalStateException("AppSearchBatchResult has failures: " + this); - } - } - @Override @NonNull public String toString() { diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchResult.java b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchResult.java index c57cf2e68993..b1cb132ee088 100644 --- a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchResult.java +++ b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchResult.java @@ -239,6 +239,8 @@ public final class AppSearchResult<ValueType> { resultCode = AppSearchResult.RESULT_INVALID_ARGUMENT; } else if (t instanceof IOException) { resultCode = AppSearchResult.RESULT_IO_ERROR; + } else if (t instanceof SecurityException) { + resultCode = AppSearchResult.RESULT_SECURITY_ERROR; } else { resultCode = AppSearchResult.RESULT_UNKNOWN_ERROR; } diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java index 237e6242b22a..0ee5e65ef775 100644 --- a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java +++ b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.appsearch.exceptions.IllegalSchemaException; import android.app.appsearch.util.BundleUtil; +import android.app.appsearch.util.IndentingStringBuilder; import android.compat.annotation.UnsupportedAppUsage; import android.os.Bundle; import android.util.ArraySet; @@ -30,6 +31,7 @@ import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -67,8 +69,45 @@ public final class AppSearchSchema { } @Override + @NonNull public String toString() { - return mBundle.toString(); + IndentingStringBuilder stringBuilder = new IndentingStringBuilder(); + appendAppSearchSchemaString(stringBuilder); + return stringBuilder.toString(); + } + + /** + * Appends a debugging string for the {@link AppSearchSchema} instance to the given string + * builder. + * + * @param builder the builder to append to. + */ + private void appendAppSearchSchemaString(@NonNull IndentingStringBuilder builder) { + Objects.requireNonNull(builder); + + builder.append("{\n"); + builder.increaseIndentLevel(); + builder.append("schemaType: \"").append(getSchemaType()).append("\",\n"); + builder.append("properties: [\n"); + + AppSearchSchema.PropertyConfig[] sortedProperties = + getProperties().toArray(new AppSearchSchema.PropertyConfig[0]); + Arrays.sort(sortedProperties, (o1, o2) -> o1.getName().compareTo(o2.getName())); + + for (int i = 0; i < sortedProperties.length; i++) { + AppSearchSchema.PropertyConfig propertyConfig = sortedProperties[i]; + builder.increaseIndentLevel(); + propertyConfig.appendPropertyConfigString(builder); + if (i != sortedProperties.length - 1) { + builder.append(",\n"); + } + builder.decreaseIndentLevel(); + } + + builder.append("\n"); + builder.append("]\n"); + builder.decreaseIndentLevel(); + builder.append("}"); } /** Returns the name of this schema type, e.g. Email. */ @@ -255,7 +294,68 @@ public final class AppSearchSchema { @Override @NonNull public String toString() { - return mBundle.toString(); + IndentingStringBuilder stringBuilder = new IndentingStringBuilder(); + appendPropertyConfigString(stringBuilder); + return stringBuilder.toString(); + } + + /** + * Appends a debug string for the {@link AppSearchSchema.PropertyConfig} instance to the + * given string builder. + * + * @param builder the builder to append to. + */ + void appendPropertyConfigString(@NonNull IndentingStringBuilder builder) { + Objects.requireNonNull(builder); + + builder.append("{\n"); + builder.increaseIndentLevel(); + builder.append("name: \"").append(getName()).append("\",\n"); + + if (this instanceof AppSearchSchema.StringPropertyConfig) { + ((StringPropertyConfig) this).appendStringPropertyConfigFields(builder); + } else if (this instanceof AppSearchSchema.DocumentPropertyConfig) { + ((DocumentPropertyConfig) this).appendDocumentPropertyConfigFields(builder); + } + + switch (getCardinality()) { + case AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED: + builder.append("cardinality: CARDINALITY_REPEATED,\n"); + break; + case AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL: + builder.append("cardinality: CARDINALITY_OPTIONAL,\n"); + break; + case AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED: + builder.append("cardinality: CARDINALITY_REQUIRED,\n"); + break; + default: + builder.append("cardinality: CARDINALITY_UNKNOWN,\n"); + } + + switch (getDataType()) { + case AppSearchSchema.PropertyConfig.DATA_TYPE_STRING: + builder.append("dataType: DATA_TYPE_STRING,\n"); + break; + case AppSearchSchema.PropertyConfig.DATA_TYPE_LONG: + builder.append("dataType: DATA_TYPE_LONG,\n"); + break; + case AppSearchSchema.PropertyConfig.DATA_TYPE_DOUBLE: + builder.append("dataType: DATA_TYPE_DOUBLE,\n"); + break; + case AppSearchSchema.PropertyConfig.DATA_TYPE_BOOLEAN: + builder.append("dataType: DATA_TYPE_BOOLEAN,\n"); + break; + case AppSearchSchema.PropertyConfig.DATA_TYPE_BYTES: + builder.append("dataType: DATA_TYPE_BYTES,\n"); + break; + case AppSearchSchema.PropertyConfig.DATA_TYPE_DOCUMENT: + builder.append("dataType: DATA_TYPE_DOCUMENT,\n"); + break; + default: + builder.append("dataType: DATA_TYPE_UNKNOWN,\n"); + } + builder.decreaseIndentLevel(); + builder.append("}"); } /** Returns the name of this property. */ @@ -506,6 +606,41 @@ public final class AppSearchSchema { return new StringPropertyConfig(bundle); } } + + /** + * Appends a debug string for the {@link StringPropertyConfig} instance to the given string + * builder. + * + * <p>This appends fields specific to a {@link StringPropertyConfig} instance. + * + * @param builder the builder to append to. + */ + void appendStringPropertyConfigFields(@NonNull IndentingStringBuilder builder) { + switch (getIndexingType()) { + case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE: + builder.append("indexingType: INDEXING_TYPE_NONE,\n"); + break; + case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS: + builder.append("indexingType: INDEXING_TYPE_EXACT_TERMS,\n"); + break; + case AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES: + builder.append("indexingType: INDEXING_TYPE_PREFIXES,\n"); + break; + default: + builder.append("indexingType: INDEXING_TYPE_UNKNOWN,\n"); + } + + switch (getTokenizerType()) { + case AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE: + builder.append("tokenizerType: TOKENIZER_TYPE_NONE,\n"); + break; + case AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN: + builder.append("tokenizerType: TOKENIZER_TYPE_PLAIN,\n"); + break; + default: + builder.append("tokenizerType: TOKENIZER_TYPE_UNKNOWN,\n"); + } + } } /** @@ -858,5 +993,21 @@ public final class AppSearchSchema { return new DocumentPropertyConfig(bundle); } } + + /** + * Appends a debug string for the {@link DocumentPropertyConfig} instance to the given + * string builder. + * + * <p>This appends fields specific to a {@link DocumentPropertyConfig} instance. + * + * @param builder the builder to append to. + */ + void appendDocumentPropertyConfigFields(@NonNull IndentingStringBuilder builder) { + builder.append("shouldIndexNestedProperties: ") + .append(shouldIndexNestedProperties()) + .append(",\n"); + + builder.append("schemaType: \"").append(getSchemaType()).append("\",\n"); + } } } diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java b/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java index bcd341ec18a8..c905f95fe4c4 100644 --- a/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java +++ b/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java @@ -22,6 +22,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.app.appsearch.util.BundleUtil; +import android.app.appsearch.util.IndentingStringBuilder; import android.compat.annotation.UnsupportedAppUsage; import android.os.Bundle; import android.os.Parcelable; @@ -50,9 +51,6 @@ import java.util.Set; public class GenericDocument { private static final String TAG = "AppSearchGenericDocumen"; - /** The maximum number of elements in a repeatable field. */ - private static final int MAX_REPEATED_PROPERTY_LENGTH = 100; - /** The maximum {@link String#length} of a {@link String} field. */ private static final int MAX_STRING_LENGTH = 20_000; @@ -861,6 +859,7 @@ public class GenericDocument { * * @hide */ + // TODO(b/171882200): Expose this API in Android T @NonNull public GenericDocument.Builder<GenericDocument.Builder<?>> toBuilder() { Bundle clonedBundle = BundleUtil.deepCopy(mBundle); @@ -890,121 +889,101 @@ public class GenericDocument { @Override @NonNull public String toString() { - StringBuilder stringBuilder = new StringBuilder(); - appendGenericDocumentString(this, /*indentLevel=*/ 0, stringBuilder); + IndentingStringBuilder stringBuilder = new IndentingStringBuilder(); + appendGenericDocumentString(stringBuilder); return stringBuilder.toString(); } - private static void appendGenericDocumentString( - @NonNull GenericDocument document, int indentLevel, @NonNull StringBuilder builder) { - Objects.requireNonNull(document); + /** + * Appends a debug string for the {@link GenericDocument} instance to the given string builder. + * + * @param builder the builder to append to. + */ + void appendGenericDocumentString(@NonNull IndentingStringBuilder builder) { Objects.requireNonNull(builder); - builder.append(getIndent(indentLevel)).append("{\n"); - - String indent1 = getIndent(indentLevel + 1); - - builder.append(indent1) - .append("namespace: \"") - .append(document.getNamespace()) - .append("\",\n"); - - builder.append(indent1).append("id: \"").append(document.getId()).append("\",\n"); - - builder.append(indent1).append("score: ").append(document.getScore()).append(",\n"); - - builder.append(indent1) - .append("schemaType: \"") - .append(document.getSchemaType()) - .append("\",\n"); - - builder.append(indent1) - .append("creationTimestampMillis: ") - .append(document.getCreationTimestampMillis()) - .append(",\n"); + builder.append("{\n"); + builder.increaseIndentLevel(); - builder.append(indent1) - .append("timeToLiveMillis: ") - .append(document.getTtlMillis()) + builder.append("namespace: \"").append(getNamespace()).append("\",\n"); + builder.append("id: \"").append(getId()).append("\",\n"); + builder.append("score: ").append(getScore()).append(",\n"); + builder.append("schemaType: \"").append(getSchemaType()).append("\",\n"); + builder.append("creationTimestampMillis: ") + .append(getCreationTimestampMillis()) .append(",\n"); + builder.append("timeToLiveMillis: ").append(getTtlMillis()).append(",\n"); - builder.append(indent1).append("properties: {\n"); + builder.append("properties: {\n"); - String[] sortedProperties = document.getPropertyNames().toArray(new String[0]); + String[] sortedProperties = getPropertyNames().toArray(new String[0]); Arrays.sort(sortedProperties); for (int i = 0; i < sortedProperties.length; i++) { - Object property = document.getProperty(sortedProperties[i]); - builder.append(getIndent(indentLevel + 2)) - .append("\"") - .append(sortedProperties[i]) - .append("\"") - .append(": "); - appendPropertyString(property, indentLevel + 2, builder); + Object property = getProperty(sortedProperties[i]); + builder.increaseIndentLevel(); + appendPropertyString(sortedProperties[i], property, builder); if (i != sortedProperties.length - 1) { builder.append(",\n"); } + builder.decreaseIndentLevel(); } builder.append("\n"); - builder.append(indent1).append("}"); + builder.append("}"); + builder.decreaseIndentLevel(); builder.append("\n"); - builder.append(getIndent(indentLevel)).append("}"); + builder.append("}"); } /** - * Appends a string for the given property to the given builder. + * Appends a debug string for the given document property to the given string builder. * + * @param propertyName name of property to create string for. * @param property property object to create string for. - * @param indentLevel base indent level for property. * @param builder the builder to append to. */ - private static void appendPropertyString( - @NonNull Object property, int indentLevel, @NonNull StringBuilder builder) { + private void appendPropertyString( + @NonNull String propertyName, + @NonNull Object property, + @NonNull IndentingStringBuilder builder) { + Objects.requireNonNull(propertyName); Objects.requireNonNull(property); Objects.requireNonNull(builder); - builder.append("["); + builder.append("\"").append(propertyName).append("\": ["); if (property instanceof GenericDocument[]) { GenericDocument[] documentValues = (GenericDocument[]) property; for (int i = 0; i < documentValues.length; ++i) { builder.append("\n"); - appendGenericDocumentString(documentValues[i], indentLevel + 1, builder); + builder.increaseIndentLevel(); + documentValues[i].appendGenericDocumentString(builder); if (i != documentValues.length - 1) { - builder.append(", "); + builder.append(","); } builder.append("\n"); + builder.decreaseIndentLevel(); } - builder.append(getIndent(indentLevel)); + builder.append("]"); } else { int propertyArrLength = Array.getLength(property); for (int i = 0; i < propertyArrLength; i++) { Object propertyElement = Array.get(property, i); if (propertyElement instanceof String) { - builder.append("\"").append(propertyElement).append("\""); + builder.append("\"").append((String) propertyElement).append("\""); } else if (propertyElement instanceof byte[]) { builder.append(Arrays.toString((byte[]) propertyElement)); } else { - builder.append(propertyElement); + builder.append(propertyElement.toString()); } if (i != propertyArrLength - 1) { builder.append(", "); + } else { + builder.append("]"); } } } - - builder.append("]"); - } - - /** Appends a string for given indent level to the given builder. */ - @NonNull - private static String getIndent(int indentLevel) { - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < indentLevel; ++i) { - builder.append(" "); - } - return builder.toString(); } /** @@ -1187,8 +1166,8 @@ public class GenericDocument { * @param name the name associated with the {@code values}. Must match the name for this * property as given in {@link AppSearchSchema.PropertyConfig#getName}. * @param values the {@code String} values of the property. - * @throws IllegalArgumentException if no values are provided, if provided values exceed - * maximum repeated property length, or if a passed in {@code String} is {@code null}. + * @throws IllegalArgumentException if no values are provided, or if a passed in {@code + * String} is {@code null}. */ @NonNull public BuilderType setPropertyString(@NonNull String name, @NonNull String... values) { @@ -1206,7 +1185,6 @@ public class GenericDocument { * @param name the name associated with the {@code values}. Must match the name for this * property as given in {@link AppSearchSchema.PropertyConfig#getName}. * @param values the {@code boolean} values of the property. - * @throws IllegalArgumentException if values exceed maximum repeated property length. */ @NonNull public BuilderType setPropertyBoolean(@NonNull String name, @NonNull boolean... values) { @@ -1223,7 +1201,6 @@ public class GenericDocument { * @param name the name associated with the {@code values}. Must match the name for this * property as given in {@link AppSearchSchema.PropertyConfig#getName}. * @param values the {@code long} values of the property. - * @throws IllegalArgumentException if values exceed maximum repeated property length. */ @NonNull public BuilderType setPropertyLong(@NonNull String name, @NonNull long... values) { @@ -1240,7 +1217,6 @@ public class GenericDocument { * @param name the name associated with the {@code values}. Must match the name for this * property as given in {@link AppSearchSchema.PropertyConfig#getName}. * @param values the {@code double} values of the property. - * @throws IllegalArgumentException if values exceed maximum repeated property length. */ @NonNull public BuilderType setPropertyDouble(@NonNull String name, @NonNull double... values) { @@ -1257,8 +1233,8 @@ public class GenericDocument { * @param name the name associated with the {@code values}. Must match the name for this * property as given in {@link AppSearchSchema.PropertyConfig#getName}. * @param values the {@code byte[]} of the property. - * @throws IllegalArgumentException if no values are provided, if provided values exceed - * maximum repeated property length, or if a passed in {@code byte[]} is {@code null}. + * @throws IllegalArgumentException if no values are provided, or if a passed in {@code + * byte[]} is {@code null}. */ @NonNull public BuilderType setPropertyBytes(@NonNull String name, @NonNull byte[]... values) { @@ -1276,8 +1252,7 @@ public class GenericDocument { * @param name the name associated with the {@code values}. Must match the name for this * property as given in {@link AppSearchSchema.PropertyConfig#getName}. * @param values the {@link GenericDocument} values of the property. - * @throws IllegalArgumentException if no values are provided, if provided values exceed if - * provided values exceed maximum repeated property length, or if a passed in {@link + * @throws IllegalArgumentException if no values are provided, or if a passed in {@link * GenericDocument} is {@code null}. */ @NonNull @@ -1308,7 +1283,6 @@ public class GenericDocument { private void putInPropertyBundle(@NonNull String name, @NonNull String[] values) throws IllegalArgumentException { - validateRepeatedPropertyLength(name, values.length); for (int i = 0; i < values.length; i++) { if (values[i] == null) { throw new IllegalArgumentException("The String at " + i + " is null."); @@ -1327,17 +1301,14 @@ public class GenericDocument { } private void putInPropertyBundle(@NonNull String name, @NonNull boolean[] values) { - validateRepeatedPropertyLength(name, values.length); mProperties.putBooleanArray(name, values); } private void putInPropertyBundle(@NonNull String name, @NonNull double[] values) { - validateRepeatedPropertyLength(name, values.length); mProperties.putDoubleArray(name, values); } private void putInPropertyBundle(@NonNull String name, @NonNull long[] values) { - validateRepeatedPropertyLength(name, values.length); mProperties.putLongArray(name, values); } @@ -1348,7 +1319,6 @@ public class GenericDocument { * into ArrayList<Bundle>, and each elements will contain a one dimension byte[]. */ private void putInPropertyBundle(@NonNull String name, @NonNull byte[][] values) { - validateRepeatedPropertyLength(name, values.length); ArrayList<Bundle> bundles = new ArrayList<>(values.length); for (int i = 0; i < values.length; i++) { if (values[i] == null) { @@ -1362,7 +1332,6 @@ public class GenericDocument { } private void putInPropertyBundle(@NonNull String name, @NonNull GenericDocument[] values) { - validateRepeatedPropertyLength(name, values.length); Parcelable[] documentBundles = new Parcelable[values.length]; for (int i = 0; i < values.length; i++) { if (values[i] == null) { @@ -1373,18 +1342,6 @@ public class GenericDocument { mProperties.putParcelableArray(name, documentBundles); } - private static void validateRepeatedPropertyLength(@NonNull String name, int length) { - if (length > MAX_REPEATED_PROPERTY_LENGTH) { - throw new IllegalArgumentException( - "Repeated property \"" - + name - + "\" has length " - + length - + ", which exceeds the limit of " - + MAX_REPEATED_PROPERTY_LENGTH); - } - } - /** Builds the {@link GenericDocument} object. */ @NonNull public GenericDocument build() { diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java index 0af3e7a8987a..b72ca9af42cb 100644 --- a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java +++ b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java @@ -169,13 +169,14 @@ public final class SetSchemaRequest { /** Builder for {@link SetSchemaRequest} objects. */ public static final class Builder { + private static final int DEFAULT_VERSION = 1; private ArraySet<AppSearchSchema> mSchemas = new ArraySet<>(); private ArraySet<String> mSchemasNotDisplayedBySystem = new ArraySet<>(); private ArrayMap<String, Set<PackageIdentifier>> mSchemasVisibleToPackages = new ArrayMap<>(); private ArrayMap<String, Migrator> mMigrators = new ArrayMap<>(); private boolean mForceOverride = false; - private int mVersion = 1; + private int mVersion = DEFAULT_VERSION; private boolean mBuilt = false; /** @@ -384,6 +385,9 @@ public final class SetSchemaRequest { * <p>The version number can stay the same, increase, or decrease relative to the current * version number that is already stored in the {@link AppSearchSession} database. * + * <p>The version of an empty database will always be 0. You cannot set version to the + * {@link SetSchemaRequest}, if it doesn't contains any {@link AppSearchSchema}. + * * @param version A positive integer representing the version of the entire set of schemas * represents the version of the whole schema in the {@link AppSearchSession} database, * default version is 1. @@ -423,7 +427,10 @@ public final class SetSchemaRequest { throw new IllegalArgumentException( "Schema types " + referencedSchemas + " referenced, but were not added."); } - + if (mSchemas.isEmpty() && mVersion != DEFAULT_VERSION) { + throw new IllegalArgumentException( + "Cannot set version to the request if schema is empty."); + } mBuilt = true; return new SetSchemaRequest( mSchemas, diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/util/IndentingStringBuilder.java b/apex/appsearch/framework/java/external/android/app/appsearch/util/IndentingStringBuilder.java new file mode 100644 index 000000000000..b494c3ce9337 --- /dev/null +++ b/apex/appsearch/framework/java/external/android/app/appsearch/util/IndentingStringBuilder.java @@ -0,0 +1,126 @@ +/* + * 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. + */ + +package android.app.appsearch.util; + +import android.annotation.NonNull; + +/** + * Utility for building indented strings. + * + * <p>This is a wrapper for {@link StringBuilder} for appending strings with indentation. The + * indentation level can be increased by calling {@link #increaseIndentLevel()} and decreased by + * calling {@link #decreaseIndentLevel()}. + * + * <p>Indentation is applied after each newline character for the given indent level. + * + * @hide + */ +public class IndentingStringBuilder { + private final StringBuilder mStringBuilder = new StringBuilder(); + + // Indicates whether next non-newline character should have an indent applied before it. + private boolean mIndentNext = false; + private int mIndentLevel = 0; + + /** Increases the indent level by one for appended strings. */ + @NonNull + public IndentingStringBuilder increaseIndentLevel() { + mIndentLevel++; + return this; + } + + /** Decreases the indent level by one for appended strings. */ + @NonNull + public IndentingStringBuilder decreaseIndentLevel() throws IllegalStateException { + if (mIndentLevel == 0) { + throw new IllegalStateException("Cannot set indent level below 0."); + } + mIndentLevel--; + return this; + } + + /** + * Appends provided {@code String} at the current indentation level. + * + * <p>Indentation is applied after each newline character. + */ + @NonNull + public IndentingStringBuilder append(@NonNull String str) { + applyIndentToString(str); + return this; + } + + /** + * Appends provided {@code Object}, represented as a {@code String}, at the current indentation + * level. + * + * <p>Indentation is applied after each newline character. + */ + @NonNull + public IndentingStringBuilder append(@NonNull Object obj) { + applyIndentToString(obj.toString()); + return this; + } + + @Override + @NonNull + public String toString() { + return mStringBuilder.toString(); + } + + /** Adds indent string to the {@link StringBuilder} instance for current indent level. */ + private void applyIndent() { + for (int i = 0; i < mIndentLevel; i++) { + mStringBuilder.append(" "); + } + } + + /** + * Applies indent, for current indent level, after each newline character. + * + * <p>Consecutive newline characters are not indented. + */ + private void applyIndentToString(@NonNull String str) { + int index = str.indexOf("\n"); + if (index == 0) { + // String begins with new line character: append newline and slide past newline. + mStringBuilder.append("\n"); + mIndentNext = true; + if (str.length() > 1) { + applyIndentToString(str.substring(index + 1)); + } + } else if (index >= 1) { + // String contains new line character: divide string between newline, append new line, + // and recurse on each string. + String beforeIndentString = str.substring(0, index); + applyIndentToString(beforeIndentString); + mStringBuilder.append("\n"); + mIndentNext = true; + if (str.length() > index + 1) { + String afterIndentString = str.substring(index + 1); + applyIndentToString(afterIndentString); + } + } else { + // String does not contain newline character: append string. + if (mIndentNext) { + applyIndent(); + mIndentNext = false; + } + mStringBuilder.append(str); + } + } +} diff --git a/apex/appsearch/service/Android.bp b/apex/appsearch/service/Android.bp index 8d606c5e61cd..e5675f688fd7 100644 --- a/apex/appsearch/service/Android.bp +++ b/apex/appsearch/service/Android.bp @@ -28,31 +28,41 @@ genrule { } java_library { - name: "service-appsearch", - srcs: [ - "java/**/*.java", - ":statslog-appsearch-java-gen", + name: "statslog-appsearch-lib", + srcs: [":statslog-appsearch-java-gen"], + libs: [ + "framework-statsd.stubs.module_lib", ], + sdk_version: "system_server_current", + apex_available: ["com.android.appsearch"], +} + +java_library { + name: "service-appsearch", + srcs: ["java/**/*.java"], + sdk_version: "system_server_current", static_libs: [ "icing-java-proto-lite", "libicing-java", - // This list must be kept in sync with jarjar.txt + "statslog-appsearch-lib", + // Entries below this line are outside of the appsearch package tree and must be kept in + // sync with jarjar.txt "modules-utils-preconditions", ], libs: [ - "framework", - "framework-appsearch", - "framework-statsd.stubs.module_lib", - "services.core", - "services.usage", + "framework-appsearch.impl", "unsupportedappusage", // TODO(b/181887768) should be removed ], required: [ "libicing", ], + defaults: ["framework-system-server-module-defaults"], + permitted_packages: [ + "com.android.server.appsearch", + "com.google.android.icing", + ], jarjar_rules: "jarjar-rules.txt", visibility: [ - "//frameworks/base/apex/appsearch:__subpackages__", // These are required until appsearch is properly unbundled. "//frameworks/base/services/tests/mockingservicestests", "//frameworks/base/services/tests/servicestests", diff --git a/apex/appsearch/service/jarjar-rules.txt b/apex/appsearch/service/jarjar-rules.txt index 569d7c558471..c79ea22ca541 100644 --- a/apex/appsearch/service/jarjar-rules.txt +++ b/apex/appsearch/service/jarjar-rules.txt @@ -1,5 +1,8 @@ +# Rename all icing classes to match our module name. OEMs could start using icing lib for some other +# purpose in system service, which would cause class collisions when loading our apex into the +# system service. rule com.google.protobuf.** com.android.server.appsearch.protobuf.@1 -rule com.google.android.icing.proto.** com.android.server.appsearch.proto.@1 +rule com.google.android.icing.proto.** com.android.server.appsearch.icing.proto.@1 # Rename all com.android.internal.util classes to prevent class name collisions # between this module and the other versions of the utility classes linked into diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java index ac584fe4b91b..ec37c3f68aaa 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java @@ -60,8 +60,8 @@ import com.android.internal.annotations.GuardedBy; import com.android.server.LocalManagerRegistry; import com.android.server.SystemService; import com.android.server.appsearch.external.localstorage.stats.CallStats; +import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore; import com.android.server.appsearch.util.PackageUtil; -import com.android.server.appsearch.visibilitystore.VisibilityStore; import com.android.server.usage.StorageStatsManagerLocal; import com.android.server.usage.StorageStatsManagerLocal.StorageStatsAugmenter; @@ -82,7 +82,10 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -/** TODO(b/142567528): add comments when implement this class */ +/** + * The main service implementation which contains AppSearch's platform functionality. + * @hide + */ public class AppSearchManagerService extends SystemService { private static final String TAG = "AppSearchManagerService"; private final Context mContext; @@ -220,9 +223,10 @@ public class AppSearchManagerService extends SystemService { } // Only clear the package's data if AppSearch exists for this user. if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) { + Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0); AppSearchUserInstance instance = mAppSearchUserInstanceManager.getOrCreateUserInstance( - mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR)); + userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR)); //TODO(b/145759910) clear visibility setting for package. instance.getAppSearchImpl().clearPackageData(packageName); instance.getLogger().removeCachedUidForPackage(packageName); @@ -243,11 +247,11 @@ public class AppSearchManagerService extends SystemService { try { // Only clear the package's data if AppSearch exists for this user. if (AppSearchUserInstanceManager.getAppSearchDir(userHandle).exists()) { + Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0); AppSearchUserInstance instance = mAppSearchUserInstanceManager.getOrCreateUserInstance( - mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR)); - List<PackageInfo> installedPackageInfos = mContext - .createContextAsUser(userHandle, /*flags=*/0) + userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR)); + List<PackageInfo> installedPackageInfos = userContext .getPackageManager() .getInstalledPackages(/*flags=*/0); Set<String> packagesToKeep = new ArraySet<>(installedPackageInfos.size()); @@ -327,8 +331,10 @@ public class AppSearchManagerService extends SystemService { int operationSuccessCount = 0; int operationFailureCount = 0; try { + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); verifyUserUnlocked(callingUser); - verifyCallingPackage(callingUser, callingUid, packageName); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size()); for (int i = 0; i < schemaBundles.size(); i++) { schemas.add(new AppSearchSchema(schemaBundles.get(i))); @@ -401,8 +407,10 @@ public class AppSearchManagerService extends SystemService { UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); verifyUserUnlocked(callingUser); - verifyCallingPackage(callingUser, callingUid, packageName); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); GetSchemaResponse response = @@ -431,8 +439,10 @@ public class AppSearchManagerService extends SystemService { UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); verifyUserUnlocked(callingUser); - verifyCallingPackage(callingUser, callingUid, packageName); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); List<String> namespaces = @@ -468,8 +478,10 @@ public class AppSearchManagerService extends SystemService { int operationSuccessCount = 0; int operationFailureCount = 0; try { + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); verifyUserUnlocked(callingUser); - verifyCallingPackage(callingUser, callingUid, packageName); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); AppSearchBatchResult.Builder<String, Void> resultBuilder = new AppSearchBatchResult.Builder<>(); instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); @@ -548,8 +560,10 @@ public class AppSearchManagerService extends SystemService { int operationSuccessCount = 0; int operationFailureCount = 0; try { + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); verifyUserUnlocked(callingUser); - verifyCallingPackage(callingUser, callingUid, packageName); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); AppSearchBatchResult.Builder<String, Bundle> resultBuilder = new AppSearchBatchResult.Builder<>(); instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); @@ -627,8 +641,10 @@ public class AppSearchManagerService extends SystemService { int operationSuccessCount = 0; int operationFailureCount = 0; try { + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); verifyUserUnlocked(callingUser); - verifyCallingPackage(callingUser, callingUid, packageName); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); SearchResultPage searchResultPage = instance.getAppSearchImpl().query( packageName, @@ -691,8 +707,10 @@ public class AppSearchManagerService extends SystemService { int operationSuccessCount = 0; int operationFailureCount = 0; try { + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); verifyUserUnlocked(callingUser); - verifyCallingPackage(callingUser, callingUid, packageName); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); boolean callerHasSystemAccess = @@ -738,9 +756,11 @@ public class AppSearchManagerService extends SystemService { @Override public void getNextPage( + @NonNull String packageName, long nextPageToken, @NonNull UserHandle userHandle, @NonNull IAppSearchResultCallback callback) { + Objects.requireNonNull(packageName); Objects.requireNonNull(userHandle); Objects.requireNonNull(callback); @@ -750,7 +770,10 @@ public class AppSearchManagerService extends SystemService { // opened it EXECUTOR.execute(() -> { try { + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); verifyUserUnlocked(callingUser); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); SearchResultPage searchResultPage = @@ -765,14 +788,19 @@ public class AppSearchManagerService extends SystemService { } @Override - public void invalidateNextPageToken(long nextPageToken, @NonNull UserHandle userHandle) { + public void invalidateNextPageToken(@NonNull String packageName, long nextPageToken, + @NonNull UserHandle userHandle) { + Objects.requireNonNull(packageName); Objects.requireNonNull(userHandle); int callingUid = Binder.getCallingUid(); UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); verifyUserUnlocked(callingUser); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); instance.getAppSearchImpl().invalidateNextPageToken(nextPageToken); @@ -803,7 +831,10 @@ public class AppSearchManagerService extends SystemService { UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - verifyCallingPackage(callingUser, callingUid, packageName); + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); + verifyUserUnlocked(callingUser); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); // we don't need to append the file. The file is always brand new. @@ -849,7 +880,10 @@ public class AppSearchManagerService extends SystemService { UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - verifyCallingPackage(callingUser, callingUid, packageName); + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); + verifyUserUnlocked(callingUser); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); @@ -908,8 +942,10 @@ public class AppSearchManagerService extends SystemService { UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); verifyUserUnlocked(callingUser); - verifyCallingPackage(callingUser, callingUid, packageName); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); @@ -957,8 +993,10 @@ public class AppSearchManagerService extends SystemService { int operationSuccessCount = 0; int operationFailureCount = 0; try { + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); verifyUserUnlocked(callingUser); - verifyCallingPackage(callingUser, callingUid, packageName); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); AppSearchBatchResult.Builder<String, Void> resultBuilder = new AppSearchBatchResult.Builder<>(); instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); @@ -1039,8 +1077,10 @@ public class AppSearchManagerService extends SystemService { int operationSuccessCount = 0; int operationFailureCount = 0; try { + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); verifyUserUnlocked(callingUser); - verifyCallingPackage(callingUser, callingUid, packageName); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); instance.getAppSearchImpl().removeByQuery( packageName, @@ -1095,8 +1135,10 @@ public class AppSearchManagerService extends SystemService { UserHandle callingUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); verifyUserUnlocked(callingUser); - verifyCallingPackage(callingUser, callingUid, packageName); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); StorageInfo storageInfo = instance.getAppSearchImpl() @@ -1112,8 +1154,10 @@ public class AppSearchManagerService extends SystemService { @Override public void persistToDisk( + @NonNull String packageName, @NonNull UserHandle userHandle, @ElapsedRealtimeLong long binderCallStartTimeMillis) { + Objects.requireNonNull(packageName); Objects.requireNonNull(userHandle); long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); @@ -1125,7 +1169,10 @@ public class AppSearchManagerService extends SystemService { int operationSuccessCount = 0; int operationFailureCount = 0; try { + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); verifyUserUnlocked(callingUser); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); instance = mAppSearchUserInstanceManager.getUserInstance(callingUser); instance.getAppSearchImpl().persistToDisk(PersistType.Code.FULL); ++operationSuccessCount; @@ -1157,24 +1204,30 @@ public class AppSearchManagerService extends SystemService { @Override public void initialize( + @NonNull String packageName, @NonNull UserHandle userHandle, @ElapsedRealtimeLong long binderCallStartTimeMillis, @NonNull IAppSearchResultCallback callback) { + Objects.requireNonNull(packageName); Objects.requireNonNull(userHandle); Objects.requireNonNull(callback); long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); UserHandle callingUser = handleIncomingUser(userHandle, callingUid); + EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; AppSearchUserInstance instance = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { + Context userContext = mContext.createContextAsUser(callingUser, /*flags=*/ 0); verifyUserUnlocked(callingUser); + verifyCallingPackage(userContext, callingUser, callingUid, packageName); + verifyNotInstantApp(userContext, packageName); instance = mAppSearchUserInstanceManager.getOrCreateUserInstance( - mContext, callingUser, AppSearchConfig.getInstance(EXECUTOR)); + userContext, callingUser, AppSearchConfig.getInstance(EXECUTOR)); ++operationSuccessCount; invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null)); } catch (Throwable t) { @@ -1204,14 +1257,15 @@ public class AppSearchManagerService extends SystemService { } private void verifyCallingPackage( + @NonNull Context userContext, @NonNull UserHandle actualCallingUser, int actualCallingUid, @NonNull String claimedCallingPackage) { Objects.requireNonNull(actualCallingUser); Objects.requireNonNull(claimedCallingPackage); - int claimedCallingUid = PackageUtil.getPackageUidAsUser( - mContext, claimedCallingPackage, actualCallingUser); + int claimedCallingUid = PackageUtil.getPackageUid( + userContext, claimedCallingPackage); if (claimedCallingUid == INVALID_UID) { throw new SecurityException( "Specified calling package [" + claimedCallingPackage + "] not found"); @@ -1317,6 +1371,21 @@ public class AppSearchManagerService extends SystemService { + Manifest.permission.INTERACT_ACROSS_USERS_FULL); } + /** + * Helper for ensuring instant apps can't make calls to AppSearch. + * + * @param userContext Context of the user making the call. + * @param packageName Package name of the caller. + * @throws SecurityException if the caller is an instant app. + */ + private void verifyNotInstantApp(@NonNull Context userContext, @NonNull String packageName) { + PackageManager callingPackageManager = userContext.getPackageManager(); + if (callingPackageManager.isInstantApp(packageName)) { + throw new SecurityException("Caller not allowed to create AppSearch session" + + "; userHandle=" + userContext.getUser() + ", callingPackage=" + packageName); + } + } + // TODO(b/179160886): Cache the previous storage stats. private class AppSearchStorageStatsAugmenter implements StorageStatsAugmenter { @Override @@ -1331,9 +1400,10 @@ public class AppSearchManagerService extends SystemService { try { verifyUserUnlocked(userHandle); + Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0); AppSearchUserInstance instance = mAppSearchUserInstanceManager.getOrCreateUserInstance( - mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR)); + userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR)); stats.dataSize += instance.getAppSearchImpl() .getStorageInfoForPackage(packageName).getSizeBytes(); } catch (Throwable t) { @@ -1359,9 +1429,10 @@ public class AppSearchManagerService extends SystemService { if (packagesForUid == null) { return; } + Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0); AppSearchUserInstance instance = mAppSearchUserInstanceManager.getOrCreateUserInstance( - mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR)); + userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR)); for (int i = 0; i < packagesForUid.length; i++) { stats.dataSize += instance.getAppSearchImpl() .getStorageInfoForPackage(packagesForUid[i]).getSizeBytes(); @@ -1387,9 +1458,10 @@ public class AppSearchManagerService extends SystemService { if (packagesForUser == null) { return; } + Context userContext = mContext.createContextAsUser(userHandle, /*flags=*/ 0); AppSearchUserInstance instance = mAppSearchUserInstanceManager.getOrCreateUserInstance( - mContext, userHandle, AppSearchConfig.getInstance(EXECUTOR)); + userContext, userHandle, AppSearchConfig.getInstance(EXECUTOR)); for (int i = 0; i < packagesForUser.size(); i++) { String packageName = packagesForUser.get(i).packageName; stats.dataSize += instance.getAppSearchImpl() diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstance.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstance.java index 7e743edaf3ee..56e2af5fa2e3 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstance.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstance.java @@ -19,7 +19,7 @@ import android.annotation.NonNull; import com.android.server.appsearch.external.localstorage.AppSearchImpl; import com.android.server.appsearch.stats.PlatformLogger; -import com.android.server.appsearch.visibilitystore.VisibilityStore; +import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl; import java.util.Objects; @@ -30,12 +30,12 @@ import java.util.Objects; public final class AppSearchUserInstance { private final PlatformLogger mLogger; private final AppSearchImpl mAppSearchImpl; - private final VisibilityStore mVisibilityStore; + private final VisibilityStoreImpl mVisibilityStore; AppSearchUserInstance( @NonNull PlatformLogger logger, @NonNull AppSearchImpl appSearchImpl, - @NonNull VisibilityStore visibilityStore) { + @NonNull VisibilityStoreImpl visibilityStore) { mLogger = Objects.requireNonNull(logger); mAppSearchImpl = Objects.requireNonNull(appSearchImpl); mVisibilityStore = Objects.requireNonNull(visibilityStore); @@ -52,7 +52,7 @@ public final class AppSearchUserInstance { } @NonNull - public VisibilityStore getVisibilityStore() { + public VisibilityStoreImpl getVisibilityStore() { return mVisibilityStore; } } diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java index cedc364f6072..e067d4bcdf72 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchUserInstanceManager.java @@ -30,7 +30,7 @@ import com.android.server.appsearch.external.localstorage.AppSearchImpl; import com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy; import com.android.server.appsearch.external.localstorage.stats.InitializeStats; import com.android.server.appsearch.stats.PlatformLogger; -import com.android.server.appsearch.visibilitystore.VisibilityStore; +import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl; import java.io.File; import java.util.Map; @@ -89,25 +89,24 @@ public final class AppSearchUserInstanceManager { * <p>If no AppSearchUserInstance exists for the unlocked user, Icing will be initialized and * one will be created. * - * @param context The context + * @param userContext Context of the user calling AppSearch * @param userHandle The multi-user handle of the device user calling AppSearch * @param config Flag manager for AppSearch * @return An initialized {@link AppSearchUserInstance} for this user */ @NonNull public AppSearchUserInstance getOrCreateUserInstance( - @NonNull Context context, + @NonNull Context userContext, @NonNull UserHandle userHandle, @NonNull AppSearchConfig config) throws AppSearchException { - Objects.requireNonNull(context); + Objects.requireNonNull(userContext); Objects.requireNonNull(userHandle); Objects.requireNonNull(config); synchronized (mInstancesLocked) { AppSearchUserInstance instance = mInstancesLocked.get(userHandle); if (instance == null) { - Context userContext = context.createContextAsUser(userHandle, /*flags=*/ 0); instance = createUserInstance(userContext, userHandle, config); mInstancesLocked.put(userHandle, instance); } @@ -169,7 +168,7 @@ public final class AppSearchUserInstanceManager { InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder(); // Initialize the classes that make up AppSearchUserInstance - PlatformLogger logger = new PlatformLogger(userContext, userHandle, config); + PlatformLogger logger = new PlatformLogger(userContext, config); File appSearchDir = getAppSearchDir(userHandle); File icingDir = new File(appSearchDir, "icing"); @@ -178,7 +177,8 @@ public final class AppSearchUserInstanceManager { AppSearchImpl.create(icingDir, initStatsBuilder, new FrameworkOptimizeStrategy()); long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime(); - VisibilityStore visibilityStore = VisibilityStore.create(appSearchImpl, userContext); + VisibilityStoreImpl visibilityStore = + VisibilityStoreImpl.create(appSearchImpl, userContext); long prepareVisibilityStoreLatencyEndMillis = SystemClock.elapsedRealtime(); initStatsBuilder diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java index 4ad1c8c56979..9dee179bd6f2 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java @@ -58,7 +58,7 @@ import com.android.server.appsearch.external.localstorage.stats.InitializeStats; import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats; import com.android.server.appsearch.external.localstorage.stats.RemoveStats; import com.android.server.appsearch.external.localstorage.stats.SearchStats; -import com.android.server.appsearch.visibilitystore.VisibilityStore; +import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore; import com.google.android.icing.IcingSearchEngine; import com.google.android.icing.proto.DeleteByQueryResultProto; diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/visibilitystore/VisibilityStore.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/visibilitystore/VisibilityStore.java new file mode 100644 index 000000000000..fb89250cb096 --- /dev/null +++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/visibilitystore/VisibilityStore.java @@ -0,0 +1,72 @@ +/* + * 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. + */ +package com.android.server.appsearch.external.localstorage.visibilitystore; + +import android.annotation.NonNull; +import android.app.appsearch.PackageIdentifier; +import android.app.appsearch.exceptions.AppSearchException; + +import com.android.internal.annotations.VisibleForTesting; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * An interface for classes that store and validate document visibility data. + * + * @hide + */ +public interface VisibilityStore { + /** + * These cannot have any of the special characters used by AppSearchImpl (e.g. {@code + * AppSearchImpl#PACKAGE_DELIMITER} or {@code AppSearchImpl#DATABASE_DELIMITER}. + */ + String PACKAGE_NAME = "VS#Pkg"; + + @VisibleForTesting String DATABASE_NAME = "VS#Db"; + + /** + * Sets visibility settings for the given database. Any previous visibility settings will be + * overwritten. + * + * @param packageName Package of app that owns the schemas. + * @param databaseName Database that owns the schemas. + * @param schemasNotDisplayedBySystem Set of prefixed schemas that should be hidden from + * platform surfaces. + * @param schemasVisibleToPackages Map of prefixed schemas to a list of package identifiers that + * have access to the schema. + * @throws AppSearchException on AppSearchImpl error. + */ + void setVisibility( + @NonNull String packageName, + @NonNull String databaseName, + @NonNull Set<String> schemasNotDisplayedBySystem, + @NonNull Map<String, List<PackageIdentifier>> schemasVisibleToPackages) + throws AppSearchException; + + /** + * Checks whether the given package has access to system-surfaceable schemas. + * + * @param callerUid UID of the app that wants to see the data. + */ + boolean isSchemaSearchableByCaller( + @NonNull String packageName, + @NonNull String databaseName, + @NonNull String prefixedSchema, + int callerUid, + boolean callerHasSystemAccess); +} diff --git a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java b/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java index 31fead5e6314..322bd119b604 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/stats/PlatformLogger.java @@ -22,7 +22,6 @@ import android.app.appsearch.exceptions.AppSearchException; import android.content.Context; import android.os.Process; import android.os.SystemClock; -import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; import android.util.SparseIntArray; @@ -55,11 +54,8 @@ import java.util.Random; public final class PlatformLogger implements AppSearchLogger { private static final String TAG = "AppSearchPlatformLogger"; - // Context of the system service. - private final Context mContext; - - // User we're logging for. - private final UserHandle mUserHandle; + // Context of the user we're logging for. + private final Context mUserContext; // Manager holding the configuration flags private final AppSearchConfig mConfig; @@ -120,10 +116,9 @@ public final class PlatformLogger implements AppSearchLogger { * Westworld constructor */ public PlatformLogger( - @NonNull Context context, @NonNull UserHandle userHandle, + @NonNull Context userContext, @NonNull AppSearchConfig config) { - mContext = Objects.requireNonNull(context); - mUserHandle = Objects.requireNonNull(userHandle); + mUserContext = Objects.requireNonNull(userContext); mConfig = Objects.requireNonNull(config); } @@ -451,7 +446,7 @@ public final class PlatformLogger implements AppSearchLogger { private int getPackageUidAsUserLocked(@NonNull String packageName) { Integer packageUid = mPackageUidCacheLocked.get(packageName); if (packageUid == null) { - packageUid = PackageUtil.getPackageUidAsUser(mContext, packageName, mUserHandle); + packageUid = PackageUtil.getPackageUid(mUserContext, packageName); if (packageUid != Process.INVALID_UID) { mPackageUidCacheLocked.put(packageName, packageUid); } diff --git a/apex/appsearch/service/java/com/android/server/appsearch/util/PackageUtil.java b/apex/appsearch/service/java/com/android/server/appsearch/util/PackageUtil.java index 53a1bedb780b..714ffb6c8b68 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/util/PackageUtil.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/util/PackageUtil.java @@ -20,7 +20,6 @@ import android.annotation.NonNull; import android.content.Context; import android.content.pm.PackageManager; import android.os.Process; -import android.os.UserHandle; /** * Utilities for interacting with {@link android.content.pm.PackageManager}, @@ -32,16 +31,6 @@ public class PackageUtil { private PackageUtil() {} /** - * Finds the UID of the {@code packageName}. Returns {@link Process#INVALID_UID} if unable to - * find the UID. - */ - public static int getPackageUidAsUser( - @NonNull Context context, @NonNull String packageName, @NonNull UserHandle user) { - Context userContext = context.createContextAsUser(user, /*flags=*/ 0); - return getPackageUid(userContext, packageName); - } - - /** * Finds the UID of the {@code packageName} in the given {@code context}. Returns * {@link Process#INVALID_UID} if unable to find the UID. */ diff --git a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStoreImpl.java index a096aef34c71..ce142d646d1c 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStore.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/visibilitystore/VisibilityStoreImpl.java @@ -30,9 +30,9 @@ import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; -import com.android.internal.annotations.VisibleForTesting; import com.android.server.appsearch.external.localstorage.AppSearchImpl; import com.android.server.appsearch.external.localstorage.util.PrefixUtil; +import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore; import com.android.server.appsearch.util.PackageUtil; import com.google.android.icing.proto.PersistType; @@ -60,23 +60,12 @@ import java.util.Set; * <p>This class doesn't handle any locking itself. Its callers should handle the locking at a * higher level. * - * <p>NOTE: This class holds an instance of AppSearchImpl and AppSearchImpl holds an instance of - * this class. Take care to not cause any circular dependencies. - * * @hide */ -public class VisibilityStore { +public class VisibilityStoreImpl implements VisibilityStore { /** Version for the visibility schema */ private static final int SCHEMA_VERSION = 0; - /** - * These cannot have any of the special characters used by AppSearchImpl (e.g. {@code - * AppSearchImpl#PACKAGE_DELIMITER} or {@code AppSearchImpl#DATABASE_DELIMITER}. - */ - public static final String PACKAGE_NAME = "VS#Pkg"; - - @VisibleForTesting public static final String DATABASE_NAME = "VS#Db"; - /** Namespace of documents that contain visibility settings */ private static final String NAMESPACE = ""; @@ -101,13 +90,13 @@ public class VisibilityStore { * @param userContext Context of the user that the call is being made as */ @NonNull - public static VisibilityStore create( + public static VisibilityStoreImpl create( @NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext) throws AppSearchException { - return new VisibilityStore(appSearchImpl, userContext); + return new VisibilityStoreImpl(appSearchImpl, userContext); } - private VisibilityStore(@NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext) + private VisibilityStoreImpl(@NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext) throws AppSearchException { mAppSearchImpl = Objects.requireNonNull(appSearchImpl); mUserContext = Objects.requireNonNull(userContext); @@ -207,18 +196,7 @@ public class VisibilityStore { } } - /** - * Sets visibility settings for the given database. Any previous visibility settings will be - * overwritten. - * - * @param packageName Package of app that owns the schemas. - * @param databaseName Database that owns the schemas. - * @param schemasNotDisplayedBySystem Set of prefixed schemas that should be hidden from the - * platform. - * @param schemasVisibleToPackages Map of prefixed schemas to a list of package identifiers that - * have access to the schema. - * @throws AppSearchException on AppSearchImpl error. - */ + @Override public void setVisibility( @NonNull String packageName, @NonNull String databaseName, @@ -282,17 +260,7 @@ public class VisibilityStore { == PackageManager.PERMISSION_GRANTED; } - /** - * Checks whether {@code prefixedSchema} can be searched over by the {@code callerUid}. - * - * @param packageName Package that owns the schema. - * @param databaseName Database within the package that owns the schema. - * @param prefixedSchema Prefixed schema type the caller is trying to access. - * @param callerUid UID of the client making the globalQuery call. - * @param callerHasSystemAccess Whether the caller has been identified as having - * access to schemas marked system surfaceable by {@link - * #doesCallerHaveSystemAccess}. - */ + @Override public boolean isSchemaSearchableByCaller( @NonNull String packageName, @NonNull String databaseName, diff --git a/apex/appsearch/synced_jetpack_changeid.txt b/apex/appsearch/synced_jetpack_changeid.txt index 9859f20643b5..65551074f9c0 100644 --- a/apex/appsearch/synced_jetpack_changeid.txt +++ b/apex/appsearch/synced_jetpack_changeid.txt @@ -1 +1 @@ -04351b43fbbf9d59ffeae41903322023931c84f2 +c7387d9b58726a23a0608a9365fb3a1b57b7b8a1 diff --git a/apex/jobscheduler/framework/java/com/android/server/AppStateTracker.java b/apex/jobscheduler/framework/java/com/android/server/AppStateTracker.java index 3c89016ec605..b0b9abccd229 100644 --- a/apex/jobscheduler/framework/java/com/android/server/AppStateTracker.java +++ b/apex/jobscheduler/framework/java/com/android/server/AppStateTracker.java @@ -25,29 +25,19 @@ public interface AppStateTracker { String TAG = "AppStateTracker"; /** - * Register a {@link ForcedAppStandbyListener} to listen for forced-app-standby changes that - * should affect services etc. + * Register a {@link ServiceStateListener} to listen for forced-app-standby changes that should + * affect services. */ - void addForcedAppStandbyListener(@NonNull ForcedAppStandbyListener listener); + void addServiceStateListener(@NonNull ServiceStateListener listener); /** - * @return {code true} if the given UID/package has been in forced app standby mode. + * A listener to listen to forced-app-standby changes that should affect services. */ - boolean isAppInForcedAppStandby(int uid, @NonNull String packageName); - - /** - * A listener to listen to forced-app-standby changes that should affect services etc. - */ - interface ForcedAppStandbyListener { - /** - * Called when an app goes in/out of forced app standby. - */ - void updateForceAppStandbyForUidPackage(int uid, String packageName, boolean standby); - + interface ServiceStateListener { /** - * Called when all apps' forced-app-standby states need to be re-evaluated, due to - * enable/disable certain feature flags. + * Called when an app goes into forced app standby and its foreground + * services need to be removed from that state. */ - void updateForcedAppStandbyForAllApps(); + void stopForegroundServicesForUidPackage(int uid, String packageName); } } diff --git a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java index 1deb3656dabe..c332a598c30b 100644 --- a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java +++ b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java @@ -60,10 +60,8 @@ import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; import java.io.PrintWriter; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.Set; /** * Class to keep track of the information related to "force app standby", which includes: @@ -162,46 +160,16 @@ public class AppStateTrackerImpl implements AppStateTracker { @GuardedBy("mLock") boolean mForcedAppStandbyEnabled; - /** - * A lock-free set of (uid, packageName) pairs in forced app standby mode. - * - * <p> - * It's bascially shadowing the {@link #mRunAnyRestrictedPackages} together with - * the {@link #mForcedAppStandbyEnabled} and the {@link #mForceAllAppsStandby} - mutations on - * them would result in copy-on-write. - * - * Note: when {@link #mForcedAppStandbyEnabled} is {@code false}, it'll be set to an empty set. - * when {@link #mForceAllAppsStandby} is {@code true}, it'll be set to null; - * </p> - */ - volatile Set<Pair<Integer, String>> mForcedAppStandbyUidPackages = Collections.emptySet(); - @Override - public void addForcedAppStandbyListener(@NonNull ForcedAppStandbyListener listener) { + public void addServiceStateListener(@NonNull ServiceStateListener listener) { addListener(new Listener() { @Override - public void updateForceAppStandbyForUidPackage(int uid, String packageName, - boolean standby) { - listener.updateForceAppStandbyForUidPackage(uid, packageName, standby); - } - - @Override - public void updateForcedAppStandbyForAllApps() { - listener.updateForcedAppStandbyForAllApps(); + public void stopForegroundServicesForUidPackage(int uid, String packageName) { + listener.stopForegroundServicesForUidPackage(uid, packageName); } }); } - @Override - public boolean isAppInForcedAppStandby(int uid, @NonNull String packageName) { - final Set<Pair<Integer, String>> fasUidPkgs = mForcedAppStandbyUidPackages; - if (fasUidPkgs == null) { - // Meaning the mForceAllAppsStandby is true. - return true; - } - return fasUidPkgs.contains(Pair.create(uid, packageName)); - } - interface Stats { int UID_FG_STATE_CHANGED = 0; int UID_ACTIVE_STATE_CHANGED = 1; @@ -265,7 +233,6 @@ public class AppStateTrackerImpl implements AppStateTracker { return; } mForcedAppStandbyEnabled = enabled; - updateForcedAppStandbyUidPackagesLocked(); if (DEBUG) { Slog.d(TAG, "Forced app standby feature flag changed: " + mForcedAppStandbyEnabled); @@ -310,11 +277,7 @@ public class AppStateTrackerImpl implements AppStateTracker { if (!sender.isRunAnyInBackgroundAppOpsAllowed(uid, packageName)) { Slog.v(TAG, "Package " + packageName + "/" + uid + " toggled into fg service restriction"); - updateForceAppStandbyForUidPackage(uid, packageName, true); - } else { - Slog.v(TAG, "Package " + packageName + "/" + uid - + " toggled out of fg service restriction"); - updateForceAppStandbyForUidPackage(uid, packageName, false); + stopForegroundServicesForUidPackage(uid, packageName); } } @@ -379,7 +342,6 @@ public class AppStateTrackerImpl implements AppStateTracker { private void onForceAllAppsStandbyChanged(AppStateTrackerImpl sender) { updateAllJobs(); updateAllAlarms(); - updateForcedAppStandbyForAllApps(); } /** @@ -404,17 +366,10 @@ public class AppStateTrackerImpl implements AppStateTracker { } /** - * Called when an app goes in/out of forced app standby. + * Called when an app goes into forced app standby and its foreground + * services need to be removed from that state. */ - public void updateForceAppStandbyForUidPackage(int uid, String packageName, - boolean standby) { - } - - /** - * Called when all apps' forced-app-standby states need to be re-evaluated due to changes of - * feature flags such as {@link #mForcedAppStandbyEnabled} or {@link #mForceAllAppsStandby}. - */ - public void updateForcedAppStandbyForAllApps() { + public void stopForegroundServicesForUidPackage(int uid, String packageName) { } /** @@ -483,12 +438,9 @@ public class AppStateTrackerImpl implements AppStateTracker { final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); // No need to notify for state change as all the alarms and jobs should be // removed too. - synchronized (mLock) { - mExemptedBucketPackages.remove(userId, pkgName); - mRunAnyRestrictedPackages.remove(Pair.create(uid, pkgName)); - updateForcedAppStandbyUidPackagesLocked(); - mActiveUids.delete(uid); - } + mExemptedBucketPackages.remove(userId, pkgName); + mRunAnyRestrictedPackages.remove(Pair.create(uid, pkgName)); + mActiveUids.delete(uid); } break; } @@ -628,29 +580,6 @@ public class AppStateTrackerImpl implements AppStateTracker { } } } - updateForcedAppStandbyUidPackagesLocked(); - } - - /** - * Update the {@link #mForcedAppStandbyUidPackages} upon mutations on - * {@link #mRunAnyRestrictedPackages}, {@link #mForcedAppStandbyEnabled} or - * {@link #mForceAllAppsStandby}. - */ - @GuardedBy("mLock") - private void updateForcedAppStandbyUidPackagesLocked() { - if (!mForcedAppStandbyEnabled) { - mForcedAppStandbyUidPackages = Collections.emptySet(); - return; - } - if (mForceAllAppsStandby) { - mForcedAppStandbyUidPackages = null; - return; - } - Set<Pair<Integer, String>> fasUidPkgs = new ArraySet<>(); - for (int i = 0, size = mRunAnyRestrictedPackages.size(); i < size; i++) { - fasUidPkgs.add(mRunAnyRestrictedPackages.valueAt(i)); - } - mForcedAppStandbyUidPackages = Collections.unmodifiableSet(fasUidPkgs); } private void updateForceAllAppStandbyState() { @@ -672,7 +601,6 @@ public class AppStateTrackerImpl implements AppStateTracker { return; } mForceAllAppsStandby = enable; - updateForcedAppStandbyUidPackagesLocked(); mHandler.notifyForceAllAppsStandbyChanged(); } @@ -717,7 +645,6 @@ public class AppStateTrackerImpl implements AppStateTracker { } else { mRunAnyRestrictedPackages.removeAt(index); } - updateForcedAppStandbyUidPackagesLocked(); return true; } @@ -969,7 +896,6 @@ public class AppStateTrackerImpl implements AppStateTracker { if (unblockAlarms) { l.unblockAllUnrestrictedAlarms(); } - l.updateForcedAppStandbyForAllApps(); } mStatLogger.logDurationStat( Stats.FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED, start); @@ -1040,7 +966,6 @@ public class AppStateTrackerImpl implements AppStateTracker { mRunAnyRestrictedPackages.removeAt(i); } } - updateForcedAppStandbyUidPackagesLocked(); cleanUpArrayForUser(mActiveUids, removedUserId); mExemptedBucketPackages.remove(removedUserId); } 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 96cbed75622f..78670c7c73b1 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java @@ -73,7 +73,9 @@ import android.util.IndentingPrintWriter; import android.util.Log; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseBooleanArray; import android.util.SparseIntArray; +import android.util.SparseLongArray; import android.util.SparseSetArray; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; @@ -686,26 +688,92 @@ public class JobSchedulerService extends com.android.server.SystemService final Constants mConstants; final ConstantsObserver mConstantsObserver; - private static final Comparator<JobStatus> sPendingJobComparator = (o1, o2) -> { - // Jobs with an override state set (via adb) should be put first as tests/developers - // expect the jobs to run immediately. - if (o1.overrideState != o2.overrideState) { - // Higher override state (OVERRIDE_FULL) should be before lower state (OVERRIDE_SOFT) - return o2.overrideState - o1.overrideState; - } - if (o1.getSourceUid() == o2.getSourceUid()) { - final boolean o1FGJ = o1.isRequestedExpeditedJob(); - if (o1FGJ != o2.isRequestedExpeditedJob()) { - // Attempt to run requested expedited jobs ahead of regular jobs, regardless of - // expedited job quota. - return o1FGJ ? -1 : 1; + @VisibleForTesting + class PendingJobComparator implements Comparator<JobStatus> { + private final SparseBooleanArray mUidHasEjCache = new SparseBooleanArray(); + private final SparseLongArray mEarliestRegEnqueueTimeCache = new SparseLongArray(); + + /** + * Refresh sorting determinants based on the current state of {@link #mPendingJobs}. + */ + @GuardedBy("mLock") + @VisibleForTesting + void refreshLocked() { + mUidHasEjCache.clear(); + mEarliestRegEnqueueTimeCache.clear(); + for (int i = 0; i < mPendingJobs.size(); ++i) { + final JobStatus job = mPendingJobs.get(i); + final int uid = job.getSourceUid(); + if (job.isRequestedExpeditedJob()) { + mUidHasEjCache.put(uid, true); + } else { + final long earliestEnqueueTime = + mEarliestRegEnqueueTimeCache.get(uid, Long.MAX_VALUE); + mEarliestRegEnqueueTimeCache.put(uid, + Math.min(earliestEnqueueTime, job.enqueueTime)); + } } } - if (o1.enqueueTime < o2.enqueueTime) { - return -1; + + @Override + public int compare(JobStatus o1, JobStatus o2) { + if (o1 == o2) { + return 0; + } + // Jobs with an override state set (via adb) should be put first as tests/developers + // expect the jobs to run immediately. + if (o1.overrideState != o2.overrideState) { + // Higher override state (OVERRIDE_FULL) should be before lower state + // (OVERRIDE_SOFT) + return o2.overrideState - o1.overrideState; + } + final boolean o1EJ = o1.isRequestedExpeditedJob(); + final boolean o2EJ = o2.isRequestedExpeditedJob(); + if (o1.getSourceUid() == o2.getSourceUid()) { + if (o1EJ != o2EJ) { + // Attempt to run requested expedited jobs ahead of regular jobs, regardless of + // expedited job quota. + return o1EJ ? -1 : 1; + } + } + final boolean uid1HasEj = mUidHasEjCache.get(o1.getSourceUid()); + final boolean uid2HasEj = mUidHasEjCache.get(o2.getSourceUid()); + if ((uid1HasEj || uid2HasEj) && (o1EJ || o2EJ)) { + // We MUST prioritize EJs ahead of regular jobs within a single app. Since we do + // that, in order to satisfy the transitivity constraint of the comparator, if + // any UID has an EJ, we must ensure that the EJ is ordered ahead of the regular + // job of a different app IF the app with an EJ had another job that came before + // the differing app. For example, if app A has regJob1 at t1 and eJob3 at t3 and + // app B has regJob2 at t2, eJob3 must be ordered before regJob2 because it will be + // ordered before regJob1. + // Regular jobs don't need to jump the line. + + final long uid1EarliestRegEnqueueTime = Math.min(o1.enqueueTime, + mEarliestRegEnqueueTimeCache.get(o1.getSourceUid(), Long.MAX_VALUE)); + final long uid2EarliestRegEnqueueTime = Math.min(o2.enqueueTime, + mEarliestRegEnqueueTimeCache.get(o2.getSourceUid(), Long.MAX_VALUE)); + + if (o1EJ && o2EJ) { + if (uid1EarliestRegEnqueueTime < uid2EarliestRegEnqueueTime) { + return -1; + } else if (uid1EarliestRegEnqueueTime > uid2EarliestRegEnqueueTime) { + return 1; + } + } else if (o1EJ && uid1EarliestRegEnqueueTime < o2.enqueueTime) { + return -1; + } else if (o2EJ && uid2EarliestRegEnqueueTime < o1.enqueueTime) { + return 1; + } + } + if (o1.enqueueTime < o2.enqueueTime) { + return -1; + } + return o1.enqueueTime > o2.enqueueTime ? 1 : 0; } - return o1.enqueueTime > o2.enqueueTime ? 1 : 0; - }; + } + + @VisibleForTesting + final PendingJobComparator mPendingJobComparator = new PendingJobComparator(); static <T> void addOrderedItem(ArrayList<T> array, T newItem, Comparator<T> comparator) { int where = Collections.binarySearch(array, newItem, comparator); @@ -1115,7 +1183,7 @@ public class JobSchedulerService extends com.android.server.SystemService // This is a new job, we can just immediately put it on the pending // list and try to run it. mJobPackageTracker.notePending(jobStatus); - addOrderedItem(mPendingJobs, jobStatus, sPendingJobComparator); + addOrderedItem(mPendingJobs, jobStatus, mPendingJobComparator); maybeRunPendingJobsLocked(); } else { evaluateControllerStatesLocked(jobStatus); @@ -1919,7 +1987,7 @@ public class JobSchedulerService extends com.android.server.SystemService if (js != null) { if (isReadyToBeExecutedLocked(js)) { mJobPackageTracker.notePending(js); - addOrderedItem(mPendingJobs, js, sPendingJobComparator); + addOrderedItem(mPendingJobs, js, mPendingJobComparator); } } else { Slog.e(TAG, "Given null job to check individually"); @@ -2064,6 +2132,7 @@ public class JobSchedulerService extends com.android.server.SystemService * Run through list of jobs and execute all possible - at least one is expired so we do * as many as we can. */ + @GuardedBy("mLock") private void queueReadyJobsForExecutionLocked() { // This method will check and capture all ready jobs, so we don't need to keep any messages // in the queue. @@ -2079,7 +2148,7 @@ public class JobSchedulerService extends com.android.server.SystemService mPendingJobs.clear(); stopNonReadyActiveJobsLocked(); mJobs.forEachJob(mReadyQueueFunctor); - mReadyQueueFunctor.postProcess(); + mReadyQueueFunctor.postProcessLocked(); if (DEBUG) { final int queuedJobs = mPendingJobs.size(); @@ -2106,16 +2175,19 @@ public class JobSchedulerService extends com.android.server.SystemService } } - public void postProcess() { + @GuardedBy("mLock") + private void postProcessLocked() { noteJobsPending(newReadyJobs); mPendingJobs.addAll(newReadyJobs); if (mPendingJobs.size() > 1) { - mPendingJobs.sort(sPendingJobComparator); + mPendingJobComparator.refreshLocked(); + mPendingJobs.sort(mPendingJobComparator); } newReadyJobs.clear(); } } + private final ReadyJobQueueFunctor mReadyQueueFunctor = new ReadyJobQueueFunctor(); /** @@ -2180,7 +2252,9 @@ public class JobSchedulerService extends com.android.server.SystemService } } - public void postProcess() { + @GuardedBy("mLock") + @VisibleForTesting + void postProcessLocked() { if (unbatchedCount > 0 || forceBatchedCount >= mConstants.MIN_READY_NON_ACTIVE_JOBS_COUNT) { if (DEBUG) { @@ -2189,7 +2263,8 @@ public class JobSchedulerService extends com.android.server.SystemService noteJobsPending(runnableJobs); mPendingJobs.addAll(runnableJobs); if (mPendingJobs.size() > 1) { - mPendingJobs.sort(sPendingJobComparator); + mPendingJobComparator.refreshLocked(); + mPendingJobs.sort(mPendingJobComparator); } } else { if (DEBUG) { @@ -2210,6 +2285,7 @@ public class JobSchedulerService extends com.android.server.SystemService } private final MaybeReadyJobQueueFunctor mMaybeQueueFunctor = new MaybeReadyJobQueueFunctor(); + @GuardedBy("mLock") private void maybeQueueReadyJobsForExecutionLocked() { if (DEBUG) Slog.d(TAG, "Maybe queuing ready jobs..."); @@ -2217,7 +2293,7 @@ public class JobSchedulerService extends com.android.server.SystemService mPendingJobs.clear(); stopNonReadyActiveJobsLocked(); mJobs.forEachJob(mMaybeQueueFunctor); - mMaybeQueueFunctor.postProcess(); + mMaybeQueueFunctor.postProcessLocked(); } /** Returns true if both the calling and source users for the job are started. */ diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java index 548a1ac14391..31a0853746e2 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java @@ -82,7 +82,11 @@ public final class BackgroundJobsController extends StateController { @Override public void evaluateStateLocked(JobStatus jobStatus) { - updateSingleJobRestrictionLocked(jobStatus, sElapsedRealtimeClock.millis(), UNKNOWN); + if (jobStatus.isRequestedExpeditedJob()) { + // Only requested-EJs could have their run-in-bg constraint change outside of something + // coming through the ForceAppStandbyListener. + updateSingleJobRestrictionLocked(jobStatus, sElapsedRealtimeClock.millis(), UNKNOWN); + } } @Override diff --git a/boot/hiddenapi/hiddenapi-max-target-o.txt b/boot/hiddenapi/hiddenapi-max-target-o.txt index 3cc28d908a38..770547e205e6 100644 --- a/boot/hiddenapi/hiddenapi-max-target-o.txt +++ b/boot/hiddenapi/hiddenapi-max-target-o.txt @@ -8961,12 +8961,6 @@ Landroid/app/slice/SliceQuery;->TAG:Ljava/lang/String; Landroid/app/slice/SliceSpec;-><init>(Landroid/os/Parcel;)V Landroid/app/slice/SliceSpec;->mRevision:I Landroid/app/slice/SliceSpec;->mType:Ljava/lang/String; -Landroid/app/StatsManager;-><init>(Landroid/content/Context;)V -Landroid/app/StatsManager;->DEBUG:Z -Landroid/app/StatsManager;->getIStatsManagerLocked()Landroid/os/IStatsManager; -Landroid/app/StatsManager;->mContext:Landroid/content/Context; -Landroid/app/StatsManager;->mService:Landroid/os/IStatsManager; -Landroid/app/StatsManager;->TAG:Ljava/lang/String; Landroid/app/StatusBarManager;->CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER:I Landroid/app/StatusBarManager;->CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP:I Landroid/app/StatusBarManager;->CAMERA_LAUNCH_SOURCE_WIGGLE:I @@ -38253,837 +38247,6 @@ Landroid/net/WebAddress;->sAddressPattern:Ljava/util/regex/Pattern; Landroid/net/WebAddress;->setAuthInfo(Ljava/lang/String;)V Landroid/net/WebAddress;->setPort(I)V Landroid/net/WebAddress;->setScheme(Ljava/lang/String;)V -Landroid/net/wifi/AnqpInformationElement;-><init>(II[B)V -Landroid/net/wifi/AnqpInformationElement;->ANQP_3GPP_NETWORK:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_CAPABILITY_LIST:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_CIVIC_LOC:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_DOM_NAME:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_EMERGENCY_ALERT:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_EMERGENCY_NAI:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_EMERGENCY_NUMBER:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_GEO_LOC:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_IP_ADDR_AVAILABILITY:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_LOC_URI:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_NAI_REALM:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_NEIGHBOR_REPORT:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_NWK_AUTH_TYPE:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_QUERY_LIST:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_ROAMING_CONSORTIUM:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_TDLS_CAP:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_VENDOR_SPEC:I -Landroid/net/wifi/AnqpInformationElement;->ANQP_VENUE_NAME:I -Landroid/net/wifi/AnqpInformationElement;->getElementId()I -Landroid/net/wifi/AnqpInformationElement;->getPayload()[B -Landroid/net/wifi/AnqpInformationElement;->getVendorId()I -Landroid/net/wifi/AnqpInformationElement;->HOTSPOT20_VENDOR_ID:I -Landroid/net/wifi/AnqpInformationElement;->HS_CAPABILITY_LIST:I -Landroid/net/wifi/AnqpInformationElement;->HS_CONN_CAPABILITY:I -Landroid/net/wifi/AnqpInformationElement;->HS_FRIENDLY_NAME:I -Landroid/net/wifi/AnqpInformationElement;->HS_ICON_FILE:I -Landroid/net/wifi/AnqpInformationElement;->HS_ICON_REQUEST:I -Landroid/net/wifi/AnqpInformationElement;->HS_NAI_HOME_REALM_QUERY:I -Landroid/net/wifi/AnqpInformationElement;->HS_OPERATING_CLASS:I -Landroid/net/wifi/AnqpInformationElement;->HS_OSU_PROVIDERS:I -Landroid/net/wifi/AnqpInformationElement;->HS_QUERY_LIST:I -Landroid/net/wifi/AnqpInformationElement;->HS_WAN_METRICS:I -Landroid/net/wifi/AnqpInformationElement;->mElementId:I -Landroid/net/wifi/AnqpInformationElement;->mPayload:[B -Landroid/net/wifi/AnqpInformationElement;->mVendorId:I -Landroid/net/wifi/aware/Characteristics;-><init>(Landroid/os/Bundle;)V -Landroid/net/wifi/aware/Characteristics;->KEY_MAX_MATCH_FILTER_LENGTH:Ljava/lang/String; -Landroid/net/wifi/aware/Characteristics;->KEY_MAX_SERVICE_NAME_LENGTH:Ljava/lang/String; -Landroid/net/wifi/aware/Characteristics;->KEY_MAX_SERVICE_SPECIFIC_INFO_LENGTH:Ljava/lang/String; -Landroid/net/wifi/aware/Characteristics;->mCharacteristics:Landroid/os/Bundle; -Landroid/net/wifi/aware/ConfigRequest$Builder;-><init>()V -Landroid/net/wifi/aware/ConfigRequest$Builder;->build()Landroid/net/wifi/aware/ConfigRequest; -Landroid/net/wifi/aware/ConfigRequest$Builder;->mClusterHigh:I -Landroid/net/wifi/aware/ConfigRequest$Builder;->mClusterLow:I -Landroid/net/wifi/aware/ConfigRequest$Builder;->mDiscoveryWindowInterval:[I -Landroid/net/wifi/aware/ConfigRequest$Builder;->mMasterPreference:I -Landroid/net/wifi/aware/ConfigRequest$Builder;->mSupport5gBand:Z -Landroid/net/wifi/aware/ConfigRequest$Builder;->setClusterHigh(I)Landroid/net/wifi/aware/ConfigRequest$Builder; -Landroid/net/wifi/aware/ConfigRequest$Builder;->setClusterLow(I)Landroid/net/wifi/aware/ConfigRequest$Builder; -Landroid/net/wifi/aware/ConfigRequest$Builder;->setDiscoveryWindowInterval(II)Landroid/net/wifi/aware/ConfigRequest$Builder; -Landroid/net/wifi/aware/ConfigRequest$Builder;->setMasterPreference(I)Landroid/net/wifi/aware/ConfigRequest$Builder; -Landroid/net/wifi/aware/ConfigRequest$Builder;->setSupport5gBand(Z)Landroid/net/wifi/aware/ConfigRequest$Builder; -Landroid/net/wifi/aware/ConfigRequest;-><init>(ZIII[I)V -Landroid/net/wifi/aware/ConfigRequest;->CLUSTER_ID_MAX:I -Landroid/net/wifi/aware/ConfigRequest;->CLUSTER_ID_MIN:I -Landroid/net/wifi/aware/ConfigRequest;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/aware/ConfigRequest;->DW_DISABLE:I -Landroid/net/wifi/aware/ConfigRequest;->DW_INTERVAL_NOT_INIT:I -Landroid/net/wifi/aware/ConfigRequest;->mClusterHigh:I -Landroid/net/wifi/aware/ConfigRequest;->mClusterLow:I -Landroid/net/wifi/aware/ConfigRequest;->mDiscoveryWindowInterval:[I -Landroid/net/wifi/aware/ConfigRequest;->mMasterPreference:I -Landroid/net/wifi/aware/ConfigRequest;->mSupport5gBand:Z -Landroid/net/wifi/aware/ConfigRequest;->NAN_BAND_24GHZ:I -Landroid/net/wifi/aware/ConfigRequest;->NAN_BAND_5GHZ:I -Landroid/net/wifi/aware/ConfigRequest;->validate()V -Landroid/net/wifi/aware/DiscoverySession;-><init>(Landroid/net/wifi/aware/WifiAwareManager;II)V -Landroid/net/wifi/aware/DiscoverySession;->DBG:Z -Landroid/net/wifi/aware/DiscoverySession;->getClientId()I -Landroid/net/wifi/aware/DiscoverySession;->getMaxSendRetryCount()I -Landroid/net/wifi/aware/DiscoverySession;->getSessionId()I -Landroid/net/wifi/aware/DiscoverySession;->MAX_SEND_RETRY_COUNT:I -Landroid/net/wifi/aware/DiscoverySession;->mClientId:I -Landroid/net/wifi/aware/DiscoverySession;->mCloseGuard:Ldalvik/system/CloseGuard; -Landroid/net/wifi/aware/DiscoverySession;->mMgr:Ljava/lang/ref/WeakReference; -Landroid/net/wifi/aware/DiscoverySession;->mSessionId:I -Landroid/net/wifi/aware/DiscoverySession;->mTerminated:Z -Landroid/net/wifi/aware/DiscoverySession;->sendMessage(Landroid/net/wifi/aware/PeerHandle;I[BI)V -Landroid/net/wifi/aware/DiscoverySession;->setTerminated()V -Landroid/net/wifi/aware/DiscoverySession;->TAG:Ljava/lang/String; -Landroid/net/wifi/aware/DiscoverySession;->VDBG:Z -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String; -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder; -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub$Proxy;->onMatch(I[B[B)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub$Proxy;->onMatchWithDistance(I[B[BI)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub$Proxy;->onMessageReceived(I[B)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub$Proxy;->onMessageSendFail(II)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub$Proxy;->onMessageSendSuccess(I)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub$Proxy;->onSessionConfigFail(I)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub$Proxy;->onSessionConfigSuccess()V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub$Proxy;->onSessionStarted(I)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub$Proxy;->onSessionTerminated(I)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub;-><init>()V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback; -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub;->DESCRIPTOR:Ljava/lang/String; -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub;->TRANSACTION_onMatch:I -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub;->TRANSACTION_onMatchWithDistance:I -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub;->TRANSACTION_onMessageReceived:I -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub;->TRANSACTION_onMessageSendFail:I -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub;->TRANSACTION_onMessageSendSuccess:I -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub;->TRANSACTION_onSessionConfigFail:I -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub;->TRANSACTION_onSessionConfigSuccess:I -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub;->TRANSACTION_onSessionStarted:I -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback$Stub;->TRANSACTION_onSessionTerminated:I -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback;->onMatch(I[B[B)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback;->onMatchWithDistance(I[B[BI)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback;->onMessageReceived(I[B)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback;->onMessageSendFail(II)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback;->onMessageSendSuccess(I)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback;->onSessionConfigFail(I)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback;->onSessionConfigSuccess()V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback;->onSessionStarted(I)V -Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback;->onSessionTerminated(I)V -Landroid/net/wifi/aware/IWifiAwareEventCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/net/wifi/aware/IWifiAwareEventCallback$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String; -Landroid/net/wifi/aware/IWifiAwareEventCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder; -Landroid/net/wifi/aware/IWifiAwareEventCallback$Stub$Proxy;->onConnectFail(I)V -Landroid/net/wifi/aware/IWifiAwareEventCallback$Stub$Proxy;->onConnectSuccess(I)V -Landroid/net/wifi/aware/IWifiAwareEventCallback$Stub$Proxy;->onIdentityChanged([B)V -Landroid/net/wifi/aware/IWifiAwareEventCallback$Stub;-><init>()V -Landroid/net/wifi/aware/IWifiAwareEventCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/aware/IWifiAwareEventCallback; -Landroid/net/wifi/aware/IWifiAwareEventCallback$Stub;->DESCRIPTOR:Ljava/lang/String; -Landroid/net/wifi/aware/IWifiAwareEventCallback$Stub;->TRANSACTION_onConnectFail:I -Landroid/net/wifi/aware/IWifiAwareEventCallback$Stub;->TRANSACTION_onConnectSuccess:I -Landroid/net/wifi/aware/IWifiAwareEventCallback$Stub;->TRANSACTION_onIdentityChanged:I -Landroid/net/wifi/aware/IWifiAwareEventCallback;->onConnectFail(I)V -Landroid/net/wifi/aware/IWifiAwareEventCallback;->onConnectSuccess(I)V -Landroid/net/wifi/aware/IWifiAwareEventCallback;->onIdentityChanged([B)V -Landroid/net/wifi/aware/IWifiAwareMacAddressProvider$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/net/wifi/aware/IWifiAwareMacAddressProvider$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String; -Landroid/net/wifi/aware/IWifiAwareMacAddressProvider$Stub$Proxy;->macAddress(Ljava/util/Map;)V -Landroid/net/wifi/aware/IWifiAwareMacAddressProvider$Stub$Proxy;->mRemote:Landroid/os/IBinder; -Landroid/net/wifi/aware/IWifiAwareMacAddressProvider$Stub;-><init>()V -Landroid/net/wifi/aware/IWifiAwareMacAddressProvider$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/aware/IWifiAwareMacAddressProvider; -Landroid/net/wifi/aware/IWifiAwareMacAddressProvider$Stub;->DESCRIPTOR:Ljava/lang/String; -Landroid/net/wifi/aware/IWifiAwareMacAddressProvider$Stub;->TRANSACTION_macAddress:I -Landroid/net/wifi/aware/IWifiAwareMacAddressProvider;->macAddress(Ljava/util/Map;)V -Landroid/net/wifi/aware/IWifiAwareManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/net/wifi/aware/IWifiAwareManager$Stub$Proxy;->connect(Landroid/os/IBinder;Ljava/lang/String;Landroid/net/wifi/aware/IWifiAwareEventCallback;Landroid/net/wifi/aware/ConfigRequest;Z)V -Landroid/net/wifi/aware/IWifiAwareManager$Stub$Proxy;->disconnect(ILandroid/os/IBinder;)V -Landroid/net/wifi/aware/IWifiAwareManager$Stub$Proxy;->getCharacteristics()Landroid/net/wifi/aware/Characteristics; -Landroid/net/wifi/aware/IWifiAwareManager$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String; -Landroid/net/wifi/aware/IWifiAwareManager$Stub$Proxy;->isUsageEnabled()Z -Landroid/net/wifi/aware/IWifiAwareManager$Stub$Proxy;->mRemote:Landroid/os/IBinder; -Landroid/net/wifi/aware/IWifiAwareManager$Stub$Proxy;->publish(Ljava/lang/String;ILandroid/net/wifi/aware/PublishConfig;Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback;)V -Landroid/net/wifi/aware/IWifiAwareManager$Stub$Proxy;->requestMacAddresses(ILjava/util/List;Landroid/net/wifi/aware/IWifiAwareMacAddressProvider;)V -Landroid/net/wifi/aware/IWifiAwareManager$Stub$Proxy;->sendMessage(III[BII)V -Landroid/net/wifi/aware/IWifiAwareManager$Stub$Proxy;->subscribe(Ljava/lang/String;ILandroid/net/wifi/aware/SubscribeConfig;Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback;)V -Landroid/net/wifi/aware/IWifiAwareManager$Stub$Proxy;->terminateSession(II)V -Landroid/net/wifi/aware/IWifiAwareManager$Stub$Proxy;->updatePublish(IILandroid/net/wifi/aware/PublishConfig;)V -Landroid/net/wifi/aware/IWifiAwareManager$Stub$Proxy;->updateSubscribe(IILandroid/net/wifi/aware/SubscribeConfig;)V -Landroid/net/wifi/aware/IWifiAwareManager$Stub;-><init>()V -Landroid/net/wifi/aware/IWifiAwareManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/aware/IWifiAwareManager; -Landroid/net/wifi/aware/IWifiAwareManager$Stub;->DESCRIPTOR:Ljava/lang/String; -Landroid/net/wifi/aware/IWifiAwareManager$Stub;->TRANSACTION_connect:I -Landroid/net/wifi/aware/IWifiAwareManager$Stub;->TRANSACTION_disconnect:I -Landroid/net/wifi/aware/IWifiAwareManager$Stub;->TRANSACTION_getCharacteristics:I -Landroid/net/wifi/aware/IWifiAwareManager$Stub;->TRANSACTION_isUsageEnabled:I -Landroid/net/wifi/aware/IWifiAwareManager$Stub;->TRANSACTION_publish:I -Landroid/net/wifi/aware/IWifiAwareManager$Stub;->TRANSACTION_requestMacAddresses:I -Landroid/net/wifi/aware/IWifiAwareManager$Stub;->TRANSACTION_sendMessage:I -Landroid/net/wifi/aware/IWifiAwareManager$Stub;->TRANSACTION_subscribe:I -Landroid/net/wifi/aware/IWifiAwareManager$Stub;->TRANSACTION_terminateSession:I -Landroid/net/wifi/aware/IWifiAwareManager$Stub;->TRANSACTION_updatePublish:I -Landroid/net/wifi/aware/IWifiAwareManager$Stub;->TRANSACTION_updateSubscribe:I -Landroid/net/wifi/aware/IWifiAwareManager;->connect(Landroid/os/IBinder;Ljava/lang/String;Landroid/net/wifi/aware/IWifiAwareEventCallback;Landroid/net/wifi/aware/ConfigRequest;Z)V -Landroid/net/wifi/aware/IWifiAwareManager;->disconnect(ILandroid/os/IBinder;)V -Landroid/net/wifi/aware/IWifiAwareManager;->getCharacteristics()Landroid/net/wifi/aware/Characteristics; -Landroid/net/wifi/aware/IWifiAwareManager;->isUsageEnabled()Z -Landroid/net/wifi/aware/IWifiAwareManager;->publish(Ljava/lang/String;ILandroid/net/wifi/aware/PublishConfig;Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback;)V -Landroid/net/wifi/aware/IWifiAwareManager;->requestMacAddresses(ILjava/util/List;Landroid/net/wifi/aware/IWifiAwareMacAddressProvider;)V -Landroid/net/wifi/aware/IWifiAwareManager;->sendMessage(III[BII)V -Landroid/net/wifi/aware/IWifiAwareManager;->subscribe(Ljava/lang/String;ILandroid/net/wifi/aware/SubscribeConfig;Landroid/net/wifi/aware/IWifiAwareDiscoverySessionCallback;)V -Landroid/net/wifi/aware/IWifiAwareManager;->terminateSession(II)V -Landroid/net/wifi/aware/IWifiAwareManager;->updatePublish(IILandroid/net/wifi/aware/PublishConfig;)V -Landroid/net/wifi/aware/IWifiAwareManager;->updateSubscribe(IILandroid/net/wifi/aware/SubscribeConfig;)V -Landroid/net/wifi/aware/PeerHandle;-><init>(I)V -Landroid/net/wifi/aware/PeerHandle;->peerId:I -Landroid/net/wifi/aware/PublishConfig$Builder;->mEnableRanging:Z -Landroid/net/wifi/aware/PublishConfig$Builder;->mEnableTerminateNotification:Z -Landroid/net/wifi/aware/PublishConfig$Builder;->mMatchFilter:[B -Landroid/net/wifi/aware/PublishConfig$Builder;->mPublishType:I -Landroid/net/wifi/aware/PublishConfig$Builder;->mServiceName:[B -Landroid/net/wifi/aware/PublishConfig$Builder;->mServiceSpecificInfo:[B -Landroid/net/wifi/aware/PublishConfig$Builder;->mTtlSec:I -Landroid/net/wifi/aware/PublishConfig;-><init>([B[B[BIIZZ)V -Landroid/net/wifi/aware/PublishConfig;->assertValid(Landroid/net/wifi/aware/Characteristics;Z)V -Landroid/net/wifi/aware/PublishConfig;->mEnableRanging:Z -Landroid/net/wifi/aware/PublishConfig;->mEnableTerminateNotification:Z -Landroid/net/wifi/aware/PublishConfig;->mMatchFilter:[B -Landroid/net/wifi/aware/PublishConfig;->mPublishType:I -Landroid/net/wifi/aware/PublishConfig;->mServiceName:[B -Landroid/net/wifi/aware/PublishConfig;->mServiceSpecificInfo:[B -Landroid/net/wifi/aware/PublishConfig;->mTtlSec:I -Landroid/net/wifi/aware/PublishDiscoverySession;-><init>(Landroid/net/wifi/aware/WifiAwareManager;II)V -Landroid/net/wifi/aware/PublishDiscoverySession;->TAG:Ljava/lang/String; -Landroid/net/wifi/aware/SubscribeConfig$Builder;->mEnableTerminateNotification:Z -Landroid/net/wifi/aware/SubscribeConfig$Builder;->mMatchFilter:[B -Landroid/net/wifi/aware/SubscribeConfig$Builder;->mMaxDistanceMm:I -Landroid/net/wifi/aware/SubscribeConfig$Builder;->mMaxDistanceMmSet:Z -Landroid/net/wifi/aware/SubscribeConfig$Builder;->mMinDistanceMm:I -Landroid/net/wifi/aware/SubscribeConfig$Builder;->mMinDistanceMmSet:Z -Landroid/net/wifi/aware/SubscribeConfig$Builder;->mServiceName:[B -Landroid/net/wifi/aware/SubscribeConfig$Builder;->mServiceSpecificInfo:[B -Landroid/net/wifi/aware/SubscribeConfig$Builder;->mSubscribeType:I -Landroid/net/wifi/aware/SubscribeConfig$Builder;->mTtlSec:I -Landroid/net/wifi/aware/SubscribeConfig;-><init>([B[B[BIIZZIZI)V -Landroid/net/wifi/aware/SubscribeConfig;->assertValid(Landroid/net/wifi/aware/Characteristics;Z)V -Landroid/net/wifi/aware/SubscribeConfig;->mEnableTerminateNotification:Z -Landroid/net/wifi/aware/SubscribeConfig;->mMatchFilter:[B -Landroid/net/wifi/aware/SubscribeConfig;->mMaxDistanceMm:I -Landroid/net/wifi/aware/SubscribeConfig;->mMaxDistanceMmSet:Z -Landroid/net/wifi/aware/SubscribeConfig;->mMinDistanceMm:I -Landroid/net/wifi/aware/SubscribeConfig;->mMinDistanceMmSet:Z -Landroid/net/wifi/aware/SubscribeConfig;->mServiceName:[B -Landroid/net/wifi/aware/SubscribeConfig;->mServiceSpecificInfo:[B -Landroid/net/wifi/aware/SubscribeConfig;->mSubscribeType:I -Landroid/net/wifi/aware/SubscribeConfig;->mTtlSec:I -Landroid/net/wifi/aware/SubscribeDiscoverySession;-><init>(Landroid/net/wifi/aware/WifiAwareManager;II)V -Landroid/net/wifi/aware/SubscribeDiscoverySession;->TAG:Ljava/lang/String; -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;-><init>(II)V -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->addHeader(II)V -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->allocate(I)Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor; -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->allocateAndPut(Ljava/util/List;)Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor; -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->checkLength(I)V -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->getActualLength()I -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->getArray()[B -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->mArray:[B -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->mArrayLength:I -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->mLengthSize:I -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->mPosition:I -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->mTypeSize:I -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->putByte(IB)Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor; -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->putByteArray(I[B)Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor; -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->putByteArray(I[BII)Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor; -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->putInt(II)Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor; -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->putShort(IS)Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor; -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->putString(ILjava/lang/String;)Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor; -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->putZeroLengthElement(I)Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor; -Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor;->wrap([B)Landroid/net/wifi/aware/TlvBufferUtils$TlvConstructor; -Landroid/net/wifi/aware/TlvBufferUtils$TlvElement;-><init>(II[BI)V -Landroid/net/wifi/aware/TlvBufferUtils$TlvElement;->getByte()B -Landroid/net/wifi/aware/TlvBufferUtils$TlvElement;->getInt()I -Landroid/net/wifi/aware/TlvBufferUtils$TlvElement;->getShort()S -Landroid/net/wifi/aware/TlvBufferUtils$TlvElement;->getString()Ljava/lang/String; -Landroid/net/wifi/aware/TlvBufferUtils$TlvElement;->length:I -Landroid/net/wifi/aware/TlvBufferUtils$TlvElement;->offset:I -Landroid/net/wifi/aware/TlvBufferUtils$TlvElement;->refArray:[B -Landroid/net/wifi/aware/TlvBufferUtils$TlvElement;->type:I -Landroid/net/wifi/aware/TlvBufferUtils$TlvIterable;-><init>(II[B)V -Landroid/net/wifi/aware/TlvBufferUtils$TlvIterable;->mArray:[B -Landroid/net/wifi/aware/TlvBufferUtils$TlvIterable;->mArrayLength:I -Landroid/net/wifi/aware/TlvBufferUtils$TlvIterable;->mLengthSize:I -Landroid/net/wifi/aware/TlvBufferUtils$TlvIterable;->mTypeSize:I -Landroid/net/wifi/aware/TlvBufferUtils$TlvIterable;->toList()Ljava/util/List; -Landroid/net/wifi/aware/TlvBufferUtils;-><init>()V -Landroid/net/wifi/aware/TlvBufferUtils;->isValid([BII)Z -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier$ByteArrayWrapper;-><init>([B)V -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier$ByteArrayWrapper;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier$ByteArrayWrapper;->mData:[B -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier;-><init>()V -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier;-><init>(Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;)V -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier;-><init>([Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;)V -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier;->assertValidFromUid(I)V -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier;->convert(Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;)Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier$ByteArrayWrapper; -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier;->initialize()V -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier;->isEmpty()Z -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier;->mDigester:Ljava/security/MessageDigest; -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier;->mNetworkSpecifiers:Ljava/util/Set; -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier;->satisfiedBy(Landroid/net/NetworkSpecifier;)Z -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier;->satisfiesAwareNetworkSpecifier(Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;)Z -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier;->TAG:Ljava/lang/String; -Landroid/net/wifi/aware/WifiAwareAgentNetworkSpecifier;->VDBG:Z -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;-><init>(Landroid/net/wifi/aware/WifiAwareManager;Landroid/os/Looper;ZLandroid/net/wifi/aware/DiscoverySessionCallback;I)V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->CALLBACK_MATCH:I -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->CALLBACK_MATCH_WITH_DISTANCE:I -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->CALLBACK_MESSAGE_RECEIVED:I -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->CALLBACK_MESSAGE_SEND_FAIL:I -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->CALLBACK_MESSAGE_SEND_SUCCESS:I -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->CALLBACK_SESSION_CONFIG_FAIL:I -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->CALLBACK_SESSION_CONFIG_SUCCESS:I -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->CALLBACK_SESSION_STARTED:I -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->CALLBACK_SESSION_TERMINATED:I -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->mAwareManager:Ljava/lang/ref/WeakReference; -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->mClientId:I -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->MESSAGE_BUNDLE_KEY_MESSAGE2:Ljava/lang/String; -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->MESSAGE_BUNDLE_KEY_MESSAGE:Ljava/lang/String; -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->mHandler:Landroid/os/Handler; -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->mIsPublish:Z -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->mOriginalCallback:Landroid/net/wifi/aware/DiscoverySessionCallback; -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->mSession:Landroid/net/wifi/aware/DiscoverySession; -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->onMatch(I[B[B)V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->onMatchCommon(II[B[BI)V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->onMatchWithDistance(I[B[BI)V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->onMessageReceived(I[B)V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->onMessageSendFail(II)V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->onMessageSendSuccess(I)V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->onProxySessionStarted(I)V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->onProxySessionTerminated(I)V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->onSessionConfigFail(I)V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->onSessionConfigSuccess()V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->onSessionStarted(I)V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareDiscoverySessionCallbackProxy;->onSessionTerminated(I)V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareEventCallbackProxy;-><init>(Landroid/net/wifi/aware/WifiAwareManager;Landroid/os/Looper;Landroid/os/Binder;Landroid/net/wifi/aware/AttachCallback;Landroid/net/wifi/aware/IdentityChangedListener;)V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareEventCallbackProxy;->CALLBACK_CONNECT_FAIL:I -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareEventCallbackProxy;->CALLBACK_CONNECT_SUCCESS:I -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareEventCallbackProxy;->CALLBACK_IDENTITY_CHANGED:I -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareEventCallbackProxy;->mAwareManager:Ljava/lang/ref/WeakReference; -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareEventCallbackProxy;->mBinder:Landroid/os/Binder; -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareEventCallbackProxy;->mHandler:Landroid/os/Handler; -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareEventCallbackProxy;->mLooper:Landroid/os/Looper; -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareEventCallbackProxy;->onConnectFail(I)V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareEventCallbackProxy;->onConnectSuccess(I)V -Landroid/net/wifi/aware/WifiAwareManager$WifiAwareEventCallbackProxy;->onIdentityChanged([B)V -Landroid/net/wifi/aware/WifiAwareManager;-><init>(Landroid/content/Context;Landroid/net/wifi/aware/IWifiAwareManager;)V -Landroid/net/wifi/aware/WifiAwareManager;->attach(Landroid/os/Handler;Landroid/net/wifi/aware/ConfigRequest;Landroid/net/wifi/aware/AttachCallback;Landroid/net/wifi/aware/IdentityChangedListener;)V -Landroid/net/wifi/aware/WifiAwareManager;->createNetworkSpecifier(IIILandroid/net/wifi/aware/PeerHandle;[BLjava/lang/String;)Landroid/net/NetworkSpecifier; -Landroid/net/wifi/aware/WifiAwareManager;->createNetworkSpecifier(II[B[BLjava/lang/String;)Landroid/net/NetworkSpecifier; -Landroid/net/wifi/aware/WifiAwareManager;->DBG:Z -Landroid/net/wifi/aware/WifiAwareManager;->disconnect(ILandroid/os/Binder;)V -Landroid/net/wifi/aware/WifiAwareManager;->mContext:Landroid/content/Context; -Landroid/net/wifi/aware/WifiAwareManager;->mLock:Ljava/lang/Object; -Landroid/net/wifi/aware/WifiAwareManager;->mService:Landroid/net/wifi/aware/IWifiAwareManager; -Landroid/net/wifi/aware/WifiAwareManager;->publish(ILandroid/os/Looper;Landroid/net/wifi/aware/PublishConfig;Landroid/net/wifi/aware/DiscoverySessionCallback;)V -Landroid/net/wifi/aware/WifiAwareManager;->sendMessage(IILandroid/net/wifi/aware/PeerHandle;[BII)V -Landroid/net/wifi/aware/WifiAwareManager;->subscribe(ILandroid/os/Looper;Landroid/net/wifi/aware/SubscribeConfig;Landroid/net/wifi/aware/DiscoverySessionCallback;)V -Landroid/net/wifi/aware/WifiAwareManager;->TAG:Ljava/lang/String; -Landroid/net/wifi/aware/WifiAwareManager;->terminateSession(II)V -Landroid/net/wifi/aware/WifiAwareManager;->updatePublish(IILandroid/net/wifi/aware/PublishConfig;)V -Landroid/net/wifi/aware/WifiAwareManager;->updateSubscribe(IILandroid/net/wifi/aware/SubscribeConfig;)V -Landroid/net/wifi/aware/WifiAwareManager;->VDBG:Z -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;-><init>(IIIII[B[BLjava/lang/String;I)V -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->assertValidFromUid(I)V -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->clientId:I -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->isOutOfBand()Z -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->NETWORK_SPECIFIER_TYPE_IB:I -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->NETWORK_SPECIFIER_TYPE_IB_ANY_PEER:I -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->NETWORK_SPECIFIER_TYPE_MAX_VALID:I -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->NETWORK_SPECIFIER_TYPE_OOB:I -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER:I -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->passphrase:Ljava/lang/String; -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->peerId:I -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->peerMac:[B -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->pmk:[B -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->requestorUid:I -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->role:I -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->satisfiedBy(Landroid/net/NetworkSpecifier;)Z -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->sessionId:I -Landroid/net/wifi/aware/WifiAwareNetworkSpecifier;->type:I -Landroid/net/wifi/aware/WifiAwareSession;-><init>(Landroid/net/wifi/aware/WifiAwareManager;Landroid/os/Binder;I)V -Landroid/net/wifi/aware/WifiAwareSession;->DBG:Z -Landroid/net/wifi/aware/WifiAwareSession;->getClientId()I -Landroid/net/wifi/aware/WifiAwareSession;->mBinder:Landroid/os/Binder; -Landroid/net/wifi/aware/WifiAwareSession;->mClientId:I -Landroid/net/wifi/aware/WifiAwareSession;->mCloseGuard:Ldalvik/system/CloseGuard; -Landroid/net/wifi/aware/WifiAwareSession;->mMgr:Ljava/lang/ref/WeakReference; -Landroid/net/wifi/aware/WifiAwareSession;->mTerminated:Z -Landroid/net/wifi/aware/WifiAwareSession;->TAG:Ljava/lang/String; -Landroid/net/wifi/aware/WifiAwareSession;->VDBG:Z -Landroid/net/wifi/aware/WifiAwareUtils;-><init>()V -Landroid/net/wifi/aware/WifiAwareUtils;->isLegacyVersion(Landroid/content/Context;I)Z -Landroid/net/wifi/aware/WifiAwareUtils;->validatePassphrase(Ljava/lang/String;)Z -Landroid/net/wifi/aware/WifiAwareUtils;->validatePmk([B)Z -Landroid/net/wifi/aware/WifiAwareUtils;->validateServiceName([B)V -Landroid/net/wifi/BatchedScanResult;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/BatchedScanResult;->TAG:Ljava/lang/String; -Landroid/net/wifi/EAPConstants;-><init>()V -Landroid/net/wifi/EAPConstants;->EAP_3Com:I -Landroid/net/wifi/EAPConstants;->EAP_ActiontecWireless:I -Landroid/net/wifi/EAPConstants;->EAP_AKA:I -Landroid/net/wifi/EAPConstants;->EAP_AKA_PRIME:I -Landroid/net/wifi/EAPConstants;->EAP_EKE:I -Landroid/net/wifi/EAPConstants;->EAP_FAST:I -Landroid/net/wifi/EAPConstants;->EAP_GPSK:I -Landroid/net/wifi/EAPConstants;->EAP_HTTPDigest:I -Landroid/net/wifi/EAPConstants;->EAP_IKEv2:I -Landroid/net/wifi/EAPConstants;->EAP_KEA:I -Landroid/net/wifi/EAPConstants;->EAP_KEA_VALIDATE:I -Landroid/net/wifi/EAPConstants;->EAP_LEAP:I -Landroid/net/wifi/EAPConstants;->EAP_Link:I -Landroid/net/wifi/EAPConstants;->EAP_MD5:I -Landroid/net/wifi/EAPConstants;->EAP_MOBAC:I -Landroid/net/wifi/EAPConstants;->EAP_MSCHAPv2:I -Landroid/net/wifi/EAPConstants;->EAP_OTP:I -Landroid/net/wifi/EAPConstants;->EAP_PAX:I -Landroid/net/wifi/EAPConstants;->EAP_PEAP:I -Landroid/net/wifi/EAPConstants;->EAP_POTP:I -Landroid/net/wifi/EAPConstants;->EAP_PSK:I -Landroid/net/wifi/EAPConstants;->EAP_PWD:I -Landroid/net/wifi/EAPConstants;->EAP_RSA:I -Landroid/net/wifi/EAPConstants;->EAP_SAKE:I -Landroid/net/wifi/EAPConstants;->EAP_SIM:I -Landroid/net/wifi/EAPConstants;->EAP_SPEKE:I -Landroid/net/wifi/EAPConstants;->EAP_TEAP:I -Landroid/net/wifi/EAPConstants;->EAP_TLS:I -Landroid/net/wifi/EAPConstants;->EAP_TTLS:I -Landroid/net/wifi/EAPConstants;->EAP_ZLXEAP:I -Landroid/net/wifi/hotspot2/ConfigParser$MimeHeader;-><init>()V -Landroid/net/wifi/hotspot2/ConfigParser$MimeHeader;->boundary:Ljava/lang/String; -Landroid/net/wifi/hotspot2/ConfigParser$MimeHeader;->contentType:Ljava/lang/String; -Landroid/net/wifi/hotspot2/ConfigParser$MimeHeader;->encodingType:Ljava/lang/String; -Landroid/net/wifi/hotspot2/ConfigParser$MimePart;-><init>()V -Landroid/net/wifi/hotspot2/ConfigParser$MimePart;->data:[B -Landroid/net/wifi/hotspot2/ConfigParser$MimePart;->isLast:Z -Landroid/net/wifi/hotspot2/ConfigParser$MimePart;->type:Ljava/lang/String; -Landroid/net/wifi/hotspot2/ConfigParser;-><init>()V -Landroid/net/wifi/hotspot2/ConfigParser;->BOUNDARY:Ljava/lang/String; -Landroid/net/wifi/hotspot2/ConfigParser;->CONTENT_TRANSFER_ENCODING:Ljava/lang/String; -Landroid/net/wifi/hotspot2/ConfigParser;->CONTENT_TYPE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/ConfigParser;->createPasspointConfig(Ljava/util/Map;)Landroid/net/wifi/hotspot2/PasspointConfiguration; -Landroid/net/wifi/hotspot2/ConfigParser;->ENCODING_BASE64:Ljava/lang/String; -Landroid/net/wifi/hotspot2/ConfigParser;->parseCACert([B)Ljava/security/cert/X509Certificate; -Landroid/net/wifi/hotspot2/ConfigParser;->parseContentType(Ljava/lang/String;)Landroid/util/Pair; -Landroid/net/wifi/hotspot2/ConfigParser;->parseHeaders(Ljava/io/LineNumberReader;)Landroid/net/wifi/hotspot2/ConfigParser$MimeHeader; -Landroid/net/wifi/hotspot2/ConfigParser;->parseMimeMultipartMessage(Ljava/io/LineNumberReader;)Ljava/util/Map; -Landroid/net/wifi/hotspot2/ConfigParser;->parseMimePart(Ljava/io/LineNumberReader;Ljava/lang/String;)Landroid/net/wifi/hotspot2/ConfigParser$MimePart; -Landroid/net/wifi/hotspot2/ConfigParser;->parsePkcs12([B)Landroid/util/Pair; -Landroid/net/wifi/hotspot2/ConfigParser;->readHeaders(Ljava/io/LineNumberReader;)Ljava/util/Map; -Landroid/net/wifi/hotspot2/ConfigParser;->TAG:Ljava/lang/String; -Landroid/net/wifi/hotspot2/ConfigParser;->TYPE_CA_CERT:Ljava/lang/String; -Landroid/net/wifi/hotspot2/ConfigParser;->TYPE_MULTIPART_MIXED:Ljava/lang/String; -Landroid/net/wifi/hotspot2/ConfigParser;->TYPE_PASSPOINT_PROFILE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/ConfigParser;->TYPE_PKCS12:Ljava/lang/String; -Landroid/net/wifi/hotspot2/ConfigParser;->TYPE_WIFI_CONFIG:Ljava/lang/String; -Landroid/net/wifi/hotspot2/IProvisioningCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/net/wifi/hotspot2/IProvisioningCallback$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String; -Landroid/net/wifi/hotspot2/IProvisioningCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder; -Landroid/net/wifi/hotspot2/IProvisioningCallback$Stub$Proxy;->onProvisioningFailure(I)V -Landroid/net/wifi/hotspot2/IProvisioningCallback$Stub$Proxy;->onProvisioningStatus(I)V -Landroid/net/wifi/hotspot2/IProvisioningCallback$Stub;-><init>()V -Landroid/net/wifi/hotspot2/IProvisioningCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/hotspot2/IProvisioningCallback; -Landroid/net/wifi/hotspot2/IProvisioningCallback$Stub;->DESCRIPTOR:Ljava/lang/String; -Landroid/net/wifi/hotspot2/IProvisioningCallback$Stub;->TRANSACTION_onProvisioningFailure:I -Landroid/net/wifi/hotspot2/IProvisioningCallback$Stub;->TRANSACTION_onProvisioningStatus:I -Landroid/net/wifi/hotspot2/IProvisioningCallback;->onProvisioningFailure(I)V -Landroid/net/wifi/hotspot2/IProvisioningCallback;->onProvisioningStatus(I)V -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$InternalNode;-><init>(Ljava/lang/String;Ljava/util/List;)V -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$InternalNode;->getChildren()Ljava/util/List; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$InternalNode;->getValue()Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$InternalNode;->isLeaf()Z -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$InternalNode;->mChildren:Ljava/util/List; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$LeafNode;-><init>(Ljava/lang/String;Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$LeafNode;->getChildren()Ljava/util/List; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$LeafNode;->getValue()Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$LeafNode;->isLeaf()Z -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$LeafNode;->mValue:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$ParsingException;-><init>(Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;-><init>(Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;->getChildren()Ljava/util/List; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;->getName()Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;->getValue()Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;->isLeaf()Z -Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;->mName:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;-><init>()V -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->buildPpsNode(Landroid/net/wifi/hotspot2/omadm/XMLNode;)Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->convertFromLongList(Ljava/util/List;)[J -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->getPpsNodeValue(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_AAA_SERVER_TRUST_ROOT:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_ABLE_TO_SHARE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_CERTIFICATE_TYPE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_CERT_SHA256_FINGERPRINT:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_CERT_URL:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_CHECK_AAA_SERVER_CERT_STATUS:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_COUNTRY:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_CREATION_DATE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_CREDENTIAL:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_CREDENTIAL_PRIORITY:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_DATA_LIMIT:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_DIGITAL_CERTIFICATE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_DOWNLINK_BANDWIDTH:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_EAP_METHOD:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_EAP_TYPE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_EXPIRATION_DATE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_EXTENSION:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_FQDN:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_FQDN_MATCH:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_FRIENDLY_NAME:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_HESSID:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_HOMESP:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_HOME_OI:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_HOME_OI_LIST:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_HOME_OI_REQUIRED:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_ICON_URL:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_INNER_EAP_TYPE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_INNER_METHOD:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_INNER_VENDOR_ID:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_INNER_VENDOR_TYPE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_IP_PROTOCOL:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_MACHINE_MANAGED:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_MAXIMUM_BSS_LOAD_VALUE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_MIN_BACKHAUL_THRESHOLD:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_NETWORK_ID:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_NETWORK_TYPE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_OTHER:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_OTHER_HOME_PARTNERS:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_PASSWORD:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_PER_PROVIDER_SUBSCRIPTION:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_POLICY:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_POLICY_UPDATE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_PORT_NUMBER:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_PREFERRED_ROAMING_PARTNER_LIST:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_PRIORITY:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_REALM:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_REQUIRED_PROTO_PORT_TUPLE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_RESTRICTION:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_ROAMING_CONSORTIUM_OI:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_SIM:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_SIM_IMSI:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_SOFT_TOKEN_APP:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_SP_EXCLUSION_LIST:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_SSID:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_START_DATE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_SUBSCRIPTION_PARAMETER:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_SUBSCRIPTION_UPDATE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_TIME_LIMIT:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_TRUST_ROOT:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_TYPE_OF_SUBSCRIPTION:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_UPDATE_IDENTIFIER:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_UPDATE_INTERVAL:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_UPDATE_METHOD:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_UPLINK_BANDWIDTH:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_URI:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_USAGE_LIMITS:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_USAGE_TIME_PERIOD:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_USERNAME:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_USERNAME_PASSWORD:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_VENDOR_ID:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->NODE_VENDOR_TYPE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseAAAServerTrustRootList(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Ljava/util/Map; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseCertificateCredential(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Landroid/net/wifi/hotspot2/pps/Credential$CertificateCredential; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseCredential(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Landroid/net/wifi/hotspot2/pps/Credential; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseDate(Ljava/lang/String;)J -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseEAPMethod(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;)V -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseHexString(Ljava/lang/String;)[B -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseHomeOIInstance(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Landroid/util/Pair; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseHomeOIList(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Landroid/util/Pair; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseHomeSP(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Landroid/net/wifi/hotspot2/pps/HomeSp; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseInteger(Ljava/lang/String;)I -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseLong(Ljava/lang/String;I)J -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseMinBackhaulThreshold(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;Landroid/net/wifi/hotspot2/pps/Policy;)V -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseMinBackhaulThresholdInstance(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;Landroid/net/wifi/hotspot2/pps/Policy;)V -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseNetworkIdInstance(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Landroid/util/Pair; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseNetworkIds(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Ljava/util/Map; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseOtherHomePartnerInstance(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseOtherHomePartners(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)[Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parsePolicy(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Landroid/net/wifi/hotspot2/pps/Policy; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parsePpsInstance(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Landroid/net/wifi/hotspot2/PasspointConfiguration; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parsePpsNode(Landroid/net/wifi/hotspot2/omadm/XMLNode;)Landroid/net/wifi/hotspot2/PasspointConfiguration; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parsePreferredRoamingPartner(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parsePreferredRoamingPartnerList(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Ljava/util/List; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseProtoPortTuple(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Landroid/util/Pair; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseRequiredProtoPortTuple(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Ljava/util/Map; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseRoamingConsortiumOI(Ljava/lang/String;)[J -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseSimCredential(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Landroid/net/wifi/hotspot2/pps/Credential$SimCredential; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseSpExclusionInstance(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseSpExclusionList(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)[Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseSubscriptionParameter(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;Landroid/net/wifi/hotspot2/PasspointConfiguration;)V -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseTrustRoot(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Landroid/util/Pair; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseUpdateParameter(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Landroid/net/wifi/hotspot2/pps/UpdateParameter; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseUpdateUserCredential(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Landroid/util/Pair; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseUrn(Landroid/net/wifi/hotspot2/omadm/XMLNode;)Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseUsageLimits(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;Landroid/net/wifi/hotspot2/PasspointConfiguration;)V -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->parseUserCredential(Landroid/net/wifi/hotspot2/omadm/PpsMoParser$PPSNode;)Landroid/net/wifi/hotspot2/pps/Credential$UserCredential; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->PPS_MO_URN:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->TAG:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->TAG_DDF_NAME:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->TAG_MANAGEMENT_TREE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->TAG_NODE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->TAG_NODE_NAME:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->TAG_RT_PROPERTIES:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->TAG_TYPE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->TAG_VALUE:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/PpsMoParser;->TAG_VER_DTD:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/XMLNode;-><init>(Landroid/net/wifi/hotspot2/omadm/XMLNode;Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/omadm/XMLNode;->addChild(Landroid/net/wifi/hotspot2/omadm/XMLNode;)V -Landroid/net/wifi/hotspot2/omadm/XMLNode;->addText(Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/omadm/XMLNode;->close()V -Landroid/net/wifi/hotspot2/omadm/XMLNode;->getChildren()Ljava/util/List; -Landroid/net/wifi/hotspot2/omadm/XMLNode;->getParent()Landroid/net/wifi/hotspot2/omadm/XMLNode; -Landroid/net/wifi/hotspot2/omadm/XMLNode;->getTag()Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/XMLNode;->getText()Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/XMLNode;->mChildren:Ljava/util/List; -Landroid/net/wifi/hotspot2/omadm/XMLNode;->mParent:Landroid/net/wifi/hotspot2/omadm/XMLNode; -Landroid/net/wifi/hotspot2/omadm/XMLNode;->mTag:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/XMLNode;->mText:Ljava/lang/String; -Landroid/net/wifi/hotspot2/omadm/XMLNode;->mTextBuilder:Ljava/lang/StringBuilder; -Landroid/net/wifi/hotspot2/omadm/XMLParser;-><init>()V -Landroid/net/wifi/hotspot2/omadm/XMLParser;->mCurrent:Landroid/net/wifi/hotspot2/omadm/XMLNode; -Landroid/net/wifi/hotspot2/omadm/XMLParser;->mRoot:Landroid/net/wifi/hotspot2/omadm/XMLNode; -Landroid/net/wifi/hotspot2/omadm/XMLParser;->parse(Ljava/lang/String;)Landroid/net/wifi/hotspot2/omadm/XMLNode; -Landroid/net/wifi/hotspot2/OsuProvider;-><init>(Landroid/net/wifi/hotspot2/OsuProvider;)V -Landroid/net/wifi/hotspot2/OsuProvider;-><init>(Landroid/net/wifi/WifiSsid;Ljava/lang/String;Ljava/lang/String;Landroid/net/Uri;Ljava/lang/String;Ljava/util/List;Landroid/graphics/drawable/Icon;)V -Landroid/net/wifi/hotspot2/OsuProvider;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/hotspot2/OsuProvider;->getFriendlyName()Ljava/lang/String; -Landroid/net/wifi/hotspot2/OsuProvider;->getIcon()Landroid/graphics/drawable/Icon; -Landroid/net/wifi/hotspot2/OsuProvider;->getMethodList()Ljava/util/List; -Landroid/net/wifi/hotspot2/OsuProvider;->getNetworkAccessIdentifier()Ljava/lang/String; -Landroid/net/wifi/hotspot2/OsuProvider;->getOsuSsid()Landroid/net/wifi/WifiSsid; -Landroid/net/wifi/hotspot2/OsuProvider;->getServerUri()Landroid/net/Uri; -Landroid/net/wifi/hotspot2/OsuProvider;->getServiceDescription()Ljava/lang/String; -Landroid/net/wifi/hotspot2/OsuProvider;->METHOD_OMA_DM:I -Landroid/net/wifi/hotspot2/OsuProvider;->METHOD_SOAP_XML_SPP:I -Landroid/net/wifi/hotspot2/OsuProvider;->mFriendlyName:Ljava/lang/String; -Landroid/net/wifi/hotspot2/OsuProvider;->mIcon:Landroid/graphics/drawable/Icon; -Landroid/net/wifi/hotspot2/OsuProvider;->mMethodList:Ljava/util/List; -Landroid/net/wifi/hotspot2/OsuProvider;->mNetworkAccessIdentifier:Ljava/lang/String; -Landroid/net/wifi/hotspot2/OsuProvider;->mOsuSsid:Landroid/net/wifi/WifiSsid; -Landroid/net/wifi/hotspot2/OsuProvider;->mServerUri:Landroid/net/Uri; -Landroid/net/wifi/hotspot2/OsuProvider;->mServiceDescription:Ljava/lang/String; -Landroid/net/wifi/hotspot2/PasspointConfiguration;->CERTIFICATE_SHA256_BYTES:I -Landroid/net/wifi/hotspot2/PasspointConfiguration;->getCredentialPriority()I -Landroid/net/wifi/hotspot2/PasspointConfiguration;->getPolicy()Landroid/net/wifi/hotspot2/pps/Policy; -Landroid/net/wifi/hotspot2/PasspointConfiguration;->getSubscriptionCreationTimeInMillis()J -Landroid/net/wifi/hotspot2/PasspointConfiguration;->getSubscriptionExpirationTimeInMillis()J -Landroid/net/wifi/hotspot2/PasspointConfiguration;->getSubscriptionType()Ljava/lang/String; -Landroid/net/wifi/hotspot2/PasspointConfiguration;->getSubscriptionUpdate()Landroid/net/wifi/hotspot2/pps/UpdateParameter; -Landroid/net/wifi/hotspot2/PasspointConfiguration;->getTrustRootCertList()Ljava/util/Map; -Landroid/net/wifi/hotspot2/PasspointConfiguration;->getUpdateIdentifier()I -Landroid/net/wifi/hotspot2/PasspointConfiguration;->getUsageLimitDataLimit()J -Landroid/net/wifi/hotspot2/PasspointConfiguration;->getUsageLimitStartTimeInMillis()J -Landroid/net/wifi/hotspot2/PasspointConfiguration;->getUsageLimitTimeLimitInMinutes()J -Landroid/net/wifi/hotspot2/PasspointConfiguration;->getUsageLimitUsageTimePeriodInMinutes()J -Landroid/net/wifi/hotspot2/PasspointConfiguration;->isTrustRootCertListEquals(Ljava/util/Map;Ljava/util/Map;)Z -Landroid/net/wifi/hotspot2/PasspointConfiguration;->MAX_URL_BYTES:I -Landroid/net/wifi/hotspot2/PasspointConfiguration;->mCredential:Landroid/net/wifi/hotspot2/pps/Credential; -Landroid/net/wifi/hotspot2/PasspointConfiguration;->mCredentialPriority:I -Landroid/net/wifi/hotspot2/PasspointConfiguration;->mHomeSp:Landroid/net/wifi/hotspot2/pps/HomeSp; -Landroid/net/wifi/hotspot2/PasspointConfiguration;->mPolicy:Landroid/net/wifi/hotspot2/pps/Policy; -Landroid/net/wifi/hotspot2/PasspointConfiguration;->mSubscriptionCreationTimeInMillis:J -Landroid/net/wifi/hotspot2/PasspointConfiguration;->mSubscriptionExpirationTimeInMillis:J -Landroid/net/wifi/hotspot2/PasspointConfiguration;->mSubscriptionType:Ljava/lang/String; -Landroid/net/wifi/hotspot2/PasspointConfiguration;->mSubscriptionUpdate:Landroid/net/wifi/hotspot2/pps/UpdateParameter; -Landroid/net/wifi/hotspot2/PasspointConfiguration;->mTrustRootCertList:Ljava/util/Map; -Landroid/net/wifi/hotspot2/PasspointConfiguration;->mUpdateIdentifier:I -Landroid/net/wifi/hotspot2/PasspointConfiguration;->mUsageLimitDataLimit:J -Landroid/net/wifi/hotspot2/PasspointConfiguration;->mUsageLimitStartTimeInMillis:J -Landroid/net/wifi/hotspot2/PasspointConfiguration;->mUsageLimitTimeLimitInMinutes:J -Landroid/net/wifi/hotspot2/PasspointConfiguration;->mUsageLimitUsageTimePeriodInMinutes:J -Landroid/net/wifi/hotspot2/PasspointConfiguration;->NULL_VALUE:I -Landroid/net/wifi/hotspot2/PasspointConfiguration;->setCredentialPriority(I)V -Landroid/net/wifi/hotspot2/PasspointConfiguration;->setPolicy(Landroid/net/wifi/hotspot2/pps/Policy;)V -Landroid/net/wifi/hotspot2/PasspointConfiguration;->setSubscriptionCreationTimeInMillis(J)V -Landroid/net/wifi/hotspot2/PasspointConfiguration;->setSubscriptionExpirationTimeInMillis(J)V -Landroid/net/wifi/hotspot2/PasspointConfiguration;->setSubscriptionType(Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/PasspointConfiguration;->setSubscriptionUpdate(Landroid/net/wifi/hotspot2/pps/UpdateParameter;)V -Landroid/net/wifi/hotspot2/PasspointConfiguration;->setTrustRootCertList(Ljava/util/Map;)V -Landroid/net/wifi/hotspot2/PasspointConfiguration;->setUpdateIdentifier(I)V -Landroid/net/wifi/hotspot2/PasspointConfiguration;->setUsageLimitDataLimit(J)V -Landroid/net/wifi/hotspot2/PasspointConfiguration;->setUsageLimitStartTimeInMillis(J)V -Landroid/net/wifi/hotspot2/PasspointConfiguration;->setUsageLimitTimeLimitInMinutes(J)V -Landroid/net/wifi/hotspot2/PasspointConfiguration;->setUsageLimitUsageTimePeriodInMinutes(J)V -Landroid/net/wifi/hotspot2/PasspointConfiguration;->TAG:Ljava/lang/String; -Landroid/net/wifi/hotspot2/PasspointConfiguration;->validate()Z -Landroid/net/wifi/hotspot2/PasspointConfiguration;->writeTrustRootCerts(Landroid/os/Parcel;Ljava/util/Map;)V -Landroid/net/wifi/hotspot2/pps/Credential$CertificateCredential;->CERT_SHA256_FINGER_PRINT_LENGTH:I -Landroid/net/wifi/hotspot2/pps/Credential$CertificateCredential;->CERT_TYPE_X509V3:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Credential$CertificateCredential;->mCertSha256Fingerprint:[B -Landroid/net/wifi/hotspot2/pps/Credential$CertificateCredential;->mCertType:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Credential$CertificateCredential;->validate()Z -Landroid/net/wifi/hotspot2/pps/Credential$SimCredential;->MAX_IMSI_LENGTH:I -Landroid/net/wifi/hotspot2/pps/Credential$SimCredential;->mEapType:I -Landroid/net/wifi/hotspot2/pps/Credential$SimCredential;->mImsi:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Credential$SimCredential;->validate()Z -Landroid/net/wifi/hotspot2/pps/Credential$SimCredential;->verifyImsi()Z -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->AUTH_METHOD_MSCHAP:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->AUTH_METHOD_MSCHAPV2:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->AUTH_METHOD_PAP:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->getAbleToShare()Z -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->getMachineManaged()Z -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->getSoftTokenApp()Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->mAbleToShare:Z -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->MAX_PASSWORD_BYTES:I -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->MAX_USERNAME_BYTES:I -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->mEapType:I -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->mMachineManaged:Z -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->mNonEapInnerMethod:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->mPassword:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->mSoftTokenApp:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->mUsername:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->setAbleToShare(Z)V -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->setMachineManaged(Z)V -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->setSoftTokenApp(Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->SUPPORTED_AUTH:Ljava/util/Set; -Landroid/net/wifi/hotspot2/pps/Credential$UserCredential;->validate()Z -Landroid/net/wifi/hotspot2/pps/Credential;->getCheckAaaServerCertStatus()Z -Landroid/net/wifi/hotspot2/pps/Credential;->getCreationTimeInMillis()J -Landroid/net/wifi/hotspot2/pps/Credential;->getExpirationTimeInMillis()J -Landroid/net/wifi/hotspot2/pps/Credential;->isPrivateKeyEquals(Ljava/security/PrivateKey;Ljava/security/PrivateKey;)Z -Landroid/net/wifi/hotspot2/pps/Credential;->isX509CertificateEquals(Ljava/security/cert/X509Certificate;Ljava/security/cert/X509Certificate;)Z -Landroid/net/wifi/hotspot2/pps/Credential;->isX509CertificatesEquals([Ljava/security/cert/X509Certificate;[Ljava/security/cert/X509Certificate;)Z -Landroid/net/wifi/hotspot2/pps/Credential;->MAX_REALM_BYTES:I -Landroid/net/wifi/hotspot2/pps/Credential;->mCaCertificate:Ljava/security/cert/X509Certificate; -Landroid/net/wifi/hotspot2/pps/Credential;->mCertCredential:Landroid/net/wifi/hotspot2/pps/Credential$CertificateCredential; -Landroid/net/wifi/hotspot2/pps/Credential;->mCheckAaaServerCertStatus:Z -Landroid/net/wifi/hotspot2/pps/Credential;->mClientCertificateChain:[Ljava/security/cert/X509Certificate; -Landroid/net/wifi/hotspot2/pps/Credential;->mClientPrivateKey:Ljava/security/PrivateKey; -Landroid/net/wifi/hotspot2/pps/Credential;->mCreationTimeInMillis:J -Landroid/net/wifi/hotspot2/pps/Credential;->mExpirationTimeInMillis:J -Landroid/net/wifi/hotspot2/pps/Credential;->mRealm:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Credential;->mSimCredential:Landroid/net/wifi/hotspot2/pps/Credential$SimCredential; -Landroid/net/wifi/hotspot2/pps/Credential;->mUserCredential:Landroid/net/wifi/hotspot2/pps/Credential$UserCredential; -Landroid/net/wifi/hotspot2/pps/Credential;->setCheckAaaServerCertStatus(Z)V -Landroid/net/wifi/hotspot2/pps/Credential;->setCreationTimeInMillis(J)V -Landroid/net/wifi/hotspot2/pps/Credential;->setExpirationTimeInMillis(J)V -Landroid/net/wifi/hotspot2/pps/Credential;->TAG:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Credential;->validate()Z -Landroid/net/wifi/hotspot2/pps/Credential;->verifyCertCredential()Z -Landroid/net/wifi/hotspot2/pps/Credential;->verifySha256Fingerprint([Ljava/security/cert/X509Certificate;[B)Z -Landroid/net/wifi/hotspot2/pps/Credential;->verifySimCredential()Z -Landroid/net/wifi/hotspot2/pps/Credential;->verifyUserCredential()Z -Landroid/net/wifi/hotspot2/pps/HomeSp;->getHomeNetworkIds()Ljava/util/Map; -Landroid/net/wifi/hotspot2/pps/HomeSp;->getIconUrl()Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/HomeSp;->getMatchAllOis()[J -Landroid/net/wifi/hotspot2/pps/HomeSp;->getMatchAnyOis()[J -Landroid/net/wifi/hotspot2/pps/HomeSp;->getOtherHomePartners()[Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/HomeSp;->MAX_SSID_BYTES:I -Landroid/net/wifi/hotspot2/pps/HomeSp;->mFqdn:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/HomeSp;->mFriendlyName:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/HomeSp;->mHomeNetworkIds:Ljava/util/Map; -Landroid/net/wifi/hotspot2/pps/HomeSp;->mIconUrl:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/HomeSp;->mMatchAllOis:[J -Landroid/net/wifi/hotspot2/pps/HomeSp;->mMatchAnyOis:[J -Landroid/net/wifi/hotspot2/pps/HomeSp;->mOtherHomePartners:[Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/HomeSp;->mRoamingConsortiumOis:[J -Landroid/net/wifi/hotspot2/pps/HomeSp;->NULL_VALUE:I -Landroid/net/wifi/hotspot2/pps/HomeSp;->setHomeNetworkIds(Ljava/util/Map;)V -Landroid/net/wifi/hotspot2/pps/HomeSp;->setIconUrl(Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/pps/HomeSp;->setMatchAllOis([J)V -Landroid/net/wifi/hotspot2/pps/HomeSp;->setMatchAnyOis([J)V -Landroid/net/wifi/hotspot2/pps/HomeSp;->setOtherHomePartners([Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/pps/HomeSp;->TAG:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/HomeSp;->validate()Z -Landroid/net/wifi/hotspot2/pps/HomeSp;->writeHomeNetworkIds(Landroid/os/Parcel;Ljava/util/Map;)V -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;-><init>()V -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;-><init>(Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;)V -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;->getCountries()Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;->getFqdn()Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;->getFqdnExactMatch()Z -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;->getPriority()I -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;->mCountries:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;->mFqdn:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;->mFqdnExactMatch:Z -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;->mPriority:I -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;->setCountries(Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;->setFqdn(Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;->setFqdnExactMatch(Z)V -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;->setPriority(I)V -Landroid/net/wifi/hotspot2/pps/Policy$RoamingPartner;->validate()Z -Landroid/net/wifi/hotspot2/pps/Policy;-><init>()V -Landroid/net/wifi/hotspot2/pps/Policy;-><init>(Landroid/net/wifi/hotspot2/pps/Policy;)V -Landroid/net/wifi/hotspot2/pps/Policy;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/hotspot2/pps/Policy;->getExcludedSsidList()[Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Policy;->getMaximumBssLoadValue()I -Landroid/net/wifi/hotspot2/pps/Policy;->getMinHomeDownlinkBandwidth()J -Landroid/net/wifi/hotspot2/pps/Policy;->getMinHomeUplinkBandwidth()J -Landroid/net/wifi/hotspot2/pps/Policy;->getMinRoamingDownlinkBandwidth()J -Landroid/net/wifi/hotspot2/pps/Policy;->getMinRoamingUplinkBandwidth()J -Landroid/net/wifi/hotspot2/pps/Policy;->getPolicyUpdate()Landroid/net/wifi/hotspot2/pps/UpdateParameter; -Landroid/net/wifi/hotspot2/pps/Policy;->getPreferredRoamingPartnerList()Ljava/util/List; -Landroid/net/wifi/hotspot2/pps/Policy;->getRequiredProtoPortMap()Ljava/util/Map; -Landroid/net/wifi/hotspot2/pps/Policy;->MAX_EXCLUSION_SSIDS:I -Landroid/net/wifi/hotspot2/pps/Policy;->MAX_PORT_STRING_BYTES:I -Landroid/net/wifi/hotspot2/pps/Policy;->MAX_SSID_BYTES:I -Landroid/net/wifi/hotspot2/pps/Policy;->mExcludedSsidList:[Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Policy;->mMaximumBssLoadValue:I -Landroid/net/wifi/hotspot2/pps/Policy;->mMinHomeDownlinkBandwidth:J -Landroid/net/wifi/hotspot2/pps/Policy;->mMinHomeUplinkBandwidth:J -Landroid/net/wifi/hotspot2/pps/Policy;->mMinRoamingDownlinkBandwidth:J -Landroid/net/wifi/hotspot2/pps/Policy;->mMinRoamingUplinkBandwidth:J -Landroid/net/wifi/hotspot2/pps/Policy;->mPolicyUpdate:Landroid/net/wifi/hotspot2/pps/UpdateParameter; -Landroid/net/wifi/hotspot2/pps/Policy;->mPreferredRoamingPartnerList:Ljava/util/List; -Landroid/net/wifi/hotspot2/pps/Policy;->mRequiredProtoPortMap:Ljava/util/Map; -Landroid/net/wifi/hotspot2/pps/Policy;->NULL_VALUE:I -Landroid/net/wifi/hotspot2/pps/Policy;->setExcludedSsidList([Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/pps/Policy;->setMaximumBssLoadValue(I)V -Landroid/net/wifi/hotspot2/pps/Policy;->setMinHomeDownlinkBandwidth(J)V -Landroid/net/wifi/hotspot2/pps/Policy;->setMinHomeUplinkBandwidth(J)V -Landroid/net/wifi/hotspot2/pps/Policy;->setMinRoamingDownlinkBandwidth(J)V -Landroid/net/wifi/hotspot2/pps/Policy;->setMinRoamingUplinkBandwidth(J)V -Landroid/net/wifi/hotspot2/pps/Policy;->setPolicyUpdate(Landroid/net/wifi/hotspot2/pps/UpdateParameter;)V -Landroid/net/wifi/hotspot2/pps/Policy;->setPreferredRoamingPartnerList(Ljava/util/List;)V -Landroid/net/wifi/hotspot2/pps/Policy;->setRequiredProtoPortMap(Ljava/util/Map;)V -Landroid/net/wifi/hotspot2/pps/Policy;->TAG:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/Policy;->validate()Z -Landroid/net/wifi/hotspot2/pps/Policy;->writeProtoPortMap(Landroid/os/Parcel;Ljava/util/Map;)V -Landroid/net/wifi/hotspot2/pps/Policy;->writeRoamingPartnerList(Landroid/os/Parcel;ILjava/util/List;)V -Landroid/net/wifi/hotspot2/pps/UpdateParameter;-><init>()V -Landroid/net/wifi/hotspot2/pps/UpdateParameter;-><init>(Landroid/net/wifi/hotspot2/pps/UpdateParameter;)V -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->CERTIFICATE_SHA256_BYTES:I -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->getBase64EncodedPassword()Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->getRestriction()Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->getServerUri()Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->getTrustRootCertSha256Fingerprint()[B -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->getTrustRootCertUrl()Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->getUpdateIntervalInMinutes()J -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->getUpdateMethod()Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->getUsername()Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->MAX_PASSWORD_BYTES:I -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->MAX_URI_BYTES:I -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->MAX_URL_BYTES:I -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->MAX_USERNAME_BYTES:I -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->mBase64EncodedPassword:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->mRestriction:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->mServerUri:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->mTrustRootCertSha256Fingerprint:[B -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->mTrustRootCertUrl:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->mUpdateIntervalInMinutes:J -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->mUpdateMethod:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->mUsername:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->setBase64EncodedPassword(Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->setRestriction(Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->setServerUri(Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->setTrustRootCertSha256Fingerprint([B)V -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->setTrustRootCertUrl(Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->setUpdateIntervalInMinutes(J)V -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->setUpdateMethod(Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->setUsername(Ljava/lang/String;)V -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->TAG:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->UPDATE_CHECK_INTERVAL_NEVER:J -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->UPDATE_METHOD_OMADM:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->UPDATE_METHOD_SSP:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->UPDATE_RESTRICTION_HOMESP:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->UPDATE_RESTRICTION_ROAMING_PARTNER:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->UPDATE_RESTRICTION_UNRESTRICTED:Ljava/lang/String; -Landroid/net/wifi/hotspot2/pps/UpdateParameter;->validate()Z Landroid/net/wifi/hotspot2/ProvisioningCallback;-><init>()V Landroid/net/wifi/hotspot2/ProvisioningCallback;->onProvisioningFailure(I)V Landroid/net/wifi/hotspot2/ProvisioningCallback;->onProvisioningStatus(I)V @@ -39099,539 +38262,6 @@ Landroid/net/wifi/hotspot2/ProvisioningCallback;->OSU_STATUS_AP_CONNECTING:I Landroid/net/wifi/hotspot2/ProvisioningCallback;->OSU_STATUS_PROVIDER_VERIFIED:I Landroid/net/wifi/hotspot2/ProvisioningCallback;->OSU_STATUS_SERVER_CONNECTED:I Landroid/net/wifi/hotspot2/ProvisioningCallback;->OSU_STATUS_SERVER_VALIDATED:I -Landroid/net/wifi/ISoftApCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/net/wifi/ISoftApCallback$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String; -Landroid/net/wifi/ISoftApCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder; -Landroid/net/wifi/ISoftApCallback$Stub$Proxy;->onNumClientsChanged(I)V -Landroid/net/wifi/ISoftApCallback$Stub$Proxy;->onStateChanged(II)V -Landroid/net/wifi/ISoftApCallback$Stub;-><init>()V -Landroid/net/wifi/ISoftApCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/ISoftApCallback; -Landroid/net/wifi/ISoftApCallback$Stub;->DESCRIPTOR:Ljava/lang/String; -Landroid/net/wifi/ISoftApCallback$Stub;->TRANSACTION_onNumClientsChanged:I -Landroid/net/wifi/ISoftApCallback$Stub;->TRANSACTION_onStateChanged:I -Landroid/net/wifi/ISoftApCallback;->onNumClientsChanged(I)V -Landroid/net/wifi/ISoftApCallback;->onStateChanged(II)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->acquireMulticastLock(Landroid/os/IBinder;Ljava/lang/String;)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->acquireWifiLock(Landroid/os/IBinder;ILjava/lang/String;Landroid/os/WorkSource;)Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->addOrUpdateNetwork(Landroid/net/wifi/WifiConfiguration;Ljava/lang/String;)I -Landroid/net/wifi/IWifiManager$Stub$Proxy;->addOrUpdatePasspointConfiguration(Landroid/net/wifi/hotspot2/PasspointConfiguration;Ljava/lang/String;)Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->deauthenticateNetwork(JZ)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->disableEphemeralNetwork(Ljava/lang/String;Ljava/lang/String;)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->disableNetwork(ILjava/lang/String;)Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->disconnect(Ljava/lang/String;)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->enableNetwork(IZLjava/lang/String;)Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->enableTdls(Ljava/lang/String;Z)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->enableTdlsWithMacAddress(Ljava/lang/String;Z)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->enableVerboseLogging(I)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->enableWifiConnectivityManager(Z)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->factoryReset(Ljava/lang/String;)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getAllMatchingWifiConfigs(Landroid/net/wifi/ScanResult;)Ljava/util/List; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getConfiguredNetworks()Landroid/content/pm/ParceledListSlice; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getConnectionInfo(Ljava/lang/String;)Landroid/net/wifi/WifiInfo; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getCountryCode()Ljava/lang/String; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getCurrentNetwork()Landroid/net/Network; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getCurrentNetworkWpsNfcConfigurationToken()Ljava/lang/String; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getDhcpInfo()Landroid/net/DhcpInfo; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getMatchingOsuProviders(Landroid/net/wifi/ScanResult;)Ljava/util/List; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getMatchingWifiConfig(Landroid/net/wifi/ScanResult;)Landroid/net/wifi/WifiConfiguration; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getPasspointConfigurations()Ljava/util/List; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getPrivilegedConfiguredNetworks()Landroid/content/pm/ParceledListSlice; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getScanResults(Ljava/lang/String;)Ljava/util/List; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getSupportedFeatures()I -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getVerboseLoggingLevel()I -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getWifiApConfiguration()Landroid/net/wifi/WifiConfiguration; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getWifiApEnabledState()I -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getWifiEnabledState()I -Landroid/net/wifi/IWifiManager$Stub$Proxy;->getWifiServiceMessenger(Ljava/lang/String;)Landroid/os/Messenger; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->initializeMulticastFiltering()V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->isDualBandSupported()Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->isMulticastEnabled()Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->isScanAlwaysAvailable()Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->matchProviderWithCurrentNetwork(Ljava/lang/String;)I -Landroid/net/wifi/IWifiManager$Stub$Proxy;->mRemote:Landroid/os/IBinder; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->needs5GHzToAnyApBandConversion()Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->queryPasspointIcon(JLjava/lang/String;)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->reassociate(Ljava/lang/String;)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->reconnect(Ljava/lang/String;)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->registerSoftApCallback(Landroid/os/IBinder;Landroid/net/wifi/ISoftApCallback;I)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->releaseMulticastLock()V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->releaseWifiLock(Landroid/os/IBinder;)Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->removeNetwork(ILjava/lang/String;)Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->removePasspointConfiguration(Ljava/lang/String;Ljava/lang/String;)Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->reportActivityInfo()Landroid/net/wifi/WifiActivityEnergyInfo; -Landroid/net/wifi/IWifiManager$Stub$Proxy;->requestActivityInfo(Landroid/os/ResultReceiver;)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->restoreBackupData([B)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->restoreSupplicantBackupData([B[B)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->retrieveBackupData()[B -Landroid/net/wifi/IWifiManager$Stub$Proxy;->setCountryCode(Ljava/lang/String;)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->setWifiApConfiguration(Landroid/net/wifi/WifiConfiguration;Ljava/lang/String;)Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->setWifiEnabled(Ljava/lang/String;Z)Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->startLocalOnlyHotspot(Landroid/os/Messenger;Landroid/os/IBinder;Ljava/lang/String;)I -Landroid/net/wifi/IWifiManager$Stub$Proxy;->startScan(Ljava/lang/String;)Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->startSoftAp(Landroid/net/wifi/WifiConfiguration;)Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->startSubscriptionProvisioning(Landroid/net/wifi/hotspot2/OsuProvider;Landroid/net/wifi/hotspot2/IProvisioningCallback;)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->startWatchLocalOnlyHotspot(Landroid/os/Messenger;Landroid/os/IBinder;)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->stopLocalOnlyHotspot()V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->stopSoftAp()Z -Landroid/net/wifi/IWifiManager$Stub$Proxy;->stopWatchLocalOnlyHotspot()V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->unregisterSoftApCallback(I)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->updateInterfaceIpState(Ljava/lang/String;I)V -Landroid/net/wifi/IWifiManager$Stub$Proxy;->updateWifiLockWorkSource(Landroid/os/IBinder;Landroid/os/WorkSource;)V -Landroid/net/wifi/IWifiManager$Stub;->DESCRIPTOR:Ljava/lang/String; -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_acquireMulticastLock:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_acquireWifiLock:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_addOrUpdateNetwork:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_addOrUpdatePasspointConfiguration:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_deauthenticateNetwork:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_disableEphemeralNetwork:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_disableNetwork:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_disconnect:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_enableNetwork:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_enableTdls:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_enableTdlsWithMacAddress:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_enableVerboseLogging:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_enableWifiConnectivityManager:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_factoryReset:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getAllMatchingWifiConfigs:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getConfiguredNetworks:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getConnectionInfo:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getCountryCode:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getCurrentNetwork:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getCurrentNetworkWpsNfcConfigurationToken:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getDhcpInfo:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getMatchingOsuProviders:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getMatchingWifiConfig:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getPasspointConfigurations:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getPrivilegedConfiguredNetworks:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getSupportedFeatures:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getVerboseLoggingLevel:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getWifiApConfiguration:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getWifiApEnabledState:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getWifiEnabledState:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getWifiServiceMessenger:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_initializeMulticastFiltering:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_isDualBandSupported:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_isMulticastEnabled:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_isScanAlwaysAvailable:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_matchProviderWithCurrentNetwork:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_needs5GHzToAnyApBandConversion:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_queryPasspointIcon:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_reassociate:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_reconnect:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_registerSoftApCallback:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_releaseMulticastLock:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_releaseWifiLock:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_removeNetwork:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_removePasspointConfiguration:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_reportActivityInfo:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_requestActivityInfo:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_restoreBackupData:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_restoreSupplicantBackupData:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_retrieveBackupData:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_setCountryCode:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_setWifiApConfiguration:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_setWifiEnabled:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_startLocalOnlyHotspot:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_startScan:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_startSoftAp:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_startSubscriptionProvisioning:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_startWatchLocalOnlyHotspot:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_stopLocalOnlyHotspot:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_stopSoftAp:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_stopWatchLocalOnlyHotspot:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_unregisterSoftApCallback:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_updateInterfaceIpState:I -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_updateWifiLockWorkSource:I -Landroid/net/wifi/IWifiManager;->acquireMulticastLock(Landroid/os/IBinder;Ljava/lang/String;)V -Landroid/net/wifi/IWifiManager;->acquireWifiLock(Landroid/os/IBinder;ILjava/lang/String;Landroid/os/WorkSource;)Z -Landroid/net/wifi/IWifiManager;->addOrUpdateNetwork(Landroid/net/wifi/WifiConfiguration;Ljava/lang/String;)I -Landroid/net/wifi/IWifiManager;->addOrUpdatePasspointConfiguration(Landroid/net/wifi/hotspot2/PasspointConfiguration;Ljava/lang/String;)Z -Landroid/net/wifi/IWifiManager;->deauthenticateNetwork(JZ)V -Landroid/net/wifi/IWifiManager;->disableEphemeralNetwork(Ljava/lang/String;Ljava/lang/String;)V -Landroid/net/wifi/IWifiManager;->disableNetwork(ILjava/lang/String;)Z -Landroid/net/wifi/IWifiManager;->disconnect(Ljava/lang/String;)V -Landroid/net/wifi/IWifiManager;->enableNetwork(IZLjava/lang/String;)Z -Landroid/net/wifi/IWifiManager;->enableTdls(Ljava/lang/String;Z)V -Landroid/net/wifi/IWifiManager;->enableTdlsWithMacAddress(Ljava/lang/String;Z)V -Landroid/net/wifi/IWifiManager;->enableVerboseLogging(I)V -Landroid/net/wifi/IWifiManager;->enableWifiConnectivityManager(Z)V -Landroid/net/wifi/IWifiManager;->factoryReset(Ljava/lang/String;)V -Landroid/net/wifi/IWifiManager;->getAllMatchingWifiConfigs(Landroid/net/wifi/ScanResult;)Ljava/util/List; -Landroid/net/wifi/IWifiManager;->getConfiguredNetworks()Landroid/content/pm/ParceledListSlice; -Landroid/net/wifi/IWifiManager;->getConnectionInfo(Ljava/lang/String;)Landroid/net/wifi/WifiInfo; -Landroid/net/wifi/IWifiManager;->getCountryCode()Ljava/lang/String; -Landroid/net/wifi/IWifiManager;->getCurrentNetworkWpsNfcConfigurationToken()Ljava/lang/String; -Landroid/net/wifi/IWifiManager;->getDhcpInfo()Landroid/net/DhcpInfo; -Landroid/net/wifi/IWifiManager;->getMatchingOsuProviders(Landroid/net/wifi/ScanResult;)Ljava/util/List; -Landroid/net/wifi/IWifiManager;->getMatchingWifiConfig(Landroid/net/wifi/ScanResult;)Landroid/net/wifi/WifiConfiguration; -Landroid/net/wifi/IWifiManager;->getPasspointConfigurations()Ljava/util/List; -Landroid/net/wifi/IWifiManager;->getPrivilegedConfiguredNetworks()Landroid/content/pm/ParceledListSlice; -Landroid/net/wifi/IWifiManager;->getScanResults(Ljava/lang/String;)Ljava/util/List; -Landroid/net/wifi/IWifiManager;->getSupportedFeatures()I -Landroid/net/wifi/IWifiManager;->getVerboseLoggingLevel()I -Landroid/net/wifi/IWifiManager;->getWifiEnabledState()I -Landroid/net/wifi/IWifiManager;->getWifiServiceMessenger(Ljava/lang/String;)Landroid/os/Messenger; -Landroid/net/wifi/IWifiManager;->initializeMulticastFiltering()V -Landroid/net/wifi/IWifiManager;->isDualBandSupported()Z -Landroid/net/wifi/IWifiManager;->isMulticastEnabled()Z -Landroid/net/wifi/IWifiManager;->isScanAlwaysAvailable()Z -Landroid/net/wifi/IWifiManager;->matchProviderWithCurrentNetwork(Ljava/lang/String;)I -Landroid/net/wifi/IWifiManager;->needs5GHzToAnyApBandConversion()Z -Landroid/net/wifi/IWifiManager;->queryPasspointIcon(JLjava/lang/String;)V -Landroid/net/wifi/IWifiManager;->reassociate(Ljava/lang/String;)V -Landroid/net/wifi/IWifiManager;->reconnect(Ljava/lang/String;)V -Landroid/net/wifi/IWifiManager;->registerSoftApCallback(Landroid/os/IBinder;Landroid/net/wifi/ISoftApCallback;I)V -Landroid/net/wifi/IWifiManager;->releaseMulticastLock()V -Landroid/net/wifi/IWifiManager;->releaseWifiLock(Landroid/os/IBinder;)Z -Landroid/net/wifi/IWifiManager;->removeNetwork(ILjava/lang/String;)Z -Landroid/net/wifi/IWifiManager;->removePasspointConfiguration(Ljava/lang/String;Ljava/lang/String;)Z -Landroid/net/wifi/IWifiManager;->reportActivityInfo()Landroid/net/wifi/WifiActivityEnergyInfo; -Landroid/net/wifi/IWifiManager;->requestActivityInfo(Landroid/os/ResultReceiver;)V -Landroid/net/wifi/IWifiManager;->restoreBackupData([B)V -Landroid/net/wifi/IWifiManager;->restoreSupplicantBackupData([B[B)V -Landroid/net/wifi/IWifiManager;->retrieveBackupData()[B -Landroid/net/wifi/IWifiManager;->setCountryCode(Ljava/lang/String;)V -Landroid/net/wifi/IWifiManager;->setWifiApConfiguration(Landroid/net/wifi/WifiConfiguration;Ljava/lang/String;)Z -Landroid/net/wifi/IWifiManager;->setWifiEnabled(Ljava/lang/String;Z)Z -Landroid/net/wifi/IWifiManager;->startLocalOnlyHotspot(Landroid/os/Messenger;Landroid/os/IBinder;Ljava/lang/String;)I -Landroid/net/wifi/IWifiManager;->startScan(Ljava/lang/String;)Z -Landroid/net/wifi/IWifiManager;->startSoftAp(Landroid/net/wifi/WifiConfiguration;)Z -Landroid/net/wifi/IWifiManager;->startSubscriptionProvisioning(Landroid/net/wifi/hotspot2/OsuProvider;Landroid/net/wifi/hotspot2/IProvisioningCallback;)V -Landroid/net/wifi/IWifiManager;->startWatchLocalOnlyHotspot(Landroid/os/Messenger;Landroid/os/IBinder;)V -Landroid/net/wifi/IWifiManager;->stopLocalOnlyHotspot()V -Landroid/net/wifi/IWifiManager;->stopSoftAp()Z -Landroid/net/wifi/IWifiManager;->stopWatchLocalOnlyHotspot()V -Landroid/net/wifi/IWifiManager;->unregisterSoftApCallback(I)V -Landroid/net/wifi/IWifiManager;->updateInterfaceIpState(Ljava/lang/String;I)V -Landroid/net/wifi/IWifiManager;->updateWifiLockWorkSource(Landroid/os/IBinder;Landroid/os/WorkSource;)V -Landroid/net/wifi/IWifiScanner$Stub$Proxy;->getAvailableChannels(I)Landroid/os/Bundle; -Landroid/net/wifi/IWifiScanner$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String; -Landroid/net/wifi/IWifiScanner$Stub$Proxy;->getMessenger()Landroid/os/Messenger; -Landroid/net/wifi/IWifiScanner$Stub;->DESCRIPTOR:Ljava/lang/String; -Landroid/net/wifi/IWifiScanner$Stub;->TRANSACTION_getAvailableChannels:I -Landroid/net/wifi/IWifiScanner$Stub;->TRANSACTION_getMessenger:I -Landroid/net/wifi/IWifiScanner;->getAvailableChannels(I)Landroid/os/Bundle; -Landroid/net/wifi/IWifiScanner;->getMessenger()Landroid/os/Messenger; -Landroid/net/wifi/p2p/IWifiP2pManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/net/wifi/p2p/IWifiP2pManager$Stub$Proxy;->checkConfigureWifiDisplayPermission()V -Landroid/net/wifi/p2p/IWifiP2pManager$Stub$Proxy;->close(Landroid/os/IBinder;)V -Landroid/net/wifi/p2p/IWifiP2pManager$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String; -Landroid/net/wifi/p2p/IWifiP2pManager$Stub$Proxy;->getMessenger(Landroid/os/IBinder;)Landroid/os/Messenger; -Landroid/net/wifi/p2p/IWifiP2pManager$Stub$Proxy;->getP2pStateMachineMessenger()Landroid/os/Messenger; -Landroid/net/wifi/p2p/IWifiP2pManager$Stub$Proxy;->mRemote:Landroid/os/IBinder; -Landroid/net/wifi/p2p/IWifiP2pManager$Stub$Proxy;->setMiracastMode(I)V -Landroid/net/wifi/p2p/IWifiP2pManager$Stub;-><init>()V -Landroid/net/wifi/p2p/IWifiP2pManager$Stub;->DESCRIPTOR:Ljava/lang/String; -Landroid/net/wifi/p2p/IWifiP2pManager$Stub;->TRANSACTION_checkConfigureWifiDisplayPermission:I -Landroid/net/wifi/p2p/IWifiP2pManager$Stub;->TRANSACTION_close:I -Landroid/net/wifi/p2p/IWifiP2pManager$Stub;->TRANSACTION_getMessenger:I -Landroid/net/wifi/p2p/IWifiP2pManager$Stub;->TRANSACTION_getP2pStateMachineMessenger:I -Landroid/net/wifi/p2p/IWifiP2pManager$Stub;->TRANSACTION_setMiracastMode:I -Landroid/net/wifi/p2p/IWifiP2pManager;->checkConfigureWifiDisplayPermission()V -Landroid/net/wifi/p2p/IWifiP2pManager;->close(Landroid/os/IBinder;)V -Landroid/net/wifi/p2p/IWifiP2pManager;->getMessenger(Landroid/os/IBinder;)Landroid/os/Messenger; -Landroid/net/wifi/p2p/IWifiP2pManager;->getP2pStateMachineMessenger()Landroid/os/Messenger; -Landroid/net/wifi/p2p/IWifiP2pManager;->setMiracastMode(I)V -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo;-><init>(Ljava/util/List;)V -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo;->compressDnsName(Ljava/lang/String;)Ljava/lang/String; -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo;->createPtrServiceQuery(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo;->createTxtServiceQuery(Ljava/lang/String;Ljava/lang/String;Landroid/net/nsd/DnsSdTxtRecord;)Ljava/lang/String; -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo;->DNS_TYPE_PTR:I -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo;->DNS_TYPE_TXT:I -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo;->sVmPacket:Ljava/util/Map; -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo;->VERSION_1:I -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequest;-><init>()V -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequest;-><init>(Ljava/lang/String;)V -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceRequest;-><init>(Ljava/lang/String;II)V -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;-><init>(IILandroid/net/wifi/p2p/WifiP2pDevice;[B)V -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;->getDnsQueryName()Ljava/lang/String; -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;->getDnsType()I -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;->getInstanceName()Ljava/lang/String; -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;->getTxtRecord()Ljava/util/Map; -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;->getVersion()I -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;->mDnsQueryName:Ljava/lang/String; -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;->mDnsType:I -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;->mInstanceName:Ljava/lang/String; -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;->mTxtRecord:Ljava/util/HashMap; -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;->mVersion:I -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;->newInstance(IILandroid/net/wifi/p2p/WifiP2pDevice;[B)Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse; -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;->parse()Z -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;->readDnsName(Ljava/io/DataInputStream;)Ljava/lang/String; -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;->readTxtData(Ljava/io/DataInputStream;)Z -Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;->sVmpack:Ljava/util/Map; -Landroid/net/wifi/p2p/nsd/WifiP2pServiceInfo;->bin2HexStr([B)Ljava/lang/String; -Landroid/net/wifi/p2p/nsd/WifiP2pServiceInfo;->getSupplicantQueryList()Ljava/util/List; -Landroid/net/wifi/p2p/nsd/WifiP2pServiceInfo;->SERVICE_TYPE_WS_DISCOVERY:I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceRequest;-><init>(IIILjava/lang/String;)V -Landroid/net/wifi/p2p/nsd/WifiP2pServiceRequest;->getSupplicantQuery()Ljava/lang/String; -Landroid/net/wifi/p2p/nsd/WifiP2pServiceRequest;->getTransactionId()I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceRequest;->mLength:I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceRequest;->mProtocolType:I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceRequest;->mQuery:Ljava/lang/String; -Landroid/net/wifi/p2p/nsd/WifiP2pServiceRequest;->mTransId:I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceRequest;->setTransactionId(I)V -Landroid/net/wifi/p2p/nsd/WifiP2pServiceRequest;->validateQuery(Ljava/lang/String;)V -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse$Status;-><init>()V -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse$Status;->BAD_REQUEST:I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse$Status;->REQUESTED_INFORMATION_NOT_AVAILABLE:I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse$Status;->SERVICE_PROTOCOL_NOT_AVAILABLE:I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse$Status;->SUCCESS:I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse$Status;->toString(I)Ljava/lang/String; -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;-><init>(IIILandroid/net/wifi/p2p/WifiP2pDevice;[B)V -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->equals(Ljava/lang/Object;Ljava/lang/Object;)Z -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->getRawData()[B -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->getServiceType()I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->getSrcDevice()Landroid/net/wifi/p2p/WifiP2pDevice; -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->getStatus()I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->getTransactionId()I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->hexStr2Bin(Ljava/lang/String;)[B -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->MAX_BUF_SIZE:I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->mData:[B -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->mDevice:Landroid/net/wifi/p2p/WifiP2pDevice; -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->mServiceType:I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->mStatus:I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->mTransId:I -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->newInstance(Ljava/lang/String;[B)Ljava/util/List; -Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;->setSrcDevice(Landroid/net/wifi/p2p/WifiP2pDevice;)V -Landroid/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo;-><init>(Ljava/util/List;)V -Landroid/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo;->createSupplicantQuery(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; -Landroid/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo;->VERSION_1_0:I -Landroid/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest;-><init>()V -Landroid/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest;-><init>(Ljava/lang/String;)V -Landroid/net/wifi/p2p/nsd/WifiP2pUpnpServiceResponse;-><init>(IILandroid/net/wifi/p2p/WifiP2pDevice;[B)V -Landroid/net/wifi/p2p/nsd/WifiP2pUpnpServiceResponse;->getUniqueServiceNames()Ljava/util/List; -Landroid/net/wifi/p2p/nsd/WifiP2pUpnpServiceResponse;->getVersion()I -Landroid/net/wifi/p2p/nsd/WifiP2pUpnpServiceResponse;->mUniqueServiceNames:Ljava/util/List; -Landroid/net/wifi/p2p/nsd/WifiP2pUpnpServiceResponse;->mVersion:I -Landroid/net/wifi/p2p/nsd/WifiP2pUpnpServiceResponse;->newInstance(IILandroid/net/wifi/p2p/WifiP2pDevice;[B)Landroid/net/wifi/p2p/nsd/WifiP2pUpnpServiceResponse; -Landroid/net/wifi/p2p/nsd/WifiP2pUpnpServiceResponse;->parse()Z -Landroid/net/wifi/p2p/WifiP2pConfig;->invalidate()V -Landroid/net/wifi/p2p/WifiP2pConfig;->MAX_GROUP_OWNER_INTENT:I -Landroid/net/wifi/p2p/WifiP2pDevice;->detailedDevicePattern:Ljava/util/regex/Pattern; -Landroid/net/wifi/p2p/WifiP2pDevice;->DEVICE_CAPAB_CLIENT_DISCOVERABILITY:I -Landroid/net/wifi/p2p/WifiP2pDevice;->DEVICE_CAPAB_CONCURRENT_OPER:I -Landroid/net/wifi/p2p/WifiP2pDevice;->DEVICE_CAPAB_DEVICE_LIMIT:I -Landroid/net/wifi/p2p/WifiP2pDevice;->DEVICE_CAPAB_INFRA_MANAGED:I -Landroid/net/wifi/p2p/WifiP2pDevice;->DEVICE_CAPAB_INVITATION_PROCEDURE:I -Landroid/net/wifi/p2p/WifiP2pDevice;->DEVICE_CAPAB_SERVICE_DISCOVERY:I -Landroid/net/wifi/p2p/WifiP2pDevice;->GROUP_CAPAB_CROSS_CONN:I -Landroid/net/wifi/p2p/WifiP2pDevice;->GROUP_CAPAB_GROUP_FORMATION:I -Landroid/net/wifi/p2p/WifiP2pDevice;->GROUP_CAPAB_GROUP_LIMIT:I -Landroid/net/wifi/p2p/WifiP2pDevice;->GROUP_CAPAB_GROUP_OWNER:I -Landroid/net/wifi/p2p/WifiP2pDevice;->GROUP_CAPAB_INTRA_BSS_DIST:I -Landroid/net/wifi/p2p/WifiP2pDevice;->GROUP_CAPAB_PERSISTENT_GROUP:I -Landroid/net/wifi/p2p/WifiP2pDevice;->GROUP_CAPAB_PERSISTENT_RECONN:I -Landroid/net/wifi/p2p/WifiP2pDevice;->isDeviceLimit()Z -Landroid/net/wifi/p2p/WifiP2pDevice;->isGroupLimit()Z -Landroid/net/wifi/p2p/WifiP2pDevice;->isInvitationCapable()Z -Landroid/net/wifi/p2p/WifiP2pDevice;->parseHex(Ljava/lang/String;)I -Landroid/net/wifi/p2p/WifiP2pDevice;->TAG:Ljava/lang/String; -Landroid/net/wifi/p2p/WifiP2pDevice;->threeTokenPattern:Ljava/util/regex/Pattern; -Landroid/net/wifi/p2p/WifiP2pDevice;->twoTokenPattern:Ljava/util/regex/Pattern; -Landroid/net/wifi/p2p/WifiP2pDevice;->updateSupplicantDetails(Landroid/net/wifi/p2p/WifiP2pDevice;)V -Landroid/net/wifi/p2p/WifiP2pDevice;->WPS_CONFIG_DISPLAY:I -Landroid/net/wifi/p2p/WifiP2pDevice;->WPS_CONFIG_KEYPAD:I -Landroid/net/wifi/p2p/WifiP2pDevice;->WPS_CONFIG_PUSHBUTTON:I -Landroid/net/wifi/p2p/WifiP2pDeviceList;-><init>(Ljava/util/ArrayList;)V -Landroid/net/wifi/p2p/WifiP2pDeviceList;->clear()Z -Landroid/net/wifi/p2p/WifiP2pDeviceList;->isGroupOwner(Ljava/lang/String;)Z -Landroid/net/wifi/p2p/WifiP2pDeviceList;->mDevices:Ljava/util/HashMap; -Landroid/net/wifi/p2p/WifiP2pDeviceList;->remove(Landroid/net/wifi/p2p/WifiP2pDevice;)Z -Landroid/net/wifi/p2p/WifiP2pDeviceList;->remove(Landroid/net/wifi/p2p/WifiP2pDeviceList;)Z -Landroid/net/wifi/p2p/WifiP2pDeviceList;->updateGroupCapability(Ljava/lang/String;I)V -Landroid/net/wifi/p2p/WifiP2pDeviceList;->updateStatus(Ljava/lang/String;I)V -Landroid/net/wifi/p2p/WifiP2pDeviceList;->updateSupplicantDetails(Landroid/net/wifi/p2p/WifiP2pDevice;)V -Landroid/net/wifi/p2p/WifiP2pDeviceList;->validateDevice(Landroid/net/wifi/p2p/WifiP2pDevice;)V -Landroid/net/wifi/p2p/WifiP2pDeviceList;->validateDeviceAddress(Ljava/lang/String;)V -Landroid/net/wifi/p2p/WifiP2pGroup;->addClient(Landroid/net/wifi/p2p/WifiP2pDevice;)V -Landroid/net/wifi/p2p/WifiP2pGroup;->addClient(Ljava/lang/String;)V -Landroid/net/wifi/p2p/WifiP2pGroup;->contains(Landroid/net/wifi/p2p/WifiP2pDevice;)Z -Landroid/net/wifi/p2p/WifiP2pGroup;->groupStartedPattern:Ljava/util/regex/Pattern; -Landroid/net/wifi/p2p/WifiP2pGroup;->mClients:Ljava/util/List; -Landroid/net/wifi/p2p/WifiP2pGroup;->mInterface:Ljava/lang/String; -Landroid/net/wifi/p2p/WifiP2pGroup;->mIsGroupOwner:Z -Landroid/net/wifi/p2p/WifiP2pGroup;->mNetId:I -Landroid/net/wifi/p2p/WifiP2pGroup;->mNetworkName:Ljava/lang/String; -Landroid/net/wifi/p2p/WifiP2pGroup;->mOwner:Landroid/net/wifi/p2p/WifiP2pDevice; -Landroid/net/wifi/p2p/WifiP2pGroup;->mPassphrase:Ljava/lang/String; -Landroid/net/wifi/p2p/WifiP2pGroup;->PERSISTENT_NET_ID:I -Landroid/net/wifi/p2p/WifiP2pGroup;->removeClient(Landroid/net/wifi/p2p/WifiP2pDevice;)Z -Landroid/net/wifi/p2p/WifiP2pGroup;->removeClient(Ljava/lang/String;)Z -Landroid/net/wifi/p2p/WifiP2pGroup;->setNetworkName(Ljava/lang/String;)V -Landroid/net/wifi/p2p/WifiP2pGroup;->setOwner(Landroid/net/wifi/p2p/WifiP2pDevice;)V -Landroid/net/wifi/p2p/WifiP2pGroup;->setPassphrase(Ljava/lang/String;)V -Landroid/net/wifi/p2p/WifiP2pGroupList$GroupDeleteListener;->onDeleteGroup(I)V -Landroid/net/wifi/p2p/WifiP2pGroupList;-><init>()V -Landroid/net/wifi/p2p/WifiP2pGroupList;->add(Landroid/net/wifi/p2p/WifiP2pGroup;)V -Landroid/net/wifi/p2p/WifiP2pGroupList;->clear()Z -Landroid/net/wifi/p2p/WifiP2pGroupList;->contains(I)Z -Landroid/net/wifi/p2p/WifiP2pGroupList;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/p2p/WifiP2pGroupList;->CREDENTIAL_MAX_NUM:I -Landroid/net/wifi/p2p/WifiP2pGroupList;->getNetworkId(Ljava/lang/String;)I -Landroid/net/wifi/p2p/WifiP2pGroupList;->getNetworkId(Ljava/lang/String;Ljava/lang/String;)I -Landroid/net/wifi/p2p/WifiP2pGroupList;->getOwnerAddr(I)Ljava/lang/String; -Landroid/net/wifi/p2p/WifiP2pGroupList;->isClearCalled:Z -Landroid/net/wifi/p2p/WifiP2pGroupList;->mListener:Landroid/net/wifi/p2p/WifiP2pGroupList$GroupDeleteListener; -Landroid/net/wifi/p2p/WifiP2pGroupList;->remove(I)V -Landroid/net/wifi/p2p/WifiP2pGroupList;->remove(Ljava/lang/String;)V -Landroid/net/wifi/p2p/WifiP2pManager$Channel;-><init>(Landroid/content/Context;Landroid/os/Looper;Landroid/net/wifi/p2p/WifiP2pManager$ChannelListener;Landroid/os/Binder;Landroid/net/wifi/p2p/WifiP2pManager;)V -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->getListener(I)Ljava/lang/Object; -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->handleDnsSdServiceResponse(Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceResponse;)V -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->handleServiceResponse(Landroid/net/wifi/p2p/nsd/WifiP2pServiceResponse;)V -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->handleUpnpServiceResponse(Landroid/net/wifi/p2p/nsd/WifiP2pUpnpServiceResponse;)V -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->INVALID_LISTENER_KEY:I -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mBinder:Landroid/os/Binder; -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mChannelListener:Landroid/net/wifi/p2p/WifiP2pManager$ChannelListener; -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mCloseGuard:Ldalvik/system/CloseGuard; -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mContext:Landroid/content/Context; -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mDnsSdServRspListener:Landroid/net/wifi/p2p/WifiP2pManager$DnsSdServiceResponseListener; -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mDnsSdTxtListener:Landroid/net/wifi/p2p/WifiP2pManager$DnsSdTxtRecordListener; -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mHandler:Landroid/net/wifi/p2p/WifiP2pManager$Channel$P2pHandler; -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mListenerKey:I -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mListenerMap:Ljava/util/HashMap; -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mListenerMapLock:Ljava/lang/Object; -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mP2pManager:Landroid/net/wifi/p2p/WifiP2pManager; -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mServRspListener:Landroid/net/wifi/p2p/WifiP2pManager$ServiceResponseListener; -Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mUpnpServRspListener:Landroid/net/wifi/p2p/WifiP2pManager$UpnpServiceResponseListener; -Landroid/net/wifi/p2p/WifiP2pManager$HandoverMessageListener;->onHandoverMessageAvailable(Ljava/lang/String;)V -Landroid/net/wifi/p2p/WifiP2pManager$PersistentGroupInfoListener;->onPersistentGroupInfoAvailable(Landroid/net/wifi/p2p/WifiP2pGroupList;)V -Landroid/net/wifi/p2p/WifiP2pManager;->ADD_LOCAL_SERVICE:I -Landroid/net/wifi/p2p/WifiP2pManager;->ADD_LOCAL_SERVICE_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->ADD_LOCAL_SERVICE_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->ADD_SERVICE_REQUEST:I -Landroid/net/wifi/p2p/WifiP2pManager;->ADD_SERVICE_REQUEST_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->ADD_SERVICE_REQUEST_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->BASE:I -Landroid/net/wifi/p2p/WifiP2pManager;->CALLING_PACKAGE:Ljava/lang/String; -Landroid/net/wifi/p2p/WifiP2pManager;->CANCEL_CONNECT:I -Landroid/net/wifi/p2p/WifiP2pManager;->CANCEL_CONNECT_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->CANCEL_CONNECT_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->checkChannel(Landroid/net/wifi/p2p/WifiP2pManager$Channel;)V -Landroid/net/wifi/p2p/WifiP2pManager;->checkP2pConfig(Landroid/net/wifi/p2p/WifiP2pConfig;)V -Landroid/net/wifi/p2p/WifiP2pManager;->checkServiceInfo(Landroid/net/wifi/p2p/nsd/WifiP2pServiceInfo;)V -Landroid/net/wifi/p2p/WifiP2pManager;->checkServiceRequest(Landroid/net/wifi/p2p/nsd/WifiP2pServiceRequest;)V -Landroid/net/wifi/p2p/WifiP2pManager;->CLEAR_LOCAL_SERVICES:I -Landroid/net/wifi/p2p/WifiP2pManager;->CLEAR_LOCAL_SERVICES_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->CLEAR_LOCAL_SERVICES_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->CLEAR_SERVICE_REQUESTS:I -Landroid/net/wifi/p2p/WifiP2pManager;->CLEAR_SERVICE_REQUESTS_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->CLEAR_SERVICE_REQUESTS_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->CONNECT:I -Landroid/net/wifi/p2p/WifiP2pManager;->CONNECT_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->CONNECT_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->CREATE_GROUP_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->CREATE_GROUP_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->DELETE_PERSISTENT_GROUP:I -Landroid/net/wifi/p2p/WifiP2pManager;->DELETE_PERSISTENT_GROUP_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->DELETE_PERSISTENT_GROUP_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->DISCOVER_PEERS:I -Landroid/net/wifi/p2p/WifiP2pManager;->DISCOVER_PEERS_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->DISCOVER_PEERS_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->DISCOVER_SERVICES:I -Landroid/net/wifi/p2p/WifiP2pManager;->DISCOVER_SERVICES_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->DISCOVER_SERVICES_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->EXTRA_HANDOVER_MESSAGE:Ljava/lang/String; -Landroid/net/wifi/p2p/WifiP2pManager;->getMessenger(Landroid/os/Binder;)Landroid/os/Messenger; -Landroid/net/wifi/p2p/WifiP2pManager;->getNfcHandoverRequest(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Landroid/net/wifi/p2p/WifiP2pManager$HandoverMessageListener;)V -Landroid/net/wifi/p2p/WifiP2pManager;->getNfcHandoverSelect(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Landroid/net/wifi/p2p/WifiP2pManager$HandoverMessageListener;)V -Landroid/net/wifi/p2p/WifiP2pManager;->getP2pStateMachineMessenger()Landroid/os/Messenger; -Landroid/net/wifi/p2p/WifiP2pManager;->GET_HANDOVER_REQUEST:I -Landroid/net/wifi/p2p/WifiP2pManager;->GET_HANDOVER_SELECT:I -Landroid/net/wifi/p2p/WifiP2pManager;->initalizeChannel(Landroid/content/Context;Landroid/os/Looper;Landroid/net/wifi/p2p/WifiP2pManager$ChannelListener;Landroid/os/Messenger;Landroid/os/Binder;)Landroid/net/wifi/p2p/WifiP2pManager$Channel; -Landroid/net/wifi/p2p/WifiP2pManager;->initializeInternal(Landroid/content/Context;Landroid/os/Looper;Landroid/net/wifi/p2p/WifiP2pManager$ChannelListener;)Landroid/net/wifi/p2p/WifiP2pManager$Channel; -Landroid/net/wifi/p2p/WifiP2pManager;->initiatorReportNfcHandover(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Ljava/lang/String;Landroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V -Landroid/net/wifi/p2p/WifiP2pManager;->INITIATOR_REPORT_NFC_HANDOVER:I -Landroid/net/wifi/p2p/WifiP2pManager;->listen(Landroid/net/wifi/p2p/WifiP2pManager$Channel;ZLandroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V -Landroid/net/wifi/p2p/WifiP2pManager;->MIRACAST_DISABLED:I -Landroid/net/wifi/p2p/WifiP2pManager;->MIRACAST_SINK:I -Landroid/net/wifi/p2p/WifiP2pManager;->MIRACAST_SOURCE:I -Landroid/net/wifi/p2p/WifiP2pManager;->mService:Landroid/net/wifi/p2p/IWifiP2pManager; -Landroid/net/wifi/p2p/WifiP2pManager;->PING:I -Landroid/net/wifi/p2p/WifiP2pManager;->REMOVE_GROUP:I -Landroid/net/wifi/p2p/WifiP2pManager;->REMOVE_GROUP_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->REMOVE_GROUP_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->REMOVE_LOCAL_SERVICE:I -Landroid/net/wifi/p2p/WifiP2pManager;->REMOVE_LOCAL_SERVICE_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->REMOVE_LOCAL_SERVICE_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->REMOVE_SERVICE_REQUEST:I -Landroid/net/wifi/p2p/WifiP2pManager;->REMOVE_SERVICE_REQUEST_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->REMOVE_SERVICE_REQUEST_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->REPORT_NFC_HANDOVER_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->REPORT_NFC_HANDOVER_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->REQUEST_CONNECTION_INFO:I -Landroid/net/wifi/p2p/WifiP2pManager;->REQUEST_GROUP_INFO:I -Landroid/net/wifi/p2p/WifiP2pManager;->REQUEST_PEERS:I -Landroid/net/wifi/p2p/WifiP2pManager;->REQUEST_PERSISTENT_GROUP_INFO:I -Landroid/net/wifi/p2p/WifiP2pManager;->responderReportNfcHandover(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Ljava/lang/String;Landroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V -Landroid/net/wifi/p2p/WifiP2pManager;->RESPONDER_REPORT_NFC_HANDOVER:I -Landroid/net/wifi/p2p/WifiP2pManager;->RESPONSE_CONNECTION_INFO:I -Landroid/net/wifi/p2p/WifiP2pManager;->RESPONSE_GET_HANDOVER_MESSAGE:I -Landroid/net/wifi/p2p/WifiP2pManager;->RESPONSE_GROUP_INFO:I -Landroid/net/wifi/p2p/WifiP2pManager;->RESPONSE_PEERS:I -Landroid/net/wifi/p2p/WifiP2pManager;->RESPONSE_PERSISTENT_GROUP_INFO:I -Landroid/net/wifi/p2p/WifiP2pManager;->RESPONSE_SERVICE:I -Landroid/net/wifi/p2p/WifiP2pManager;->SET_CHANNEL:I -Landroid/net/wifi/p2p/WifiP2pManager;->SET_CHANNEL_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->SET_CHANNEL_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->SET_DEVICE_NAME:I -Landroid/net/wifi/p2p/WifiP2pManager;->SET_DEVICE_NAME_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->SET_DEVICE_NAME_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->SET_WFD_INFO:I -Landroid/net/wifi/p2p/WifiP2pManager;->SET_WFD_INFO_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->SET_WFD_INFO_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->START_LISTEN:I -Landroid/net/wifi/p2p/WifiP2pManager;->START_LISTEN_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->START_LISTEN_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->START_WPS:I -Landroid/net/wifi/p2p/WifiP2pManager;->START_WPS_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->START_WPS_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->STOP_DISCOVERY:I -Landroid/net/wifi/p2p/WifiP2pManager;->STOP_DISCOVERY_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->STOP_DISCOVERY_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->STOP_LISTEN:I -Landroid/net/wifi/p2p/WifiP2pManager;->STOP_LISTEN_FAILED:I -Landroid/net/wifi/p2p/WifiP2pManager;->STOP_LISTEN_SUCCEEDED:I -Landroid/net/wifi/p2p/WifiP2pManager;->TAG:Ljava/lang/String; -Landroid/net/wifi/p2p/WifiP2pManager;->WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION:Ljava/lang/String; -Landroid/net/wifi/p2p/WifiP2pProvDiscEvent;-><init>(Ljava/lang/String;)V -Landroid/net/wifi/p2p/WifiP2pProvDiscEvent;->ENTER_PIN:I -Landroid/net/wifi/p2p/WifiP2pProvDiscEvent;->PBC_REQ:I -Landroid/net/wifi/p2p/WifiP2pProvDiscEvent;->PBC_RSP:I -Landroid/net/wifi/p2p/WifiP2pProvDiscEvent;->SHOW_PIN:I -Landroid/net/wifi/p2p/WifiP2pProvDiscEvent;->TAG:Ljava/lang/String; -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->COUPLED_SINK_SUPPORT_AT_SINK:I -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->COUPLED_SINK_SUPPORT_AT_SOURCE:I -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->DEVICE_TYPE:I -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->getControlPort()I -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->getDeviceInfoHex()Ljava/lang/String; -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->getMaxThroughput()I -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->isCoupledSinkSupportedAtSink()Z -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->isCoupledSinkSupportedAtSource()Z -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->isSessionAvailable()Z -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->mCtrlPort:I -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->mDeviceInfo:I -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->mMaxThroughput:I -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->mWfdEnabled:Z -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->PRIMARY_SINK:I -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->readFromParcel(Landroid/os/Parcel;)V -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->SECONDARY_SINK:I -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->SESSION_AVAILABLE:I -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->SESSION_AVAILABLE_BIT1:I -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->SESSION_AVAILABLE_BIT2:I -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->setCoupledSinkSupportAtSink(Z)V -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->setCoupledSinkSupportAtSource(Z)V -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->SOURCE_OR_PRIMARY_SINK:I -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->TAG:Ljava/lang/String; -Landroid/net/wifi/p2p/WifiP2pWfdInfo;->WFD_SOURCE:I -Landroid/net/wifi/ParcelUtil;-><init>()V -Landroid/net/wifi/ParcelUtil;->readCertificate(Landroid/os/Parcel;)Ljava/security/cert/X509Certificate; -Landroid/net/wifi/ParcelUtil;->readCertificates(Landroid/os/Parcel;)[Ljava/security/cert/X509Certificate; -Landroid/net/wifi/ParcelUtil;->readPrivateKey(Landroid/os/Parcel;)Ljava/security/PrivateKey; -Landroid/net/wifi/ParcelUtil;->writeCertificate(Landroid/os/Parcel;Ljava/security/cert/X509Certificate;)V -Landroid/net/wifi/ParcelUtil;->writeCertificates(Landroid/os/Parcel;[Ljava/security/cert/X509Certificate;)V -Landroid/net/wifi/ParcelUtil;->writePrivateKey(Landroid/os/Parcel;Ljava/security/PrivateKey;)V Landroid/net/wifi/PasspointManagementObjectDefinition;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V Landroid/net/wifi/PasspointManagementObjectDefinition;->CREATOR:Landroid/os/Parcelable$Creator; Landroid/net/wifi/PasspointManagementObjectDefinition;->getBaseUri()Ljava/lang/String; @@ -39647,121 +38277,6 @@ Landroid/net/wifi/RssiPacketCountInfo;->rssi:I Landroid/net/wifi/RssiPacketCountInfo;->rxgood:I Landroid/net/wifi/RssiPacketCountInfo;->txbad:I Landroid/net/wifi/RssiPacketCountInfo;->txgood:I -Landroid/net/wifi/rtt/IRttCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/net/wifi/rtt/IRttCallback$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String; -Landroid/net/wifi/rtt/IRttCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder; -Landroid/net/wifi/rtt/IRttCallback$Stub$Proxy;->onRangingFailure(I)V -Landroid/net/wifi/rtt/IRttCallback$Stub$Proxy;->onRangingResults(Ljava/util/List;)V -Landroid/net/wifi/rtt/IRttCallback$Stub;-><init>()V -Landroid/net/wifi/rtt/IRttCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/rtt/IRttCallback; -Landroid/net/wifi/rtt/IRttCallback$Stub;->DESCRIPTOR:Ljava/lang/String; -Landroid/net/wifi/rtt/IRttCallback$Stub;->TRANSACTION_onRangingFailure:I -Landroid/net/wifi/rtt/IRttCallback$Stub;->TRANSACTION_onRangingResults:I -Landroid/net/wifi/rtt/IRttCallback;->onRangingFailure(I)V -Landroid/net/wifi/rtt/IRttCallback;->onRangingResults(Ljava/util/List;)V -Landroid/net/wifi/rtt/IWifiRttManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/net/wifi/rtt/IWifiRttManager$Stub$Proxy;->cancelRanging(Landroid/os/WorkSource;)V -Landroid/net/wifi/rtt/IWifiRttManager$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String; -Landroid/net/wifi/rtt/IWifiRttManager$Stub$Proxy;->isAvailable()Z -Landroid/net/wifi/rtt/IWifiRttManager$Stub$Proxy;->mRemote:Landroid/os/IBinder; -Landroid/net/wifi/rtt/IWifiRttManager$Stub$Proxy;->startRanging(Landroid/os/IBinder;Ljava/lang/String;Landroid/os/WorkSource;Landroid/net/wifi/rtt/RangingRequest;Landroid/net/wifi/rtt/IRttCallback;)V -Landroid/net/wifi/rtt/IWifiRttManager$Stub;-><init>()V -Landroid/net/wifi/rtt/IWifiRttManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/rtt/IWifiRttManager; -Landroid/net/wifi/rtt/IWifiRttManager$Stub;->DESCRIPTOR:Ljava/lang/String; -Landroid/net/wifi/rtt/IWifiRttManager$Stub;->TRANSACTION_cancelRanging:I -Landroid/net/wifi/rtt/IWifiRttManager$Stub;->TRANSACTION_isAvailable:I -Landroid/net/wifi/rtt/IWifiRttManager$Stub;->TRANSACTION_startRanging:I -Landroid/net/wifi/rtt/IWifiRttManager;->cancelRanging(Landroid/os/WorkSource;)V -Landroid/net/wifi/rtt/IWifiRttManager;->isAvailable()Z -Landroid/net/wifi/rtt/IWifiRttManager;->startRanging(Landroid/os/IBinder;Ljava/lang/String;Landroid/os/WorkSource;Landroid/net/wifi/rtt/RangingRequest;Landroid/net/wifi/rtt/IRttCallback;)V -Landroid/net/wifi/rtt/RangingRequest$Builder;->mRttPeers:Ljava/util/List; -Landroid/net/wifi/rtt/RangingRequest;-><init>(Ljava/util/List;)V -Landroid/net/wifi/rtt/RangingRequest;->enforceValidity(Z)V -Landroid/net/wifi/rtt/RangingRequest;->MAX_PEERS:I -Landroid/net/wifi/rtt/RangingRequest;->mRttPeers:Ljava/util/List; -Landroid/net/wifi/rtt/RangingResult;-><init>(ILandroid/net/MacAddress;IIIII[B[BJ)V -Landroid/net/wifi/rtt/RangingResult;-><init>(ILandroid/net/wifi/aware/PeerHandle;IIIII[B[BJ)V -Landroid/net/wifi/rtt/RangingResult;->EMPTY_BYTE_ARRAY:[B -Landroid/net/wifi/rtt/RangingResult;->mDistanceMm:I -Landroid/net/wifi/rtt/RangingResult;->mDistanceStdDevMm:I -Landroid/net/wifi/rtt/RangingResult;->mLci:[B -Landroid/net/wifi/rtt/RangingResult;->mLcr:[B -Landroid/net/wifi/rtt/RangingResult;->mMac:Landroid/net/MacAddress; -Landroid/net/wifi/rtt/RangingResult;->mNumAttemptedMeasurements:I -Landroid/net/wifi/rtt/RangingResult;->mNumSuccessfulMeasurements:I -Landroid/net/wifi/rtt/RangingResult;->mPeerHandle:Landroid/net/wifi/aware/PeerHandle; -Landroid/net/wifi/rtt/RangingResult;->mRssi:I -Landroid/net/wifi/rtt/RangingResult;->mStatus:I -Landroid/net/wifi/rtt/RangingResult;->mTimestamp:J -Landroid/net/wifi/rtt/RangingResult;->TAG:Ljava/lang/String; -Landroid/net/wifi/rtt/ResponderConfig;-><init>(Landroid/net/MacAddress;Landroid/net/wifi/aware/PeerHandle;IZIIIII)V -Landroid/net/wifi/rtt/ResponderConfig;->AWARE_BAND_2_DISCOVERY_CHANNEL:I -Landroid/net/wifi/rtt/ResponderConfig;->isValid(Z)Z -Landroid/net/wifi/rtt/ResponderConfig;->TAG:Ljava/lang/String; -Landroid/net/wifi/rtt/ResponderConfig;->translateScanResultChannelWidth(I)I -Landroid/net/wifi/rtt/WifiRttManager;-><init>(Landroid/content/Context;Landroid/net/wifi/rtt/IWifiRttManager;)V -Landroid/net/wifi/rtt/WifiRttManager;->mContext:Landroid/content/Context; -Landroid/net/wifi/rtt/WifiRttManager;->mService:Landroid/net/wifi/rtt/IWifiRttManager; -Landroid/net/wifi/rtt/WifiRttManager;->TAG:Ljava/lang/String; -Landroid/net/wifi/rtt/WifiRttManager;->VDBG:Z -Landroid/net/wifi/RttManager$ParcelableRttParams;-><init>([Landroid/net/wifi/RttManager$RttParams;)V -Landroid/net/wifi/RttManager$ParcelableRttParams;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/RttManager$ParcelableRttResults;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/RttManager$RttCapabilities;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/RttManager;-><init>(Landroid/content/Context;Landroid/net/wifi/rtt/WifiRttManager;)V -Landroid/net/wifi/RttManager;->CMD_OP_REG_BINDER:I -Landroid/net/wifi/RttManager;->DBG:Z -Landroid/net/wifi/RttManager;->mContext:Landroid/content/Context; -Landroid/net/wifi/RttManager;->mNewService:Landroid/net/wifi/rtt/WifiRttManager; -Landroid/net/wifi/RttManager;->mRttCapabilities:Landroid/net/wifi/RttManager$RttCapabilities; -Landroid/net/wifi/RttManager;->TAG:Ljava/lang/String; -Landroid/net/wifi/ScanResult$InformationElement;-><init>()V -Landroid/net/wifi/ScanResult$InformationElement;-><init>(Landroid/net/wifi/ScanResult$InformationElement;)V -Landroid/net/wifi/ScanResult$InformationElement;->EID_HT_CAPABILITIES:I -Landroid/net/wifi/ScanResult$InformationElement;->EID_VHT_CAPABILITIES:I -Landroid/net/wifi/ScanResult$RadioChainInfo;-><init>()V -Landroid/net/wifi/ScanResult$RadioChainInfo;->id:I -Landroid/net/wifi/ScanResult$RadioChainInfo;->level:I -Landroid/net/wifi/ScanResult;-><init>()V -Landroid/net/wifi/ScanResult;-><init>(Landroid/net/wifi/ScanResult;)V -Landroid/net/wifi/ScanResult;-><init>(Landroid/net/wifi/WifiSsid;Ljava/lang/String;JI[BLjava/lang/String;IIJ)V -Landroid/net/wifi/ScanResult;-><init>(Landroid/net/wifi/WifiSsid;Ljava/lang/String;Ljava/lang/String;IIJII)V -Landroid/net/wifi/ScanResult;-><init>(Landroid/net/wifi/WifiSsid;Ljava/lang/String;Ljava/lang/String;JILjava/lang/String;IIJIIIIIZ)V -Landroid/net/wifi/ScanResult;-><init>(Ljava/lang/String;Ljava/lang/String;JILjava/lang/String;IIJIIIIIZ)V -Landroid/net/wifi/ScanResult;->anqpElements:[Landroid/net/wifi/AnqpInformationElement; -Landroid/net/wifi/ScanResult;->carrierApEapType:I -Landroid/net/wifi/ScanResult;->carrierName:Ljava/lang/String; -Landroid/net/wifi/ScanResult;->CIPHER_CCMP:I -Landroid/net/wifi/ScanResult;->CIPHER_NONE:I -Landroid/net/wifi/ScanResult;->CIPHER_NO_GROUP_ADDRESSED:I -Landroid/net/wifi/ScanResult;->CIPHER_TKIP:I -Landroid/net/wifi/ScanResult;->clearFlag(J)V -Landroid/net/wifi/ScanResult;->FLAG_80211mc_RESPONDER:J -Landroid/net/wifi/ScanResult;->FLAG_PASSPOINT_NETWORK:J -Landroid/net/wifi/ScanResult;->is24GHz()Z -Landroid/net/wifi/ScanResult;->is24GHz(I)Z -Landroid/net/wifi/ScanResult;->is5GHz()Z -Landroid/net/wifi/ScanResult;->is5GHz(I)Z -Landroid/net/wifi/ScanResult;->isCarrierAp:Z -Landroid/net/wifi/ScanResult;->KEY_MGMT_EAP:I -Landroid/net/wifi/ScanResult;->KEY_MGMT_EAP_SHA256:I -Landroid/net/wifi/ScanResult;->KEY_MGMT_FT_EAP:I -Landroid/net/wifi/ScanResult;->KEY_MGMT_FT_PSK:I -Landroid/net/wifi/ScanResult;->KEY_MGMT_NONE:I -Landroid/net/wifi/ScanResult;->KEY_MGMT_OSEN:I -Landroid/net/wifi/ScanResult;->KEY_MGMT_PSK:I -Landroid/net/wifi/ScanResult;->KEY_MGMT_PSK_SHA256:I -Landroid/net/wifi/ScanResult;->PROTOCOL_NONE:I -Landroid/net/wifi/ScanResult;->PROTOCOL_OSEN:I -Landroid/net/wifi/ScanResult;->PROTOCOL_WPA2:I -Landroid/net/wifi/ScanResult;->PROTOCOL_WPA:I -Landroid/net/wifi/ScanResult;->radioChainInfos:[Landroid/net/wifi/ScanResult$RadioChainInfo; -Landroid/net/wifi/ScanResult;->setFlag(J)V -Landroid/net/wifi/ScanResult;->UNSPECIFIED:I -Landroid/net/wifi/SupplicantState;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/SupplicantState;->isConnecting(Landroid/net/wifi/SupplicantState;)Z -Landroid/net/wifi/SupplicantState;->isDriverActive(Landroid/net/wifi/SupplicantState;)Z -Landroid/net/wifi/SupplicantState;->isHandshakeState(Landroid/net/wifi/SupplicantState;)Z Landroid/net/wifi/WifiActivityEnergyInfo;-><init>(JIJ[JJJJJ)V Landroid/net/wifi/WifiActivityEnergyInfo;->CREATOR:Landroid/os/Parcelable$Creator; Landroid/net/wifi/WifiActivityEnergyInfo;->getControllerEnergyUsed()J @@ -39785,460 +38300,6 @@ Landroid/net/wifi/WifiActivityEnergyInfo;->STACK_STATE_INVALID:I Landroid/net/wifi/WifiActivityEnergyInfo;->STACK_STATE_STATE_ACTIVE:I Landroid/net/wifi/WifiActivityEnergyInfo;->STACK_STATE_STATE_IDLE:I Landroid/net/wifi/WifiActivityEnergyInfo;->STACK_STATE_STATE_SCANNING:I -Landroid/net/wifi/WifiConfiguration$AuthAlgorithm;-><init>()V -Landroid/net/wifi/WifiConfiguration$GroupCipher;-><init>()V -Landroid/net/wifi/WifiConfiguration$GroupCipher;->GTK_NOT_USED:I -Landroid/net/wifi/WifiConfiguration$KeyMgmt;-><init>()V -Landroid/net/wifi/WifiConfiguration$KeyMgmt;->FT_EAP:I -Landroid/net/wifi/WifiConfiguration$KeyMgmt;->FT_PSK:I -Landroid/net/wifi/WifiConfiguration$KeyMgmt;->OSEN:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;-><init>()V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->clearDisableReasonCounter()V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->clearDisableReasonCounter(I)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->CONNECT_CHOICE_EXISTS:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->CONNECT_CHOICE_NOT_EXISTS:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->copy(Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->DISABLED_ASSOCIATION_REJECTION:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->DISABLED_AUTHENTICATION_FAILURE:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->DISABLED_AUTHENTICATION_NO_CREDENTIALS:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->DISABLED_BAD_LINK:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->DISABLED_BY_WIFI_MANAGER:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->DISABLED_BY_WRONG_PASSWORD:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->DISABLED_DHCP_FAILURE:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->DISABLED_DNS_FAILURE:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->DISABLED_DUE_TO_USER_SWITCH:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->DISABLED_NO_INTERNET_PERMANENT:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->DISABLED_NO_INTERNET_TEMPORARY:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->DISABLED_TLS_VERSION_MISMATCH:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->DISABLED_WPS_START:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getCandidate()Landroid/net/wifi/ScanResult; -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getCandidateScore()I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getConnectChoice()Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getConnectChoiceTimestamp()J -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getDisableReasonCounter(I)I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getDisableTime()J -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getHasEverConnected()Z -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getNetworkDisableReasonString()Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getNetworkDisableReasonString(I)Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getNetworkSelectionBSSID()Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getNetworkSelectionDisableReason()I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getNetworkSelectionStatus()I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getNetworkStatusString()Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getSeenInLastQualifiedNetworkSelection()Z -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->incrementDisableReasonCounter(I)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP:J -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->isDisabledByReason(I)Z -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->isNetworkEnabled()Z -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->isNetworkPermanentlyDisabled()Z -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->isNetworkTemporaryDisabled()Z -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->isNotRecommended()Z -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->mCandidate:Landroid/net/wifi/ScanResult; -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->mCandidateScore:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->mConnectChoice:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->mConnectChoiceTimestamp:J -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->mHasEverConnected:Z -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->mNetworkSeclectionDisableCounter:[I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->mNetworkSelectionBSSID:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->mNetworkSelectionDisableReason:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->mNotRecommended:Z -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->mSeenInLastQualifiedNetworkSelection:Z -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->mStatus:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->mTemporarilyDisabledTimestamp:J -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->NETWORK_SELECTION_DISABLED_MAX:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->NETWORK_SELECTION_DISABLED_STARTING_INDEX:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->NETWORK_SELECTION_ENABLE:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->NETWORK_SELECTION_ENABLED:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->NETWORK_SELECTION_PERMANENTLY_DISABLED:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->NETWORK_SELECTION_STATUS_MAX:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->NETWORK_SELECTION_TEMPORARY_DISABLED:I -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->QUALITY_NETWORK_SELECTION_DISABLE_REASON:[Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->QUALITY_NETWORK_SELECTION_STATUS:[Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->readFromParcel(Landroid/os/Parcel;)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->setCandidate(Landroid/net/wifi/ScanResult;)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->setCandidateScore(I)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->setConnectChoice(Ljava/lang/String;)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->setConnectChoiceTimestamp(J)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->setDisableReasonCounter(II)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->setDisableTime(J)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->setHasEverConnected(Z)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->setNetworkSelectionBSSID(Ljava/lang/String;)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->setNetworkSelectionDisableReason(I)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->setNetworkSelectionStatus(I)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->setNotRecommended(Z)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->setSeenInLastQualifiedNetworkSelection(Z)V -Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->writeToParcel(Landroid/os/Parcel;)V -Landroid/net/wifi/WifiConfiguration$PairwiseCipher;-><init>()V -Landroid/net/wifi/WifiConfiguration$Protocol;-><init>()V -Landroid/net/wifi/WifiConfiguration$Protocol;->OSEN:I -Landroid/net/wifi/WifiConfiguration$RecentFailure;-><init>()V -Landroid/net/wifi/WifiConfiguration$RecentFailure;->clear()V -Landroid/net/wifi/WifiConfiguration$RecentFailure;->getAssociationStatus()I -Landroid/net/wifi/WifiConfiguration$RecentFailure;->mAssociationStatus:I -Landroid/net/wifi/WifiConfiguration$RecentFailure;->NONE:I -Landroid/net/wifi/WifiConfiguration$RecentFailure;->setAssociationStatus(I)V -Landroid/net/wifi/WifiConfiguration$RecentFailure;->STATUS_AP_UNABLE_TO_HANDLE_NEW_STA:I -Landroid/net/wifi/WifiConfiguration$Status;-><init>()V -Landroid/net/wifi/WifiConfiguration;->AP_BAND_2GHZ:I -Landroid/net/wifi/WifiConfiguration;->AP_BAND_5GHZ:I -Landroid/net/wifi/WifiConfiguration;->AP_BAND_ANY:I -Landroid/net/wifi/WifiConfiguration;->BACKUP_VERSION:I -Landroid/net/wifi/WifiConfiguration;->bssidVarName:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->configKey()Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->configKey(Z)Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->creationTime:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->dhcpServer:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->didSelfAdd:Z -Landroid/net/wifi/WifiConfiguration;->dtimInterval:I -Landroid/net/wifi/WifiConfiguration;->ephemeral:Z -Landroid/net/wifi/WifiConfiguration;->getBytesForBackup()[B -Landroid/net/wifi/WifiConfiguration;->getKeyIdForCredentials(Landroid/net/wifi/WifiConfiguration;)Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->getMoTree()Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->getNetworkSelectionStatus()Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus; -Landroid/net/wifi/WifiConfiguration;->getOrCreateRandomizedMacAddress()Landroid/net/MacAddress; -Landroid/net/wifi/WifiConfiguration;->getRandomizedMacAddress()Landroid/net/MacAddress; -Landroid/net/wifi/WifiConfiguration;->getWifiConfigFromBackup(Ljava/io/DataInputStream;)Landroid/net/wifi/WifiConfiguration; -Landroid/net/wifi/WifiConfiguration;->hiddenSSIDVarName:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->HOME_NETWORK_RSSI_BOOST:I -Landroid/net/wifi/WifiConfiguration;->INVALID_NETWORK_ID:I -Landroid/net/wifi/WifiConfiguration;->isLegacyPasspointConfig:Z -Landroid/net/wifi/WifiConfiguration;->isLinked(Landroid/net/wifi/WifiConfiguration;)Z -Landroid/net/wifi/WifiConfiguration;->isMetered(Landroid/net/wifi/WifiConfiguration;Landroid/net/wifi/WifiInfo;)Z -Landroid/net/wifi/WifiConfiguration;->isOpenNetwork()Z -Landroid/net/wifi/WifiConfiguration;->isValidMacAddressForRandomization(Landroid/net/MacAddress;)Z -Landroid/net/wifi/WifiConfiguration;->lastConnected:J -Landroid/net/wifi/WifiConfiguration;->lastDisconnected:J -Landroid/net/wifi/WifiConfiguration;->linkedConfigurations:Ljava/util/HashMap; -Landroid/net/wifi/WifiConfiguration;->LOCAL_ONLY_NETWORK_ID:I -Landroid/net/wifi/WifiConfiguration;->MAXIMUM_RANDOM_MAC_GENERATION_RETRY:I -Landroid/net/wifi/WifiConfiguration;->mCachedConfigKey:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->meteredOverride:I -Landroid/net/wifi/WifiConfiguration;->METERED_OVERRIDE_METERED:I -Landroid/net/wifi/WifiConfiguration;->METERED_OVERRIDE_NONE:I -Landroid/net/wifi/WifiConfiguration;->METERED_OVERRIDE_NOT_METERED:I -Landroid/net/wifi/WifiConfiguration;->mNetworkSelectionStatus:Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus; -Landroid/net/wifi/WifiConfiguration;->mPasspointManagementObjectTree:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->mRandomizedMacAddress:Landroid/net/MacAddress; -Landroid/net/wifi/WifiConfiguration;->peerWifiConfiguration:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->pmfVarName:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->priorityVarName:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->pskVarName:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->readBitSet(Landroid/os/Parcel;)Ljava/util/BitSet; -Landroid/net/wifi/WifiConfiguration;->recentFailure:Landroid/net/wifi/WifiConfiguration$RecentFailure; -Landroid/net/wifi/WifiConfiguration;->requirePMF:Z -Landroid/net/wifi/WifiConfiguration;->setNetworkSelectionStatus(Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;)V -Landroid/net/wifi/WifiConfiguration;->setPasspointManagementObjectTree(Ljava/lang/String;)V -Landroid/net/wifi/WifiConfiguration;->setRandomizedMacAddress(Landroid/net/MacAddress;)V -Landroid/net/wifi/WifiConfiguration;->ssidVarName:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->TAG:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->trimStringForKeyId(Ljava/lang/String;)Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->UNKNOWN_UID:I -Landroid/net/wifi/WifiConfiguration;->updateIdentiferVarName:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->updateIdentifier:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->updateTime:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->userApproved:I -Landroid/net/wifi/WifiConfiguration;->userApprovedAsString(I)Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->USER_APPROVED:I -Landroid/net/wifi/WifiConfiguration;->USER_BANNED:I -Landroid/net/wifi/WifiConfiguration;->USER_PENDING:I -Landroid/net/wifi/WifiConfiguration;->USER_UNSPECIFIED:I -Landroid/net/wifi/WifiConfiguration;->wepTxKeyIdxVarName:Ljava/lang/String; -Landroid/net/wifi/WifiConfiguration;->writeBitSet(Landroid/os/Parcel;Ljava/util/BitSet;)V -Landroid/net/wifi/WifiEnterpriseConfig$Eap;-><init>()V -Landroid/net/wifi/WifiEnterpriseConfig$Eap;->strings:[Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig$Phase2;-><init>()V -Landroid/net/wifi/WifiEnterpriseConfig$Phase2;->AUTHEAP_PREFIX:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig$Phase2;->AUTH_PREFIX:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig$Phase2;->strings:[Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig$SupplicantLoader;->loadValue(Ljava/lang/String;)Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig$SupplicantSaver;->saveValue(Ljava/lang/String;Ljava/lang/String;)Z -Landroid/net/wifi/WifiEnterpriseConfig;->ALTSUBJECT_MATCH_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->ANON_IDENTITY_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->CA_CERT_ALIAS_DELIMITER:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->CA_CERT_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->CA_CERT_PREFIX:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->CA_PATH_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->CLIENT_CERT_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->CLIENT_CERT_PREFIX:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->convertToQuotedString(Ljava/lang/String;)Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->copyFrom(Landroid/net/wifi/WifiEnterpriseConfig;ZLjava/lang/String;)V -Landroid/net/wifi/WifiEnterpriseConfig;->copyFromExternal(Landroid/net/wifi/WifiEnterpriseConfig;Ljava/lang/String;)V -Landroid/net/wifi/WifiEnterpriseConfig;->decodeCaCertificateAlias(Ljava/lang/String;)Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->DOM_SUFFIX_MATCH_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->EAP_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->EMPTY_VALUE:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->encodeCaCertificateAlias(Ljava/lang/String;)Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->ENGINE_DISABLE:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->ENGINE_ENABLE:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->ENGINE_ID_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->ENGINE_ID_KEYSTORE:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->ENGINE_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->getCaCertificateAliases()[Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->getCaPath()Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->getClientPrivateKey()Ljava/security/PrivateKey; -Landroid/net/wifi/WifiEnterpriseConfig;->getFieldValue(Ljava/lang/String;)Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->getFieldValue(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->getKeyId(Landroid/net/wifi/WifiEnterpriseConfig;)Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->getStringIndex([Ljava/lang/String;Ljava/lang/String;I)I -Landroid/net/wifi/WifiEnterpriseConfig;->IDENTITY_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->isEapMethodValid()Z -Landroid/net/wifi/WifiEnterpriseConfig;->KEYSTORES_URI:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->KEYSTORE_URI:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->loadFromSupplicant(Landroid/net/wifi/WifiEnterpriseConfig$SupplicantLoader;)V -Landroid/net/wifi/WifiEnterpriseConfig;->mCaCerts:[Ljava/security/cert/X509Certificate; -Landroid/net/wifi/WifiEnterpriseConfig;->mClientCertificateChain:[Ljava/security/cert/X509Certificate; -Landroid/net/wifi/WifiEnterpriseConfig;->mClientPrivateKey:Ljava/security/PrivateKey; -Landroid/net/wifi/WifiEnterpriseConfig;->mEapMethod:I -Landroid/net/wifi/WifiEnterpriseConfig;->mPhase2Method:I -Landroid/net/wifi/WifiEnterpriseConfig;->OPP_KEY_CACHING:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->PASSWORD_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->PHASE2_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->PLMN_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->PRIVATE_KEY_ID_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->REALM_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->removeDoubleQuotes(Ljava/lang/String;)Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->resetCaCertificate()V -Landroid/net/wifi/WifiEnterpriseConfig;->resetClientKeyEntry()V -Landroid/net/wifi/WifiEnterpriseConfig;->saveToSupplicant(Landroid/net/wifi/WifiEnterpriseConfig$SupplicantSaver;)Z -Landroid/net/wifi/WifiEnterpriseConfig;->setCaCertificateAliases([Ljava/lang/String;)V -Landroid/net/wifi/WifiEnterpriseConfig;->setCaPath(Ljava/lang/String;)V -Landroid/net/wifi/WifiEnterpriseConfig;->setFieldValue(Ljava/lang/String;Ljava/lang/String;)V -Landroid/net/wifi/WifiEnterpriseConfig;->setFieldValue(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V -Landroid/net/wifi/WifiEnterpriseConfig;->SUBJECT_MATCH_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->SUPPLICANT_CONFIG_KEYS:[Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->TAG:Ljava/lang/String; -Landroid/net/wifi/WifiEnterpriseConfig;->UNQUOTED_KEYS:Ljava/util/List; -Landroid/net/wifi/WifiInfo;-><init>(Landroid/net/wifi/WifiInfo;)V -Landroid/net/wifi/WifiInfo;->hasRealMacAddress()Z -Landroid/net/wifi/WifiInfo;->is24GHz()Z -Landroid/net/wifi/WifiInfo;->MAX_RSSI:I -Landroid/net/wifi/WifiInfo;->mEphemeral:Z -Landroid/net/wifi/WifiInfo;->mFrequency:I -Landroid/net/wifi/WifiInfo;->MIN_RSSI:I -Landroid/net/wifi/WifiInfo;->mLinkSpeed:I -Landroid/net/wifi/WifiInfo;->mMeteredHint:Z -Landroid/net/wifi/WifiInfo;->mNetworkId:I -Landroid/net/wifi/WifiInfo;->mRssi:I -Landroid/net/wifi/WifiInfo;->mSupplicantState:Landroid/net/wifi/SupplicantState; -Landroid/net/wifi/WifiInfo;->reset()V -Landroid/net/wifi/WifiInfo;->rxSuccess:J -Landroid/net/wifi/WifiInfo;->rxSuccessRate:D -Landroid/net/wifi/WifiInfo;->setEphemeral(Z)V -Landroid/net/wifi/WifiInfo;->setFrequency(I)V -Landroid/net/wifi/WifiInfo;->setInetAddress(Ljava/net/InetAddress;)V -Landroid/net/wifi/WifiInfo;->setMeteredHint(Z)V -Landroid/net/wifi/WifiInfo;->setSSID(Landroid/net/wifi/WifiSsid;)V -Landroid/net/wifi/WifiInfo;->stateMap:Ljava/util/EnumMap; -Landroid/net/wifi/WifiInfo;->TAG:Ljava/lang/String; -Landroid/net/wifi/WifiInfo;->txBad:J -Landroid/net/wifi/WifiInfo;->txBadRate:D -Landroid/net/wifi/WifiInfo;->txRetries:J -Landroid/net/wifi/WifiInfo;->txRetriesRate:D -Landroid/net/wifi/WifiInfo;->txSuccess:J -Landroid/net/wifi/WifiInfo;->txSuccessRate:D -Landroid/net/wifi/WifiInfo;->valueOf(Ljava/lang/String;)Landroid/net/wifi/SupplicantState; -Landroid/net/wifi/WifiManager$LocalOnlyHotspotCallback;->REQUEST_REGISTERED:I -Landroid/net/wifi/WifiManager$LocalOnlyHotspotCallbackProxy;-><init>(Landroid/net/wifi/WifiManager;Landroid/os/Looper;Landroid/net/wifi/WifiManager$LocalOnlyHotspotCallback;)V -Landroid/net/wifi/WifiManager$LocalOnlyHotspotCallbackProxy;->getMessenger()Landroid/os/Messenger; -Landroid/net/wifi/WifiManager$LocalOnlyHotspotCallbackProxy;->mHandler:Landroid/os/Handler; -Landroid/net/wifi/WifiManager$LocalOnlyHotspotCallbackProxy;->mLooper:Landroid/os/Looper; -Landroid/net/wifi/WifiManager$LocalOnlyHotspotCallbackProxy;->mMessenger:Landroid/os/Messenger; -Landroid/net/wifi/WifiManager$LocalOnlyHotspotCallbackProxy;->mWifiManager:Ljava/lang/ref/WeakReference; -Landroid/net/wifi/WifiManager$LocalOnlyHotspotCallbackProxy;->notifyFailed(I)V -Landroid/net/wifi/WifiManager$LocalOnlyHotspotObserver;-><init>()V -Landroid/net/wifi/WifiManager$LocalOnlyHotspotObserver;->onRegistered(Landroid/net/wifi/WifiManager$LocalOnlyHotspotSubscription;)V -Landroid/net/wifi/WifiManager$LocalOnlyHotspotObserver;->onStarted(Landroid/net/wifi/WifiConfiguration;)V -Landroid/net/wifi/WifiManager$LocalOnlyHotspotObserver;->onStopped()V -Landroid/net/wifi/WifiManager$LocalOnlyHotspotObserverProxy;-><init>(Landroid/net/wifi/WifiManager;Landroid/os/Looper;Landroid/net/wifi/WifiManager$LocalOnlyHotspotObserver;)V -Landroid/net/wifi/WifiManager$LocalOnlyHotspotObserverProxy;->getMessenger()Landroid/os/Messenger; -Landroid/net/wifi/WifiManager$LocalOnlyHotspotObserverProxy;->mHandler:Landroid/os/Handler; -Landroid/net/wifi/WifiManager$LocalOnlyHotspotObserverProxy;->mLooper:Landroid/os/Looper; -Landroid/net/wifi/WifiManager$LocalOnlyHotspotObserverProxy;->mMessenger:Landroid/os/Messenger; -Landroid/net/wifi/WifiManager$LocalOnlyHotspotObserverProxy;->mWifiManager:Ljava/lang/ref/WeakReference; -Landroid/net/wifi/WifiManager$LocalOnlyHotspotObserverProxy;->registered()V -Landroid/net/wifi/WifiManager$LocalOnlyHotspotReservation;->mCloseGuard:Ldalvik/system/CloseGuard; -Landroid/net/wifi/WifiManager$LocalOnlyHotspotReservation;->mConfig:Landroid/net/wifi/WifiConfiguration; -Landroid/net/wifi/WifiManager$LocalOnlyHotspotSubscription;->mCloseGuard:Ldalvik/system/CloseGuard; -Landroid/net/wifi/WifiManager$MulticastLock;->mBinder:Landroid/os/IBinder; -Landroid/net/wifi/WifiManager$MulticastLock;->mHeld:Z -Landroid/net/wifi/WifiManager$MulticastLock;->mRefCount:I -Landroid/net/wifi/WifiManager$MulticastLock;->mRefCounted:Z -Landroid/net/wifi/WifiManager$MulticastLock;->mTag:Ljava/lang/String; -Landroid/net/wifi/WifiManager$ProvisioningCallbackProxy;-><init>(Landroid/os/Looper;Landroid/net/wifi/hotspot2/ProvisioningCallback;)V -Landroid/net/wifi/WifiManager$ProvisioningCallbackProxy;->mCallback:Landroid/net/wifi/hotspot2/ProvisioningCallback; -Landroid/net/wifi/WifiManager$ProvisioningCallbackProxy;->mHandler:Landroid/os/Handler; -Landroid/net/wifi/WifiManager$ProvisioningCallbackProxy;->onProvisioningFailure(I)V -Landroid/net/wifi/WifiManager$ProvisioningCallbackProxy;->onProvisioningStatus(I)V -Landroid/net/wifi/WifiManager$ServiceHandler;->dispatchMessageToListeners(Landroid/os/Message;)V -Landroid/net/wifi/WifiManager$SoftApCallback;->onNumClientsChanged(I)V -Landroid/net/wifi/WifiManager$SoftApCallback;->onStateChanged(II)V -Landroid/net/wifi/WifiManager$SoftApCallbackProxy;-><init>(Landroid/os/Looper;Landroid/net/wifi/WifiManager$SoftApCallback;)V -Landroid/net/wifi/WifiManager$SoftApCallbackProxy;->mCallback:Landroid/net/wifi/WifiManager$SoftApCallback; -Landroid/net/wifi/WifiManager$SoftApCallbackProxy;->mHandler:Landroid/os/Handler; -Landroid/net/wifi/WifiManager$SoftApCallbackProxy;->onNumClientsChanged(I)V -Landroid/net/wifi/WifiManager$SoftApCallbackProxy;->onStateChanged(II)V -Landroid/net/wifi/WifiManager$TxPacketCountListener;->onFailure(I)V -Landroid/net/wifi/WifiManager$TxPacketCountListener;->onSuccess(I)V -Landroid/net/wifi/WifiManager$WifiLock;->mBinder:Landroid/os/IBinder; -Landroid/net/wifi/WifiManager$WifiLock;->mHeld:Z -Landroid/net/wifi/WifiManager$WifiLock;->mLockType:I -Landroid/net/wifi/WifiManager$WifiLock;->mRefCount:I -Landroid/net/wifi/WifiManager$WifiLock;->mRefCounted:Z -Landroid/net/wifi/WifiManager$WifiLock;->mTag:Ljava/lang/String; -Landroid/net/wifi/WifiManager$WifiLock;->mWorkSource:Landroid/os/WorkSource; -Landroid/net/wifi/WifiManager;-><init>(Landroid/content/Context;Landroid/net/wifi/IWifiManager;Landroid/os/Looper;)V -Landroid/net/wifi/WifiManager;->ACTION_PASSPOINT_DEAUTH_IMMINENT:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->ACTION_PASSPOINT_ICON:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->ACTION_PASSPOINT_OSU_PROVIDERS_LIST:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->ACTION_REQUEST_DISABLE:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->ACTION_REQUEST_ENABLE:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->addOrUpdateNetwork(Landroid/net/wifi/WifiConfiguration;)I -Landroid/net/wifi/WifiManager;->BASE:I -Landroid/net/wifi/WifiManager;->BATCHED_SCAN_RESULTS_AVAILABLE_ACTION:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->BUSY:I -Landroid/net/wifi/WifiManager;->CANCEL_WPS:I -Landroid/net/wifi/WifiManager;->CANCEL_WPS_FAILED:I -Landroid/net/wifi/WifiManager;->CANCEL_WPS_SUCCEDED:I -Landroid/net/wifi/WifiManager;->CONNECT_NETWORK:I -Landroid/net/wifi/WifiManager;->CONNECT_NETWORK_FAILED:I -Landroid/net/wifi/WifiManager;->CONNECT_NETWORK_SUCCEEDED:I -Landroid/net/wifi/WifiManager;->DATA_ACTIVITY_IN:I -Landroid/net/wifi/WifiManager;->DATA_ACTIVITY_INOUT:I -Landroid/net/wifi/WifiManager;->DATA_ACTIVITY_NONE:I -Landroid/net/wifi/WifiManager;->DATA_ACTIVITY_NOTIFICATION:I -Landroid/net/wifi/WifiManager;->DATA_ACTIVITY_OUT:I -Landroid/net/wifi/WifiManager;->deauthenticateNetwork(JZ)V -Landroid/net/wifi/WifiManager;->DEFAULT_POOR_NETWORK_AVOIDANCE_ENABLED:Z -Landroid/net/wifi/WifiManager;->disableEphemeralNetwork(Ljava/lang/String;)V -Landroid/net/wifi/WifiManager;->DISABLE_NETWORK:I -Landroid/net/wifi/WifiManager;->DISABLE_NETWORK_FAILED:I -Landroid/net/wifi/WifiManager;->DISABLE_NETWORK_SUCCEEDED:I -Landroid/net/wifi/WifiManager;->enableWifiConnectivityManager(Z)V -Landroid/net/wifi/WifiManager;->ERROR:I -Landroid/net/wifi/WifiManager;->ERROR_AUTH_FAILURE_EAP_FAILURE:I -Landroid/net/wifi/WifiManager;->ERROR_AUTH_FAILURE_NONE:I -Landroid/net/wifi/WifiManager;->ERROR_AUTH_FAILURE_TIMEOUT:I -Landroid/net/wifi/WifiManager;->ERROR_AUTH_FAILURE_WRONG_PSWD:I -Landroid/net/wifi/WifiManager;->EXTRA_ANQP_ELEMENT_DATA:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->EXTRA_BSSID_LONG:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->EXTRA_DELAY:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->EXTRA_ESS:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->EXTRA_FILENAME:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->EXTRA_ICON:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->EXTRA_LINK_PROPERTIES:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->EXTRA_NETWORK_CAPABILITIES:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->EXTRA_SCAN_AVAILABLE:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->EXTRA_SUBSCRIPTION_REMEDIATION_METHOD:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->EXTRA_SUPPLICANT_ERROR_REASON:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->EXTRA_URL:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->EXTRA_WIFI_AP_FAILURE_REASON:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->EXTRA_WIFI_AP_INTERFACE_NAME:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->EXTRA_WIFI_AP_MODE:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->factoryReset()V -Landroid/net/wifi/WifiManager;->FORGET_NETWORK:I -Landroid/net/wifi/WifiManager;->FORGET_NETWORK_FAILED:I -Landroid/net/wifi/WifiManager;->FORGET_NETWORK_SUCCEEDED:I -Landroid/net/wifi/WifiManager;->getAllMatchingWifiConfigs(Landroid/net/wifi/ScanResult;)Ljava/util/List; -Landroid/net/wifi/WifiManager;->getChannel()Lcom/android/internal/util/AsyncChannel; -Landroid/net/wifi/WifiManager;->getControllerActivityEnergyInfo(I)Landroid/net/wifi/WifiActivityEnergyInfo; -Landroid/net/wifi/WifiManager;->getCurrentNetworkWpsNfcConfigurationToken()Ljava/lang/String; -Landroid/net/wifi/WifiManager;->getEnableAutoJoinWhenAssociated()Z -Landroid/net/wifi/WifiManager;->getMatchingOsuProviders(Landroid/net/wifi/ScanResult;)Ljava/util/List; -Landroid/net/wifi/WifiManager;->getSupportedFeatures()I -Landroid/net/wifi/WifiManager;->getTxPacketCount(Landroid/net/wifi/WifiManager$TxPacketCountListener;)V -Landroid/net/wifi/WifiManager;->HOTSPOT_FAILED:I -Landroid/net/wifi/WifiManager;->HOTSPOT_OBSERVER_REGISTERED:I -Landroid/net/wifi/WifiManager;->HOTSPOT_STARTED:I -Landroid/net/wifi/WifiManager;->HOTSPOT_STOPPED:I -Landroid/net/wifi/WifiManager;->IFACE_IP_MODE_CONFIGURATION_ERROR:I -Landroid/net/wifi/WifiManager;->IFACE_IP_MODE_LOCAL_ONLY:I -Landroid/net/wifi/WifiManager;->IFACE_IP_MODE_TETHERED:I -Landroid/net/wifi/WifiManager;->IFACE_IP_MODE_UNSPECIFIED:I -Landroid/net/wifi/WifiManager;->INVALID_ARGS:I -Landroid/net/wifi/WifiManager;->INVALID_KEY:I -Landroid/net/wifi/WifiManager;->IN_PROGRESS:I -Landroid/net/wifi/WifiManager;->isAdditionalStaSupported()Z -Landroid/net/wifi/WifiManager;->isDualModeSupported()Z -Landroid/net/wifi/WifiManager;->isFeatureSupported(I)Z -Landroid/net/wifi/WifiManager;->isMulticastEnabled()Z -Landroid/net/wifi/WifiManager;->isOffChannelTdlsSupported()Z -Landroid/net/wifi/WifiManager;->isPasspointSupported()Z -Landroid/net/wifi/WifiManager;->isWifiAwareSupported()Z -Landroid/net/wifi/WifiManager;->mAsyncChannel:Lcom/android/internal/util/AsyncChannel; -Landroid/net/wifi/WifiManager;->matchProviderWithCurrentNetwork(Ljava/lang/String;)I -Landroid/net/wifi/WifiManager;->MAX_ACTIVE_LOCKS:I -Landroid/net/wifi/WifiManager;->mConnected:Ljava/util/concurrent/CountDownLatch; -Landroid/net/wifi/WifiManager;->mContext:Landroid/content/Context; -Landroid/net/wifi/WifiManager;->mListenerKey:I -Landroid/net/wifi/WifiManager;->mListenerMap:Landroid/util/SparseArray; -Landroid/net/wifi/WifiManager;->mListenerMapLock:Ljava/lang/Object; -Landroid/net/wifi/WifiManager;->mLock:Ljava/lang/Object; -Landroid/net/wifi/WifiManager;->mLOHSCallbackProxy:Landroid/net/wifi/WifiManager$LocalOnlyHotspotCallbackProxy; -Landroid/net/wifi/WifiManager;->mLOHSObserverProxy:Landroid/net/wifi/WifiManager$LocalOnlyHotspotObserverProxy; -Landroid/net/wifi/WifiManager;->mLooper:Landroid/os/Looper; -Landroid/net/wifi/WifiManager;->mTargetSdkVersion:I -Landroid/net/wifi/WifiManager;->NOT_AUTHORIZED:I -Landroid/net/wifi/WifiManager;->putListener(Ljava/lang/Object;)I -Landroid/net/wifi/WifiManager;->queryPasspointIcon(JLjava/lang/String;)V -Landroid/net/wifi/WifiManager;->registerSoftApCallback(Landroid/net/wifi/WifiManager$SoftApCallback;Landroid/os/Handler;)V -Landroid/net/wifi/WifiManager;->removeListener(I)Ljava/lang/Object; -Landroid/net/wifi/WifiManager;->restoreBackupData([B)V -Landroid/net/wifi/WifiManager;->restoreSupplicantBackupData([B[B)V -Landroid/net/wifi/WifiManager;->retrieveBackupData()[B -Landroid/net/wifi/WifiManager;->RSSI_PKTCNT_FETCH:I -Landroid/net/wifi/WifiManager;->RSSI_PKTCNT_FETCH_FAILED:I -Landroid/net/wifi/WifiManager;->RSSI_PKTCNT_FETCH_SUCCEEDED:I -Landroid/net/wifi/WifiManager;->SAP_START_FAILURE_GENERAL:I -Landroid/net/wifi/WifiManager;->SAP_START_FAILURE_NO_CHANNEL:I -Landroid/net/wifi/WifiManager;->SAVE_NETWORK:I -Landroid/net/wifi/WifiManager;->SAVE_NETWORK_FAILED:I -Landroid/net/wifi/WifiManager;->SAVE_NETWORK_SUCCEEDED:I -Landroid/net/wifi/WifiManager;->setCountryCode(Ljava/lang/String;)V -Landroid/net/wifi/WifiManager;->setEnableAutoJoinWhenAssociated(Z)Z -Landroid/net/wifi/WifiManager;->sServiceHandlerDispatchLock:Ljava/lang/Object; -Landroid/net/wifi/WifiManager;->startSoftAp(Landroid/net/wifi/WifiConfiguration;)Z -Landroid/net/wifi/WifiManager;->startSubscriptionProvisioning(Landroid/net/wifi/hotspot2/OsuProvider;Landroid/net/wifi/hotspot2/ProvisioningCallback;Landroid/os/Handler;)V -Landroid/net/wifi/WifiManager;->START_WPS:I -Landroid/net/wifi/WifiManager;->START_WPS_SUCCEEDED:I -Landroid/net/wifi/WifiManager;->stopLocalOnlyHotspot()V -Landroid/net/wifi/WifiManager;->stopSoftAp()Z -Landroid/net/wifi/WifiManager;->TAG:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->unregisterLocalOnlyHotspotObserver()V -Landroid/net/wifi/WifiManager;->unregisterSoftApCallback(Landroid/net/wifi/WifiManager$SoftApCallback;)V -Landroid/net/wifi/WifiManager;->updateInterfaceIpState(Ljava/lang/String;I)V -Landroid/net/wifi/WifiManager;->watchLocalOnlyHotspot(Landroid/net/wifi/WifiManager$LocalOnlyHotspotObserver;Landroid/os/Handler;)V -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_ADDITIONAL_STA:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_AP_STA:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_AWARE:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_BATCH_SCAN:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_CONFIG_NDO:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_CONTROL_ROAMING:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_D2AP_RTT:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_D2D_RTT:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_EPR:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_HAL_EPNO:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_IE_WHITELIST:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_INFRA:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_INFRA_5G:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_LINK_LAYER_STATS:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_LOGGER:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_MKEEP_ALIVE:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_MOBILE_HOTSPOT:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_P2P:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_PASSPOINT:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_PNO:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_RSSI_MONITOR:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_SCANNER:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_SCAN_RAND:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_TDLS:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_TDLS_OFFCHANNEL:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_TRANSMIT_POWER:I -Landroid/net/wifi/WifiManager;->WIFI_FEATURE_TX_POWER_LIMIT:I -Landroid/net/wifi/WifiManager;->WIFI_MODE_NO_LOCKS_HELD:I -Landroid/net/wifi/WifiManager;->WIFI_SCAN_AVAILABLE:Ljava/lang/String; -Landroid/net/wifi/WifiManager;->WPS_COMPLETED:I -Landroid/net/wifi/WifiManager;->WPS_FAILED:I -Landroid/net/wifi/WifiNetworkConnectionStatistics;->TAG:Ljava/lang/String; Landroid/net/wifi/WifiNetworkScoreCache$CacheListener;-><init>(Landroid/os/Handler;)V Landroid/net/wifi/WifiNetworkScoreCache$CacheListener;->mHandler:Landroid/os/Handler; Landroid/net/wifi/WifiNetworkScoreCache$CacheListener;->networkCacheUpdated(Ljava/util/List;)V @@ -40268,116 +38329,6 @@ Landroid/net/wifi/WifiNetworkScoreCache;->registerListener(Landroid/net/wifi/Wif Landroid/net/wifi/WifiNetworkScoreCache;->TAG:Ljava/lang/String; Landroid/net/wifi/WifiNetworkScoreCache;->unregisterListener()V Landroid/net/wifi/WifiNetworkScoreCache;->updateScores(Ljava/util/List;)V -Landroid/net/wifi/WifiScanner$ChannelSpec;->dwellTimeMS:I -Landroid/net/wifi/WifiScanner$ChannelSpec;->passive:Z -Landroid/net/wifi/WifiScanner$HotlistSettings;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/WifiScanner$OperationResult;-><init>(ILjava/lang/String;)V -Landroid/net/wifi/WifiScanner$OperationResult;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/WifiScanner$OperationResult;->description:Ljava/lang/String; -Landroid/net/wifi/WifiScanner$OperationResult;->reason:I -Landroid/net/wifi/WifiScanner$ParcelableScanData;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/WifiScanner$ParcelableScanResults;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/WifiScanner$PnoScanListener;->onPnoNetworkFound([Landroid/net/wifi/ScanResult;)V -Landroid/net/wifi/WifiScanner$PnoSettings$PnoNetwork;-><init>(Ljava/lang/String;)V -Landroid/net/wifi/WifiScanner$PnoSettings$PnoNetwork;->authBitField:B -Landroid/net/wifi/WifiScanner$PnoSettings$PnoNetwork;->AUTH_CODE_EAPOL:B -Landroid/net/wifi/WifiScanner$PnoSettings$PnoNetwork;->AUTH_CODE_OPEN:B -Landroid/net/wifi/WifiScanner$PnoSettings$PnoNetwork;->AUTH_CODE_PSK:B -Landroid/net/wifi/WifiScanner$PnoSettings$PnoNetwork;->flags:B -Landroid/net/wifi/WifiScanner$PnoSettings$PnoNetwork;->FLAG_A_BAND:B -Landroid/net/wifi/WifiScanner$PnoSettings$PnoNetwork;->FLAG_DIRECTED_SCAN:B -Landroid/net/wifi/WifiScanner$PnoSettings$PnoNetwork;->FLAG_G_BAND:B -Landroid/net/wifi/WifiScanner$PnoSettings$PnoNetwork;->FLAG_SAME_NETWORK:B -Landroid/net/wifi/WifiScanner$PnoSettings$PnoNetwork;->FLAG_STRICT_MATCH:B -Landroid/net/wifi/WifiScanner$PnoSettings$PnoNetwork;->ssid:Ljava/lang/String; -Landroid/net/wifi/WifiScanner$PnoSettings;-><init>()V -Landroid/net/wifi/WifiScanner$PnoSettings;->band5GHzBonus:I -Landroid/net/wifi/WifiScanner$PnoSettings;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/WifiScanner$PnoSettings;->currentConnectionBonus:I -Landroid/net/wifi/WifiScanner$PnoSettings;->initialScoreMax:I -Landroid/net/wifi/WifiScanner$PnoSettings;->isConnected:Z -Landroid/net/wifi/WifiScanner$PnoSettings;->min24GHzRssi:I -Landroid/net/wifi/WifiScanner$PnoSettings;->min5GHzRssi:I -Landroid/net/wifi/WifiScanner$PnoSettings;->networkList:[Landroid/net/wifi/WifiScanner$PnoSettings$PnoNetwork; -Landroid/net/wifi/WifiScanner$PnoSettings;->sameNetworkBonus:I -Landroid/net/wifi/WifiScanner$PnoSettings;->secureBonus:I -Landroid/net/wifi/WifiScanner$ScanData;-><init>()V -Landroid/net/wifi/WifiScanner$ScanData;-><init>(IIIZ[Landroid/net/wifi/ScanResult;)V -Landroid/net/wifi/WifiScanner$ScanData;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/WifiScanner$ScanData;->getBucketsScanned()I -Landroid/net/wifi/WifiScanner$ScanData;->isAllChannelsScanned()Z -Landroid/net/wifi/WifiScanner$ScanData;->mAllChannelsScanned:Z -Landroid/net/wifi/WifiScanner$ScanData;->mBucketsScanned:I -Landroid/net/wifi/WifiScanner$ScanData;->mFlags:I -Landroid/net/wifi/WifiScanner$ScanData;->mId:I -Landroid/net/wifi/WifiScanner$ScanData;->mResults:[Landroid/net/wifi/ScanResult; -Landroid/net/wifi/WifiScanner$ScanSettings$HiddenNetwork;-><init>(Ljava/lang/String;)V -Landroid/net/wifi/WifiScanner$ScanSettings$HiddenNetwork;->ssid:Ljava/lang/String; -Landroid/net/wifi/WifiScanner$ScanSettings;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/WifiScanner$ScanSettings;->hiddenNetworks:[Landroid/net/wifi/WifiScanner$ScanSettings$HiddenNetwork; -Landroid/net/wifi/WifiScanner$ScanSettings;->isPnoScan:Z -Landroid/net/wifi/WifiScanner$ScanSettings;->type:I -Landroid/net/wifi/WifiScanner$WifiChangeSettings;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/wifi/WifiScanner;-><init>(Landroid/content/Context;Landroid/net/wifi/IWifiScanner;Landroid/os/Looper;)V -Landroid/net/wifi/WifiScanner;->addListener(Landroid/net/wifi/WifiScanner$ActionListener;)I -Landroid/net/wifi/WifiScanner;->BASE:I -Landroid/net/wifi/WifiScanner;->CMD_DEREGISTER_SCAN_LISTENER:I -Landroid/net/wifi/WifiScanner;->CMD_FULL_SCAN_RESULT:I -Landroid/net/wifi/WifiScanner;->CMD_GET_SCAN_RESULTS:I -Landroid/net/wifi/WifiScanner;->CMD_GET_SINGLE_SCAN_RESULTS:I -Landroid/net/wifi/WifiScanner;->CMD_OP_FAILED:I -Landroid/net/wifi/WifiScanner;->CMD_OP_SUCCEEDED:I -Landroid/net/wifi/WifiScanner;->CMD_PNO_NETWORK_FOUND:I -Landroid/net/wifi/WifiScanner;->CMD_REGISTER_SCAN_LISTENER:I -Landroid/net/wifi/WifiScanner;->CMD_SCAN_RESULT:I -Landroid/net/wifi/WifiScanner;->CMD_SINGLE_SCAN_COMPLETED:I -Landroid/net/wifi/WifiScanner;->CMD_START_BACKGROUND_SCAN:I -Landroid/net/wifi/WifiScanner;->CMD_START_PNO_SCAN:I -Landroid/net/wifi/WifiScanner;->CMD_START_SINGLE_SCAN:I -Landroid/net/wifi/WifiScanner;->CMD_STOP_BACKGROUND_SCAN:I -Landroid/net/wifi/WifiScanner;->CMD_STOP_PNO_SCAN:I -Landroid/net/wifi/WifiScanner;->CMD_STOP_SINGLE_SCAN:I -Landroid/net/wifi/WifiScanner;->DBG:Z -Landroid/net/wifi/WifiScanner;->deregisterScanListener(Landroid/net/wifi/WifiScanner$ScanListener;)V -Landroid/net/wifi/WifiScanner;->getAvailableChannels(I)Ljava/util/List; -Landroid/net/wifi/WifiScanner;->getListener(I)Ljava/lang/Object; -Landroid/net/wifi/WifiScanner;->getListenerKey(Ljava/lang/Object;)I -Landroid/net/wifi/WifiScanner;->getSingleScanResults()Ljava/util/List; -Landroid/net/wifi/WifiScanner;->GET_AVAILABLE_CHANNELS_EXTRA:Ljava/lang/String; -Landroid/net/wifi/WifiScanner;->INVALID_KEY:I -Landroid/net/wifi/WifiScanner;->mAsyncChannel:Lcom/android/internal/util/AsyncChannel; -Landroid/net/wifi/WifiScanner;->mContext:Landroid/content/Context; -Landroid/net/wifi/WifiScanner;->mInternalHandler:Landroid/os/Handler; -Landroid/net/wifi/WifiScanner;->mListenerKey:I -Landroid/net/wifi/WifiScanner;->mListenerMap:Landroid/util/SparseArray; -Landroid/net/wifi/WifiScanner;->mListenerMapLock:Ljava/lang/Object; -Landroid/net/wifi/WifiScanner;->mService:Landroid/net/wifi/IWifiScanner; -Landroid/net/wifi/WifiScanner;->PNO_PARAMS_PNO_SETTINGS_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiScanner;->PNO_PARAMS_SCAN_SETTINGS_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiScanner;->putListener(Ljava/lang/Object;)I -Landroid/net/wifi/WifiScanner;->registerScanListener(Landroid/net/wifi/WifiScanner$ScanListener;)V -Landroid/net/wifi/WifiScanner;->removeListener(I)Ljava/lang/Object; -Landroid/net/wifi/WifiScanner;->removeListener(Ljava/lang/Object;)I -Landroid/net/wifi/WifiScanner;->SCAN_PARAMS_SCAN_SETTINGS_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiScanner;->SCAN_PARAMS_WORK_SOURCE_KEY:Ljava/lang/String; -Landroid/net/wifi/WifiScanner;->startConnectedPnoScan(Landroid/net/wifi/WifiScanner$ScanSettings;Landroid/net/wifi/WifiScanner$PnoSettings;Landroid/net/wifi/WifiScanner$PnoScanListener;)V -Landroid/net/wifi/WifiScanner;->startDisconnectedPnoScan(Landroid/net/wifi/WifiScanner$ScanSettings;Landroid/net/wifi/WifiScanner$PnoSettings;Landroid/net/wifi/WifiScanner$PnoScanListener;)V -Landroid/net/wifi/WifiScanner;->startPnoScan(Landroid/net/wifi/WifiScanner$ScanSettings;Landroid/net/wifi/WifiScanner$PnoSettings;I)V -Landroid/net/wifi/WifiScanner;->stopPnoScan(Landroid/net/wifi/WifiScanner$ScanListener;)V -Landroid/net/wifi/WifiScanner;->TAG:Ljava/lang/String; -Landroid/net/wifi/WifiScanner;->TYPE_HIGH_ACCURACY:I -Landroid/net/wifi/WifiScanner;->TYPE_LOW_LATENCY:I -Landroid/net/wifi/WifiScanner;->TYPE_LOW_POWER:I -Landroid/net/wifi/WifiScanner;->validateChannel()V -Landroid/net/wifi/WifiSsid;-><init>()V -Landroid/net/wifi/WifiSsid;->convertToBytes(Ljava/lang/String;)V -Landroid/net/wifi/WifiSsid;->createFromByteArray([B)Landroid/net/wifi/WifiSsid; -Landroid/net/wifi/WifiSsid;->createFromHex(Ljava/lang/String;)Landroid/net/wifi/WifiSsid; -Landroid/net/wifi/WifiSsid;->getHexString()Ljava/lang/String; -Landroid/net/wifi/WifiSsid;->HEX_RADIX:I -Landroid/net/wifi/WifiSsid;->isArrayAllZeroes([B)Z -Landroid/net/wifi/WifiSsid;->isHidden()Z -Landroid/net/wifi/WifiSsid;->TAG:Ljava/lang/String; Landroid/net/wifi/WifiWakeReasonAndCounts;-><init>()V Landroid/net/wifi/WifiWakeReasonAndCounts;->cmdEventWakeCntArray:[I Landroid/net/wifi/WifiWakeReasonAndCounts;->CREATOR:Landroid/os/Parcelable$Creator; @@ -43626,45 +41577,6 @@ Landroid/os/IServiceManager;->listServices(I)[Ljava/lang/String; Landroid/os/IServiceManager;->LIST_SERVICES_TRANSACTION:I Landroid/os/IServiceManager;->setPermissionController(Landroid/os/IPermissionController;)V Landroid/os/IServiceManager;->SET_PERMISSION_CONTROLLER_TRANSACTION:I -Landroid/os/IStatsCompanionService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/os/IStatsCompanionService$Stub$Proxy;->cancelAlarmForSubscriberTriggering()V -Landroid/os/IStatsCompanionService$Stub$Proxy;->cancelAnomalyAlarm()V -Landroid/os/IStatsCompanionService$Stub$Proxy;->cancelPullingAlarm()V -Landroid/os/IStatsCompanionService$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String; -Landroid/os/IStatsCompanionService$Stub$Proxy;->mRemote:Landroid/os/IBinder; -Landroid/os/IStatsCompanionService$Stub$Proxy;->pullData(I)[Landroid/os/StatsLogEventWrapper; -Landroid/os/IStatsCompanionService$Stub$Proxy;->sendDataBroadcast(Landroid/os/IBinder;J)V -Landroid/os/IStatsCompanionService$Stub$Proxy;->sendSubscriberBroadcast(Landroid/os/IBinder;JJJJ[Ljava/lang/String;Landroid/os/StatsDimensionsValue;)V -Landroid/os/IStatsCompanionService$Stub$Proxy;->setAlarmForSubscriberTriggering(J)V -Landroid/os/IStatsCompanionService$Stub$Proxy;->setAnomalyAlarm(J)V -Landroid/os/IStatsCompanionService$Stub$Proxy;->setPullingAlarm(J)V -Landroid/os/IStatsCompanionService$Stub$Proxy;->statsdReady()V -Landroid/os/IStatsCompanionService$Stub$Proxy;->triggerUidSnapshot()V -Landroid/os/IStatsCompanionService$Stub;-><init>()V -Landroid/os/IStatsCompanionService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IStatsCompanionService; -Landroid/os/IStatsCompanionService$Stub;->DESCRIPTOR:Ljava/lang/String; -Landroid/os/IStatsCompanionService$Stub;->TRANSACTION_cancelAlarmForSubscriberTriggering:I -Landroid/os/IStatsCompanionService$Stub;->TRANSACTION_cancelAnomalyAlarm:I -Landroid/os/IStatsCompanionService$Stub;->TRANSACTION_cancelPullingAlarm:I -Landroid/os/IStatsCompanionService$Stub;->TRANSACTION_pullData:I -Landroid/os/IStatsCompanionService$Stub;->TRANSACTION_sendDataBroadcast:I -Landroid/os/IStatsCompanionService$Stub;->TRANSACTION_sendSubscriberBroadcast:I -Landroid/os/IStatsCompanionService$Stub;->TRANSACTION_setAlarmForSubscriberTriggering:I -Landroid/os/IStatsCompanionService$Stub;->TRANSACTION_setAnomalyAlarm:I -Landroid/os/IStatsCompanionService$Stub;->TRANSACTION_setPullingAlarm:I -Landroid/os/IStatsCompanionService$Stub;->TRANSACTION_statsdReady:I -Landroid/os/IStatsCompanionService$Stub;->TRANSACTION_triggerUidSnapshot:I -Landroid/os/IStatsCompanionService;->cancelAlarmForSubscriberTriggering()V -Landroid/os/IStatsCompanionService;->cancelAnomalyAlarm()V -Landroid/os/IStatsCompanionService;->cancelPullingAlarm()V -Landroid/os/IStatsCompanionService;->pullData(I)[Landroid/os/StatsLogEventWrapper; -Landroid/os/IStatsCompanionService;->sendDataBroadcast(Landroid/os/IBinder;J)V -Landroid/os/IStatsCompanionService;->sendSubscriberBroadcast(Landroid/os/IBinder;JJJJ[Ljava/lang/String;Landroid/os/StatsDimensionsValue;)V -Landroid/os/IStatsCompanionService;->setAlarmForSubscriberTriggering(J)V -Landroid/os/IStatsCompanionService;->setAnomalyAlarm(J)V -Landroid/os/IStatsCompanionService;->setPullingAlarm(J)V -Landroid/os/IStatsCompanionService;->statsdReady()V -Landroid/os/IStatsCompanionService;->triggerUidSnapshot()V Landroid/os/IStatsManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/os/IStatsManager$Stub$Proxy;->addConfiguration(J[BLjava/lang/String;)V Landroid/os/IStatsManager$Stub$Proxy;->getData(JLjava/lang/String;)[B @@ -45217,13 +43129,6 @@ Landroid/os/ShellCommand;->TAG:Ljava/lang/String; Landroid/os/SimpleClock;-><init>(Ljava/time/ZoneId;)V Landroid/os/SimpleClock;->zone:Ljava/time/ZoneId; Landroid/os/StatFs;->doStat(Ljava/lang/String;)Landroid/system/StructStatVfs; -Landroid/os/StatsDimensionsValue;-><init>(Landroid/os/Parcel;)V -Landroid/os/StatsDimensionsValue;->mField:I -Landroid/os/StatsDimensionsValue;->mValue:Ljava/lang/Object; -Landroid/os/StatsDimensionsValue;->mValueType:I -Landroid/os/StatsDimensionsValue;->readValueFromParcel(ILandroid/os/Parcel;)Ljava/lang/Object; -Landroid/os/StatsDimensionsValue;->TAG:Ljava/lang/String; -Landroid/os/StatsDimensionsValue;->writeValueToParcel(ILjava/lang/Object;Landroid/os/Parcel;I)Z Landroid/os/StatsLogEventWrapper;-><init>(JII)V Landroid/os/StatsLogEventWrapper;-><init>(Landroid/os/Parcel;)V Landroid/os/StatsLogEventWrapper;->CREATOR:Landroid/os/Parcelable$Creator; @@ -48671,33 +46576,6 @@ Landroid/provider/FontsContract;->SYNC_FONT_FETCH_TIMEOUT_MS:J Landroid/provider/FontsContract;->TAG:Ljava/lang/String; Landroid/provider/FontsContract;->THREAD_RENEWAL_THRESHOLD_MS:I Landroid/provider/LiveFolders;-><init>()V -Landroid/provider/MediaStore$Audio$AudioColumns;->ALBUM_ARTIST:Ljava/lang/String; -Landroid/provider/MediaStore$Audio$AudioColumns;->COMPILATION:Ljava/lang/String; -Landroid/provider/MediaStore$Audio$AudioColumns;->GENRE:Ljava/lang/String; -Landroid/provider/MediaStore$Audio$AudioColumns;->TITLE_RESOURCE_URI:Ljava/lang/String; -Landroid/provider/MediaStore$Audio$Media;->EXTERNAL_PATHS:[Ljava/lang/String; -Landroid/provider/MediaStore$Audio$Radio;-><init>()V -Landroid/provider/MediaStore$Files;->getDirectoryUri(Ljava/lang/String;)Landroid/net/Uri; -Landroid/provider/MediaStore$Images$Media;->StoreThumbnail(Landroid/content/ContentResolver;Landroid/graphics/Bitmap;JFFI)Landroid/graphics/Bitmap; -Landroid/provider/MediaStore$InternalThumbnails;-><init>()V -Landroid/provider/MediaStore$InternalThumbnails;->cancelThumbnailRequest(Landroid/content/ContentResolver;JLandroid/net/Uri;J)V -Landroid/provider/MediaStore$InternalThumbnails;->DEFAULT_GROUP_ID:I -Landroid/provider/MediaStore$InternalThumbnails;->FULL_SCREEN_KIND:I -Landroid/provider/MediaStore$InternalThumbnails;->getMiniThumbFromFile(Landroid/database/Cursor;Landroid/net/Uri;Landroid/content/ContentResolver;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap; -Landroid/provider/MediaStore$InternalThumbnails;->getThumbnail(Landroid/content/ContentResolver;JJILandroid/graphics/BitmapFactory$Options;Landroid/net/Uri;Z)Landroid/graphics/Bitmap; -Landroid/provider/MediaStore$InternalThumbnails;->MICRO_KIND:I -Landroid/provider/MediaStore$InternalThumbnails;->MINI_KIND:I -Landroid/provider/MediaStore$InternalThumbnails;->PROJECTION:[Ljava/lang/String; -Landroid/provider/MediaStore$InternalThumbnails;->sThumbBuf:[B -Landroid/provider/MediaStore$InternalThumbnails;->sThumbBufLock:Ljava/lang/Object; -Landroid/provider/MediaStore$MediaColumns;->MEDIA_SCANNER_NEW_OBJECT_ID:Ljava/lang/String; -Landroid/provider/MediaStore;->CONTENT_AUTHORITY_SLASH:Ljava/lang/String; -Landroid/provider/MediaStore;->getDocumentUri(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/util/List;)Landroid/net/Uri; -Landroid/provider/MediaStore;->getFilePath(Landroid/content/ContentResolver;Landroid/net/Uri;)Ljava/lang/String; -Landroid/provider/MediaStore;->PARAM_DELETE_DATA:Ljava/lang/String; -Landroid/provider/MediaStore;->RETRANSLATE_CALL:Ljava/lang/String; -Landroid/provider/MediaStore;->TAG:Ljava/lang/String; -Landroid/provider/MediaStore;->UNHIDE_CALL:Ljava/lang/String; Landroid/provider/MetadataReader;-><init>()V Landroid/provider/MetadataReader;->DEFAULT_EXIF_TAGS:[Ljava/lang/String; Landroid/provider/MetadataReader;->getExifData(Ljava/io/InputStream;[Ljava/lang/String;)Landroid/os/Bundle; @@ -65005,412 +62883,6 @@ Landroid/util/StateSet;->VIEW_STATE_PRESSED:I Landroid/util/StateSet;->VIEW_STATE_SELECTED:I Landroid/util/StateSet;->VIEW_STATE_SETS:[[I Landroid/util/StateSet;->VIEW_STATE_WINDOW_FOCUSED:I -Landroid/util/StatsLog;-><init>()V -Landroid/util/StatsLog;->DEBUG:Z -Landroid/util/StatsLog;->getIStatsManagerLocked()Landroid/os/IStatsManager; -Landroid/util/StatsLog;->sService:Landroid/os/IStatsManager; -Landroid/util/StatsLog;->TAG:Ljava/lang/String; -Landroid/util/StatsLogInternal;-><init>()V -Landroid/util/StatsLogInternal;->ACTIVITY_FOREGROUND_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__BACKGROUND:I -Landroid/util/StatsLogInternal;->ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__FOREGROUND:I -Landroid/util/StatsLogInternal;->ANOMALY_DETECTED:I -Landroid/util/StatsLogInternal;->ANROCCURRED__FOREGROUND_STATE__BACKGROUND:I -Landroid/util/StatsLogInternal;->ANROCCURRED__FOREGROUND_STATE__FOREGROUND:I -Landroid/util/StatsLogInternal;->ANROCCURRED__FOREGROUND_STATE__UNKNOWN:I -Landroid/util/StatsLogInternal;->ANROCCURRED__IS_INSTANT_APP__FALSE:I -Landroid/util/StatsLogInternal;->ANROCCURRED__IS_INSTANT_APP__TRUE:I -Landroid/util/StatsLogInternal;->ANROCCURRED__IS_INSTANT_APP__UNAVAILABLE:I -Landroid/util/StatsLogInternal;->ANR_OCCURRED:I -Landroid/util/StatsLogInternal;->APP_BREADCRUMB_REPORTED:I -Landroid/util/StatsLogInternal;->APP_BREADCRUMB_REPORTED__STATE__START:I -Landroid/util/StatsLogInternal;->APP_BREADCRUMB_REPORTED__STATE__STOP:I -Landroid/util/StatsLogInternal;->APP_BREADCRUMB_REPORTED__STATE__UNKNOWN:I -Landroid/util/StatsLogInternal;->APP_BREADCRUMB_REPORTED__STATE__UNSPECIFIED:I -Landroid/util/StatsLogInternal;->APP_CRASH_OCCURRED:I -Landroid/util/StatsLogInternal;->APP_CRASH_OCCURRED__FOREGROUND_STATE__BACKGROUND:I -Landroid/util/StatsLogInternal;->APP_CRASH_OCCURRED__FOREGROUND_STATE__FOREGROUND:I -Landroid/util/StatsLogInternal;->APP_CRASH_OCCURRED__FOREGROUND_STATE__UNKNOWN:I -Landroid/util/StatsLogInternal;->APP_CRASH_OCCURRED__IS_INSTANT_APP__FALSE:I -Landroid/util/StatsLogInternal;->APP_CRASH_OCCURRED__IS_INSTANT_APP__TRUE:I -Landroid/util/StatsLogInternal;->APP_CRASH_OCCURRED__IS_INSTANT_APP__UNAVAILABLE:I -Landroid/util/StatsLogInternal;->APP_DIED:I -Landroid/util/StatsLogInternal;->APP_START_CANCELED:I -Landroid/util/StatsLogInternal;->APP_START_CANCELED__TYPE__COLD:I -Landroid/util/StatsLogInternal;->APP_START_CANCELED__TYPE__HOT:I -Landroid/util/StatsLogInternal;->APP_START_CANCELED__TYPE__UNKNOWN:I -Landroid/util/StatsLogInternal;->APP_START_CANCELED__TYPE__WARM:I -Landroid/util/StatsLogInternal;->APP_START_FULLY_DRAWN:I -Landroid/util/StatsLogInternal;->APP_START_FULLY_DRAWN__TYPE__UNKNOWN:I -Landroid/util/StatsLogInternal;->APP_START_FULLY_DRAWN__TYPE__WITHOUT_BUNDLE:I -Landroid/util/StatsLogInternal;->APP_START_FULLY_DRAWN__TYPE__WITH_BUNDLE:I -Landroid/util/StatsLogInternal;->APP_START_MEMORY_STATE_CAPTURED:I -Landroid/util/StatsLogInternal;->APP_START_OCCURRED:I -Landroid/util/StatsLogInternal;->APP_START_OCCURRED__REASON__APP_TRANSITION_REASON_UNKNOWN:I -Landroid/util/StatsLogInternal;->APP_START_OCCURRED__REASON__APP_TRANSITION_RECENTS_ANIM:I -Landroid/util/StatsLogInternal;->APP_START_OCCURRED__REASON__APP_TRANSITION_SNAPSHOT:I -Landroid/util/StatsLogInternal;->APP_START_OCCURRED__REASON__APP_TRANSITION_SPLASH_SCREEN:I -Landroid/util/StatsLogInternal;->APP_START_OCCURRED__REASON__APP_TRANSITION_TIMEOUT:I -Landroid/util/StatsLogInternal;->APP_START_OCCURRED__REASON__APP_TRANSITION_WINDOWS_DRAWN:I -Landroid/util/StatsLogInternal;->APP_START_OCCURRED__TYPE__COLD:I -Landroid/util/StatsLogInternal;->APP_START_OCCURRED__TYPE__HOT:I -Landroid/util/StatsLogInternal;->APP_START_OCCURRED__TYPE__UNKNOWN:I -Landroid/util/StatsLogInternal;->APP_START_OCCURRED__TYPE__WARM:I -Landroid/util/StatsLogInternal;->AUDIO_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->AUDIO_STATE_CHANGED__STATE__OFF:I -Landroid/util/StatsLogInternal;->AUDIO_STATE_CHANGED__STATE__ON:I -Landroid/util/StatsLogInternal;->AUDIO_STATE_CHANGED__STATE__RESET:I -Landroid/util/StatsLogInternal;->BATTERY_LEVEL_CHANGED:I -Landroid/util/StatsLogInternal;->BATTERY_SAVER_MODE_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF:I -Landroid/util/StatsLogInternal;->BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON:I -Landroid/util/StatsLogInternal;->BLE_SCAN_RESULT_RECEIVED:I -Landroid/util/StatsLogInternal;->BLE_SCAN_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->BLE_SCAN_STATE_CHANGED__STATE__OFF:I -Landroid/util/StatsLogInternal;->BLE_SCAN_STATE_CHANGED__STATE__ON:I -Landroid/util/StatsLogInternal;->BLE_SCAN_STATE_CHANGED__STATE__RESET:I -Landroid/util/StatsLogInternal;->BLUETOOTH_ACTIVITY_INFO:I -Landroid/util/StatsLogInternal;->BLUETOOTH_BYTES_TRANSFER:I -Landroid/util/StatsLogInternal;->BLUETOOTH_CONNECTION_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->BLUETOOTH_CONNECTION_STATE_CHANGED__STATE__CONNECTION_STATE_CONNECTED:I -Landroid/util/StatsLogInternal;->BLUETOOTH_CONNECTION_STATE_CHANGED__STATE__CONNECTION_STATE_CONNECTING:I -Landroid/util/StatsLogInternal;->BLUETOOTH_CONNECTION_STATE_CHANGED__STATE__CONNECTION_STATE_DISCONNECTED:I -Landroid/util/StatsLogInternal;->BLUETOOTH_CONNECTION_STATE_CHANGED__STATE__CONNECTION_STATE_DISCONNECTING:I -Landroid/util/StatsLogInternal;->BLUETOOTH_ENABLED_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->BLUETOOTH_ENABLED_STATE_CHANGED__REASON__ENABLE_DISABLE_REASON_AIRPLANE_MODE:I -Landroid/util/StatsLogInternal;->BLUETOOTH_ENABLED_STATE_CHANGED__REASON__ENABLE_DISABLE_REASON_APPLICATION_REQUEST:I -Landroid/util/StatsLogInternal;->BLUETOOTH_ENABLED_STATE_CHANGED__REASON__ENABLE_DISABLE_REASON_CRASH:I -Landroid/util/StatsLogInternal;->BLUETOOTH_ENABLED_STATE_CHANGED__REASON__ENABLE_DISABLE_REASON_DISALLOWED:I -Landroid/util/StatsLogInternal;->BLUETOOTH_ENABLED_STATE_CHANGED__REASON__ENABLE_DISABLE_REASON_RESTARTED:I -Landroid/util/StatsLogInternal;->BLUETOOTH_ENABLED_STATE_CHANGED__REASON__ENABLE_DISABLE_REASON_RESTORE_USER_SETTING:I -Landroid/util/StatsLogInternal;->BLUETOOTH_ENABLED_STATE_CHANGED__REASON__ENABLE_DISABLE_REASON_START_ERROR:I -Landroid/util/StatsLogInternal;->BLUETOOTH_ENABLED_STATE_CHANGED__REASON__ENABLE_DISABLE_REASON_SYSTEM_BOOT:I -Landroid/util/StatsLogInternal;->BLUETOOTH_ENABLED_STATE_CHANGED__REASON__ENABLE_DISABLE_REASON_UNSPECIFIED:I -Landroid/util/StatsLogInternal;->BLUETOOTH_ENABLED_STATE_CHANGED__REASON__ENABLE_DISABLE_REASON_USER_SWITCH:I -Landroid/util/StatsLogInternal;->BLUETOOTH_ENABLED_STATE_CHANGED__STATE__DISABLED:I -Landroid/util/StatsLogInternal;->BLUETOOTH_ENABLED_STATE_CHANGED__STATE__ENABLED:I -Landroid/util/StatsLogInternal;->BLUETOOTH_ENABLED_STATE_CHANGED__STATE__UNKNOWN:I -Landroid/util/StatsLogInternal;->BOOT_SEQUENCE_REPORTED:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__CALL_STATE__ABORTED:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__CALL_STATE__ACTIVE:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__CALL_STATE__CONNECTING:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__CALL_STATE__DIALING:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__CALL_STATE__DISCONNECTED:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__CALL_STATE__DISCONNECTING:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__CALL_STATE__NEW:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__CALL_STATE__ON_HOLD:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__CALL_STATE__PULLING:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__CALL_STATE__RINGING:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__CALL_STATE__SELECT_PHONE_ACCOUNT:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__DISCONNECT_CAUSE__ANSWERED_ELSEWHERE:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__DISCONNECT_CAUSE__BUSY:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__DISCONNECT_CAUSE__CALL_PULLED:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__DISCONNECT_CAUSE__CANCELED:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__DISCONNECT_CAUSE__CONNECTION_MANAGER_NOT_SUPPORTED:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__DISCONNECT_CAUSE__ERROR:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__DISCONNECT_CAUSE__LOCAL:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__DISCONNECT_CAUSE__MISSED:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__DISCONNECT_CAUSE__OTHER:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__DISCONNECT_CAUSE__REJECTED:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__DISCONNECT_CAUSE__REMOTE:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__DISCONNECT_CAUSE__RESTRICTED:I -Landroid/util/StatsLogInternal;->CALL_STATE_CHANGED__DISCONNECT_CAUSE__UNKNOWN:I -Landroid/util/StatsLogInternal;->CAMERA_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->CAMERA_STATE_CHANGED__STATE__OFF:I -Landroid/util/StatsLogInternal;->CAMERA_STATE_CHANGED__STATE__ON:I -Landroid/util/StatsLogInternal;->CAMERA_STATE_CHANGED__STATE__RESET:I -Landroid/util/StatsLogInternal;->CHARGE_CYCLES_REPORTED:I -Landroid/util/StatsLogInternal;->CHARGING_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->CHARGING_STATE_CHANGED__STATE__BATTERY_STATUS_CHARGING:I -Landroid/util/StatsLogInternal;->CHARGING_STATE_CHANGED__STATE__BATTERY_STATUS_DISCHARGING:I -Landroid/util/StatsLogInternal;->CHARGING_STATE_CHANGED__STATE__BATTERY_STATUS_FULL:I -Landroid/util/StatsLogInternal;->CHARGING_STATE_CHANGED__STATE__BATTERY_STATUS_INVALID:I -Landroid/util/StatsLogInternal;->CHARGING_STATE_CHANGED__STATE__BATTERY_STATUS_NOT_CHARGING:I -Landroid/util/StatsLogInternal;->CHARGING_STATE_CHANGED__STATE__BATTERY_STATUS_UNKNOWN:I -Landroid/util/StatsLogInternal;->CPU_ACTIVE_TIME:I -Landroid/util/StatsLogInternal;->CPU_CLUSTER_TIME:I -Landroid/util/StatsLogInternal;->CPU_TIME_PER_FREQ:I -Landroid/util/StatsLogInternal;->CPU_TIME_PER_UID:I -Landroid/util/StatsLogInternal;->CPU_TIME_PER_UID_FREQ:I -Landroid/util/StatsLogInternal;->DAVEY_OCCURRED:I -Landroid/util/StatsLogInternal;->DEVICE_IDLE_MODE_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->DEVICE_IDLE_MODE_STATE_CHANGED__STATE__DEVICE_IDLE_MODE_DEEP:I -Landroid/util/StatsLogInternal;->DEVICE_IDLE_MODE_STATE_CHANGED__STATE__DEVICE_IDLE_MODE_LIGHT:I -Landroid/util/StatsLogInternal;->DEVICE_IDLE_MODE_STATE_CHANGED__STATE__DEVICE_IDLE_MODE_OFF:I -Landroid/util/StatsLogInternal;->DEVICE_IDLING_MODE_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->DEVICE_IDLING_MODE_STATE_CHANGED__STATE__DEVICE_IDLE_MODE_DEEP:I -Landroid/util/StatsLogInternal;->DEVICE_IDLING_MODE_STATE_CHANGED__STATE__DEVICE_IDLE_MODE_LIGHT:I -Landroid/util/StatsLogInternal;->DEVICE_IDLING_MODE_STATE_CHANGED__STATE__DEVICE_IDLE_MODE_OFF:I -Landroid/util/StatsLogInternal;->DISK_SPACE:I -Landroid/util/StatsLogInternal;->FLASHLIGHT_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->FLASHLIGHT_STATE_CHANGED__STATE__OFF:I -Landroid/util/StatsLogInternal;->FLASHLIGHT_STATE_CHANGED__STATE__ON:I -Landroid/util/StatsLogInternal;->FLASHLIGHT_STATE_CHANGED__STATE__RESET:I -Landroid/util/StatsLogInternal;->FOREGROUND_SERVICE_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER:I -Landroid/util/StatsLogInternal;->FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT:I -Landroid/util/StatsLogInternal;->FULL_BATTERY_CAPACITY:I -Landroid/util/StatsLogInternal;->GPS_SCAN_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->GPS_SCAN_STATE_CHANGED__STATE__OFF:I -Landroid/util/StatsLogInternal;->GPS_SCAN_STATE_CHANGED__STATE__ON:I -Landroid/util/StatsLogInternal;->HARDWARE_FAILED:I -Landroid/util/StatsLogInternal;->HARDWARE_FAILED__HARDWARE_TYPE__HARDWARE_FAILED_CODEC:I -Landroid/util/StatsLogInternal;->HARDWARE_FAILED__HARDWARE_TYPE__HARDWARE_FAILED_FINGERPRINT:I -Landroid/util/StatsLogInternal;->HARDWARE_FAILED__HARDWARE_TYPE__HARDWARE_FAILED_MICROPHONE:I -Landroid/util/StatsLogInternal;->HARDWARE_FAILED__HARDWARE_TYPE__HARDWARE_FAILED_SPEAKER:I -Landroid/util/StatsLogInternal;->HARDWARE_FAILED__HARDWARE_TYPE__HARDWARE_FAILED_UNKNOWN:I -Landroid/util/StatsLogInternal;->ISOLATED_UID_CHANGED:I -Landroid/util/StatsLogInternal;->ISOLATED_UID_CHANGED__EVENT__CREATED:I -Landroid/util/StatsLogInternal;->ISOLATED_UID_CHANGED__EVENT__REMOVED:I -Landroid/util/StatsLogInternal;->KERNEL_WAKELOCK:I -Landroid/util/StatsLogInternal;->KERNEL_WAKEUP_REPORTED:I -Landroid/util/StatsLogInternal;->KEYGUARD_BOUNCER_PASSWORD_ENTERED:I -Landroid/util/StatsLogInternal;->KEYGUARD_BOUNCER_PASSWORD_ENTERED__RESULT__FAILURE:I -Landroid/util/StatsLogInternal;->KEYGUARD_BOUNCER_PASSWORD_ENTERED__RESULT__SUCCESS:I -Landroid/util/StatsLogInternal;->KEYGUARD_BOUNCER_PASSWORD_ENTERED__RESULT__UNKNOWN:I -Landroid/util/StatsLogInternal;->KEYGUARD_BOUNCER_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->KEYGUARD_BOUNCER_STATE_CHANGED__STATE__HIDDEN:I -Landroid/util/StatsLogInternal;->KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN:I -Landroid/util/StatsLogInternal;->KEYGUARD_BOUNCER_STATE_CHANGED__STATE__UNKNOWN:I -Landroid/util/StatsLogInternal;->KEYGUARD_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->KEYGUARD_STATE_CHANGED__STATE__HIDDEN:I -Landroid/util/StatsLogInternal;->KEYGUARD_STATE_CHANGED__STATE__OCCLUDED:I -Landroid/util/StatsLogInternal;->KEYGUARD_STATE_CHANGED__STATE__SHOWN:I -Landroid/util/StatsLogInternal;->KEYGUARD_STATE_CHANGED__STATE__UNKNOWN:I -Landroid/util/StatsLogInternal;->LMK_KILL_OCCURRED:I -Landroid/util/StatsLogInternal;->LMK_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->LMK_STATE_CHANGED__STATE__START:I -Landroid/util/StatsLogInternal;->LMK_STATE_CHANGED__STATE__STOP:I -Landroid/util/StatsLogInternal;->LMK_STATE_CHANGED__STATE__UNKNOWN:I -Landroid/util/StatsLogInternal;->LONG_PARTIAL_WAKELOCK_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF:I -Landroid/util/StatsLogInternal;->LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON:I -Landroid/util/StatsLogInternal;->LOW_MEM_REPORTED:I -Landroid/util/StatsLogInternal;->MEDIA_CODEC_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->MEDIA_CODEC_STATE_CHANGED__STATE__OFF:I -Landroid/util/StatsLogInternal;->MEDIA_CODEC_STATE_CHANGED__STATE__ON:I -Landroid/util/StatsLogInternal;->MEDIA_CODEC_STATE_CHANGED__STATE__RESET:I -Landroid/util/StatsLogInternal;->MOBILE_BYTES_TRANSFER:I -Landroid/util/StatsLogInternal;->MOBILE_BYTES_TRANSFER_BY_FG_BG:I -Landroid/util/StatsLogInternal;->MOBILE_CONNECTION_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->MOBILE_CONNECTION_STATE_CHANGED__STATE__ACTIVATING:I -Landroid/util/StatsLogInternal;->MOBILE_CONNECTION_STATE_CHANGED__STATE__ACTIVE:I -Landroid/util/StatsLogInternal;->MOBILE_CONNECTION_STATE_CHANGED__STATE__DISCONNECTING:I -Landroid/util/StatsLogInternal;->MOBILE_CONNECTION_STATE_CHANGED__STATE__DISCONNECTION_ERROR_CREATING_CONNECTION:I -Landroid/util/StatsLogInternal;->MOBILE_CONNECTION_STATE_CHANGED__STATE__INACTIVE:I -Landroid/util/StatsLogInternal;->MOBILE_CONNECTION_STATE_CHANGED__STATE__UNKNOWN:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_POWER_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_POWER_STATE_CHANGED__STATE__DATA_CONNECTION_POWER_STATE_HIGH:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_POWER_STATE_CHANGED__STATE__DATA_CONNECTION_POWER_STATE_LOW:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_POWER_STATE_CHANGED__STATE__DATA_CONNECTION_POWER_STATE_MEDIUM:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_POWER_STATE_CHANGED__STATE__DATA_CONNECTION_POWER_STATE_UNKNOWN:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_1XRTT:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_CDMA:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_EDGE:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_EHRPD:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_EVDO_0:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_EVDO_A:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_EVDO_B:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_GPRS:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_GSM:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_HSDPA:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_HSPA:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_HSPAP:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_HSUPA:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_IDEN:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_IWLAN:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_LTE:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_LTE_CA:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_TD_SCDMA:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_UMTS:I -Landroid/util/StatsLogInternal;->MOBILE_RADIO_TECHNOLOGY_CHANGED__STATE__NETWORK_TYPE_UNKNOWN:I -Landroid/util/StatsLogInternal;->MODEM_ACTIVITY_INFO:I -Landroid/util/StatsLogInternal;->OVERLAY_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->OVERLAY_STATE_CHANGED__STATE__ENTERED:I -Landroid/util/StatsLogInternal;->OVERLAY_STATE_CHANGED__STATE__EXITED:I -Landroid/util/StatsLogInternal;->PACKET_WAKEUP_OCCURRED:I -Landroid/util/StatsLogInternal;->PHONE_SIGNAL_STRENGTH_CHANGED:I -Landroid/util/StatsLogInternal;->PHONE_SIGNAL_STRENGTH_CHANGED__SIGNAL_STRENGTH__SIGNAL_STRENGTH_GOOD:I -Landroid/util/StatsLogInternal;->PHONE_SIGNAL_STRENGTH_CHANGED__SIGNAL_STRENGTH__SIGNAL_STRENGTH_GREAT:I -Landroid/util/StatsLogInternal;->PHONE_SIGNAL_STRENGTH_CHANGED__SIGNAL_STRENGTH__SIGNAL_STRENGTH_MODERATE:I -Landroid/util/StatsLogInternal;->PHONE_SIGNAL_STRENGTH_CHANGED__SIGNAL_STRENGTH__SIGNAL_STRENGTH_NONE_OR_UNKNOWN:I -Landroid/util/StatsLogInternal;->PHONE_SIGNAL_STRENGTH_CHANGED__SIGNAL_STRENGTH__SIGNAL_STRENGTH_POOR:I -Landroid/util/StatsLogInternal;->PHYSICAL_DROP_DETECTED:I -Landroid/util/StatsLogInternal;->PICTURE_IN_PICTURE_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->PICTURE_IN_PICTURE_STATE_CHANGED__STATE__DISMISSED:I -Landroid/util/StatsLogInternal;->PICTURE_IN_PICTURE_STATE_CHANGED__STATE__ENTERED:I -Landroid/util/StatsLogInternal;->PICTURE_IN_PICTURE_STATE_CHANGED__STATE__EXPANDED_TO_FULL_SCREEN:I -Landroid/util/StatsLogInternal;->PICTURE_IN_PICTURE_STATE_CHANGED__STATE__MINIMIZED:I -Landroid/util/StatsLogInternal;->PLUGGED_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->PLUGGED_STATE_CHANGED__STATE__BATTERY_PLUGGED_AC:I -Landroid/util/StatsLogInternal;->PLUGGED_STATE_CHANGED__STATE__BATTERY_PLUGGED_NONE:I -Landroid/util/StatsLogInternal;->PLUGGED_STATE_CHANGED__STATE__BATTERY_PLUGGED_USB:I -Landroid/util/StatsLogInternal;->PLUGGED_STATE_CHANGED__STATE__BATTERY_PLUGGED_WIRELESS:I -Landroid/util/StatsLogInternal;->PROCESS_LIFE_CYCLE_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__CRASHED:I -Landroid/util/StatsLogInternal;->PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__FINISHED:I -Landroid/util/StatsLogInternal;->PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__STARTED:I -Landroid/util/StatsLogInternal;->PROCESS_MEMORY_STATE:I -Landroid/util/StatsLogInternal;->REMAINING_BATTERY_CAPACITY:I -Landroid/util/StatsLogInternal;->RESOURCE_CONFIGURATION_CHANGED:I -Landroid/util/StatsLogInternal;->SCHEDULED_JOB_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED:I -Landroid/util/StatsLogInternal;->SCHEDULED_JOB_STATE_CHANGED__STATE__SCHEDULED:I -Landroid/util/StatsLogInternal;->SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED:I -Landroid/util/StatsLogInternal;->SCHEDULED_JOB_STATE_CHANGED__STOP_REASON__STOP_REASON_CANCELLED:I -Landroid/util/StatsLogInternal;->SCHEDULED_JOB_STATE_CHANGED__STOP_REASON__STOP_REASON_CONSTRAINTS_NOT_SATISFIED:I -Landroid/util/StatsLogInternal;->SCHEDULED_JOB_STATE_CHANGED__STOP_REASON__STOP_REASON_DEVICE_IDLE:I -Landroid/util/StatsLogInternal;->SCHEDULED_JOB_STATE_CHANGED__STOP_REASON__STOP_REASON_PREEMPT:I -Landroid/util/StatsLogInternal;->SCHEDULED_JOB_STATE_CHANGED__STOP_REASON__STOP_REASON_TIMEOUT:I -Landroid/util/StatsLogInternal;->SCHEDULED_JOB_STATE_CHANGED__STOP_REASON__STOP_REASON_UNKNOWN:I -Landroid/util/StatsLogInternal;->SCREEN_BRIGHTNESS_CHANGED:I -Landroid/util/StatsLogInternal;->SCREEN_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_DOZE:I -Landroid/util/StatsLogInternal;->SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_DOZE_SUSPEND:I -Landroid/util/StatsLogInternal;->SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_OFF:I -Landroid/util/StatsLogInternal;->SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_ON:I -Landroid/util/StatsLogInternal;->SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_ON_SUSPEND:I -Landroid/util/StatsLogInternal;->SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_UNKNOWN:I -Landroid/util/StatsLogInternal;->SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_VR:I -Landroid/util/StatsLogInternal;->SENSOR_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->SENSOR_STATE_CHANGED__STATE__OFF:I -Landroid/util/StatsLogInternal;->SENSOR_STATE_CHANGED__STATE__ON:I -Landroid/util/StatsLogInternal;->SETTING_CHANGED:I -Landroid/util/StatsLogInternal;->SETTING_CHANGED__REASON__DELETED:I -Landroid/util/StatsLogInternal;->SETTING_CHANGED__REASON__UPDATED:I -Landroid/util/StatsLogInternal;->SHUTDOWN_SEQUENCE_REPORTED:I -Landroid/util/StatsLogInternal;->SPEAKER_IMPEDANCE_REPORTED:I -Landroid/util/StatsLogInternal;->SUBSYSTEM_SLEEP_STATE:I -Landroid/util/StatsLogInternal;->SYNC_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->SYNC_STATE_CHANGED__STATE__OFF:I -Landroid/util/StatsLogInternal;->SYNC_STATE_CHANGED__STATE__ON:I -Landroid/util/StatsLogInternal;->SYSTEM_ELAPSED_REALTIME:I -Landroid/util/StatsLogInternal;->SYSTEM_UPTIME:I -Landroid/util/StatsLogInternal;->TEMPERATURE:I -Landroid/util/StatsLogInternal;->TEMPERATURE__SENSOR_LOCATION__TEMPERATURE_TYPE_BATTERY:I -Landroid/util/StatsLogInternal;->TEMPERATURE__SENSOR_LOCATION__TEMPERATURE_TYPE_CPU:I -Landroid/util/StatsLogInternal;->TEMPERATURE__SENSOR_LOCATION__TEMPERATURE_TYPE_GPU:I -Landroid/util/StatsLogInternal;->TEMPERATURE__SENSOR_LOCATION__TEMPERATURE_TYPE_SKIN:I -Landroid/util/StatsLogInternal;->TEMPERATURE__SENSOR_LOCATION__TEMPERATURE_TYPE_UNKNOWN:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_BACKUP:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_BOUND_FOREGROUND_SERVICE:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_CACHED_ACTIVITY:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_CACHED_ACTIVITY_CLIENT:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_CACHED_EMPTY:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_CACHED_RECENT:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_FOREGROUND_SERVICE:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_HEAVY_WEIGHT:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_HOME:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_IMPORTANT_BACKGROUND:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_IMPORTANT_FOREGROUND:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_LAST_ACTIVITY:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_NONEXISTENT:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_PERSISTENT:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_PERSISTENT_UI:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_RECEIVER:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_SERVICE:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_TOP:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_TOP_SLEEPING:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_TRANSIENT_BACKGROUND:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_UNKNOWN:I -Landroid/util/StatsLogInternal;->UID_PROCESS_STATE_CHANGED__STATE__PROCESS_STATE_UNKNOWN_TO_PROTO:I -Landroid/util/StatsLogInternal;->USB_CONNECTOR_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->USB_CONNECTOR_STATE_CHANGED__STATE__CONNECTED:I -Landroid/util/StatsLogInternal;->USB_CONNECTOR_STATE_CHANGED__STATE__DISCONNECTED:I -Landroid/util/StatsLogInternal;->USB_DEVICE_ATTACHED:I -Landroid/util/StatsLogInternal;->WAKELOCK_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->WAKELOCK_STATE_CHANGED__LEVEL__DOZE_WAKE_LOCK:I -Landroid/util/StatsLogInternal;->WAKELOCK_STATE_CHANGED__LEVEL__DRAW_WAKE_LOCK:I -Landroid/util/StatsLogInternal;->WAKELOCK_STATE_CHANGED__LEVEL__FULL_WAKE_LOCK:I -Landroid/util/StatsLogInternal;->WAKELOCK_STATE_CHANGED__LEVEL__PARTIAL_WAKE_LOCK:I -Landroid/util/StatsLogInternal;->WAKELOCK_STATE_CHANGED__LEVEL__PROXIMITY_SCREEN_OFF_WAKE_LOCK:I -Landroid/util/StatsLogInternal;->WAKELOCK_STATE_CHANGED__LEVEL__SCREEN_BRIGHT_WAKE_LOCK:I -Landroid/util/StatsLogInternal;->WAKELOCK_STATE_CHANGED__LEVEL__SCREEN_DIM_WAKE_LOCK:I -Landroid/util/StatsLogInternal;->WAKELOCK_STATE_CHANGED__STATE__ACQUIRE:I -Landroid/util/StatsLogInternal;->WAKELOCK_STATE_CHANGED__STATE__CHANGE_ACQUIRE:I -Landroid/util/StatsLogInternal;->WAKELOCK_STATE_CHANGED__STATE__CHANGE_RELEASE:I -Landroid/util/StatsLogInternal;->WAKELOCK_STATE_CHANGED__STATE__RELEASE:I -Landroid/util/StatsLogInternal;->WAKEUP_ALARM_OCCURRED:I -Landroid/util/StatsLogInternal;->WIFI_ACTIVITY_INFO:I -Landroid/util/StatsLogInternal;->WIFI_BYTES_TRANSFER:I -Landroid/util/StatsLogInternal;->WIFI_BYTES_TRANSFER_BY_FG_BG:I -Landroid/util/StatsLogInternal;->WIFI_LOCK_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->WIFI_LOCK_STATE_CHANGED__STATE__OFF:I -Landroid/util/StatsLogInternal;->WIFI_LOCK_STATE_CHANGED__STATE__ON:I -Landroid/util/StatsLogInternal;->WIFI_MULTICAST_LOCK_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->WIFI_MULTICAST_LOCK_STATE_CHANGED__STATE__OFF:I -Landroid/util/StatsLogInternal;->WIFI_MULTICAST_LOCK_STATE_CHANGED__STATE__ON:I -Landroid/util/StatsLogInternal;->WIFI_RADIO_POWER_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->WIFI_RADIO_POWER_STATE_CHANGED__STATE__DATA_CONNECTION_POWER_STATE_HIGH:I -Landroid/util/StatsLogInternal;->WIFI_RADIO_POWER_STATE_CHANGED__STATE__DATA_CONNECTION_POWER_STATE_LOW:I -Landroid/util/StatsLogInternal;->WIFI_RADIO_POWER_STATE_CHANGED__STATE__DATA_CONNECTION_POWER_STATE_MEDIUM:I -Landroid/util/StatsLogInternal;->WIFI_RADIO_POWER_STATE_CHANGED__STATE__DATA_CONNECTION_POWER_STATE_UNKNOWN:I -Landroid/util/StatsLogInternal;->WIFI_SCAN_STATE_CHANGED:I -Landroid/util/StatsLogInternal;->WIFI_SCAN_STATE_CHANGED__STATE__OFF:I -Landroid/util/StatsLogInternal;->WIFI_SCAN_STATE_CHANGED__STATE__ON:I -Landroid/util/StatsLogInternal;->WIFI_SIGNAL_STRENGTH_CHANGED:I -Landroid/util/StatsLogInternal;->WIFI_SIGNAL_STRENGTH_CHANGED__SIGNAL_STRENGTH__SIGNAL_STRENGTH_GOOD:I -Landroid/util/StatsLogInternal;->WIFI_SIGNAL_STRENGTH_CHANGED__SIGNAL_STRENGTH__SIGNAL_STRENGTH_GREAT:I -Landroid/util/StatsLogInternal;->WIFI_SIGNAL_STRENGTH_CHANGED__SIGNAL_STRENGTH__SIGNAL_STRENGTH_MODERATE:I -Landroid/util/StatsLogInternal;->WIFI_SIGNAL_STRENGTH_CHANGED__SIGNAL_STRENGTH__SIGNAL_STRENGTH_NONE_OR_UNKNOWN:I -Landroid/util/StatsLogInternal;->WIFI_SIGNAL_STRENGTH_CHANGED__SIGNAL_STRENGTH__SIGNAL_STRENGTH_POOR:I -Landroid/util/StatsLogInternal;->write(I)I -Landroid/util/StatsLogInternal;->write(II)I -Landroid/util/StatsLogInternal;->write(III)I -Landroid/util/StatsLogInternal;->write(IIIFIIIIIIIIIIIIII)I -Landroid/util/StatsLogInternal;->write(IIII)I -Landroid/util/StatsLogInternal;->write(IIIIIIIII)I -Landroid/util/StatsLogInternal;->write(IIIIJZ)I -Landroid/util/StatsLogInternal;->write(IIIJ)I -Landroid/util/StatsLogInternal;->write(IIIZZ)I -Landroid/util/StatsLogInternal;->write(IIIZZZ)I -Landroid/util/StatsLogInternal;->write(IIJ)I -Landroid/util/StatsLogInternal;->write(IIJJ)I -Landroid/util/StatsLogInternal;->write(IIJJJJ)I -Landroid/util/StatsLogInternal;->write(IILjava/lang/String;I)I -Landroid/util/StatsLogInternal;->write(IILjava/lang/String;IJJJJJ)I -Landroid/util/StatsLogInternal;->write(IILjava/lang/String;ILjava/lang/String;)I -Landroid/util/StatsLogInternal;->write(IILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;III)I -Landroid/util/StatsLogInternal;->write(IILjava/lang/String;ILjava/lang/String;Ljava/lang/String;ZJIIIIILjava/lang/String;II)I -Landroid/util/StatsLogInternal;->write(IILjava/lang/String;ILjava/lang/String;ZJ)I -Landroid/util/StatsLogInternal;->write(IILjava/lang/String;Ljava/lang/String;I)I -Landroid/util/StatsLogInternal;->write(IILjava/lang/String;Ljava/lang/String;ILjava/lang/String;II)I -Landroid/util/StatsLogInternal;->write(IILjava/lang/String;Ljava/lang/String;JJJJJ)I -Landroid/util/StatsLogInternal;->write(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;II)I -Landroid/util/StatsLogInternal;->write(IILjava/lang/String;ZI)I -Landroid/util/StatsLogInternal;->write(IIZJJJJ)I -Landroid/util/StatsLogInternal;->write(IJ)I -Landroid/util/StatsLogInternal;->write(IJIJJJJ)I -Landroid/util/StatsLogInternal;->write(IJJJ)I -Landroid/util/StatsLogInternal;->write(IJJJJJJJJJJ)I -Landroid/util/StatsLogInternal;->write(ILjava/lang/String;IIJ)I -Landroid/util/StatsLogInternal;->write(ILjava/lang/String;J)I -Landroid/util/StatsLogInternal;->write(ILjava/lang/String;Ljava/lang/String;JJ)I -Landroid/util/StatsLogInternal;->write(ILjava/lang/String;Ljava/lang/String;JJJJ)I -Landroid/util/StatsLogInternal;->write(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZII)I -Landroid/util/StatsLogInternal;->write(IZLjava/lang/String;JJ)I -Landroid/util/StatsLogInternal;->write(I[I[Ljava/lang/String;I)I -Landroid/util/StatsLogInternal;->write(I[I[Ljava/lang/String;II)I -Landroid/util/StatsLogInternal;->write(I[I[Ljava/lang/String;IILjava/lang/String;)I -Landroid/util/StatsLogInternal;->write(I[I[Ljava/lang/String;ILjava/lang/String;I)I -Landroid/util/StatsLogInternal;->write(I[I[Ljava/lang/String;IZZZ)I -Landroid/util/StatsLogInternal;->write(I[I[Ljava/lang/String;Ljava/lang/String;)I -Landroid/util/StatsLogInternal;->write(I[I[Ljava/lang/String;Ljava/lang/String;I)I -Landroid/util/StatsLogInternal;->write(I[I[Ljava/lang/String;Ljava/lang/String;II)I -Landroid/util/StatsLogInternal;->write(I[I[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)I -Landroid/util/StatsLogInternal;->write_non_chained(IILjava/lang/String;I)I -Landroid/util/StatsLogInternal;->write_non_chained(IILjava/lang/String;II)I -Landroid/util/StatsLogInternal;->write_non_chained(IILjava/lang/String;IILjava/lang/String;)I -Landroid/util/StatsLogInternal;->write_non_chained(IILjava/lang/String;ILjava/lang/String;I)I -Landroid/util/StatsLogInternal;->write_non_chained(IILjava/lang/String;IZZZ)I -Landroid/util/StatsLogInternal;->write_non_chained(IILjava/lang/String;Ljava/lang/String;)I -Landroid/util/StatsLogInternal;->write_non_chained(IILjava/lang/String;Ljava/lang/String;I)I -Landroid/util/StatsLogInternal;->write_non_chained(IILjava/lang/String;Ljava/lang/String;II)I -Landroid/util/StatsLogInternal;->write_non_chained(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;I)I -Landroid/util/StatsLogInternal;->WTF_OCCURRED:I Landroid/util/StringBuilderPrinter;->mBuilder:Ljava/lang/StringBuilder; Landroid/util/SuperNotCalledException;-><init>(Ljava/lang/String;)V Landroid/util/TextLogEntry;-><init>()V diff --git a/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt b/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt index 753bc69be95b..79d2521b892c 100644 --- a/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt +++ b/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt @@ -23,8 +23,6 @@ Landroid/media/IVolumeController$Stub;->asInterface(Landroid/os/IBinder;)Landroi Landroid/net/INetworkPolicyListener$Stub;-><init>()V Landroid/net/nsd/INsdManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/nsd/INsdManager; Landroid/net/sip/ISipSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/sip/ISipSession; -Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getScanResults:I -Landroid/net/wifi/p2p/IWifiP2pManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/p2p/IWifiP2pManager; Landroid/nfc/INfcAdapter$Stub;->TRANSACTION_enable:I Landroid/os/IPowerManager$Stub;->TRANSACTION_acquireWakeLock:I Landroid/os/IPowerManager$Stub;->TRANSACTION_goToSleep:I diff --git a/boot/hiddenapi/hiddenapi-unsupported.txt b/boot/hiddenapi/hiddenapi-unsupported.txt index 4281b0dda41a..0265df5e93f5 100644 --- a/boot/hiddenapi/hiddenapi-unsupported.txt +++ b/boot/hiddenapi/hiddenapi-unsupported.txt @@ -183,12 +183,6 @@ Landroid/net/INetworkScoreService$Stub;->asInterface(Landroid/os/IBinder;)Landro Landroid/net/INetworkStatsService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/net/INetworkStatsService$Stub$Proxy;->getMobileIfaces()[Ljava/lang/String; Landroid/net/INetworkStatsService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkStatsService; -Landroid/net/wifi/IWifiManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/net/wifi/IWifiManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/IWifiManager; -Landroid/net/wifi/IWifiScanner$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/net/wifi/IWifiScanner$Stub$Proxy;->mRemote:Landroid/os/IBinder; -Landroid/net/wifi/IWifiScanner$Stub;-><init>()V -Landroid/net/wifi/IWifiScanner$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/IWifiScanner; Landroid/os/IBatteryPropertiesRegistrar$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/os/IDeviceIdentifiersPolicyService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdentifiersPolicyService; Landroid/os/IDeviceIdleController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdleController; diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 317e51c27d90..8a265788a94b 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -19,6 +19,7 @@ package android.app; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; +import android.app.ActivityManager.ProcessCapability; import android.content.ComponentName; import android.content.IIntentReceiver; import android.content.IIntentSender; @@ -634,4 +635,9 @@ public abstract class ActivityManagerInternal { * Return the temp allowlist type when server push messaging is over the quota. */ public abstract @TempAllowListType int getPushMessagingOverQuotaBehavior(); + + /** + * Returns the capability of the given uid + */ + public abstract @ProcessCapability int getUidCapability(int uid); } diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 034ad8e83fd3..4182ac3e572d 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -36,7 +36,6 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility.PACK import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.UserIdInt; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; import android.app.backup.BackupAgent; @@ -62,7 +61,6 @@ import android.content.ContentCaptureOptions; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; -import android.content.Context.CreatePackageOptions; import android.content.IContentProvider; import android.content.IIntentReceiver; import android.content.Intent; @@ -73,7 +71,6 @@ import android.content.pm.IPackageManager; import android.content.pm.InstrumentationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManager.ApplicationInfoFlags; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ParceledListSlice; import android.content.pm.PermissionInfo; @@ -221,6 +218,8 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.lang.reflect.Method; import java.net.InetAddress; @@ -231,6 +230,7 @@ import java.text.DateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -419,6 +419,16 @@ public final class ActivityThread extends ClientTransactionHandler @GuardedBy("mResourcesManager") @UnsupportedAppUsage final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages = new ArrayMap<>(); + + @GuardedBy("mResourcesManager") + private final ArrayMap<List<String>, WeakReference<LoadedApk>> mPackageNonAMS = + new ArrayMap<>(); + @GuardedBy("mResourcesManager") + private final ArrayMap<List<String>, WeakReference<LoadedApk>> mResourcePackagesNonAMS = + new ArrayMap<>(); + @GuardedBy("mResourcesManager") + private final ReferenceQueue<LoadedApk> mPackageRefQueue = new ReferenceQueue<>(); + @GuardedBy("mResourcesManager") final ArrayList<ActivityClientRecord> mRelaunchingActivities = new ArrayList<>(); @GuardedBy("mResourcesManager") @@ -1172,6 +1182,7 @@ public final class ActivityThread extends ClientTransactionHandler } public void scheduleApplicationInfoChanged(ApplicationInfo ai) { + mResourcesManager.updatePendingAppInfoUpdates(ai); mH.removeMessages(H.APPLICATION_INFO_CHANGED, ai); sendMessage(H.APPLICATION_INFO_CHANGED, ai); } @@ -2374,72 +2385,281 @@ public final class ActivityThread extends ClientTransactionHandler return mH; } - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, - @CreatePackageOptions int flags) { - return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId()); + /** + * If {@code retainReferences} is false, prunes all {@link LoadedApk} representing any of the + * specified packages from the package caches. + * + * @return whether the cache contains a loaded apk representing any of the specified packages + */ + private boolean clearCachedApks() { + synchronized (mResourcesManager) { + Reference<? extends LoadedApk> enqueuedRef = mPackageRefQueue.poll(); + if (enqueuedRef == null) { + return false; + } + + final HashSet<Reference<? extends LoadedApk>> deadReferences = new HashSet<>(); + for (; enqueuedRef != null; enqueuedRef = mPackageRefQueue.poll()) { + deadReferences.add(enqueuedRef); + } + + return cleanWeakMapValues(mPackages, deadReferences) + || cleanWeakMapValues(mResourcePackages, deadReferences) + || cleanWeakMapValues(mPackageNonAMS, deadReferences) + || cleanWeakMapValues(mResourcePackages, deadReferences); + } } - public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, - @CreatePackageOptions int flags, @UserIdInt int userId) { - return getPackageInfo(packageName, compatInfo, flags, userId, 0 /* packageFlags */); + private static <K> boolean cleanWeakMapValues(ArrayMap<K, WeakReference<LoadedApk>> map, + HashSet<Reference<? extends LoadedApk>> deadReferences) { + boolean hasPkgInfo = false; + for (int i = map.size() - 1; i >= 0; i--) { + if (deadReferences.contains(map.valueAt(i))) { + map.removeAt(i); + hasPkgInfo = true; + } + } + return hasPkgInfo; } - public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, - @CreatePackageOptions int flags, @UserIdInt int userId, - @ApplicationInfoFlags int packageFlags) { - final boolean differentUser = (UserHandle.myUserId() != userId); - ApplicationInfo ai = PackageManager.getApplicationInfoAsUserCached( - packageName, - packageFlags | PackageManager.GET_SHARED_LIBRARY_FILES - | PackageManager.MATCH_DEBUG_TRIAGED_MISSING, - (userId < 0) ? UserHandle.myUserId() : userId); + /** + * Retrieves the previously cached {@link LoadedApk} that was created/updated with the most + * recent {@link ApplicationInfo} sent from the activity manager service. + */ + @Nullable + private LoadedApk peekLatestCachedApkFromAMS(@NonNull String packageName, boolean includeCode) { synchronized (mResourcesManager) { WeakReference<LoadedApk> ref; - if (differentUser) { - // Caching not supported across users - ref = null; - } else if ((flags & Context.CONTEXT_INCLUDE_CODE) != 0) { - ref = mPackages.get(packageName); + if (includeCode) { + return ((ref = mPackages.get(packageName)) != null) ? ref.get() : null; } else { - ref = mResourcePackages.get(packageName); + return ((ref = mResourcePackages.get(packageName)) != null) ? ref.get() : null; + } + } + } + + /** + * Updates the previously cached {@link LoadedApk} that was created/updated using an + * {@link ApplicationInfo} sent from activity manager service. + * + * If {@code appInfo} is null, the most up-to-date {@link ApplicationInfo} will be fetched and + * used to update the cached package; otherwise, the specified app info will be used. + */ + private boolean updateLatestCachedApkFromAMS(@NonNull String packageName, + @Nullable ApplicationInfo appInfo, boolean updateActivityRecords) { + final LoadedApk[] loadedPackages = new LoadedApk[]{ + peekLatestCachedApkFromAMS(packageName, true), + peekLatestCachedApkFromAMS(packageName, false) + }; + + try { + if (appInfo == null) { + appInfo = sPackageManager.getApplicationInfo( + packageName, PackageManager.GET_SHARED_LIBRARY_FILES, + UserHandle.myUserId()); + } + } catch (RemoteException e) { + Slog.v(TAG, "Failed to get most recent app info for '" + packageName + "'", e); + return false; + } + + boolean hasPackage = false; + final String[] oldResDirs = new String[loadedPackages.length]; + for (int i = loadedPackages.length - 1; i >= 0; i--) { + final LoadedApk loadedPackage = loadedPackages[i]; + if (loadedPackage == null) { + continue; } - LoadedApk packageInfo = ref != null ? ref.get() : null; - if (ai != null && packageInfo != null) { - if (!isLoadedApkResourceDirsUpToDate(packageInfo, ai)) { - List<String> oldPaths = new ArrayList<>(); - LoadedApk.makePaths(this, ai, oldPaths); - packageInfo.updateApplicationInfo(ai, oldPaths); + // If the package is being updated, yet it still has a valid LoadedApk object, the + // package was updated with PACKAGE_REMOVED_DONT_KILL. Adjust it's internal references + // to the application info and resources. + hasPackage = true; + if (updateActivityRecords && mActivities.size() > 0) { + for (ActivityClientRecord ar : mActivities.values()) { + if (ar.activityInfo.applicationInfo.packageName.equals(packageName)) { + ar.activityInfo.applicationInfo = appInfo; + ar.packageInfo = loadedPackage; + } } + } + + updateLoadedApk(loadedPackage, appInfo); + oldResDirs[i] = loadedPackage.getResDir(); + } + if (hasPackage) { + synchronized (mResourcesManager) { + mResourcesManager.applyNewResourceDirs(appInfo, oldResDirs); + } + } + return hasPackage; + } + + private static List<String> makeNonAMSKey(@NonNull ApplicationInfo appInfo) { + final List<String> paths = new ArrayList<>(); + paths.add(appInfo.sourceDir); + if (appInfo.resourceDirs != null) { + for (String path : appInfo.resourceDirs) { + paths.add(path); + } + } + return paths; + } + + /** + * Retrieves the previously cached {@link LoadedApk}. + * + * If {@code isAppInfoFromAMS} is true, then {@code appInfo} will be used to update the paths + * of the previously cached {@link LoadedApk} that was created/updated using an + * {@link ApplicationInfo} sent from activity manager service. + */ + @Nullable + private LoadedApk retrieveCachedApk(@NonNull ApplicationInfo appInfo, boolean includeCode, + boolean isAppInfoFromAMS) { + if (UserHandle.myUserId() != UserHandle.getUserId(appInfo.uid)) { + // Caching not supported across users. + return null; + } + + if (isAppInfoFromAMS) { + LoadedApk loadedPackage = peekLatestCachedApkFromAMS(appInfo.packageName, includeCode); + if (loadedPackage != null) { + updateLoadedApk(loadedPackage, appInfo); + } + return loadedPackage; + } + + synchronized (mResourcesManager) { + WeakReference<LoadedApk> ref; + if (includeCode) { + return ((ref = mPackageNonAMS.get(makeNonAMSKey(appInfo))) != null) + ? ref.get() : null; + } else { + return ((ref = mResourcePackagesNonAMS.get(makeNonAMSKey(appInfo))) != null) + ? ref.get() : null; + } + } + } + + private static boolean isLoadedApkResourceDirsUpToDate(LoadedApk loadedApk, + ApplicationInfo appInfo) { + boolean baseDirsUpToDate = loadedApk.getResDir().equals(appInfo.sourceDir); + boolean resourceDirsUpToDate = Arrays.equals( + ArrayUtils.defeatNullable(appInfo.resourceDirs), + ArrayUtils.defeatNullable(loadedApk.getOverlayDirs())); + boolean overlayPathsUpToDate = Arrays.equals( + ArrayUtils.defeatNullable(appInfo.overlayPaths), + ArrayUtils.defeatNullable(loadedApk.getOverlayPaths())); + + return (loadedApk.mResources == null || loadedApk.mResources.getAssets().isUpToDate()) + && baseDirsUpToDate && resourceDirsUpToDate && overlayPathsUpToDate; + } - if (packageInfo.isSecurityViolation() - && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) { - throw new SecurityException( - "Requesting code from " + packageName - + " to be run in process " - + mBoundApplication.processName - + "/" + mBoundApplication.appInfo.uid); + private void updateLoadedApk(@NonNull LoadedApk loadedPackage, + @NonNull ApplicationInfo appInfo) { + if (isLoadedApkResourceDirsUpToDate(loadedPackage, appInfo)) { + return; + } + + final List<String> oldPaths = new ArrayList<>(); + LoadedApk.makePaths(this, appInfo, oldPaths); + loadedPackage.updateApplicationInfo(appInfo, oldPaths); + } + + @Nullable + private LoadedApk createLoadedPackage(@NonNull ApplicationInfo appInfo, + @Nullable CompatibilityInfo compatInfo, @Nullable ClassLoader baseLoader, + boolean securityViolation, boolean includeCode, boolean registerPackage, + boolean isAppInfoFromAMS) { + final LoadedApk packageInfo = + new LoadedApk(this, appInfo, compatInfo, baseLoader, + securityViolation, includeCode + && (appInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage); + + if (mSystemThread && "android".equals(appInfo.packageName)) { + packageInfo.installSystemApplicationInfo(appInfo, + getSystemContext().mPackageInfo.getClassLoader()); + } + + if (UserHandle.myUserId() != UserHandle.getUserId(appInfo.uid)) { + // Caching not supported across users + return packageInfo; + } + + synchronized (mResourcesManager) { + if (includeCode) { + if (isAppInfoFromAMS) { + mPackages.put(appInfo.packageName, + new WeakReference<>(packageInfo, mPackageRefQueue)); + } else { + mPackageNonAMS.put(makeNonAMSKey(appInfo), + new WeakReference<>(packageInfo, mPackageRefQueue)); + } + } else { + if (isAppInfoFromAMS) { + mResourcePackages.put(appInfo.packageName, + new WeakReference<>(packageInfo, mPackageRefQueue)); + } else { + mResourcePackagesNonAMS.put(makeNonAMSKey(appInfo), + new WeakReference<>(packageInfo, mPackageRefQueue)); } - return packageInfo; } + return packageInfo; } + } + + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) + public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, + int flags) { + return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId()); + } + public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, + int flags, int userId) { + final ApplicationInfo ai = PackageManager.getApplicationInfoAsUserCached( + packageName, + PackageManager.GET_SHARED_LIBRARY_FILES + | PackageManager.MATCH_DEBUG_TRIAGED_MISSING, + (userId < 0) ? UserHandle.myUserId() : userId); + LoadedApk packageInfo = null; if (ai != null) { - return getPackageInfo(ai, compatInfo, flags); + packageInfo = retrieveCachedApk(ai, + (flags & Context.CONTEXT_INCLUDE_CODE) != 0, + false); + } + + if (packageInfo != null) { + if (packageInfo.isSecurityViolation() + && (flags & Context.CONTEXT_IGNORE_SECURITY) == 0) { + throw new SecurityException( + "Requesting code from " + packageName + + " to be run in process " + + mBoundApplication.processName + + "/" + mBoundApplication.appInfo.uid); + } + return packageInfo; } - return null; + return ai == null ? null : getPackageInfo(ai, compatInfo, flags, false); } + /** + * @deprecated Use {@link #getPackageInfo(ApplicationInfo, CompatibilityInfo, int, boolean)} + * instead. + */ + @Deprecated @UnsupportedAppUsage(trackingBug = 171933273) public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo, - @CreatePackageOptions int flags) { + int flags) { + return getPackageInfo(ai, compatInfo, flags, true); + } + + public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo, + @Context.CreatePackageOptions int flags, boolean isAppInfoFromAMS) { boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0; boolean securityViolation = includeCode && ai.uid != 0 - && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null - ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid) - : true); + && ai.uid != Process.SYSTEM_UID && (mBoundApplication == null + || !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)); boolean registerPackage = includeCode && (flags&Context.CONTEXT_REGISTER_PACKAGE) != 0; if ((flags&(Context.CONTEXT_INCLUDE_CODE |Context.CONTEXT_IGNORE_SECURITY)) @@ -2449,107 +2669,47 @@ public final class ActivityThread extends ClientTransactionHandler + " (with uid " + ai.uid + ")"; if (mBoundApplication != null) { msg = msg + " to be run in process " - + mBoundApplication.processName + " (with uid " - + mBoundApplication.appInfo.uid + ")"; + + mBoundApplication.processName + " (with uid " + + mBoundApplication.appInfo.uid + ")"; } throw new SecurityException(msg); } } return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode, - registerPackage); + registerPackage, isAppInfoFromAMS); } @Override @UnsupportedAppUsage public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai, CompatibilityInfo compatInfo) { - return getPackageInfo(ai, compatInfo, null, false, true, false); + return getPackageInfo(ai, compatInfo, null, false, true, false, true); } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) { synchronized (mResourcesManager) { - WeakReference<LoadedApk> ref; - if (includeCode) { - ref = mPackages.get(packageName); - } else { - ref = mResourcePackages.get(packageName); - } - return ref != null ? ref.get() : null; + return peekLatestCachedApkFromAMS(packageName, includeCode); } } private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo, ClassLoader baseLoader, boolean securityViolation, boolean includeCode, - boolean registerPackage) { - final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid)); - synchronized (mResourcesManager) { - WeakReference<LoadedApk> ref; - if (differentUser) { - // Caching not supported across users - ref = null; - } else if (includeCode) { - ref = mPackages.get(aInfo.packageName); - } else { - ref = mResourcePackages.get(aInfo.packageName); - } - - LoadedApk packageInfo = ref != null ? ref.get() : null; - - if (packageInfo != null) { - if (!isLoadedApkResourceDirsUpToDate(packageInfo, aInfo)) { - List<String> oldPaths = new ArrayList<>(); - LoadedApk.makePaths(this, aInfo, oldPaths); - packageInfo.updateApplicationInfo(aInfo, oldPaths); - } - - return packageInfo; - } - - if (localLOGV) { - Slog.v(TAG, (includeCode ? "Loading code package " - : "Loading resource-only package ") + aInfo.packageName - + " (in " + (mBoundApplication != null - ? mBoundApplication.processName : null) - + ")"); - } - - packageInfo = - new LoadedApk(this, aInfo, compatInfo, baseLoader, - securityViolation, includeCode - && (aInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage); - - if (mSystemThread && "android".equals(aInfo.packageName)) { - packageInfo.installSystemApplicationInfo(aInfo, - getSystemContext().mPackageInfo.getClassLoader()); - } - - if (differentUser) { - // Caching not supported across users - } else if (includeCode) { - mPackages.put(aInfo.packageName, - new WeakReference<LoadedApk>(packageInfo)); - } else { - mResourcePackages.put(aInfo.packageName, - new WeakReference<LoadedApk>(packageInfo)); - } - + boolean registerPackage, boolean isAppInfoFromAMS) { + LoadedApk packageInfo = retrieveCachedApk(aInfo, includeCode, + isAppInfoFromAMS); + if (packageInfo != null) { return packageInfo; } - } - - private static boolean isLoadedApkResourceDirsUpToDate(LoadedApk loadedApk, - ApplicationInfo appInfo) { - Resources packageResources = loadedApk.mResources; - boolean resourceDirsUpToDate = Arrays.equals( - ArrayUtils.defeatNullable(appInfo.resourceDirs), - ArrayUtils.defeatNullable(loadedApk.getOverlayDirs())); - boolean overlayPathsUpToDate = Arrays.equals( - ArrayUtils.defeatNullable(appInfo.overlayPaths), - ArrayUtils.defeatNullable(loadedApk.getOverlayPaths())); - - return (packageResources == null || packageResources.getAssets().isUpToDate()) - && resourceDirsUpToDate && overlayPathsUpToDate; + if (localLOGV) { + Slog.v(TAG, (includeCode ? "Loading code package " + : "Loading resource-only package ") + aInfo.packageName + + " (in " + (mBoundApplication != null + ? mBoundApplication.processName : null) + + ")"); + } + return createLoadedPackage(aInfo, compatInfo, baseLoader, + securityViolation, includeCode, registerPackage, isAppInfoFromAMS); } @UnsupportedAppUsage @@ -3511,7 +3671,7 @@ public final class ActivityThread extends ClientTransactionHandler ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, - Context.CONTEXT_INCLUDE_CODE); + Context.CONTEXT_INCLUDE_CODE, true); } ComponentName component = r.intent.getComponent(); @@ -5994,40 +6154,10 @@ public final class ActivityThread extends ClientTransactionHandler @VisibleForTesting(visibility = PACKAGE) public void handleApplicationInfoChanged(@NonNull final ApplicationInfo ai) { - // Updates triggered by package installation go through a package update - // receiver. Here we try to capture ApplicationInfo changes that are - // caused by other sources, such as overlays. That means we want to be as conservative - // about code changes as possible. Take the diff of the old ApplicationInfo and the new - // to see if anything needs to change. - LoadedApk apk; - LoadedApk resApk; - // Update all affected loaded packages with new package information - synchronized (mResourcesManager) { - WeakReference<LoadedApk> ref = mPackages.get(ai.packageName); - apk = ref != null ? ref.get() : null; - ref = mResourcePackages.get(ai.packageName); - resApk = ref != null ? ref.get() : null; - } - - final String[] oldResDirs = new String[2]; - - if (apk != null) { - oldResDirs[0] = apk.getResDir(); - final ArrayList<String> oldPaths = new ArrayList<>(); - LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths); - apk.updateApplicationInfo(ai, oldPaths); - } - if (resApk != null) { - oldResDirs[1] = resApk.getResDir(); - final ArrayList<String> oldPaths = new ArrayList<>(); - LoadedApk.makePaths(this, resApk.getApplicationInfo(), oldPaths); - resApk.updateApplicationInfo(ai, oldPaths); - } - - synchronized (mResourcesManager) { - // Update all affected Resources objects to use new ResourcesImpl - mResourcesManager.applyNewResourceDirs(ai, oldResDirs); - } + // Updates triggered by package installation go through a package update receiver. Here we + // try to capture ApplicationInfo changes that are caused by other sources, such as + // overlays. That means we want to be as conservative about code changes as possible. + updateLatestCachedApkFromAMS(ai.packageName, ai, false); } /** @@ -6204,29 +6334,7 @@ public final class ActivityThread extends ClientTransactionHandler case ApplicationThreadConstants.PACKAGE_REMOVED: case ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL: { - final boolean killApp = cmd == ApplicationThreadConstants.PACKAGE_REMOVED; - if (packages == null) { - break; - } - synchronized (mResourcesManager) { - for (int i = packages.length - 1; i >= 0; i--) { - if (!hasPkgInfo) { - WeakReference<LoadedApk> ref = mPackages.get(packages[i]); - if (ref != null && ref.get() != null) { - hasPkgInfo = true; - } else { - ref = mResourcePackages.get(packages[i]); - if (ref != null && ref.get() != null) { - hasPkgInfo = true; - } - } - } - if (killApp) { - mPackages.remove(packages[i]); - mResourcePackages.remove(packages[i]); - } - } - } + hasPkgInfo = clearCachedApks(); break; } case ApplicationThreadConstants.PACKAGE_REPLACED: @@ -6234,68 +6342,19 @@ public final class ActivityThread extends ClientTransactionHandler if (packages == null) { break; } - - List<String> packagesHandled = new ArrayList<>(); - - synchronized (mResourcesManager) { - for (int i = packages.length - 1; i >= 0; i--) { - String packageName = packages[i]; - WeakReference<LoadedApk> ref = mPackages.get(packageName); - LoadedApk pkgInfo = ref != null ? ref.get() : null; - if (pkgInfo != null) { - hasPkgInfo = true; - } else { - ref = mResourcePackages.get(packageName); - pkgInfo = ref != null ? ref.get() : null; - if (pkgInfo != null) { - hasPkgInfo = true; - } - } - // If the package is being replaced, yet it still has a valid - // LoadedApk object, the package was updated with _DONT_KILL. - // Adjust it's internal references to the application info and - // resources. - if (pkgInfo != null) { - packagesHandled.add(packageName); - try { - final ApplicationInfo aInfo = - sPackageManager.getApplicationInfo( - packageName, - PackageManager.GET_SHARED_LIBRARY_FILES, - UserHandle.myUserId()); - - if (mActivities.size() > 0) { - for (ActivityClientRecord ar : mActivities.values()) { - if (ar.activityInfo.applicationInfo.packageName - .equals(packageName)) { - ar.activityInfo.applicationInfo = aInfo; - ar.packageInfo = pkgInfo; - } - } - } - - final String[] oldResDirs = { pkgInfo.getResDir() }; - - final ArrayList<String> oldPaths = new ArrayList<>(); - LoadedApk.makePaths(this, pkgInfo.getApplicationInfo(), oldPaths); - pkgInfo.updateApplicationInfo(aInfo, oldPaths); - - synchronized (mResourcesManager) { - // Update affected Resources objects to use new ResourcesImpl - mResourcesManager.applyNewResourceDirs(aInfo, oldResDirs); - } - } catch (RemoteException e) { - } - } + final List<String> packagesHandled = new ArrayList<>(); + for (int i = packages.length - 1; i >= 0; i--) { + final String packageName = packages[i]; + if (updateLatestCachedApkFromAMS(packageName, null, true)) { + hasPkgInfo = true; + packagesHandled.add(packageName); } } - try { getPackageManager().notifyPackagesReplacedReceived( packagesHandled.toArray(new String[0])); } catch (RemoteException ignored) { } - break; } } @@ -6854,7 +6913,7 @@ public final class ActivityThread extends ClientTransactionHandler ii.copyTo(instrApp); instrApp.initForUser(UserHandle.myUserId()); final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, - appContext.getClassLoader(), false, true, false); + appContext.getClassLoader(), false, true, false, true); // The test context's op package name == the target app's op package name, because // the app ops manager checks the op package name against the real calling UID, diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 96d59b80b479..9bd6c750fb13 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -4804,6 +4804,16 @@ public class AppOpsManager { public static final int HISTORY_FLAG_DISCRETE = 1 << 1; /** + * Flag for querying app op history: assemble attribution chains, and attach the last visible + * node in the chain to the start as a proxy info. This only applies to discrete accesses. + * + * TODO 191512294: Add to @SystemApi + * + * @hide + */ + public static final int HISTORY_FLAG_GET_ATTRIBUTION_CHAINS = 1 << 2; + + /** * Flag for querying app op history: get all types of historical access information. * * @see #getHistoricalOps(HistoricalOpsRequest, Executor, Consumer) @@ -4819,7 +4829,8 @@ public class AppOpsManager { @Retention(RetentionPolicy.SOURCE) @IntDef(flag = true, prefix = { "HISTORY_FLAG_" }, value = { HISTORY_FLAG_AGGREGATE, - HISTORY_FLAG_DISCRETE + HISTORY_FLAG_DISCRETE, + HISTORY_FLAG_GET_ATTRIBUTION_CHAINS }) public @interface OpHistoryFlags {} @@ -5037,7 +5048,8 @@ public class AppOpsManager { * @return This builder. */ public @NonNull Builder setHistoryFlags(@OpHistoryFlags int flags) { - Preconditions.checkFlagsArgument(flags, HISTORY_FLAGS_ALL); + Preconditions.checkFlagsArgument(flags, + HISTORY_FLAGS_ALL | HISTORY_FLAG_GET_ATTRIBUTION_CHAINS); mHistoryFlags = flags; return this; } @@ -5290,8 +5302,17 @@ public class AppOpsManager { @Nullable String attributionTag, @UidState int uidState, @OpFlags int opFlag, long discreteAccessTime, long discreteAccessDuration) { getOrCreateHistoricalUidOps(uid).addDiscreteAccess(opCode, packageName, attributionTag, - uidState, opFlag, discreteAccessTime, discreteAccessDuration); - }; + uidState, opFlag, discreteAccessTime, discreteAccessDuration, null); + } + + /** @hide */ + public void addDiscreteAccess(int opCode, int uid, @NonNull String packageName, + @Nullable String attributionTag, @UidState int uidState, @OpFlags int opFlag, + long discreteAccessTime, long discreteAccessDuration, + @Nullable OpEventProxyInfo proxy) { + getOrCreateHistoricalUidOps(uid).addDiscreteAccess(opCode, packageName, attributionTag, + uidState, opFlag, discreteAccessTime, discreteAccessDuration, proxy); + } /** @hide */ @@ -5623,9 +5644,10 @@ public class AppOpsManager { private void addDiscreteAccess(int opCode, @NonNull String packageName, @Nullable String attributionTag, @UidState int uidState, - @OpFlags int flag, long discreteAccessTime, long discreteAccessDuration) { + @OpFlags int flag, long discreteAccessTime, long discreteAccessDuration, + @Nullable OpEventProxyInfo proxy) { getOrCreateHistoricalPackageOps(packageName).addDiscreteAccess(opCode, attributionTag, - uidState, flag, discreteAccessTime, discreteAccessDuration); + uidState, flag, discreteAccessTime, discreteAccessDuration, proxy); }; /** @@ -5889,9 +5911,9 @@ public class AppOpsManager { private void addDiscreteAccess(int opCode, @Nullable String attributionTag, @UidState int uidState, @OpFlags int flag, long discreteAccessTime, - long discreteAccessDuration) { + long discreteAccessDuration, @Nullable OpEventProxyInfo proxy) { getOrCreateAttributedHistoricalOps(attributionTag).addDiscreteAccess(opCode, uidState, - flag, discreteAccessTime, discreteAccessDuration); + flag, discreteAccessTime, discreteAccessDuration, proxy); } /** @@ -6212,9 +6234,10 @@ public class AppOpsManager { } private void addDiscreteAccess(int opCode, @UidState int uidState, @OpFlags int flag, - long discreteAccessTime, long discreteAccessDuration) { + long discreteAccessTime, long discreteAccessDuration, + @Nullable OpEventProxyInfo proxy) { getOrCreateHistoricalOp(opCode).addDiscreteAccess(uidState,flag, discreteAccessTime, - discreteAccessDuration); + discreteAccessDuration, proxy); } /** @@ -6583,11 +6606,12 @@ public class AppOpsManager { } private void addDiscreteAccess(@UidState int uidState, @OpFlags int flag, - long discreteAccessTime, long discreteAccessDuration) { + long discreteAccessTime, long discreteAccessDuration, + @Nullable OpEventProxyInfo proxy) { List<AttributedOpEntry> discreteAccesses = getOrCreateDiscreteAccesses(); LongSparseArray<NoteOpEvent> accessEvents = new LongSparseArray<>(); long key = makeKey(uidState, flag); - NoteOpEvent note = new NoteOpEvent(discreteAccessTime, discreteAccessDuration, null); + NoteOpEvent note = new NoteOpEvent(discreteAccessTime, discreteAccessDuration, proxy); accessEvents.append(key, note); AttributedOpEntry access = new AttributedOpEntry(mOp, false, accessEvents, null); int insertionPoint = discreteAccesses.size() - 1; @@ -10022,6 +10046,8 @@ public class AppOpsManager { NoteOpEvent existingAccess = accessEvents.get(key); if (existingAccess == null || existingAccess.getDuration() == -1) { accessEvents.append(key, access); + } else if (existingAccess.mProxy == null && access.mProxy != null ) { + existingAccess.mProxy = access.mProxy; } } if (reject != null) { diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java index c17d98f3dce5..363b5a75b214 100644 --- a/core/java/android/app/AppOpsManagerInternal.java +++ b/core/java/android/app/AppOpsManagerInternal.java @@ -29,6 +29,7 @@ import com.android.internal.util.function.DecFunction; import com.android.internal.util.function.HeptFunction; import com.android.internal.util.function.HexFunction; import com.android.internal.util.function.QuadFunction; +import com.android.internal.util.function.QuintConsumer; import com.android.internal.util.function.QuintFunction; import com.android.internal.util.function.TriFunction; import com.android.internal.util.function.UndecFunction; @@ -155,6 +156,21 @@ public abstract class AppOpsManagerInternal { SyncNotedAppOp> superImpl); /** + * Allows overriding finish op. + * + * @param clientId The client state. + * @param code The op code to finish. + * @param uid The UID for which the op was noted. + * @param packageName The package for which it was noted. {@code null} for system package. + * @param attributionTag the attribution tag. + */ + default void finishOperation(IBinder clientId, int code, int uid, String packageName, + String attributionTag, + @NonNull QuintConsumer<IBinder, Integer, Integer, String, String> superImpl) { + superImpl.accept(clientId, code, uid, packageName, attributionTag); + } + + /** * Allows overriding finish proxy op. * * @param code The op code to finish. diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 16b6ea5bcf42..d24196813387 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -48,7 +48,6 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; -import android.content.pm.PackageManager.ApplicationInfoFlags; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.AssetManager; import android.content.res.CompatResources; @@ -2462,7 +2461,7 @@ class ContextImpl extends Context { public Context createApplicationContext(ApplicationInfo application, int flags) throws NameNotFoundException { LoadedApk pi = mMainThread.getPackageInfo(application, mResources.getCompatibilityInfo(), - flags | CONTEXT_REGISTER_PACKAGE); + flags | CONTEXT_REGISTER_PACKAGE, false); if (pi != null) { ContextImpl c = new ContextImpl(this, mMainThread, pi, ContextParams.EMPTY, mAttributionSource.getAttributionTag(), @@ -2494,13 +2493,6 @@ class ContextImpl extends Context { @Override public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) throws NameNotFoundException { - return createPackageContextAsUser(packageName, flags, user, 0 /* packageFlags */); - } - - @Override - public Context createPackageContextAsUser( - @NonNull String packageName, @CreatePackageOptions int flags, @NonNull UserHandle user, - @ApplicationInfoFlags int packageFlags) throws PackageManager.NameNotFoundException { if (packageName.equals("system") || packageName.equals("android")) { // The system resources are loaded in every application, so we can safely copy // the context without reloading Resources. @@ -2511,7 +2503,7 @@ class ContextImpl extends Context { } LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), - flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier(), packageFlags); + flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier()); if (pi != null) { ContextImpl c = new ContextImpl(this, mMainThread, pi, mParams, mAttributionSource.getAttributionTag(), diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 9ed76c1c13d1..a2c9795204ad 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -546,6 +546,10 @@ public final class LoadedApk { if (aInfo.sharedLibraryFiles != null) { int index = 0; for (String lib : aInfo.sharedLibraryFiles) { + // sharedLibraryFiles might contain native shared libraries that are not APK paths. + if (!lib.endsWith(".apk")) { + continue; + } if (!outSeenPaths.contains(lib) && !outZipPaths.contains(lib)) { outZipPaths.add(index, lib); index++; diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 506dfe09f3fa..6454d2027f58 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -6344,11 +6344,10 @@ public class Notification implements Parcelable ApplicationInfo applicationInfo = n.extras.getParcelable( EXTRA_BUILDER_APPLICATION_INFO); Context builderContext; - if (applicationInfo != null && applicationInfo.packageName != null) { + if (applicationInfo != null) { try { - builderContext = context.createPackageContextAsUser(applicationInfo.packageName, - Context.CONTEXT_RESTRICTED, - UserHandle.getUserHandleForUid(applicationInfo.uid)); + builderContext = context.createApplicationContext(applicationInfo, + Context.CONTEXT_RESTRICTED); } catch (NameNotFoundException e) { Log.e(TAG, "ApplicationInfo " + applicationInfo + " not found"); builderContext = context; // try with our context diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index f28c760d54d9..dfd1e2b61fae 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -42,10 +42,10 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.DisplayMetrics; import android.util.Log; -import android.util.Pair; import android.util.Slog; import android.view.Display; import android.view.DisplayAdjustments; +import android.view.DisplayInfo; import android.window.WindowContext; import com.android.internal.annotations.VisibleForTesting; @@ -56,7 +56,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; @@ -99,6 +98,12 @@ public class ResourcesManager { private int mResDisplayId = DEFAULT_DISPLAY; /** + * ApplicationInfo changes that need to be applied to Resources when the next configuration + * change occurs. + */ + private ArrayList<ApplicationInfo> mPendingAppInfoUpdates; + + /** * A mapping of ResourceImpls and their configurations. These are heavy weight objects * which should be reused as much as possible. */ @@ -251,12 +256,6 @@ public class ResourcesManager { new WeakHashMap<>(); /** - * A cache of DisplayId, DisplayAdjustments to Display. - */ - private final ArrayMap<Pair<Integer, DisplayAdjustments>, SoftReference<Display>> - mAdjustedDisplays = new ArrayMap<>(); - - /** * Callback implementation for handling updates to Resources objects. */ private final UpdateHandler mUpdateCallbacks = new UpdateHandler(); @@ -331,10 +330,12 @@ public class ResourcesManager { */ @VisibleForTesting protected @NonNull DisplayMetrics getDisplayMetrics(int displayId, DisplayAdjustments da) { - DisplayMetrics dm = new DisplayMetrics(); - final Display display = getAdjustedDisplay(displayId, da); - if (display != null) { - display.getMetrics(dm); + final DisplayManagerGlobal displayManagerGlobal = DisplayManagerGlobal.getInstance(); + final DisplayMetrics dm = new DisplayMetrics(); + final DisplayInfo displayInfo = displayManagerGlobal != null + ? displayManagerGlobal.getDisplayInfo(displayId) : null; + if (displayInfo != null) { + displayInfo.getAppMetrics(dm, da); } else { dm.setToDefaults(); } @@ -376,45 +377,6 @@ public class ResourcesManager { /** * Returns an adjusted {@link Display} object based on the inputs or null if display isn't - * available. This method is only used within {@link ResourcesManager} to calculate display - * metrics based on a set {@link DisplayAdjustments}. All other usages should instead call - * {@link ResourcesManager#getAdjustedDisplay(int, Resources)}. - * - * @param displayId display Id. - * @param displayAdjustments display adjustments. - */ - private Display getAdjustedDisplay(final int displayId, - @Nullable DisplayAdjustments displayAdjustments) { - final DisplayAdjustments displayAdjustmentsCopy = (displayAdjustments != null) - ? new DisplayAdjustments(displayAdjustments) : new DisplayAdjustments(); - final Pair<Integer, DisplayAdjustments> key = - Pair.create(displayId, displayAdjustmentsCopy); - SoftReference<Display> sd; - synchronized (mLock) { - sd = mAdjustedDisplays.get(key); - } - if (sd != null) { - final Display display = sd.get(); - if (display != null) { - return display; - } - } - final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); - if (dm == null) { - // may be null early in system startup - return null; - } - final Display display = dm.getCompatibleDisplay(displayId, key.second); - if (display != null) { - synchronized (mLock) { - mAdjustedDisplays.put(key, new SoftReference<>(display)); - } - } - return display; - } - - /** - * Returns an adjusted {@link Display} object based on the inputs or null if display isn't * available. * * @param displayId display Id. @@ -1032,7 +994,7 @@ public class ResourcesManager { * @param classLoader The classloader to use for the Resources object. * If null, {@link ClassLoader#getSystemClassLoader()} is used. * @return A Resources object that gets updated when - * {@link #applyConfigurationToResourcesLocked(Configuration, CompatibilityInfo)} + * {@link #applyConfigurationToResources(Configuration, CompatibilityInfo)} * is called. */ @Nullable @@ -1159,8 +1121,8 @@ public class ResourcesManager { /** * Updates an Activity's Resources object with overrideConfig. The Resources object * that was previously returned by {@link #getResources(IBinder, String, String[], String[], - * String[], Integer, Configuration, CompatibilityInfo, ClassLoader, List)} is still valid and - * will have the updated configuration. + * String[], String[], Integer, Configuration, CompatibilityInfo, ClassLoader, List)} is still + * valid and will have the updated configuration. * * @param activityToken The Activity token. * @param overrideConfig The configuration override to update. @@ -1311,6 +1273,22 @@ public class ResourcesManager { return newKey; } + public void updatePendingAppInfoUpdates(@NonNull ApplicationInfo appInfo) { + synchronized (mLock) { + if (mPendingAppInfoUpdates == null) { + mPendingAppInfoUpdates = new ArrayList<>(); + } + // Clear previous app info changes for the package to prevent multiple ResourcesImpl + // recreations when only the last recreation will be used. + for (int i = mPendingAppInfoUpdates.size() - 1; i >= 0; i--) { + if (appInfo.sourceDir.equals(mPendingAppInfoUpdates.get(i).sourceDir)) { + mPendingAppInfoUpdates.remove(i); + } + } + mPendingAppInfoUpdates.add(appInfo); + } + } + public final boolean applyConfigurationToResources(@NonNull Configuration config, @Nullable CompatibilityInfo compat) { return applyConfigurationToResources(config, compat, null /* adjustments */); @@ -1324,7 +1302,18 @@ public class ResourcesManager { Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#applyConfigurationToResources"); - if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) { + final boolean assetsUpdated = mPendingAppInfoUpdates != null + && config.assetsSeq > mResConfiguration.assetsSeq; + if (assetsUpdated) { + for (int i = 0, n = mPendingAppInfoUpdates.size(); i < n; i++) { + final ApplicationInfo appInfo = mPendingAppInfoUpdates.get(i); + applyNewResourceDirs(appInfo, new String[]{appInfo.sourceDir}); + } + mPendingAppInfoUpdates = null; + } + + if (!assetsUpdated && !mResConfiguration.isOtherSeqNewer(config) + && compat == null) { if (DEBUG || DEBUG_CONFIGURATION) { Slog.v(TAG, "Skipping new config: curSeq=" + mResConfiguration.seq + ", newSeq=" + config.seq); @@ -1332,9 +1321,6 @@ public class ResourcesManager { return false; } - // Things might have changed in display manager, so clear the cached displays. - mAdjustedDisplays.clear(); - int changes = mResConfiguration.updateFrom(config); if (compat != null && (mResCompatibilityInfo == null || !mResCompatibilityInfo.equals(compat))) { @@ -1367,7 +1353,7 @@ public class ResourcesManager { } } - return changes != 0; + return assetsUpdated || changes != 0; } finally { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } diff --git a/core/java/android/app/WallpaperColors.java b/core/java/android/app/WallpaperColors.java index 2777a7aae517..7ef0a19ec44c 100644 --- a/core/java/android/app/WallpaperColors.java +++ b/core/java/android/app/WallpaperColors.java @@ -420,7 +420,7 @@ public final class WallpaperColors implements Parcelable { for (Map.Entry<Integer, Integer> colorEntry : mAllColors.entrySet()) { if (colorEntry.getKey() != null) { dest.writeInt(colorEntry.getKey()); - Integer population = mAllColors.get(colorEntry.getValue()); + Integer population = colorEntry.getValue(); int populationInt = (population != null) ? population : 0; dest.writeInt(populationInt); } diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl index eb4c624be0b2..585eb61b6f57 100644 --- a/core/java/android/app/usage/IUsageStatsManager.aidl +++ b/core/java/android/app/usage/IUsageStatsManager.aidl @@ -68,5 +68,5 @@ interface IUsageStatsManager { void reportUserInteraction(String packageName, int userId); int getUsageSource(); void forceUsageSourceSettingRead(); - long getLastTimeAnyComponentUsed(String packageName); + long getLastTimeAnyComponentUsed(String packageName, String callingPackage); } diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index e8175c709d85..ac7a31874682 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -1287,7 +1287,7 @@ public final class UsageStatsManager { android.Manifest.permission.PACKAGE_USAGE_STATS}) public long getLastTimeAnyComponentUsed(@NonNull String packageName) { try { - return mService.getLastTimeAnyComponentUsed(packageName); + return mService.getLastTimeAnyComponentUsed(packageName, mContext.getOpPackageName()); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index 3b11a19f9acc..ba3fc1e55c54 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -37,7 +37,6 @@ import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Parcelable; -import android.os.UserHandle; import android.util.AttributeSet; import android.util.Log; import android.util.Pair; @@ -719,10 +718,9 @@ public class AppWidgetHostView extends FrameLayout { protected Context getRemoteContext() { try { // Return if cloned successfully, otherwise default - final ApplicationInfo info = mInfo.providerInfo.applicationInfo; - Context newContext = mContext.createPackageContextAsUser(info.packageName, - Context.CONTEXT_RESTRICTED, - UserHandle.getUserHandleForUid(info.uid)); + Context newContext = mContext.createApplicationContext( + mInfo.providerInfo.applicationInfo, + Context.CONTEXT_RESTRICTED); if (mColorResources != null) { mColorResources.apply(newContext); } diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index ded5e6e27a68..5b72b76c3578 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -3054,6 +3054,9 @@ public final class BluetoothAdapter { return true; } return false; + } else if (profile == BluetoothProfile.LE_AUDIO) { + BluetoothLeAudio leAudio = new BluetoothLeAudio(context, listener, this); + return true; } else { return false; } @@ -3142,6 +3145,10 @@ public final class BluetoothAdapter { case BluetoothProfile.HEARING_AID: BluetoothHearingAid hearingAid = (BluetoothHearingAid) proxy; hearingAid.close(); + break; + case BluetoothProfile.LE_AUDIO: + BluetoothLeAudio leAudio = (BluetoothLeAudio) proxy; + leAudio.close(); } } diff --git a/core/java/android/companion/OWNERS b/core/java/android/companion/OWNERS index da723b3b67da..54b35fc32f62 100644 --- a/core/java/android/companion/OWNERS +++ b/core/java/android/companion/OWNERS @@ -1 +1,4 @@ -eugenesusla@google.com
\ No newline at end of file +ewol@google.com +evanxinchen@google.com +guojing@google.com +svetoslavganov@google.com
\ No newline at end of file diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 9c60f431b06e..c02dcfd3d681 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -46,7 +46,6 @@ import android.app.time.TimeManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManager.ApplicationInfoFlags; import android.content.res.AssetManager; import android.content.res.ColorStateList; import android.content.res.Configuration; @@ -6269,23 +6268,6 @@ public abstract class Context { } /** - * Similar to {@link #createPackageContextAsUser(String, int, UserHandle)}, but also allows - * specifying the flags used to retrieve the {@link ApplicationInfo} of the package. - * - * @hide - */ - @NonNull - public Context createPackageContextAsUser( - @NonNull String packageName, @CreatePackageOptions int flags, @NonNull UserHandle user, - @ApplicationInfoFlags int packageFlags) - throws PackageManager.NameNotFoundException { - if (Build.IS_ENG) { - throw new IllegalStateException("createPackageContextAsUser not overridden!"); - } - return this; - } - - /** * Similar to {@link #createPackageContext(String, int)}, but for the own package with a * different {@link UserHandle}. For example, {@link #getContentResolver()} * will open any {@link Uri} as the given user. @@ -6304,18 +6286,10 @@ public abstract class Context { /** * Creates a context given an {@link android.content.pm.ApplicationInfo}. * - * @deprecated use {@link #createPackageContextAsUser(String, int, UserHandle, int)} - * If an application caches an ApplicationInfo and uses it to call this method, - * the app will not get the most recent version of Runtime Resource Overlays for - * that application. To make things worse, the LoadedApk stored in - * {@code ActivityThread#mResourcePackages} is updated using the old ApplicationInfo - * causing further uses of the cached LoadedApk to return outdated information. - * * @hide */ @SuppressWarnings("HiddenAbstractMethod") @UnsupportedAppUsage - @Deprecated public abstract Context createApplicationContext(ApplicationInfo application, @CreatePackageOptions int flags) throws PackageManager.NameNotFoundException; diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index cf0dc8c92ea1..6324d0ecb0e0 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -1009,14 +1009,6 @@ public class ContextWrapper extends Context { /** @hide */ @Override - public Context createPackageContextAsUser(String packageName, int flags, UserHandle user, - int packageFlags) - throws PackageManager.NameNotFoundException { - return mBase.createPackageContextAsUser(packageName, flags, user, packageFlags); - } - - /** @hide */ - @Override public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) { return mBase.createContextAsUser(user, flags); } diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 75dd9fb24e35..3f8aedb31ea9 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -2111,28 +2111,28 @@ public class PackageInstaller { * <p> * Defaults to {@link #USER_ACTION_UNSPECIFIED} unless otherwise set. When unspecified for * installers using the - * {@link android.Manifest.permission#REQUEST_INSTALL_PACKAGES android.permission - * #REQUEST_INSTALL_PACKAGES} permission will behave as if set to - * {@link #USER_ACTION_REQUIRED}, and {@link #USER_ACTION_NOT_REQUIRED} otherwise. - * When {@code requireUserAction} is set to {@link #USER_ACTION_REQUIRED}, installers will - * receive a {@link #STATUS_PENDING_USER_ACTION} callback once the session is committed, - * indicating that user action is required for the install to proceed. + * {@link android.Manifest.permission#REQUEST_INSTALL_PACKAGES REQUEST_INSTALL_PACKAGES} + * permission will behave as if set to {@link #USER_ACTION_REQUIRED}, and + * {@link #USER_ACTION_NOT_REQUIRED} otherwise. When {@code requireUserAction} is set to + * {@link #USER_ACTION_REQUIRED}, installers will receive a + * {@link #STATUS_PENDING_USER_ACTION} callback once the session is committed, indicating + * that user action is required for the install to proceed. * <p> * For installers that have been granted the - * {@link android.Manifest.permission#REQUEST_INSTALL_PACKAGES android.permission - * .REQUEST_INSTALL_PACKAGES} permission, user action will not be required when all of - * the following conditions are met: + * {@link android.Manifest.permission#REQUEST_INSTALL_PACKAGES REQUEST_INSTALL_PACKAGES} + * permission, user action will not be required when all of the following conditions are + * met: * * <ul> * <li>{@code requireUserAction} is set to {@link #USER_ACTION_NOT_REQUIRED}.</li> * <li>The app being installed targets {@link android.os.Build.VERSION_CODES#Q API 29} * or higher.</li> * <li>The installer is the {@link InstallSourceInfo#getInstallingPackageName() - * installer of record} of an existing version of the app (i.e.: this install session - * is an app update) or the installer is updating itself.</li> + * installer of record} of an existing version of the app (in other words, this install + * session is an app update) or the installer is updating itself.</li> * <li>The installer declares the - * {@link android.Manifest.permission#UPDATE_PACKAGES_WITHOUT_USER_ACTION android - * .permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION} permission.</li> + * {@link android.Manifest.permission#UPDATE_PACKAGES_WITHOUT_USER_ACTION + * UPDATE_PACKAGES_WITHOUT_USER_ACTION} permission.</li> * </ul> * <p> * Note: The target API level requirement will advance in future Android versions. diff --git a/core/java/android/content/pm/parsing/component/ParsedIntentInfo.java b/core/java/android/content/pm/parsing/component/ParsedIntentInfo.java index 6b797bcb6ab2..463a1810b511 100644 --- a/core/java/android/content/pm/parsing/component/ParsedIntentInfo.java +++ b/core/java/android/content/pm/parsing/component/ParsedIntentInfo.java @@ -19,7 +19,6 @@ package android.content.pm.parsing.component; import android.annotation.Nullable; import android.content.IntentFilter; import android.os.Parcel; -import android.os.Parcelable; import android.util.Pair; import com.android.internal.util.Parcelling; @@ -167,19 +166,6 @@ public final class ParsedIntentInfo extends IntentFilter { + '}'; } - public static final Parcelable.Creator<ParsedIntentInfo> CREATOR = - new Parcelable.Creator<ParsedIntentInfo>() { - @Override - public ParsedIntentInfo createFromParcel(Parcel source) { - return new ParsedIntentInfo(source); - } - - @Override - public ParsedIntentInfo[] newArray(int size) { - return new ParsedIntentInfo[size]; - } - }; - public boolean isHasDefault() { return hasDefault; } diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java index 37469e916eef..08f5a8a582db 100644 --- a/core/java/android/hardware/Sensor.java +++ b/core/java/android/hardware/Sensor.java @@ -848,8 +848,10 @@ public final class Sensor { /** * Get the highest supported direct report mode rate level of the sensor. * - * @return Highest direct report rate level of this sensor. If the sensor does not support - * direct report mode, this returns {@link SensorDirectChannel#RATE_STOP}. + * @return Highest direct report rate level of this sensor. Note that if the app does not have + * the {@link android.Manifest.permission#HIGH_SAMPLING_RATE_SENSORS} permission, the highest + * direct report rate level is {@link SensorDirectChannel#RATE_NORMAL}. If the sensor + * does not support direct report mode, this returns {@link SensorDirectChannel#RATE_STOP}. * @see SensorDirectChannel#RATE_STOP * @see SensorDirectChannel#RATE_NORMAL * @see SensorDirectChannel#RATE_FAST @@ -1002,9 +1004,11 @@ public final class Sensor { } /** - * @return the minimum delay allowed between two events in microsecond + * @return the minimum delay allowed between two events in microseconds * or zero if this sensor only returns a value when the data it's measuring - * changes. + * changes. Note that if the app does not have the + * {@link android.Manifest.permission#HIGH_SAMPLING_RATE_SENSORS} permission, the + * minimum delay is capped at 5000 microseconds (200 Hz). */ public int getMinDelay() { return mMinDelay; diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java index 713b66abed21..572a8a81883a 100644 --- a/core/java/android/hardware/SensorManager.java +++ b/core/java/android/hardware/SensorManager.java @@ -46,6 +46,13 @@ import java.util.List; * at {@link TriggerEventListener}. {@link Sensor#TYPE_SIGNIFICANT_MOTION} * is an example of a trigger sensor. * </p> + * <p> + * In order to access sensor data at high sampling rates (i.e. greater than 200 Hz + * for {@link SensorEventListener} and greater than {@link SensorDirectChannel#RATE_NORMAL} + * for {@link SensorDirectChannel}), apps must declare + * the {@link android.Manifest.permission#HIGH_SAMPLING_RATE_SENSORS} permission + * in their AndroidManifest.xml file. + * </p> * <pre class="prettyprint"> * public class SensorActivity extends Activity implements SensorEventListener { * private final SensorManager mSensorManager; diff --git a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java index e24332a1885a..5cfba3d945cd 100644 --- a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java @@ -25,6 +25,7 @@ import android.graphics.ImageFormat; import android.hardware.camera2.extension.IAdvancedExtenderImpl; import android.hardware.camera2.extension.ICameraExtensionsProxyService; import android.hardware.camera2.extension.IImageCaptureExtenderImpl; +import android.hardware.camera2.extension.IInitializeSessionCallback; import android.hardware.camera2.extension.IPreviewExtenderImpl; import android.hardware.camera2.extension.LatencyRange; import android.hardware.camera2.extension.SizeList; @@ -212,9 +213,9 @@ public final class CameraExtensionCharacteristics { */ private static final class CameraExtensionManagerGlobal { private static final String TAG = "CameraExtensionManagerGlobal"; - private static final String PROXY_PACKAGE_NAME = "com.android.camera"; + private static final String PROXY_PACKAGE_NAME = "com.android.cameraextensions"; private static final String PROXY_SERVICE_NAME = - "com.android.camera.CameraExtensionsProxyService"; + "com.android.cameraextensions.CameraExtensionsProxyService"; // Singleton instance private static final CameraExtensionManagerGlobal GLOBAL_CAMERA_MANAGER = @@ -357,6 +358,27 @@ public final class CameraExtensionCharacteristics { } } + public void initializeSession(IInitializeSessionCallback cb) throws RemoteException { + synchronized (mLock) { + if (mProxy != null) { + mProxy.initializeSession(cb); + } + } + } + + public void releaseSession() { + synchronized (mLock) { + if (mProxy != null) { + try { + mProxy.releaseSession(); + } catch (RemoteException e) { + Log.e(TAG, "Failed to release session! Extension service does" + + " not respond!"); + } + } + } + } + public boolean areAdvancedExtensionsSupported() { return mSupportsAdvancedExtensions; } @@ -412,6 +434,20 @@ public final class CameraExtensionCharacteristics { /** * @hide */ + public static void initializeSession(IInitializeSessionCallback cb) throws RemoteException { + CameraExtensionManagerGlobal.get().initializeSession(cb); + } + + /** + * @hide + */ + public static void releaseSession() { + CameraExtensionManagerGlobal.get().releaseSession(); + } + + /** + * @hide + */ public static boolean areAdvancedExtensionsSupported() { return CameraExtensionManagerGlobal.get().areAdvancedExtensionsSupported(); } diff --git a/core/java/android/hardware/camera2/CameraExtensionSession.java b/core/java/android/hardware/camera2/CameraExtensionSession.java index e1b817768461..5892f682dd49 100644 --- a/core/java/android/hardware/camera2/CameraExtensionSession.java +++ b/core/java/android/hardware/camera2/CameraExtensionSession.java @@ -195,8 +195,9 @@ public abstract class CameraExtensionSession implements AutoCloseable { * This method is called if the session cannot be configured as requested. * * <p>This can happen if the set of requested outputs contains unsupported sizes, - * too many outputs are requested at once or the camera device encounters an - * unrecoverable error during configuration.</p> + * too many outputs are requested at once or when trying to initialize multiple + * concurrent extension sessions from two (or more) separate camera devices + * or the camera device encounters an unrecoverable error during configuration.</p> * * <p>The session is considered to be closed, and all methods called on it after this * callback is invoked will throw an IllegalStateException.</p> diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index a1c8d29566be..5833b3dbef86 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -162,6 +162,9 @@ public final class CameraManager { * <p>The set of combinations may include camera devices that may be in use by other camera API * clients.</p> * + * <p>Concurrent camera extension sessions {@link CameraExtensionSession} are not currently + * supported.</p> + * * <p>The set of combinations doesn't contain physical cameras that can only be used as * part of a logical multi-camera device.</p> * diff --git a/core/java/android/hardware/camera2/extension/ICameraExtensionsProxyService.aidl b/core/java/android/hardware/camera2/extension/ICameraExtensionsProxyService.aidl index bc29e9a481ae..b52c650086f4 100644 --- a/core/java/android/hardware/camera2/extension/ICameraExtensionsProxyService.aidl +++ b/core/java/android/hardware/camera2/extension/ICameraExtensionsProxyService.aidl @@ -18,6 +18,7 @@ package android.hardware.camera2.extension; import android.hardware.camera2.extension.IAdvancedExtenderImpl; import android.hardware.camera2.extension.IPreviewExtenderImpl; import android.hardware.camera2.extension.IImageCaptureExtenderImpl; +import android.hardware.camera2.extension.IInitializeSessionCallback; /** @hide */ interface ICameraExtensionsProxyService @@ -25,6 +26,8 @@ interface ICameraExtensionsProxyService long registerClient(); void unregisterClient(long clientId); boolean advancedExtensionsSupported(); + void initializeSession(in IInitializeSessionCallback cb); + void releaseSession(); @nullable IPreviewExtenderImpl initializePreviewExtension(int extensionType); @nullable IImageCaptureExtenderImpl initializeImageExtension(int extensionType); @nullable IAdvancedExtenderImpl initializeAdvancedExtension(int extensionType); diff --git a/core/java/android/hardware/camera2/extension/IInitializeSessionCallback.aidl b/core/java/android/hardware/camera2/extension/IInitializeSessionCallback.aidl new file mode 100644 index 000000000000..1747760d7d8c --- /dev/null +++ b/core/java/android/hardware/camera2/extension/IInitializeSessionCallback.aidl @@ -0,0 +1,23 @@ +/** + * 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.camera2.extension; + +/** @hide */ +interface IInitializeSessionCallback +{ + void onSuccess(); + void onFailure(); +} diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java index 5cf50a25de78..bfc1f2765c3b 100644 --- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java @@ -35,9 +35,11 @@ import android.hardware.camera2.CaptureResult; import android.hardware.camera2.TotalCaptureResult; import android.hardware.camera2.extension.CameraOutputConfig; import android.hardware.camera2.extension.CameraSessionConfig; +import android.hardware.camera2.extension.CaptureStageImpl; import android.hardware.camera2.extension.IAdvancedExtenderImpl; import android.hardware.camera2.extension.ICaptureCallback; import android.hardware.camera2.extension.IImageProcessorImpl; +import android.hardware.camera2.extension.IInitializeSessionCallback; import android.hardware.camera2.extension.IRequestCallback; import android.hardware.camera2.extension.IRequestProcessorImpl; import android.hardware.camera2.extension.ISessionProcessorImpl; @@ -89,6 +91,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes private Surface mClientCaptureSurface; private CameraCaptureSession mCaptureSession = null; private ISessionProcessorImpl mSessionProcessor = null; + private final InitializeSessionHandler mInitializeHandler; private boolean mInitialized; @@ -181,6 +184,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); mInitialized = false; + mInitializeHandler = new InitializeSessionHandler(); } /** @@ -444,7 +448,6 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes public void release() { synchronized (mInterfaceLock) { - mInitialized = false; mHandlerThread.quitSafely(); if (mSessionProcessor != null) { @@ -459,7 +462,11 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes if (mExtensionClientId >= 0) { CameraExtensionCharacteristics.unregisterClient(mExtensionClientId); + if (mInitialized) { + CameraExtensionCharacteristics.releaseSession(); + } } + mInitialized = false; for (ImageReader reader : mReaderMap.values()) { reader.close(); @@ -512,17 +519,32 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes @Override public void onConfigured(@NonNull CameraCaptureSession session) { - boolean status = true; synchronized (mInterfaceLock) { mCaptureSession = session; try { + CameraExtensionCharacteristics.initializeSession(mInitializeHandler); + } catch (RemoteException e) { + Log.e(TAG, "Failed to initialize session! Extension service does" + + " not respond!"); + notifyConfigurationFailure(); + } + } + } + } + + private class InitializeSessionHandler extends IInitializeSessionCallback.Stub { + @Override + public void onSuccess() { + boolean status = true; + synchronized (mInterfaceLock) { + try { mSessionProcessor.onCaptureSessionStart(mRequestProcessor); mInitialized = true; } catch (RemoteException e) { Log.e(TAG, "Failed to start capture session," + " extension service does not respond!"); status = false; - session.close(); + mCaptureSession.close(); } } @@ -538,6 +560,15 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes notifyConfigurationFailure(); } } + + @Override + public void onFailure() { + mCaptureSession.close(); + Log.e(TAG, "Failed to initialize proxy service session!" + + " This can happen when trying to configure multiple " + + "concurrent extension sessions!"); + notifyConfigurationFailure(); + } } private final class RequestCallbackHandler extends ICaptureCallback.Stub { diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java index 4bcc4942d8a0..537b894d9a6a 100644 --- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java @@ -34,6 +34,7 @@ import android.hardware.camera2.extension.CaptureBundle; import android.hardware.camera2.extension.CaptureStageImpl; import android.hardware.camera2.extension.ICaptureProcessorImpl; import android.hardware.camera2.extension.IImageCaptureExtenderImpl; +import android.hardware.camera2.extension.IInitializeSessionCallback; import android.hardware.camera2.extension.IPreviewExtenderImpl; import android.hardware.camera2.extension.IRequestUpdateProcessorImpl; import android.hardware.camera2.extension.ParcelImage; @@ -48,6 +49,8 @@ import android.media.ImageWriter; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; +import android.os.IBinder; +import android.os.IInterface; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.annotation.NonNull; @@ -80,6 +83,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession { private final HandlerThread mHandlerThread; private final StateCallback mCallbacks; private final List<Size> mSupportedPreviewSizes; + private final InitializeSessionHandler mInitializeHandler; private CameraCaptureSession mCaptureSession = null; private Surface mCameraRepeatingSurface, mClientRepeatingRequestSurface; @@ -216,6 +220,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession { mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); mInitialized = false; + mInitializeHandler = new InitializeSessionHandler(); } private void initializeRepeatingRequestPipeline() throws RemoteException { @@ -621,7 +626,6 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession { public void release() { synchronized (mInterfaceLock) { mInternalRepeatingRequestEnabled = false; - mInitialized = false; mHandlerThread.quitSafely(); try { @@ -634,7 +638,11 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession { if (mExtensionClientId >= 0) { CameraExtensionCharacteristics.unregisterClient(mExtensionClientId); + if (mInitialized) { + CameraExtensionCharacteristics.releaseSession(); + } } + mInitialized = false; if (mRepeatingRequestImageCallback != null) { mRepeatingRequestImageCallback.close(); @@ -739,36 +747,63 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession { @Override public void onConfigured(@NonNull CameraCaptureSession session) { - boolean status = true; synchronized (mInterfaceLock) { mCaptureSession = session; + try { + CameraExtensionCharacteristics.initializeSession(mInitializeHandler); + } catch (RemoteException e) { + Log.e(TAG, "Failed to initialize session! Extension service does" + + " not respond!"); + notifyConfigurationFailure(); + } + } + } + } - ArrayList<CaptureStageImpl> initialRequestList = compileInitialRequestList(); - if (!initialRequestList.isEmpty()) { - try { - setInitialCaptureRequest(initialRequestList, - new InitialRequestHandler(mRepeatingRequestImageCallback)); - } catch (CameraAccessException e) { - Log.e(TAG, "Failed to initialize the initial capture request!"); - status = false; - } - } else { - try { - setRepeatingRequest(mPreviewExtender.getCaptureStage(), - new RepeatingRequestHandler(null, null, null, - mRepeatingRequestImageCallback)); - } catch (CameraAccessException | RemoteException e) { - Log.e(TAG, "Failed to initialize internal repeating request!"); - status = false; - } - + private class InitializeSessionHandler extends IInitializeSessionCallback.Stub { + @Override + public void onSuccess() { + boolean status = true; + ArrayList<CaptureStageImpl> initialRequestList = + compileInitialRequestList(); + if (!initialRequestList.isEmpty()) { + try { + setInitialCaptureRequest(initialRequestList, + new InitialRequestHandler( + mRepeatingRequestImageCallback)); + } catch (CameraAccessException e) { + Log.e(TAG, + "Failed to initialize the initial capture " + + "request!"); + status = false; } + } else { + try { + setRepeatingRequest(mPreviewExtender.getCaptureStage(), + new RepeatingRequestHandler(null, null, null, + mRepeatingRequestImageCallback)); + } catch (CameraAccessException | RemoteException e) { + Log.e(TAG, + "Failed to initialize internal repeating " + + "request!"); + status = false; + } + } if (!status) { notifyConfigurationFailure(); } } + + @Override + public void onFailure() { + mCaptureSession.close(); + Log.e(TAG, "Failed to initialize proxy service session!" + + " This can happen when trying to configure multiple " + + "concurrent extension sessions!"); + notifyConfigurationFailure(); + } } private class BurstRequestHandler extends CameraCaptureSession.CaptureCallback { diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index 0819835f5fb5..68dd62343eb0 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -1376,7 +1376,7 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing return context.getString( com.android.internal.R.string.fingerprint_error_security_update_required); case FINGERPRINT_ERROR_BAD_CALIBARTION: - context.getString( + return context.getString( com.android.internal.R.string.fingerprint_error_bad_calibration); case FINGERPRINT_ERROR_VENDOR: { String[] msgArray = context.getResources().getStringArray( diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java index 662ebb356f4c..5c2855307509 100644 --- a/core/java/android/net/VpnManager.java +++ b/core/java/android/net/VpnManager.java @@ -389,6 +389,10 @@ public class VpnManager { /** * Starts a legacy VPN. + * + * Legacy VPN is deprecated starting from Android S. So this API shouldn't be called if the + * initial SDK version of device is Android S+. Otherwise, UnsupportedOperationException will be + * thrown. * @hide */ public void startLegacyVpn(VpnProfile profile) { diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java index 86cd23d1e942..752ef3e39ab6 100644 --- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java +++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java @@ -352,6 +352,7 @@ public final class VcnGatewayConnectionConfig { public int hashCode() { return Objects.hash( mGatewayConnectionName, + mTunnelConnectionParams, mExposedCapabilities, Arrays.hashCode(mRetryIntervalsMs), mMaxMtu); @@ -365,6 +366,7 @@ public final class VcnGatewayConnectionConfig { final VcnGatewayConnectionConfig rhs = (VcnGatewayConnectionConfig) other; return mGatewayConnectionName.equals(rhs.mGatewayConnectionName) + && mTunnelConnectionParams.equals(rhs.mTunnelConnectionParams) && mExposedCapabilities.equals(rhs.mExposedCapabilities) && Arrays.equals(mRetryIntervalsMs, rhs.mRetryIntervalsMs) && mMaxMtu == rhs.mMaxMtu; diff --git a/core/java/android/os/FileBridge.java b/core/java/android/os/FileBridge.java index 7b84575a8955..9dcdbf93f296 100644 --- a/core/java/android/os/FileBridge.java +++ b/core/java/android/os/FileBridge.java @@ -32,6 +32,7 @@ import libcore.io.Streams; import java.io.FileDescriptor; import java.io.IOException; import java.io.OutputStream; +import java.nio.ByteBuffer; import java.nio.ByteOrder; /** @@ -95,9 +96,11 @@ public class FileBridge extends Thread { @Override public void run() { - final byte[] temp = new byte[8192]; + final ByteBuffer tempBuffer = ByteBuffer.allocateDirect(8192); + final byte[] temp = tempBuffer.hasArray() ? tempBuffer.array() : new byte[8192]; try { - while (IoBridge.read(mServer.getFileDescriptor(), temp, 0, MSG_LENGTH) == MSG_LENGTH) { + while (IoBridge.read(mServer.getFileDescriptor(), temp, + 0, MSG_LENGTH) == MSG_LENGTH) { final int cmd = Memory.peekInt(temp, 0, ByteOrder.BIG_ENDIAN); if (cmd == CMD_WRITE) { // Shuttle data into local file @@ -138,7 +141,10 @@ public class FileBridge extends Thread { public static class FileBridgeOutputStream extends OutputStream { private final ParcelFileDescriptor mClientPfd; private final FileDescriptor mClient; - private final byte[] mTemp = new byte[MSG_LENGTH]; + private final ByteBuffer mTempBuffer = ByteBuffer.allocateDirect(MSG_LENGTH); + private final byte[] mTemp = mTempBuffer.hasArray() + ? mTempBuffer.array() + : new byte[MSG_LENGTH]; public FileBridgeOutputStream(ParcelFileDescriptor clientPfd) { mClientPfd = clientPfd; diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java index fd8948cbeea8..0c3debb1b54e 100644 --- a/core/java/android/os/SystemVibrator.java +++ b/core/java/android/os/SystemVibrator.java @@ -26,6 +26,7 @@ import android.util.Log; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.Objects; @@ -254,11 +255,14 @@ public class SystemVibrator extends Vibrator { * <p>This uses the first vibrator on the list as the default one for all hardware spec, but * uses an intersection of all vibrators to decide the capabilities and effect/primitive * support. + * + * @hide */ - private static class AllVibratorsInfo extends VibratorInfo { + @VisibleForTesting + public static class AllVibratorsInfo extends VibratorInfo { private final VibratorInfo[] mVibratorInfos; - AllVibratorsInfo(VibratorInfo[] vibrators) { + public AllVibratorsInfo(VibratorInfo[] vibrators) { super(/* id= */ -1, capabilitiesIntersection(vibrators), vibrators.length > 0 ? vibrators[0] : VibratorInfo.EMPTY_VIBRATOR_INFO); mVibratorInfos = vibrators; @@ -266,6 +270,9 @@ public class SystemVibrator extends Vibrator { @Override public int isEffectSupported(int effectId) { + if (mVibratorInfos.length == 0) { + return Vibrator.VIBRATION_EFFECT_SUPPORT_NO; + } int supported = Vibrator.VIBRATION_EFFECT_SUPPORT_YES; for (VibratorInfo info : mVibratorInfos) { int effectSupported = info.isEffectSupported(effectId); @@ -280,6 +287,9 @@ public class SystemVibrator extends Vibrator { @Override public boolean isPrimitiveSupported(int primitiveId) { + if (mVibratorInfos.length == 0) { + return false; + } for (VibratorInfo info : mVibratorInfos) { if (!info.isPrimitiveSupported(primitiveId)) { return false; @@ -288,6 +298,19 @@ public class SystemVibrator extends Vibrator { return true; } + @Override + public int getPrimitiveDuration(int primitiveId) { + int maxDuration = 0; + for (VibratorInfo info : mVibratorInfos) { + int duration = info.getPrimitiveDuration(primitiveId); + if (duration == 0) { + return 0; + } + maxDuration = Math.max(maxDuration, duration); + } + return maxDuration; + } + private static int capabilitiesIntersection(VibratorInfo[] infos) { if (infos.length == 0) { return 0; diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index c5d0cd40bc6d..4ef0e6e785e8 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -908,9 +908,32 @@ public final class PermissionManager { */ public static boolean shouldShowPackageForIndicatorCached(@NonNull Context context, @NonNull String packageName) { - if (SYSTEM_PKG.equals(packageName)) { - return false; + return !getIndicatorExemptedPackages(context).contains(packageName); + } + + /** + * Get the list of packages that are not shown by the indicators. Only a select few roles, and + * the system app itself, are hidden. These values are updated at most every 15 seconds. + * @hide + */ + public static Set<String> getIndicatorExemptedPackages(@NonNull Context context) { + updateIndicatorExemptedPackages(context); + ArraySet<String> pkgNames = new ArraySet<>(); + pkgNames.add(SYSTEM_PKG); + for (int i = 0; i < INDICATOR_EXEMPTED_PACKAGES.length; i++) { + String exemptedPackage = INDICATOR_EXEMPTED_PACKAGES[i]; + if (exemptedPackage != null) { + pkgNames.add(exemptedPackage); + } } + return pkgNames; + } + + /** + * Update the cached indicator exempted packages + * @hide + */ + public static void updateIndicatorExemptedPackages(@NonNull Context context) { long now = SystemClock.elapsedRealtime(); if (sLastIndicatorUpdateTime == -1 || (now - sLastIndicatorUpdateTime) > EXEMPTED_INDICATOR_ROLE_UPDATE_FREQUENCY_MS) { @@ -919,14 +942,6 @@ public final class PermissionManager { INDICATOR_EXEMPTED_PACKAGES[i] = context.getString(EXEMPTED_ROLES[i]); } } - for (int i = 0; i < EXEMPTED_ROLES.length; i++) { - String exemptedPackage = INDICATOR_EXEMPTED_PACKAGES[i]; - if (exemptedPackage != null && exemptedPackage.equals(packageName)) { - return false; - } - } - - return true; } /** * Gets the list of packages that have permissions that specified diff --git a/core/java/android/permission/PermissionUsageHelper.java b/core/java/android/permission/PermissionUsageHelper.java index d4e548e1df1e..791764b4342f 100644 --- a/core/java/android/permission/PermissionUsageHelper.java +++ b/core/java/android/permission/PermissionUsageHelper.java @@ -410,7 +410,9 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis int usageAttr = usage.getPackageIdHash(); // If this usage has a proxy, but is not a proxy, it is the end of a chain. - if (!proxies.containsKey(usageAttr) && usage.proxy != null) { + // TODO remove once camera converted + if (!proxies.containsKey(usageAttr) && usage.proxy != null + && !usage.op.equals(OPSTR_RECORD_AUDIO)) { proxyLabels.put(usage, new ArrayList<>()); proxyPackages.add(usage.getPackageIdHash()); } diff --git a/core/java/android/service/contentcapture/ActivityEvent.java b/core/java/android/service/contentcapture/ActivityEvent.java index 1188a3f1021e..74a735518120 100644 --- a/core/java/android/service/contentcapture/ActivityEvent.java +++ b/core/java/android/service/contentcapture/ActivityEvent.java @@ -55,12 +55,25 @@ public final class ActivityEvent implements Parcelable { */ public static final int TYPE_ACTIVITY_DESTROYED = Event.ACTIVITY_DESTROYED; + /** + * TODO: change to public field. + * The activity was started. + * + * <p>There are some reason, ACTIVITY_START cannot be added into UsageStats. We don't depend on + * UsageEvents for Activity start. + * </p> + * + * @hide + */ + public static final int TYPE_ACTIVITY_STARTED = 10000; + /** @hide */ @IntDef(prefix = { "TYPE_" }, value = { TYPE_ACTIVITY_RESUMED, TYPE_ACTIVITY_PAUSED, TYPE_ACTIVITY_STOPPED, - TYPE_ACTIVITY_DESTROYED + TYPE_ACTIVITY_DESTROYED, + TYPE_ACTIVITY_STARTED }) @Retention(RetentionPolicy.SOURCE) public @interface ActivityEventType{} @@ -86,7 +99,8 @@ public final class ActivityEvent implements Parcelable { * Gets the event type. * * @return either {@link #TYPE_ACTIVITY_RESUMED}, {@value #TYPE_ACTIVITY_PAUSED}, - * {@value #TYPE_ACTIVITY_STOPPED}, or {@value #TYPE_ACTIVITY_DESTROYED}. + * {@value #TYPE_ACTIVITY_STOPPED}, {@value #TYPE_ACTIVITY_DESTROYED} or 10000 if the Activity + * was started. */ @ActivityEventType public int getEventType() { @@ -104,6 +118,8 @@ public final class ActivityEvent implements Parcelable { return "ACTIVITY_STOPPED"; case TYPE_ACTIVITY_DESTROYED: return "ACTIVITY_DESTROYED"; + case TYPE_ACTIVITY_STARTED: + return "ACTIVITY_STARTED"; default: return "UKNOWN_TYPE: " + type; } diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java index 863d71f6f793..8e4a68e52697 100644 --- a/core/java/android/service/notification/StatusBarNotification.java +++ b/core/java/android/service/notification/StatusBarNotification.java @@ -434,8 +434,11 @@ public class StatusBarNotification implements Parcelable { public Context getPackageContext(Context context) { if (mContext == null) { try { - mContext = context.createPackageContextAsUser(pkg, Context.CONTEXT_RESTRICTED, user, - PackageManager.MATCH_UNINSTALLED_PACKAGES); + ApplicationInfo ai = context.getPackageManager() + .getApplicationInfoAsUser(pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES, + getUserId()); + mContext = context.createApplicationContext(ai, + Context.CONTEXT_RESTRICTED); } catch (PackageManager.NameNotFoundException e) { mContext = null; } diff --git a/core/java/android/service/voice/HotwordDetectedResult.java b/core/java/android/service/voice/HotwordDetectedResult.java index 846f2f94d055..315392bf6a58 100644 --- a/core/java/android/service/voice/HotwordDetectedResult.java +++ b/core/java/android/service/voice/HotwordDetectedResult.java @@ -20,11 +20,18 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.content.res.Resources; +import android.media.AudioRecord; import android.media.MediaSyncEvent; +import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; +import com.android.internal.R; import com.android.internal.util.DataClass; +import com.android.internal.util.Preconditions; + +import java.util.Objects; /** * Represents a result supporting the hotword detection. @@ -187,16 +194,20 @@ public final class HotwordDetectedResult implements Parcelable { return new PersistableBundle(); } + private static int sMaxBundleSize = -1; + /** * Returns the maximum byte size of the information contained in the bundle. * - * <p>The total size will be calculated as a sum of byte sizes over all bundle keys. - * - * <p>For example, for a bundle containing a single key: {@code "example_key" -> 42.0f}, the - * bundle size will be {@code 11 + Float.BYTES = 15} bytes. + * <p>The total size will be calculated by how much bundle data should be written into the + * Parcel. */ public static int getMaxBundleSize() { - return 50; + if (sMaxBundleSize < 0) { + sMaxBundleSize = Resources.getSystem().getInteger( + R.integer.config_hotwordDetectedResultMaxBundleSize); + } + return sMaxBundleSize; } /** @@ -212,6 +223,34 @@ public final class HotwordDetectedResult implements Parcelable { return mMediaSyncEvent; } + /** + * Returns how many bytes should be written into the Parcel + * + * @hide + */ + public static int getParcelableSize(@NonNull Parcelable parcelable) { + final Parcel p = Parcel.obtain(); + parcelable.writeToParcel(p, 0); + p.setDataPosition(0); + final int size = p.dataSize(); + p.recycle(); + return size; + } + + private void onConstructed() { + Preconditions.checkArgumentInRange(mScore, 0, getMaxScore(), "score"); + Preconditions.checkArgumentInRange(mPersonalizedScore, 0, getMaxScore(), + "personalizedScore"); + Preconditions.checkArgumentInRange(mHotwordPhraseId, 0, getMaxHotwordPhraseId(), + "hotwordPhraseId"); + Preconditions.checkArgumentInRange((long) mHotwordDurationMillis, 0, + AudioRecord.getMaxSharedAudioHistoryMillis(), "hotwordDurationMillis"); + if (!mExtras.isEmpty()) { + Preconditions.checkArgumentInRange(getParcelableSize(mExtras), 0, getMaxBundleSize(), + "extras"); + } + } + // Code below generated by codegen v1.0.23. @@ -290,7 +329,7 @@ public final class HotwordDetectedResult implements Parcelable { com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mExtras); - // onConstructed(); // You can define this method to get a callback + onConstructed(); } /** @@ -422,7 +461,7 @@ public final class HotwordDetectedResult implements Parcelable { //noinspection PointlessBooleanExpression return true && mConfidenceLevel == that.mConfidenceLevel - && java.util.Objects.equals(mMediaSyncEvent, that.mMediaSyncEvent) + && Objects.equals(mMediaSyncEvent, that.mMediaSyncEvent) && mHotwordOffsetMillis == that.mHotwordOffsetMillis && mHotwordDurationMillis == that.mHotwordDurationMillis && mAudioChannel == that.mAudioChannel @@ -430,7 +469,7 @@ public final class HotwordDetectedResult implements Parcelable { && mScore == that.mScore && mPersonalizedScore == that.mPersonalizedScore && mHotwordPhraseId == that.mHotwordPhraseId - && java.util.Objects.equals(mExtras, that.mExtras); + && Objects.equals(mExtras, that.mExtras); } @Override @@ -441,7 +480,7 @@ public final class HotwordDetectedResult implements Parcelable { int _hash = 1; _hash = 31 * _hash + mConfidenceLevel; - _hash = 31 * _hash + java.util.Objects.hashCode(mMediaSyncEvent); + _hash = 31 * _hash + Objects.hashCode(mMediaSyncEvent); _hash = 31 * _hash + mHotwordOffsetMillis; _hash = 31 * _hash + mHotwordDurationMillis; _hash = 31 * _hash + mAudioChannel; @@ -449,13 +488,13 @@ public final class HotwordDetectedResult implements Parcelable { _hash = 31 * _hash + mScore; _hash = 31 * _hash + mPersonalizedScore; _hash = 31 * _hash + mHotwordPhraseId; - _hash = 31 * _hash + java.util.Objects.hashCode(mExtras); + _hash = 31 * _hash + Objects.hashCode(mExtras); return _hash; } @Override @DataClass.Generated.Member - public void writeToParcel(@NonNull android.os.Parcel dest, int flags) { + public void writeToParcel(@NonNull Parcel dest, int flags) { // You can override field parcelling by defining methods like: // void parcelFieldName(Parcel dest, int flags) { ... } @@ -481,7 +520,7 @@ public final class HotwordDetectedResult implements Parcelable { /** @hide */ @SuppressWarnings({"unchecked", "RedundantCast"}) @DataClass.Generated.Member - /* package-private */ HotwordDetectedResult(@NonNull android.os.Parcel in) { + /* package-private */ HotwordDetectedResult(@NonNull Parcel in) { // You can override field unparcelling by defining methods like: // static FieldType unparcelFieldName(Parcel in) { ... } @@ -512,7 +551,7 @@ public final class HotwordDetectedResult implements Parcelable { com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mExtras); - // onConstructed(); // You can define this method to get a callback + onConstructed(); } @DataClass.Generated.Member @@ -524,7 +563,7 @@ public final class HotwordDetectedResult implements Parcelable { } @Override - public HotwordDetectedResult createFromParcel(@NonNull android.os.Parcel in) { + public HotwordDetectedResult createFromParcel(@NonNull Parcel in) { return new HotwordDetectedResult(in); } }; @@ -745,10 +784,10 @@ public final class HotwordDetectedResult implements Parcelable { } @DataClass.Generated( - time = 1621943150502L, + time = 1624361647985L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/service/voice/HotwordDetectedResult.java", - inputSignatures = "public static final int CONFIDENCE_LEVEL_NONE\npublic static final int CONFIDENCE_LEVEL_LOW\npublic static final int CONFIDENCE_LEVEL_LOW_MEDIUM\npublic static final int CONFIDENCE_LEVEL_MEDIUM\npublic static final int CONFIDENCE_LEVEL_MEDIUM_HIGH\npublic static final int CONFIDENCE_LEVEL_HIGH\npublic static final int CONFIDENCE_LEVEL_VERY_HIGH\npublic static final int HOTWORD_OFFSET_UNSET\npublic static final int AUDIO_CHANNEL_UNSET\nprivate final @android.service.voice.HotwordDetectedResult.HotwordConfidenceLevelValue int mConfidenceLevel\nprivate @android.annotation.Nullable android.media.MediaSyncEvent mMediaSyncEvent\nprivate int mHotwordOffsetMillis\nprivate int mHotwordDurationMillis\nprivate int mAudioChannel\nprivate boolean mHotwordDetectionPersonalized\nprivate final int mScore\nprivate final int mPersonalizedScore\nprivate final int mHotwordPhraseId\nprivate final @android.annotation.NonNull android.os.PersistableBundle mExtras\nprivate static int defaultConfidenceLevel()\nprivate static int defaultScore()\nprivate static int defaultPersonalizedScore()\npublic static int getMaxScore()\nprivate static int defaultHotwordPhraseId()\npublic static int getMaxHotwordPhraseId()\nprivate static android.os.PersistableBundle defaultExtras()\npublic static int getMaxBundleSize()\npublic @android.annotation.Nullable android.media.MediaSyncEvent getMediaSyncEvent()\nclass HotwordDetectedResult extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genHiddenConstDefs=true, genParcelable=true, genToString=true)") + inputSignatures = "public static final int CONFIDENCE_LEVEL_NONE\npublic static final int CONFIDENCE_LEVEL_LOW\npublic static final int CONFIDENCE_LEVEL_LOW_MEDIUM\npublic static final int CONFIDENCE_LEVEL_MEDIUM\npublic static final int CONFIDENCE_LEVEL_MEDIUM_HIGH\npublic static final int CONFIDENCE_LEVEL_HIGH\npublic static final int CONFIDENCE_LEVEL_VERY_HIGH\npublic static final int HOTWORD_OFFSET_UNSET\npublic static final int AUDIO_CHANNEL_UNSET\nprivate final @android.service.voice.HotwordDetectedResult.HotwordConfidenceLevelValue int mConfidenceLevel\nprivate @android.annotation.Nullable android.media.MediaSyncEvent mMediaSyncEvent\nprivate int mHotwordOffsetMillis\nprivate int mHotwordDurationMillis\nprivate int mAudioChannel\nprivate boolean mHotwordDetectionPersonalized\nprivate final int mScore\nprivate final int mPersonalizedScore\nprivate final int mHotwordPhraseId\nprivate final @android.annotation.NonNull android.os.PersistableBundle mExtras\nprivate static int sMaxBundleSize\nprivate static int defaultConfidenceLevel()\nprivate static int defaultScore()\nprivate static int defaultPersonalizedScore()\npublic static int getMaxScore()\nprivate static int defaultHotwordPhraseId()\npublic static int getMaxHotwordPhraseId()\nprivate static android.os.PersistableBundle defaultExtras()\npublic static int getMaxBundleSize()\npublic @android.annotation.Nullable android.media.MediaSyncEvent getMediaSyncEvent()\npublic static int getParcelableSize(android.os.Parcelable)\nprivate void onConstructed()\nclass HotwordDetectedResult extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genHiddenConstDefs=true, genParcelable=true, genToString=true)") @Deprecated private void __metadata() {} diff --git a/core/java/android/service/voice/HotwordDetectionService.java b/core/java/android/service/voice/HotwordDetectionService.java index 93a7ec793536..567ee2f65565 100644 --- a/core/java/android/service/voice/HotwordDetectionService.java +++ b/core/java/android/service/voice/HotwordDetectionService.java @@ -76,6 +76,7 @@ public abstract class HotwordDetectionService extends Service { private static final boolean DBG = true; private static final long UPDATE_TIMEOUT_MILLIS = 5000; + /** @hide */ public static final String KEY_INITIALIZATION_STATUS = "initialization_status"; @@ -388,6 +389,14 @@ public abstract class HotwordDetectionService extends Service { */ public void onDetected(@NonNull HotwordDetectedResult result) { requireNonNull(result); + final PersistableBundle persistableBundle = result.getExtras(); + if (!persistableBundle.isEmpty() && HotwordDetectedResult.getParcelableSize( + persistableBundle) > HotwordDetectedResult.getMaxBundleSize()) { + throw new IllegalArgumentException( + "The bundle size of result is larger than max bundle size (" + + HotwordDetectedResult.getMaxBundleSize() + + ") of HotwordDetectedResult"); + } try { mRemoteCallback.onDetected(result); } catch (RemoteException e) { diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 05ed75a7d8fb..fe1fcfc489c1 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -20,6 +20,7 @@ import static android.graphics.Matrix.MSCALE_X; import static android.graphics.Matrix.MSCALE_Y; import static android.graphics.Matrix.MSKEW_X; import static android.graphics.Matrix.MSKEW_Y; +import static android.view.SurfaceControl.METADATA_WINDOW_TYPE; import static android.view.View.SYSTEM_UI_FLAG_VISIBLE; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; @@ -1024,6 +1025,8 @@ public abstract class WallpaperService extends Service { mBbqSurfaceControl = new SurfaceControl.Builder() .setName("Wallpaper BBQ wrapper") .setHidden(false) + // TODO(b/192291754) + .setMetadata(METADATA_WINDOW_TYPE, TYPE_WALLPAPER) .setBLASTLayer() .setParent(mSurfaceControl) .setCallsite("Wallpaper#relayout") @@ -1570,6 +1573,7 @@ public abstract class WallpaperService extends Service { + page.getBitmap().getWidth() + " x " + page.getBitmap().getHeight()); } for (RectF area: page.getAreas()) { + if (area == null) continue; RectF subArea = generateSubRect(area, pageIndx, numPages); Bitmap b = page.getBitmap(); int x = Math.round(b.getWidth() * subArea.left); @@ -1933,6 +1937,7 @@ public abstract class WallpaperService extends Service { } private boolean isValid(RectF area) { + if (area == null) return false; boolean valid = area.bottom > area.top && area.left < area.right && LOCAL_COLOR_BOUNDS.contains(area); return valid; diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index f0f0867d414b..505f400c60d2 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -2351,7 +2351,10 @@ public abstract class Layout { final int ellipsisStringLen = ellipsisString.length(); // Use the ellipsis string only if there are that at least as many characters to replace. final boolean useEllipsisString = ellipsisCount >= ellipsisStringLen; - for (int i = 0; i < ellipsisCount; i++) { + final int min = Math.max(0, start - ellipsisStart - lineStart); + final int max = Math.min(ellipsisCount, end - ellipsisStart - lineStart); + + for (int i = min; i < max; i++) { final char c; if (useEllipsisString && i < ellipsisStringLen) { c = ellipsisString.charAt(i); @@ -2360,9 +2363,7 @@ public abstract class Layout { } final int a = i + ellipsisStart + lineStart; - if (start <= a && a < end) { - dest[destoff + a - start] = c; - } + dest[destoff + a - start] = c; } } diff --git a/core/java/android/view/CrossWindowBlurListeners.java b/core/java/android/view/CrossWindowBlurListeners.java index e307b969ef91..761a2b88dec2 100644 --- a/core/java/android/view/CrossWindowBlurListeners.java +++ b/core/java/android/view/CrossWindowBlurListeners.java @@ -73,14 +73,14 @@ public final class CrossWindowBlurListeners { return instance; } - boolean isCrossWindowBlurEnabled() { + public boolean isCrossWindowBlurEnabled() { synchronized (sLock) { attachInternalListenerIfNeededLocked(); return mCrossWindowBlurEnabled; } } - void addListener(@NonNull @CallbackExecutor Executor executor, + public void addListener(@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> listener) { Preconditions.checkNotNull(listener, "listener cannot be null"); Preconditions.checkNotNull(executor, "executor cannot be null"); @@ -94,7 +94,7 @@ public final class CrossWindowBlurListeners { } - void removeListener(Consumer<Boolean> listener) { + public void removeListener(Consumer<Boolean> listener) { Preconditions.checkNotNull(listener, "listener cannot be null"); synchronized (sLock) { diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java index 85ff93bcc5e1..1506ee4c2c7a 100644 --- a/core/java/android/view/InsetsSourceControl.java +++ b/core/java/android/view/InsetsSourceControl.java @@ -48,6 +48,7 @@ public class InsetsSourceControl implements Parcelable { private Insets mInsetsHint; private boolean mSkipAnimationOnce; + private int mParcelableFlags; public InsetsSourceControl(@InternalInsetsType int type, @Nullable SurfaceControl leash, Point surfacePosition, Insets insetsHint) { @@ -132,6 +133,10 @@ public class InsetsSourceControl implements Parcelable { return result; } + public void setParcelableFlags(int parcelableFlags) { + mParcelableFlags = parcelableFlags; + } + @Override public int describeContents() { return 0; @@ -140,9 +145,9 @@ public class InsetsSourceControl implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mType); - dest.writeTypedObject(mLeash, 0 /* parcelableFlags */); - dest.writeTypedObject(mSurfacePosition, 0 /* parcelableFlags */); - dest.writeTypedObject(mInsetsHint, 0 /* parcelableFlags */); + dest.writeTypedObject(mLeash, mParcelableFlags); + dest.writeTypedObject(mSurfacePosition, mParcelableFlags); + dest.writeTypedObject(mInsetsHint, mParcelableFlags); dest.writeBoolean(mSkipAnimationOnce); } diff --git a/core/java/android/view/ScrollCaptureTarget.java b/core/java/android/view/ScrollCaptureTarget.java index a8bb037af5f9..44017ed0d831 100644 --- a/core/java/android/view/ScrollCaptureTarget.java +++ b/core/java/android/view/ScrollCaptureTarget.java @@ -21,10 +21,13 @@ import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UiThread; +import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; import android.os.CancellationSignal; +import com.android.internal.util.FastMath; + import java.io.PrintWriter; import java.util.function.Consumer; @@ -40,7 +43,8 @@ public final class ScrollCaptureTarget { private final int mHint; private Rect mScrollBounds; - private final int[] mTmpIntArr = new int[2]; + private final float[] mTmpFloatArr = new float[2]; + private final Matrix mMatrixViewLocalToWindow = new Matrix(); public ScrollCaptureTarget(@NonNull View scrollTarget, @NonNull Rect localVisibleRect, @NonNull Point positionInWindow, @NonNull ScrollCaptureCallback callback) { @@ -113,15 +117,28 @@ public final class ScrollCaptureTarget { } } + private static void zero(float[] pointArray) { + pointArray[0] = 0; + pointArray[1] = 0; + } + + private static void roundIntoPoint(Point pointObj, float[] pointArray) { + pointObj.x = FastMath.round(pointArray[0]); + pointObj.y = FastMath.round(pointArray[1]); + } + /** - * Refresh the local visible bounds and its offset within the window, based on the current + * Refresh the local visible bounds and it's offset within the window, based on the current * state of the {@code containing view}. */ @UiThread public void updatePositionInWindow() { - mContainingView.getLocationInWindow(mTmpIntArr); - mPositionInWindow.x = mTmpIntArr[0]; - mPositionInWindow.y = mTmpIntArr[1]; + mMatrixViewLocalToWindow.reset(); + mContainingView.transformMatrixToGlobal(mMatrixViewLocalToWindow); + + zero(mTmpFloatArr); + mMatrixViewLocalToWindow.mapPoints(mTmpFloatArr); + roundIntoPoint(mPositionInWindow, mTmpFloatArr); } public String toString() { diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 4e66ceb76a60..c03db6d67356 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -2610,16 +2610,6 @@ public final class SurfaceControl implements Parcelable { = sRegistry.registerNativeAllocation(this, mNativeObject); } - /** - * Create a transaction object that wraps a native peer. - * @hide - */ - Transaction(long nativeObject) { - mNativeObject = nativeObject; - mFreeNativeResources = - sRegistry.registerNativeAllocation(this, mNativeObject); - } - private Transaction(Parcel in) { readFromParcel(in); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 573ae998305e..5a248af7a097 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1371,8 +1371,12 @@ public final class ViewRootImpl implements ViewParent, HardwareRenderer.ASurfaceTransactionCallback callback = (nativeTransactionObj, nativeSurfaceControlObj, frameNr) -> { - Transaction t = new Transaction(nativeTransactionObj); - mergeWithNextTransaction(t, frameNr); + if (mBlastBufferQueue == null) { + return false; + } else { + mBlastBufferQueue.mergeWithNextTransaction(nativeTransactionObj, frameNr); + return true; + } }; mAttachInfo.mThreadedRenderer.setASurfaceTransactionCallback(callback); } @@ -5290,7 +5294,16 @@ public final class ViewRootImpl implements ViewParent, // b) When loosing control, controller can restore server state by taking last // dispatched state as truth. mInsetsController.onStateChanged((InsetsState) args.arg1); - mInsetsController.onControlsChanged((InsetsSourceControl[]) args.arg2); + InsetsSourceControl[] controls = (InsetsSourceControl[]) args.arg2; + if (mAdded) { + mInsetsController.onControlsChanged(controls); + } else if (controls != null) { + for (InsetsSourceControl control : controls) { + if (control != null) { + control.release(SurfaceControl::release); + } + } + } args.recycle(); break; } @@ -8136,6 +8149,10 @@ public final class ViewRootImpl implements ViewParent, } } + // If our window is removed, we might not get notified about losing control. + // Invoking this can release the leashes as soon as possible instead of relying on GC. + mInsetsController.onControlsChanged(null); + mAdded = false; } WindowManagerGlobal.getInstance().doRemoveView(this); diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 5964f632da1a..2996c3d87120 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -3781,6 +3781,7 @@ public interface WindowManager extends ViewManager { out.writeInt(screenOrientation); out.writeFloat(preferredRefreshRate); out.writeInt(preferredDisplayModeId); + out.writeFloat(preferredMaxDisplayRefreshRate); out.writeInt(systemUiVisibility); out.writeInt(subtreeSystemUiVisibility); out.writeBoolean(hasSystemUiListeners); @@ -3851,6 +3852,7 @@ public interface WindowManager extends ViewManager { screenOrientation = in.readInt(); preferredRefreshRate = in.readFloat(); preferredDisplayModeId = in.readInt(); + preferredMaxDisplayRefreshRate = in.readFloat(); systemUiVisibility = in.readInt(); subtreeSystemUiVisibility = in.readInt(); hasSystemUiListeners = in.readBoolean(); @@ -3928,6 +3930,8 @@ public interface WindowManager extends ViewManager { public static final int MINIMAL_POST_PROCESSING_PREFERENCE_CHANGED = 1 << 28; /** {@hide} */ public static final int BLUR_BEHIND_RADIUS_CHANGED = 1 << 29; + /** {@hide} */ + public static final int PREFERRED_MAX_DISPLAY_REFRESH_RATE = 1 << 30; // internal buffer to backup/restore parameters under compatibility mode. private int[] mCompatibilityParamsBackup = null; @@ -4059,6 +4063,11 @@ public interface WindowManager extends ViewManager { changes |= PREFERRED_DISPLAY_MODE_ID; } + if (preferredMaxDisplayRefreshRate != o.preferredMaxDisplayRefreshRate) { + preferredMaxDisplayRefreshRate = o.preferredMaxDisplayRefreshRate; + changes |= PREFERRED_MAX_DISPLAY_REFRESH_RATE; + } + if (systemUiVisibility != o.systemUiVisibility || subtreeSystemUiVisibility != o.subtreeSystemUiVisibility) { systemUiVisibility = o.systemUiVisibility; @@ -4263,6 +4272,10 @@ public interface WindowManager extends ViewManager { sb.append(" preferredDisplayMode="); sb.append(preferredDisplayModeId); } + if (preferredMaxDisplayRefreshRate != 0) { + sb.append(" preferredMaxDisplayRefreshRate="); + sb.append(preferredMaxDisplayRefreshRate); + } if (hasSystemUiListeners) { sb.append(" sysuil="); sb.append(hasSystemUiListeners); diff --git a/core/java/android/view/contentcapture/ContentCaptureEvent.java b/core/java/android/view/contentcapture/ContentCaptureEvent.java index 10ae69118f54..ce6d034c585e 100644 --- a/core/java/android/view/contentcapture/ContentCaptureEvent.java +++ b/core/java/android/view/contentcapture/ContentCaptureEvent.java @@ -286,6 +286,15 @@ public final class ContentCaptureEvent implements Parcelable { return this; } + boolean hasSameComposingSpan(@NonNull ContentCaptureEvent other) { + return mComposingStart == other.mComposingStart && mComposingEnd == other.mComposingEnd; + } + + boolean hasSameSelectionSpan(@NonNull ContentCaptureEvent other) { + return mSelectionStartIndex == other.mSelectionStartIndex + && mSelectionEndIndex == other.mSelectionEndIndex; + } + private int getComposingStart() { return mComposingStart; } diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index bcb914208958..e0a7bf23f488 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -323,9 +323,11 @@ public final class MainContentCaptureSession extends ContentCaptureSession { if (!hasStarted() && eventType != ContentCaptureEvent.TYPE_SESSION_STARTED && eventType != ContentCaptureEvent.TYPE_CONTEXT_UPDATED) { // TODO(b/120494182): comment when this could happen (dialogs?) - Log.v(TAG, "handleSendEvent(" + getDebugState() + ", " - + ContentCaptureEvent.getTypeAsString(eventType) - + "): dropping because session not started yet"); + if (sVerbose) { + Log.v(TAG, "handleSendEvent(" + getDebugState() + ", " + + ContentCaptureEvent.getTypeAsString(eventType) + + "): dropping because session not started yet"); + } return; } if (mDisabled.get()) { @@ -368,7 +370,10 @@ public final class MainContentCaptureSession extends ContentCaptureSession { final CharSequence lastText = lastEvent.getText(); final boolean bothNonEmpty = !TextUtils.isEmpty(lastText) && !TextUtils.isEmpty(text); - boolean equalContent = TextUtils.equals(lastText, text); + boolean equalContent = + TextUtils.equals(lastText, text) + && lastEvent.hasSameComposingSpan(event) + && lastEvent.hasSameSelectionSpan(event); if (equalContent) { addEvent = false; } else if (bothNonEmpty) { diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java index bdd12063e6cf..c4540b0d8726 100644 --- a/core/java/android/view/inputmethod/BaseInputConnection.java +++ b/core/java/android/view/inputmethod/BaseInputConnection.java @@ -163,6 +163,17 @@ public class BaseInputConnection implements InputConnection { } /** + * Called after only the composing region is modified (so it isn't called if the text also + * changes). + * <p> + * Default implementation does nothing. + * + * @hide + */ + public void endComposingRegionEditInternal() { + } + + /** * Default implementation calls {@link #finishComposingText()} and * {@code setImeConsumesInput(false)}. */ @@ -468,6 +479,7 @@ public class BaseInputConnection implements InputConnection { // Note: sendCurrentText does nothing unless mFallbackMode is set sendCurrentText(); endBatchEdit(); + endComposingRegionEditInternal(); } return true; } @@ -734,6 +746,7 @@ public class BaseInputConnection implements InputConnection { // Note: sendCurrentText does nothing unless mFallbackMode is set sendCurrentText(); endBatchEdit(); + endComposingRegionEditInternal(); } return true; } diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java index 5ac878d88100..592993cc3d3e 100644 --- a/core/java/android/view/translation/UiTranslationController.java +++ b/core/java/android/view/translation/UiTranslationController.java @@ -424,7 +424,7 @@ public class UiTranslationController { if (callback == null) { if (view instanceof TextView) { // developer doesn't provide their override, we set the default TextView - // implememtation. + // implementation. callback = new TextViewTranslationCallback(); view.setViewTranslationCallback(callback); } else { diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index 8d27cded6338..cf6807e41e8a 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -33,7 +33,6 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.Trace; -import android.os.UserHandle; import android.util.AndroidRuntimeException; import android.util.ArraySet; import android.util.Log; @@ -468,12 +467,9 @@ public final class WebViewFactory { sTimestamps.mCreateContextStart = SystemClock.uptimeMillis(); try { // Construct an app context to load the Java code into the current app. - Context webViewContext = initialApplication.createPackageContextAsUser( - ai.packageName, - Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY, - UserHandle.getUserHandleForUid(ai.uid), - PackageManager.MATCH_UNINSTALLED_PACKAGES - | PackageManager.MATCH_DEBUG_TRIAGED_MISSING); + Context webViewContext = initialApplication.createApplicationContext( + ai, + Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY); sPackageInfo = newPackageInfo; return webViewContext; } finally { diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java index f2827f3fec73..472e3e72ab2f 100644 --- a/core/java/android/widget/EdgeEffect.java +++ b/core/java/android/widget/EdgeEffect.java @@ -98,12 +98,28 @@ public class EdgeEffect { private static final double VELOCITY_THRESHOLD = 0.01; /** + * The speed at which we should start linearly interpolating to the destination. + * When using a spring, as it gets closer to the destination, the speed drops off exponentially. + * Instead of landing very slowly, a better experience is achieved if the final + * destination is arrived at quicker. + */ + private static final float LINEAR_VELOCITY_TAKE_OVER = 200f; + + /** * The value threshold before the spring animation is considered close enough to * the destination to be settled. This should be around 0.01 pixel. */ private static final double VALUE_THRESHOLD = 0.001; /** + * The maximum distance at which we should start linearly interpolating to the destination. + * When using a spring, as it gets closer to the destination, the speed drops off exponentially. + * Instead of landing very slowly, a better experience is achieved if the final + * destination is arrived at quicker. + */ + private static final double LINEAR_DISTANCE_TAKE_OVER = 8.0; + + /** * The natural frequency of the stretch spring. */ private static final double NATURAL_FREQUENCY = 24.657; @@ -587,55 +603,57 @@ public class EdgeEffect { if (mState == STATE_RECEDE) { updateSpring(); } - RecordingCanvas recordingCanvas = (RecordingCanvas) canvas; - if (mTmpMatrix == null) { - mTmpMatrix = new Matrix(); - mTmpPoints = new float[12]; - } - //noinspection deprecation - recordingCanvas.getMatrix(mTmpMatrix); - - mTmpPoints[0] = 0; - mTmpPoints[1] = 0; // top-left - mTmpPoints[2] = mWidth; - mTmpPoints[3] = 0; // top-right - mTmpPoints[4] = mWidth; - mTmpPoints[5] = mHeight; // bottom-right - mTmpPoints[6] = 0; - mTmpPoints[7] = mHeight; // bottom-left - mTmpPoints[8] = mWidth * mDisplacement; - mTmpPoints[9] = 0; // drag start point - mTmpPoints[10] = mWidth * mDisplacement; - mTmpPoints[11] = mHeight * mDistance; // drag point - mTmpMatrix.mapPoints(mTmpPoints); - - RenderNode renderNode = recordingCanvas.mNode; - - float left = renderNode.getLeft() + if (mDistance != 0f) { + RecordingCanvas recordingCanvas = (RecordingCanvas) canvas; + if (mTmpMatrix == null) { + mTmpMatrix = new Matrix(); + mTmpPoints = new float[12]; + } + //noinspection deprecation + recordingCanvas.getMatrix(mTmpMatrix); + + mTmpPoints[0] = 0; + mTmpPoints[1] = 0; // top-left + mTmpPoints[2] = mWidth; + mTmpPoints[3] = 0; // top-right + mTmpPoints[4] = mWidth; + mTmpPoints[5] = mHeight; // bottom-right + mTmpPoints[6] = 0; + mTmpPoints[7] = mHeight; // bottom-left + mTmpPoints[8] = mWidth * mDisplacement; + mTmpPoints[9] = 0; // drag start point + mTmpPoints[10] = mWidth * mDisplacement; + mTmpPoints[11] = mHeight * mDistance; // drag point + mTmpMatrix.mapPoints(mTmpPoints); + + RenderNode renderNode = recordingCanvas.mNode; + + float left = renderNode.getLeft() + min(mTmpPoints[0], mTmpPoints[2], mTmpPoints[4], mTmpPoints[6]); - float top = renderNode.getTop() + float top = renderNode.getTop() + min(mTmpPoints[1], mTmpPoints[3], mTmpPoints[5], mTmpPoints[7]); - float right = renderNode.getLeft() + float right = renderNode.getLeft() + max(mTmpPoints[0], mTmpPoints[2], mTmpPoints[4], mTmpPoints[6]); - float bottom = renderNode.getTop() + float bottom = renderNode.getTop() + max(mTmpPoints[1], mTmpPoints[3], mTmpPoints[5], mTmpPoints[7]); - // assume rotations of increments of 90 degrees - float x = mTmpPoints[10] - mTmpPoints[8]; - float width = right - left; - float vecX = dampStretchVector(Math.max(-1f, Math.min(1f, x / width))); - - float y = mTmpPoints[11] - mTmpPoints[9]; - float height = bottom - top; - float vecY = dampStretchVector(Math.max(-1f, Math.min(1f, y / height))); - - boolean hasValidVectors = Float.isFinite(vecX) && Float.isFinite(vecY); - if (right > left && bottom > top && mWidth > 0 && mHeight > 0 && hasValidVectors) { - renderNode.stretch( + // assume rotations of increments of 90 degrees + float x = mTmpPoints[10] - mTmpPoints[8]; + float width = right - left; + float vecX = dampStretchVector(Math.max(-1f, Math.min(1f, x / width))); + + float y = mTmpPoints[11] - mTmpPoints[9]; + float height = bottom - top; + float vecY = dampStretchVector(Math.max(-1f, Math.min(1f, y / height))); + + boolean hasValidVectors = Float.isFinite(vecX) && Float.isFinite(vecY); + if (right > left && bottom > top && mWidth > 0 && mHeight > 0 && hasValidVectors) { + renderNode.stretch( vecX, // horizontal stretch intensity vecY, // vertical stretch intensity mWidth, // max horizontal stretch in pixels mHeight // max vertical stretch in pixels - ); + ); + } } } else { // Animations have been disabled or this is TYPE_STRETCH and drawing into a Canvas @@ -730,6 +748,26 @@ public class EdgeEffect { if (deltaT < 0.001f) { return; // Must have at least 1 ms difference } + mStartTime = time; + + if (Math.abs(mVelocity) <= LINEAR_VELOCITY_TAKE_OVER + && Math.abs(mDistance * mHeight) < LINEAR_DISTANCE_TAKE_OVER + && Math.signum(mVelocity) == -Math.signum(mDistance) + ) { + // This is close. The spring will slowly reach the destination. Instead, we + // will interpolate linearly so that it arrives at its destination quicker. + mVelocity = Math.signum(mVelocity) * LINEAR_VELOCITY_TAKE_OVER; + + float targetDistance = mDistance + (mVelocity * deltaT / mHeight); + if (Math.signum(targetDistance) != Math.signum(mDistance)) { + // We have arrived + mDistance = 0; + mVelocity = 0; + } else { + mDistance = targetDistance; + } + return; + } final double mDampedFreq = NATURAL_FREQUENCY * Math.sqrt(1 - DAMPING_RATIO * DAMPING_RATIO); // We're always underdamped, so we can use only those equations: @@ -745,9 +783,7 @@ public class EdgeEffect { + mDampedFreq * sinCoeff * Math.cos(mDampedFreq * deltaT)); mDistance = (float) distance / mHeight; mVelocity = (float) velocity; - mStartTime = time; if (isAtEquilibrium()) { - mState = STATE_IDLE; mDistance = 0; mVelocity = 0; } diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 8a044fd06dd5..e827f0a31bfd 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -5831,9 +5831,8 @@ public class RemoteViews implements Parcelable, Filter { return context; } try { - return context.createPackageContextAsUser(mApplication.packageName, - Context.CONTEXT_RESTRICTED, - UserHandle.getUserHandleForUid(mApplication.uid)); + return context.createApplicationContext(mApplication, + Context.CONTEXT_RESTRICTED); } catch (NameNotFoundException e) { Log.e(LOG_TAG, "Package name " + mApplication.packageName + " not found"); } diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java index eb6bce4a2f59..3fed9beeaaba 100644 --- a/core/java/android/widget/SelectionActionModeHelper.java +++ b/core/java/android/widget/SelectionActionModeHelper.java @@ -565,6 +565,7 @@ public final class SelectionActionModeHelper { */ public void onSmartSelection(SelectionResult result) { onClassifiedSelection(result); + mTextView.notifyContentCaptureTextChanged(); mLogger.logSelectionModified( result.mStart, result.mEnd, result.mClassification, result.mSelection); } @@ -595,6 +596,7 @@ public final class SelectionActionModeHelper { mSelectionStart = selectionStart; mSelectionEnd = selectionEnd; mAllowReset = false; + mTextView.notifyContentCaptureTextChanged(); mLogger.logSelectionModified(selectionStart, selectionEnd, classification, null); } } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 3c4fd5e93580..37374ef37ada 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -129,7 +129,6 @@ import android.text.method.TextKeyListener; import android.text.method.TimeKeyListener; import android.text.method.TransformationMethod; import android.text.method.TransformationMethod2; -import android.text.method.TranslationTransformationMethod; import android.text.method.WordIterator; import android.text.style.CharacterStyle; import android.text.style.ClickableSpan; @@ -199,7 +198,6 @@ import android.view.translation.TranslationSpec; import android.view.translation.UiTranslationController; import android.view.translation.ViewTranslationCallback; import android.view.translation.ViewTranslationRequest; -import android.view.translation.ViewTranslationResponse; import android.widget.RemoteViews.RemoteView; import com.android.internal.annotations.VisibleForTesting; @@ -10832,11 +10830,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } + notifyContentCaptureTextChanged(); + } + + /** + * Notifies the ContentCapture service that the text of the view has changed (only if + * ContentCapture has been notified of this view's existence already). + * + * @hide + */ + public void notifyContentCaptureTextChanged() { // TODO(b/121045053): should use a flag / boolean to keep status of SHOWN / HIDDEN instead // of using isLaidout(), so it's not called in cases where it's laid out but a // notifyAppeared was not sent. - - // ContentCapture if (isLaidOut() && isImportantForContentCapture() && getNotifiedContentCaptureAppeared()) { final ContentCaptureManager cm = mContext.getSystemService(ContentCaptureManager.class); if (cm != null && cm.isContentCaptureEnabled()) { @@ -13925,8 +13931,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener Log.w(LOG_TAG, "Cannot create translation request. editable = " + isTextEditable() + ", isPassword = " + isPassword + ", selectable = " + isTextSelectable()); - return; } + return; } // TODO(b/176488462): apply the view's important for translation requestBuilder.setValue(ViewTranslationRequest.ID_TEXT, @@ -13938,33 +13944,4 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } requestsCollector.accept(requestBuilder.build()); } - - /** - * - * Called when the content from {@link #onCreateViewTranslationRequest} had been translated by - * the TranslationService. The default implementation will replace the current - * {@link TransformationMethod} to transform the original text to the translated text display. - * - * @param response a {@link ViewTranslationResponse} that contains the translated information - * which can be shown in the view. - */ - @Override - public void onViewTranslationResponse(@NonNull ViewTranslationResponse response) { - // set ViewTranslationResponse - super.onViewTranslationResponse(response); - // TODO(b/178353965): move to ViewTranslationCallback.onShow() - ViewTranslationCallback callback = getViewTranslationCallback(); - if (callback instanceof TextViewTranslationCallback) { - TextViewTranslationCallback textViewDefaultCallback = - (TextViewTranslationCallback) callback; - TranslationTransformationMethod oldTranslationMethod = - textViewDefaultCallback.getTranslationTransformation(); - TransformationMethod originalTranslationMethod = oldTranslationMethod != null - ? oldTranslationMethod.getOriginalTransformationMethod() : mTransformation; - TranslationTransformationMethod newTranslationMethod = - new TranslationTransformationMethod(response, originalTranslationMethod); - // TODO(b/178353965): well-handle setTransformationMethod. - textViewDefaultCallback.setTranslationTransformation(newTranslationMethod); - } - } } diff --git a/core/java/android/widget/TextViewTranslationCallback.java b/core/java/android/widget/TextViewTranslationCallback.java index a7d5ee465299..e1b04f8957e5 100644 --- a/core/java/android/widget/TextViewTranslationCallback.java +++ b/core/java/android/widget/TextViewTranslationCallback.java @@ -56,26 +56,6 @@ public class TextViewTranslationCallback implements ViewTranslationCallback { private CharSequence mContentDescription; - /** - * Invoked by the platform when receiving the successful {@link ViewTranslationResponse} for the - * view that provides the translatable information by {@link View#createTranslationRequest} and - * sent by the platform. - */ - void setTranslationTransformation(TranslationTransformationMethod method) { - if (method == null) { - if (DEBUG) { - Log.w(TAG, "setTranslationTransformation: should not set null " - + "TranslationTransformationMethod"); - } - return; - } - mTranslationTransformation = method; - } - - TranslationTransformationMethod getTranslationTransformation() { - return mTranslationTransformation; - } - private void clearTranslationTransformation() { if (DEBUG) { Log.v(TAG, "clearTranslationTransformation: " + mTranslationTransformation); @@ -88,34 +68,33 @@ public class TextViewTranslationCallback implements ViewTranslationCallback { */ @Override public boolean onShowTranslation(@NonNull View view) { - if (view.getViewTranslationResponse() == null) { - Log.wtf(TAG, "onShowTranslation() shouldn't be called before " + ViewTranslationResponse response = view.getViewTranslationResponse(); + if (response == null) { + Log.e(TAG, "onShowTranslation() shouldn't be called before " + "onViewTranslationResponse()."); return false; } - if (mTranslationTransformation != null) { - final TransformationMethod transformation = mTranslationTransformation; - runWithAnimation( - (TextView) view, - () -> { - mIsShowingTranslation = true; - ((TextView) view).setTransformationMethod(transformation); - }); - ViewTranslationResponse response = view.getViewTranslationResponse(); - if (response.getKeys().contains(ViewTranslationRequest.ID_CONTENT_DESCRIPTION)) { - CharSequence translatedContentDescription = - response.getValue(ViewTranslationRequest.ID_CONTENT_DESCRIPTION).getText(); - if (!TextUtils.isEmpty(translatedContentDescription)) { - mContentDescription = view.getContentDescription(); - view.setContentDescription(translatedContentDescription); - } - } - } else { - if (DEBUG) { - // TODO(b/182433547): remove before S release - Log.w(TAG, "onShowTranslation(): no translated text."); + if (mTranslationTransformation == null) { + TransformationMethod originalTranslationMethod = + ((TextView) view).getTransformationMethod(); + mTranslationTransformation = new TranslationTransformationMethod(response, + originalTranslationMethod); + } + final TransformationMethod transformation = mTranslationTransformation; + runWithAnimation( + (TextView) view, + () -> { + mIsShowingTranslation = true; + // TODO(b/178353965): well-handle setTransformationMethod. + ((TextView) view).setTransformationMethod(transformation); + }); + if (response.getKeys().contains(ViewTranslationRequest.ID_CONTENT_DESCRIPTION)) { + CharSequence translatedContentDescription = + response.getValue(ViewTranslationRequest.ID_CONTENT_DESCRIPTION).getText(); + if (!TextUtils.isEmpty(translatedContentDescription)) { + mContentDescription = view.getContentDescription(); + view.setContentDescription(translatedContentDescription); } - return false; } return true; } @@ -126,7 +105,7 @@ public class TextViewTranslationCallback implements ViewTranslationCallback { @Override public boolean onHideTranslation(@NonNull View view) { if (view.getViewTranslationResponse() == null) { - Log.wtf(TAG, "onHideTranslation() shouldn't be called before " + Log.e(TAG, "onHideTranslation() shouldn't be called before " + "onViewTranslationResponse()."); return false; } diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java index 4a3bf91645f2..148986a558e7 100644 --- a/core/java/android/window/SplashScreenView.java +++ b/core/java/android/window/SplashScreenView.java @@ -292,6 +292,7 @@ public final class SplashScreenView extends FrameLayout { private SurfaceView createSurfaceView(@NonNull SplashScreenView view) { final SurfaceView surfaceView = new SurfaceView(view.getContext()); + surfaceView.setPadding(0, 0, 0, 0); if (mSurfacePackage == null) { if (DEBUG) { Log.d(TAG, diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 08db74f5e351..7000ed75d5be 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -464,8 +464,8 @@ public class ChooserActivity extends ResolverActivity implements private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED = 5; private static final int LIST_VIEW_UPDATE_MESSAGE = 6; - private static final int WATCHDOG_TIMEOUT_MAX_MILLIS = 10000; - private static final int WATCHDOG_TIMEOUT_MIN_MILLIS = 3000; + private static final int WATCHDOG_TIMEOUT_MAX_MILLIS = 1000; + private static final int WATCHDOG_TIMEOUT_MIN_MILLIS = 300; private boolean mMinTimeoutPassed = false; diff --git a/core/java/com/android/internal/os/AppZygoteInit.java b/core/java/com/android/internal/os/AppZygoteInit.java index 0e83e41a7423..f925afc2a921 100644 --- a/core/java/com/android/internal/os/AppZygoteInit.java +++ b/core/java/com/android/internal/os/AppZygoteInit.java @@ -91,7 +91,9 @@ class AppZygoteInit { } else { Constructor<?> ctor = cl.getConstructor(); ZygotePreload preloadObject = (ZygotePreload) ctor.newInstance(); + Zygote.markOpenedFilesBeforePreload(); preloadObject.doPreload(appInfo); + Zygote.allowFilesOpenedByPreload(); } } catch (ReflectiveOperationException e) { Log.e(TAG, "AppZygote application preload failed for " diff --git a/core/java/com/android/internal/os/BatterySipper.java b/core/java/com/android/internal/os/BatterySipper.java index 4f2f973b51b1..dfd561a8cc30 100644 --- a/core/java/com/android/internal/os/BatterySipper.java +++ b/core/java/com/android/internal/os/BatterySipper.java @@ -23,7 +23,10 @@ import java.util.List; /** * Contains power usage of an application, system service, or hardware type. + * + * @deprecated Please use BatteryStatsManager.getBatteryUsageStats instead. */ +@Deprecated public class BatterySipper implements Comparable<BatterySipper> { @UnsupportedAppUsage public int userId; diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java index b20f50d62de4..608782a39f6b 100644 --- a/core/java/com/android/internal/os/BatteryStatsHelper.java +++ b/core/java/com/android/internal/os/BatteryStatsHelper.java @@ -59,7 +59,10 @@ import java.util.List; * * The caller must initialize this class as soon as activity object is ready to use (for example, in * onAttach() for Fragment), call create() in onCreate() and call destroy() in onDestroy(). + * + * @deprecated Please use BatteryStatsManager.getBatteryUsageStats instead. */ +@Deprecated public class BatteryStatsHelper { static final boolean DEBUG = false; diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java index 8943db6c8a1e..00385793b62b 100644 --- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java +++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java @@ -23,6 +23,7 @@ import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.SystemClock; import android.os.UidBatteryConsumer; +import android.util.Log; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; @@ -36,6 +37,7 @@ import java.util.Map; * usage data attributed to subsystems and UIDs. */ public class BatteryUsageStatsProvider { + private static final String TAG = "BatteryUsageStatsProv"; private final Context mContext; private final BatteryStats mStats; private final BatteryUsageStatsStore mBatteryUsageStatsStore; @@ -234,6 +236,11 @@ public class BatteryUsageStatsProvider { final BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder( mStats.getCustomEnergyConsumerNames(), includePowerModels); + if (mBatteryUsageStatsStore == null) { + Log.e(TAG, "BatteryUsageStatsStore is unavailable"); + return builder.build(); + } + final long[] timestamps = mBatteryUsageStatsStore.listBatteryUsageStatsTimestamps(); for (long timestamp : timestamps) { if (timestamp > query.getFromTimestamp() && timestamp <= query.getToTimestamp()) { diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java index 6f911cbd6121..6ce7cea12dfa 100644 --- a/core/java/com/android/internal/os/BinderCallsStats.java +++ b/core/java/com/android/internal/os/BinderCallsStats.java @@ -220,7 +220,8 @@ public class BinderCallsStats implements BinderInternal.Observer { public CallSession callStarted(Binder binder, int code, int workSourceUid) { noteNativeThreadId(); - if (!canCollect()) { + // We always want to collect data for latency if it's enabled, regardless of device state. + if (!mCollectLatencyData && !canCollect()) { return null; } @@ -267,6 +268,11 @@ public class BinderCallsStats implements BinderInternal.Observer { mLatencyObserver.callEnded(s); } + // Latency collection has already been processed so check if the rest should be processed. + if (!canCollect()) { + return; + } + UidEntry uidEntry = null; final boolean recordCall; if (s.recordedCall) { @@ -1190,15 +1196,12 @@ public class BinderCallsStats implements BinderInternal.Observer { private final Context mContext; private final KeyValueListParser mParser = new KeyValueListParser(','); private final BinderCallsStats mBinderCallsStats; - private final int mProcessSource; - public SettingsObserver(Context context, BinderCallsStats binderCallsStats, - int processSource) { + public SettingsObserver(Context context, BinderCallsStats binderCallsStats) { super(BackgroundThread.getHandler()); mContext = context; context.getContentResolver().registerContentObserver(mUri, false, this); mBinderCallsStats = binderCallsStats; - mProcessSource = processSource; // Always kick once to ensure that we match current state onChange(); } diff --git a/core/java/com/android/internal/os/BinderLatencyObserver.java b/core/java/com/android/internal/os/BinderLatencyObserver.java index ed7e172e8071..20cf102953e4 100644 --- a/core/java/com/android/internal/os/BinderLatencyObserver.java +++ b/core/java/com/android/internal/os/BinderLatencyObserver.java @@ -370,4 +370,9 @@ public class BinderLatencyObserver { public Runnable getStatsdPushRunnable() { return mLatencyObserverRunnable; } + + @VisibleForTesting + public int getProcessSource() { + return mProcessSource; + } } diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index 0c9dded42bda..e4e28a926ed6 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -500,6 +500,36 @@ public final class Zygote { } /** + * Scans file descriptors in /proc/self/fd/, stores their metadata from readlink(2)/stat(2) when + * available. Saves this information in a global on native side, to be used by subsequent call + * to allowFilesOpenedByPreload(). Fatally fails if the FDs are of unsupported type and are not + * explicitly allowed. Ignores repeated invocations. + * + * Inspecting the FDs is more permissive than in forkAndSpecialize() because preload is invoked + * earlier and hence needs to allow a few open sockets. The checks in forkAndSpecialize() + * enforce that these sockets are closed when forking. + */ + static void markOpenedFilesBeforePreload() { + nativeMarkOpenedFilesBeforePreload(); + } + + private static native void nativeMarkOpenedFilesBeforePreload(); + + /** + * By scanning /proc/self/fd/ determines file descriptor numbers in this process opened since + * the first call to markOpenedFilesBeforePreload(). These FDs are treated as 'owned' by the + * custom preload of the App Zygote - the app is responsible for not sharing data with its other + * processes using these FDs, including by lseek(2). File descriptor types and file names are + * not checked. Changes in FDs recorded by markOpenedFilesBeforePreload() are not expected and + * kill the current process. + */ + static void allowFilesOpenedByPreload() { + nativeAllowFilesOpenedByPreload(); + } + + private static native void nativeAllowFilesOpenedByPreload(); + + /** * Installs a seccomp filter that limits setresuid()/setresgid() to the passed-in range * @param uidGidMin The smallest allowed uid/gid * @param uidGidMax The largest allowed uid/gid diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 6ff656c3f8db..0f26f57e2155 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -127,6 +127,12 @@ public class ZygoteInit { private static boolean sPreloadComplete; + /** + * Cached classloader to use for the system server. Will only be populated in the system + * server process. + */ + private static ClassLoader sCachedSystemServerClassLoader = null; + static void preload(TimingsTraceLog bootTimingsTraceLog) { Log.d(TAG, "begin preload"); bootTimingsTraceLog.traceBegin("BeginPreload"); @@ -540,10 +546,8 @@ public class ZygoteInit { throw new IllegalStateException("Unexpected return from WrapperInit.execApplication"); } else { - ClassLoader cl = null; - if (systemServerClasspath != null) { - cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion); - + ClassLoader cl = getOrCreateSystemServerClassLoader(); + if (cl != null) { Thread.currentThread().setContextClassLoader(cl); } @@ -559,6 +563,23 @@ public class ZygoteInit { } /** + * Create the classloader for the system server and store it in + * {@link sCachedSystemServerClassLoader}. This function may be called through JNI in + * system server startup, when the runtime is in a critically low state. Do not do + * extended computation etc here. + */ + private static ClassLoader getOrCreateSystemServerClassLoader() { + if (sCachedSystemServerClassLoader == null) { + final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); + if (systemServerClasspath != null) { + sCachedSystemServerClassLoader = createPathClassLoader(systemServerClasspath, + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT); + } + } + return sCachedSystemServerClassLoader; + } + + /** * Note that preparing the profiles for system server does not require special selinux * permissions. From the installer perspective the system server is a regular package which can * capture profile information. diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 1a23cc11fca8..134b1587ee58 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -70,12 +70,12 @@ import android.transition.TransitionInflater; import android.transition.TransitionManager; import android.transition.TransitionSet; import android.util.AndroidRuntimeException; -import android.view.AttachedSurfaceControl; import android.util.EventLog; import android.util.Log; import android.util.Pair; import android.util.SparseArray; import android.util.TypedValue; +import android.view.AttachedSurfaceControl; import android.view.ContextThemeWrapper; import android.view.CrossWindowBlurListeners; import android.view.Gravity; @@ -3148,7 +3148,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { if (cb == null || isDestroyed()) { result = false; } else { - sendCloseSystemWindows("search"); int deviceId = event.getDeviceId(); SearchEvent searchEvent = null; if (deviceId != 0) { diff --git a/core/java/com/android/internal/util/function/DodecConsumer.java b/core/java/com/android/internal/util/function/DodecConsumer.java new file mode 100644 index 000000000000..b4d2fb94d245 --- /dev/null +++ b/core/java/com/android/internal/util/function/DodecConsumer.java @@ -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 com.android.internal.util.function; + +import java.util.function.Consumer; + + +/** + * A 12-argument {@link Consumer} + * + * @hide + */ +public interface DodecConsumer<A, B, C, D, E, F, G, H, I, J, K, L> { + void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l); +} diff --git a/core/java/com/android/internal/util/function/DodecFunction.java b/core/java/com/android/internal/util/function/DodecFunction.java new file mode 100644 index 000000000000..178b2c111fd7 --- /dev/null +++ b/core/java/com/android/internal/util/function/DodecFunction.java @@ -0,0 +1,28 @@ +/* + * 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.util.function; + +import java.util.function.Function; + +/** + * A 12-argument {@link Function} + * + * @hide + */ +public interface DodecFunction<A, B, C, D, E, F, G, H, I, J, K, L, R> { + R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l); +} diff --git a/core/java/com/android/internal/util/function/DodecPredicate.java b/core/java/com/android/internal/util/function/DodecPredicate.java new file mode 100644 index 000000000000..d3a2b856100f --- /dev/null +++ b/core/java/com/android/internal/util/function/DodecPredicate.java @@ -0,0 +1,28 @@ +/* + * 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.util.function; + +import java.util.function.Predicate; + +/** + * A 12-argument {@link Predicate} + * + * @hide + */ +public interface DodecPredicate<A, B, C, D, E, F, G, H, I, J, K, L> { + boolean test(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l); +} diff --git a/core/java/com/android/internal/util/function/pooled/PooledLambda.java b/core/java/com/android/internal/util/function/pooled/PooledLambda.java index a60cc0fb101f..f073c1c046c5 100755 --- a/core/java/com/android/internal/util/function/pooled/PooledLambda.java +++ b/core/java/com/android/internal/util/function/pooled/PooledLambda.java @@ -23,6 +23,8 @@ import android.os.Message; import com.android.internal.util.function.DecConsumer; import com.android.internal.util.function.DecFunction; +import com.android.internal.util.function.DodecConsumer; +import com.android.internal.util.function.DodecFunction; import com.android.internal.util.function.HeptConsumer; import com.android.internal.util.function.HeptFunction; import com.android.internal.util.function.HexConsumer; @@ -188,7 +190,7 @@ public interface PooledLambda { A arg1) { return acquire(PooledLambdaImpl.sPool, function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -205,7 +207,7 @@ public interface PooledLambda { A arg1) { return acquire(PooledLambdaImpl.sPool, function, 1, 0, ReturnType.BOOLEAN, arg1, null, null, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -222,7 +224,7 @@ public interface PooledLambda { A arg1) { return acquire(PooledLambdaImpl.sPool, function, 1, 0, ReturnType.OBJECT, arg1, null, null, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -253,7 +255,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null, null, null, - null, null, null); + null, null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -273,7 +275,7 @@ public interface PooledLambda { A arg1, B arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -291,7 +293,7 @@ public interface PooledLambda { A arg1, B arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 0, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -309,7 +311,7 @@ public interface PooledLambda { A arg1, B arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 0, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -327,7 +329,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -345,7 +347,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -364,7 +366,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2, C arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 1, ReturnType.BOOLEAN, arg1, arg2, arg3, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -384,7 +386,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.BOOLEAN, arg1, arg2, arg3, arg4, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -405,7 +407,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4, E arg5) { return acquire(PooledLambdaImpl.sPool, function, 5, 1, ReturnType.BOOLEAN, arg1, arg2, arg3, arg4, arg5, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -423,7 +425,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -441,7 +443,7 @@ public interface PooledLambda { A arg1, ArgumentPlaceholder<B> arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -459,7 +461,7 @@ public interface PooledLambda { A arg1, ArgumentPlaceholder<B> arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -477,7 +479,7 @@ public interface PooledLambda { A arg1, ArgumentPlaceholder<B> arg2) { return acquire(PooledLambdaImpl.sPool, function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -509,7 +511,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null, - null, null, null); + null, null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -530,7 +532,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -549,7 +551,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 0, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -568,7 +570,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2, C arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -587,7 +589,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2, C arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -606,7 +608,7 @@ public interface PooledLambda { A arg1, ArgumentPlaceholder<B> arg2, C arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -625,7 +627,7 @@ public interface PooledLambda { A arg1, ArgumentPlaceholder<B> arg2, C arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -644,7 +646,7 @@ public interface PooledLambda { A arg1, B arg2, ArgumentPlaceholder<C> arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -663,7 +665,7 @@ public interface PooledLambda { A arg1, B arg2, ArgumentPlaceholder<C> arg3) { return acquire(PooledLambdaImpl.sPool, function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -696,7 +698,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null, - null, null, null); + null, null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -718,7 +720,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -738,7 +740,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -758,7 +760,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -778,7 +780,7 @@ public interface PooledLambda { ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -798,7 +800,7 @@ public interface PooledLambda { A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -818,7 +820,7 @@ public interface PooledLambda { A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -838,7 +840,7 @@ public interface PooledLambda { A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -858,7 +860,7 @@ public interface PooledLambda { A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -878,7 +880,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -898,7 +900,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4) { return acquire(PooledLambdaImpl.sPool, function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -932,7 +934,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null, - null, null, null); + null, null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -955,7 +957,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, D arg4, E arg5) { return acquire(PooledLambdaImpl.sPool, function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -976,7 +978,7 @@ public interface PooledLambda { function, A arg1, B arg2, C arg3, D arg4, E arg5) { return acquire(PooledLambdaImpl.sPool, function, 5, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, null, null, null, - null, null, null); + null, null, null, null); } /** @@ -1012,7 +1014,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null, null, null, - null, null, null); + null, null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -1036,7 +1038,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) { return acquire(PooledLambdaImpl.sPool, function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null, - null, null, null); + null, null, null, null); } /** @@ -1058,7 +1060,7 @@ public interface PooledLambda { ? extends R> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) { return acquire(PooledLambdaImpl.sPool, function, 6, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, null, null, - null, null, null); + null, null, null, null); } /** @@ -1095,7 +1097,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null, - null, null, null); + null, null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -1120,7 +1122,7 @@ public interface PooledLambda { ? super G> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) { return acquire(PooledLambdaImpl.sPool, function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null, - null, null, null); + null, null, null, null); } /** @@ -1144,7 +1146,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) { return acquire(PooledLambdaImpl.sPool, function, 7, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null, - null, null, null); + null, null, null, null); } /** @@ -1182,7 +1184,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null, - null, null, null); + null, null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -1209,7 +1211,7 @@ public interface PooledLambda { H arg8) { return acquire(PooledLambdaImpl.sPool, function, 8, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - null, null, null); + null, null, null, null); } /** @@ -1234,7 +1236,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8) { return acquire(PooledLambdaImpl.sPool, function, 8, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - null, null, null); + null, null, null, null); } /** @@ -1274,7 +1276,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 8, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - null, null, null); + null, null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -1302,7 +1304,7 @@ public interface PooledLambda { E arg5, F arg6, G arg7, H arg8, I arg9) { return acquire(PooledLambdaImpl.sPool, function, 9, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - arg9, null, null); + arg9, null, null, null); } /** @@ -1328,7 +1330,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9) { return acquire(PooledLambdaImpl.sPool, function, 9, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - arg9, null, null); + arg9, null, null, null); } /** @@ -1369,7 +1371,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 9, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - arg9, null, null); + arg9, null, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -1398,7 +1400,7 @@ public interface PooledLambda { D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10) { return acquire(PooledLambdaImpl.sPool, function, 10, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - arg9, arg10, null); + arg9, arg10, null, null); } /** @@ -1425,7 +1427,7 @@ public interface PooledLambda { A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10) { return acquire(PooledLambdaImpl.sPool, function, 10, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - arg9, arg10, null); + arg9, arg10, null, null); } /** @@ -1467,7 +1469,7 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 10, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, - arg8, arg9, arg10, null); + arg8, arg9, arg10, null, null); return Message.obtain().setCallback(callback.recycleOnUse()); } } @@ -1498,7 +1500,7 @@ public interface PooledLambda { C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, K arg11) { return acquire(PooledLambdaImpl.sPool, function, 11, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - arg9, arg10, arg11); + arg9, arg10, arg11, null); } /** @@ -1528,7 +1530,7 @@ public interface PooledLambda { K arg11) { return acquire(PooledLambdaImpl.sPool, function, 11, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, - arg9, arg10, arg11); + arg9, arg10, arg11, null); } /** @@ -1571,7 +1573,118 @@ public interface PooledLambda { synchronized (Message.sPoolSync) { PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, function, 11, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, - arg8, arg9, arg10, arg11); + arg8, arg9, arg10, arg11, null); + return Message.obtain().setCallback(callback.recycleOnUse()); + } + } + + /** + * {@link PooledRunnable} factory + * + * @param function non-capturing lambda(typically an unbounded method reference) + * to be invoked on call + * @param arg1 parameter supplied to {@code function} on call + * @param arg2 parameter supplied to {@code function} on call + * @param arg3 parameter supplied to {@code function} on call + * @param arg4 parameter supplied to {@code function} on call + * @param arg5 parameter supplied to {@code function} on call + * @param arg6 parameter supplied to {@code function} on call + * @param arg7 parameter supplied to {@code function} on call + * @param arg8 parameter supplied to {@code function} on call + * @param arg9 parameter supplied to {@code function} on call + * @param arg10 parameter supplied to {@code function} on call + * @param arg11 parameter supplied to {@code function} on call + * @param arg12 parameter supplied to {@code function} on call + * @return a {@link PooledRunnable}, equivalent to lambda: + * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, + * arg11, arg12) } + */ + static <A, B, C, D, E, F, G, H, I, J, K, L> PooledRunnable obtainRunnable( + DodecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, + ? super G, ? super H, ? super I, ? super J, ? super K, + ? super L> function, + A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, + K arg11, L arg12) { + return acquire(PooledLambdaImpl.sPool, + function, 12, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, + arg9, arg10, arg11, arg12); + } + + /** + * {@link PooledSupplier} factory + * + * @param function non-capturing lambda(typically an unbounded method reference) + * to be invoked on call + * @param arg1 parameter supplied to {@code function} on call + * @param arg2 parameter supplied to {@code function} on call + * @param arg3 parameter supplied to {@code function} on call + * @param arg4 parameter supplied to {@code function} on call + * @param arg5 parameter supplied to {@code function} on call + * @param arg6 parameter supplied to {@code function} on call + * @param arg7 parameter supplied to {@code function} on call + * @param arg8 parameter supplied to {@code function} on call + * @param arg9 parameter supplied to {@code function} on call + * @param arg10 parameter supplied to {@code function} on call + * @param arg11 parameter supplied to {@code function} on call + * @param arg12 parameter supplied to {@code function} on call + * @return a {@link PooledSupplier}, equivalent to lambda: + * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, + * arg11) } + */ + static <A, B, C, D, E, F, G, H, I, J, K, L, R> PooledSupplier<R> obtainSupplier( + DodecFunction<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, + ? super G, ? super H, ? super I, ? super J, ? super K, ? extends L, + ? extends R> function, + A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, + K arg11, L arg12) { + return acquire(PooledLambdaImpl.sPool, + function, 11, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, + arg9, arg10, arg11, arg12); + } + + /** + * Factory of {@link Message}s that contain an + * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its + * {@link Message#getCallback internal callback}. + * + * The callback is equivalent to one obtainable via + * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)} + * + * Note that using this method with {@link android.os.Handler#handleMessage} + * is more efficient than the alternative of {@link android.os.Handler#post} + * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points + * when obtaining {@link Message} and {@link PooledRunnable} from pools separately + * + * You may optionally set a {@link Message#what} for the message if you want to be + * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise + * there's no need to do so + * + * @param function non-capturing lambda(typically an unbounded method reference) + * to be invoked on call + * @param arg1 parameter supplied to {@code function} on call + * @param arg2 parameter supplied to {@code function} on call + * @param arg3 parameter supplied to {@code function} on call + * @param arg4 parameter supplied to {@code function} on call + * @param arg5 parameter supplied to {@code function} on call + * @param arg6 parameter supplied to {@code function} on call + * @param arg7 parameter supplied to {@code function} on call + * @param arg8 parameter supplied to {@code function} on call + * @param arg9 parameter supplied to {@code function} on call + * @param arg10 parameter supplied to {@code function} on call + * @param arg11 parameter supplied to {@code function} on call + * @param arg12 parameter supplied to {@code function} on call + * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6, + * arg7, arg8, arg9, arg10, arg11) } when handled + */ + static <A, B, C, D, E, F, G, H, I, J, K, L> Message obtainMessage( + DodecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, + ? super G, ? super H, ? super I, ? super J, ? super K, ? super L> function, + A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, + K arg11, L arg12) { + synchronized (Message.sPoolSync) { + PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool, + function, 11, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, + arg8, arg9, arg10, arg11, arg12); return Message.obtain().setCallback(callback.recycleOnUse()); } } diff --git a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java index 1646a07b8001..19f0816e3e48 100755 --- a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java +++ b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java @@ -28,6 +28,9 @@ import com.android.internal.util.FunctionalUtils; import com.android.internal.util.function.DecConsumer; import com.android.internal.util.function.DecFunction; import com.android.internal.util.function.DecPredicate; +import com.android.internal.util.function.DodecConsumer; +import com.android.internal.util.function.DodecFunction; +import com.android.internal.util.function.DodecPredicate; import com.android.internal.util.function.HeptConsumer; import com.android.internal.util.function.HeptFunction; import com.android.internal.util.function.HeptPredicate; @@ -458,6 +461,28 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object, } } } break; + + case 12: { + switch (returnType) { + case LambdaType.ReturnType.VOID: { + ((DodecConsumer) mFunc).accept(popArg(0), popArg(1), + popArg(2), popArg(3), popArg(4), popArg(5), + popArg(6), popArg(7), popArg(8), popArg(9), popArg(10), popArg(11)); + return null; + } + case LambdaType.ReturnType.BOOLEAN: { + return (R) (Object) ((DodecPredicate) mFunc).test(popArg(0), + popArg(1), popArg(2), popArg(3), popArg(4), + popArg(5), popArg(6), popArg(7), popArg(8), popArg(9), popArg(10), + popArg(11)); + } + case LambdaType.ReturnType.OBJECT: { + return (R) ((DodecFunction) mFunc).apply(popArg(0), popArg(1), + popArg(2), popArg(3), popArg(4), popArg(5), + popArg(6), popArg(7), popArg(8), popArg(9), popArg(10), popArg(11)); + } + } + } break; } throw new IllegalStateException("Unknown function type: " + LambdaType.toString(funcType)); } @@ -523,7 +548,8 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object, */ static <E extends PooledLambda> E acquire(Pool pool, Object func, int fNumArgs, int numPlaceholders, int fReturnType, Object a, Object b, Object c, - Object d, Object e, Object f, Object g, Object h, Object i, Object j, Object k) { + Object d, Object e, Object f, Object g, Object h, Object i, Object j, Object k, + Object l) { PooledLambdaImpl r = acquire(pool); if (DEBUG) { Log.i(LOG_TAG, @@ -543,6 +569,7 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object, + ", i = " + i + ", j = " + j + ", k = " + k + + ", l = " + l + ")"); } r.mFunc = Objects.requireNonNull(func); @@ -560,6 +587,7 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object, setIfInBounds(r.mArgs, 8, i); setIfInBounds(r.mArgs, 9, j); setIfInBounds(r.mArgs, 10, k); + setIfInBounds(r.mArgs, 11, l); return (E) r; } diff --git a/core/java/com/android/internal/view/ListViewCaptureHelper.java b/core/java/com/android/internal/view/ListViewCaptureHelper.java new file mode 100644 index 000000000000..c25b4b59930d --- /dev/null +++ b/core/java/com/android/internal/view/ListViewCaptureHelper.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.view; + +import static com.android.internal.view.ScrollCaptureViewSupport.computeScrollAmount; +import static com.android.internal.view.ScrollCaptureViewSupport.findScrollingReferenceView; +import static com.android.internal.view.ScrollCaptureViewSupport.transformFromContainerToRequest; +import static com.android.internal.view.ScrollCaptureViewSupport.transformFromRequestToContainer; + +import android.annotation.NonNull; +import android.graphics.Rect; +import android.util.Log; +import android.view.View; +import android.widget.ListView; + +/** + * Scroll capture support for ListView. + * + * @see ScrollCaptureViewSupport + */ +public class ListViewCaptureHelper implements ScrollCaptureViewHelper<ListView> { + private static final String TAG = "LVCaptureHelper"; + private int mScrollDelta; + private boolean mScrollBarWasEnabled; + private int mOverScrollMode; + + @Override + public void onPrepareForStart(@NonNull ListView view, Rect scrollBounds) { + mScrollDelta = 0; + + mOverScrollMode = view.getOverScrollMode(); + view.setOverScrollMode(View.OVER_SCROLL_NEVER); + + mScrollBarWasEnabled = view.isVerticalScrollBarEnabled(); + view.setVerticalScrollBarEnabled(false); + } + + @Override + public ScrollResult onScrollRequested(@NonNull ListView listView, Rect scrollBounds, + Rect requestRect) { + Log.d(TAG, "-----------------------------------------------------------"); + Log.d(TAG, "onScrollRequested(scrollBounds=" + scrollBounds + ", " + + "requestRect=" + requestRect + ")"); + + ScrollResult result = new ScrollResult(); + result.requestedArea = new Rect(requestRect); + result.scrollDelta = mScrollDelta; + result.availableArea = new Rect(); // empty + + if (!listView.isVisibleToUser() || listView.getChildCount() == 0) { + Log.w(TAG, "listView is empty or not visible, cannot continue"); + return result; // result.availableArea == empty Rect + } + + // Make requestRect relative to RecyclerView (from scrollBounds) + Rect requestedContainerBounds = + transformFromRequestToContainer(mScrollDelta, scrollBounds, requestRect); + + Rect recyclerLocalVisible = new Rect(); + listView.getLocalVisibleRect(recyclerLocalVisible); + + // Expand request rect match visible bounds to center the requested rect vertically + Rect adjustedContainerBounds = new Rect(requestedContainerBounds); + int remainingHeight = recyclerLocalVisible.height() - requestedContainerBounds.height(); + if (remainingHeight > 0) { + adjustedContainerBounds.inset(0, -remainingHeight / 2); + } + + int scrollAmount = computeScrollAmount(recyclerLocalVisible, adjustedContainerBounds); + if (scrollAmount < 0) { + Log.d(TAG, "About to scroll UP (content moves down within parent)"); + } else if (scrollAmount > 0) { + Log.d(TAG, "About to scroll DOWN (content moves up within parent)"); + } + Log.d(TAG, "scrollAmount: " + scrollAmount); + + View refView = findScrollingReferenceView(listView, scrollAmount); + int refTop = refView.getTop(); + + listView.scrollListBy(scrollAmount); + int scrollDistance = refTop - refView.getTop(); + Log.d(TAG, "Parent view has scrolled vertically by " + scrollDistance + " px"); + + mScrollDelta += scrollDistance; + result.scrollDelta = mScrollDelta; + if (scrollDistance != 0) { + Log.d(TAG, "Scroll delta is now " + mScrollDelta + " px"); + } + + // Update, post-scroll + requestedContainerBounds = new Rect( + transformFromRequestToContainer(mScrollDelta, scrollBounds, requestRect)); + + listView.getLocalVisibleRect(recyclerLocalVisible); + if (requestedContainerBounds.intersect(recyclerLocalVisible)) { + result.availableArea = transformFromContainerToRequest( + mScrollDelta, scrollBounds, requestedContainerBounds); + } + Log.d(TAG, "-----------------------------------------------------------"); + return result; + } + + + @Override + public void onPrepareForEnd(@NonNull ListView listView) { + // Restore original position and state + listView.scrollListBy(-mScrollDelta); + listView.setOverScrollMode(mOverScrollMode); + listView.setVerticalScrollBarEnabled(mScrollBarWasEnabled); + } +} diff --git a/core/java/com/android/internal/view/RecyclerViewCaptureHelper.java b/core/java/com/android/internal/view/RecyclerViewCaptureHelper.java index 75bf1ce136c9..b29cf1c2cb1a 100644 --- a/core/java/com/android/internal/view/RecyclerViewCaptureHelper.java +++ b/core/java/com/android/internal/view/RecyclerViewCaptureHelper.java @@ -16,7 +16,11 @@ package com.android.internal.view; -import android.animation.ValueAnimator; +import static com.android.internal.view.ScrollCaptureViewSupport.computeScrollAmount; +import static com.android.internal.view.ScrollCaptureViewSupport.findScrollingReferenceView; +import static com.android.internal.view.ScrollCaptureViewSupport.transformFromContainerToRequest; +import static com.android.internal.view.ScrollCaptureViewSupport.transformFromRequestToContainer; + import android.annotation.NonNull; import android.graphics.Rect; import android.util.Log; @@ -38,17 +42,10 @@ import android.view.ViewParent; * @see ScrollCaptureViewSupport */ public class RecyclerViewCaptureHelper implements ScrollCaptureViewHelper<ViewGroup> { - - // Experiment - private static final boolean DISABLE_ANIMATORS = false; - // Experiment - private static final boolean STOP_RENDER_THREAD = false; - private static final String TAG = "RVCaptureHelper"; private int mScrollDelta; private boolean mScrollBarWasEnabled; private int mOverScrollMode; - private float mDurationScale; @Override public void onPrepareForStart(@NonNull ViewGroup view, Rect scrollBounds) { @@ -59,152 +56,87 @@ public class RecyclerViewCaptureHelper implements ScrollCaptureViewHelper<ViewGr mScrollBarWasEnabled = view.isVerticalScrollBarEnabled(); view.setVerticalScrollBarEnabled(false); - if (DISABLE_ANIMATORS) { - mDurationScale = ValueAnimator.getDurationScale(); - ValueAnimator.setDurationScale(0); - } - if (STOP_RENDER_THREAD) { - view.getThreadedRenderer().stop(); - } } @Override public ScrollResult onScrollRequested(@NonNull ViewGroup recyclerView, Rect scrollBounds, Rect requestRect) { + Log.d(TAG, "-----------------------------------------------------------"); + Log.d(TAG, "onScrollRequested(scrollBounds=" + scrollBounds + ", " + + "requestRect=" + requestRect + ")"); + ScrollResult result = new ScrollResult(); result.requestedArea = new Rect(requestRect); result.scrollDelta = mScrollDelta; result.availableArea = new Rect(); // empty - Log.d(TAG, "current scrollDelta: " + mScrollDelta); if (!recyclerView.isVisibleToUser() || recyclerView.getChildCount() == 0) { Log.w(TAG, "recyclerView is empty or not visible, cannot continue"); return result; // result.availableArea == empty Rect } - // move from scrollBounds-relative to parent-local coordinates - Rect requestedContainerBounds = new Rect(requestRect); - requestedContainerBounds.offset(0, -mScrollDelta); - requestedContainerBounds.offset(scrollBounds.left, scrollBounds.top); + // Make requestRect relative to RecyclerView (from scrollBounds) + Rect requestedContainerBounds = + transformFromRequestToContainer(mScrollDelta, scrollBounds, requestRect); - // requestedContainerBounds is now in recyclerview-local coordinates - Log.d(TAG, "requestedContainerBounds: " + requestedContainerBounds); + Rect recyclerLocalVisible = new Rect(); + recyclerView.getLocalVisibleRect(recyclerLocalVisible); + + // Expand request rect match visible bounds to center the requested rect vertically + Rect adjustedContainerBounds = new Rect(requestedContainerBounds); + int remainingHeight = recyclerLocalVisible.height() - requestedContainerBounds.height(); + if (remainingHeight > 0) { + adjustedContainerBounds.inset(0, -remainingHeight / 2); + } - // Save a copy for later - View anchor = findChildNearestTarget(recyclerView, requestedContainerBounds); - if (anchor == null) { - Log.d(TAG, "Failed to locate anchor view"); - return result; // result.availableArea == null + int scrollAmount = computeScrollAmount(recyclerLocalVisible, adjustedContainerBounds); + if (scrollAmount < 0) { + Log.d(TAG, "About to scroll UP (content moves down within parent)"); + } else if (scrollAmount > 0) { + Log.d(TAG, "About to scroll DOWN (content moves up within parent)"); } + Log.d(TAG, "scrollAmount: " + scrollAmount); + + View refView = findScrollingReferenceView(recyclerView, scrollAmount); + int refTop = refView.getTop(); - Log.d(TAG, "Anchor view:" + anchor); - Rect requestedContentBounds = new Rect(requestedContainerBounds); - recyclerView.offsetRectIntoDescendantCoords(anchor, requestedContentBounds); + // Map the request into the child view coords + Rect requestedContentBounds = new Rect(adjustedContainerBounds); + recyclerView.offsetRectIntoDescendantCoords(refView, requestedContentBounds); + Log.d(TAG, "request rect, in child view space = " + requestedContentBounds); - Log.d(TAG, "requestedContentBounds = " + requestedContentBounds); - int prevAnchorTop = anchor.getTop(); // Note: requestChildRectangleOnScreen may modify rectangle, must pass pass in a copy here - Rect input = new Rect(requestedContentBounds); - // Expand input rect to get the requested rect to be in the center - int remainingHeight = recyclerView.getHeight() - recyclerView.getPaddingTop() - - recyclerView.getPaddingBottom() - input.height(); - if (remainingHeight > 0) { - input.inset(0, -remainingHeight / 2); - } - Log.d(TAG, "input (post center adjustment) = " + input); - - if (recyclerView.requestChildRectangleOnScreen(anchor, input, true)) { - int scrolled = prevAnchorTop - anchor.getTop(); // inverse of movement - Log.d(TAG, "RecyclerView scrolled by " + scrolled + " px"); - mScrollDelta += scrolled; // view.top-- is equivalent to parent.scrollY++ - result.scrollDelta = mScrollDelta; - Log.d(TAG, "requestedContentBounds, (post-request-rect) = " + requestedContentBounds); + Rect request = new Rect(requestedContentBounds); + recyclerView.requestChildRectangleOnScreen(refView, request, true); + + int scrollDistance = refTop - refView.getTop(); + Log.d(TAG, "Parent view scrolled vertically by " + scrollDistance + " px"); + + mScrollDelta += scrollDistance; + result.scrollDelta = mScrollDelta; + if (scrollDistance != 0) { + Log.d(TAG, "Scroll delta is now " + mScrollDelta + " px"); } - requestedContainerBounds.set(requestedContentBounds); - recyclerView.offsetDescendantRectToMyCoords(anchor, requestedContainerBounds); - Log.d(TAG, "requestedContainerBounds, (post-scroll): " + requestedContainerBounds); + // Update, post-scroll + requestedContainerBounds = new Rect( + transformFromRequestToContainer(mScrollDelta, scrollBounds, requestRect)); - Rect recyclerLocalVisible = new Rect(scrollBounds); + // in case it might have changed (nested scrolling) recyclerView.getLocalVisibleRect(recyclerLocalVisible); - Log.d(TAG, "recyclerLocalVisible: " + recyclerLocalVisible); - - if (!requestedContainerBounds.intersect(recyclerLocalVisible)) { - // Requested area is still not visible - Log.d(TAG, "requested bounds not visible!"); - return result; + if (requestedContainerBounds.intersect(recyclerLocalVisible)) { + result.availableArea = transformFromContainerToRequest( + mScrollDelta, scrollBounds, requestedContainerBounds); } - Rect available = new Rect(requestedContainerBounds); - available.offset(-scrollBounds.left, -scrollBounds.top); - available.offset(0, mScrollDelta); - result.availableArea = available; - Log.d(TAG, "availableArea: " + result.availableArea); + Log.d(TAG, "-----------------------------------------------------------"); return result; } - /** - * Find a view that is located "closest" to targetRect. Returns the first view to fully - * vertically overlap the target targetRect. If none found, returns the view with an edge - * nearest the target targetRect. - * - * @param parent the parent vertical layout - * @param targetRect a rectangle in local coordinates of <code>parent</code> - * @return a child view within parent matching the criteria or null - */ - static View findChildNearestTarget(ViewGroup parent, Rect targetRect) { - View selected = null; - int minCenterDistance = Integer.MAX_VALUE; - int maxOverlap = 0; - - // allowable center-center distance, relative to targetRect. - // if within this range, taller views are preferred - final float preferredRangeFromCenterPercent = 0.25f; - final int preferredDistance = - (int) (preferredRangeFromCenterPercent * targetRect.height()); - - Rect parentLocalVis = new Rect(); - parent.getLocalVisibleRect(parentLocalVis); - Log.d(TAG, "findChildNearestTarget: parentVis=" + parentLocalVis - + " targetRect=" + targetRect); - - Rect frame = new Rect(); - for (int i = 0; i < parent.getChildCount(); i++) { - final View child = parent.getChildAt(i); - child.getHitRect(frame); - Log.d(TAG, "child #" + i + " hitRect=" + frame); - - if (child.getVisibility() != View.VISIBLE) { - Log.d(TAG, "child #" + i + " is not visible"); - continue; - } - - int centerDistance = Math.abs(targetRect.centerY() - frame.centerY()); - Log.d(TAG, "child #" + i + " : center to center: " + centerDistance + "px"); - - if (centerDistance < minCenterDistance) { - // closer to center - minCenterDistance = centerDistance; - selected = child; - } else if (frame.intersect(targetRect) && (frame.height() > preferredDistance)) { - // within X% pixels of center, but taller - selected = child; - } - } - return selected; - } - - @Override public void onPrepareForEnd(@NonNull ViewGroup view) { // Restore original position and state view.scrollBy(0, -mScrollDelta); view.setOverScrollMode(mOverScrollMode); view.setVerticalScrollBarEnabled(mScrollBarWasEnabled); - if (DISABLE_ANIMATORS) { - ValueAnimator.setDurationScale(mDurationScale); - } - if (STOP_RENDER_THREAD) { - view.getThreadedRenderer().start(); - } } } diff --git a/core/java/com/android/internal/view/ScrollCaptureInternal.java b/core/java/com/android/internal/view/ScrollCaptureInternal.java index 4b9a1606975b..ffee16a151df 100644 --- a/core/java/com/android/internal/view/ScrollCaptureInternal.java +++ b/core/java/com/android/internal/view/ScrollCaptureInternal.java @@ -25,6 +25,7 @@ import android.util.Log; import android.view.ScrollCaptureCallback; import android.view.View; import android.view.ViewGroup; +import android.widget.ListView; /** * Provides built-in framework level Scroll Capture support for standard scrolling Views. @@ -180,6 +181,11 @@ public class ScrollCaptureInternal { + "[" + resolveId(view.getContext(), view.getId()) + "]" + " -> TYPE_RECYCLING"); } + if (view instanceof ListView) { + // ListView is special. + return new ScrollCaptureViewSupport<>((ListView) view, + new ListViewCaptureHelper()); + } return new ScrollCaptureViewSupport<>((ViewGroup) view, new RecyclerViewCaptureHelper()); case TYPE_FIXED: diff --git a/core/java/com/android/internal/view/ScrollCaptureViewSupport.java b/core/java/com/android/internal/view/ScrollCaptureViewSupport.java index 9e09006f608d..8d63a400c63c 100644 --- a/core/java/com/android/internal/view/ScrollCaptureViewSupport.java +++ b/core/java/com/android/internal/view/ScrollCaptureViewSupport.java @@ -21,10 +21,8 @@ import android.content.ContentResolver; import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.HardwareRenderer; -import android.graphics.Matrix; import android.graphics.RecordingCanvas; import android.graphics.Rect; -import android.graphics.RectF; import android.graphics.RenderNode; import android.os.CancellationSignal; import android.provider.Settings; @@ -35,6 +33,7 @@ import android.view.ScrollCaptureCallback; import android.view.ScrollCaptureSession; import android.view.Surface; import android.view.View; +import android.view.ViewGroup; import com.android.internal.view.ScrollCaptureViewHelper.ScrollResult; @@ -88,6 +87,113 @@ public class ScrollCaptureViewSupport<V extends View> implements ScrollCaptureCa return colorMode; } + /** + * Maps a rect in request bounds relative space (relative to requestBounds) to container-local + * space, accounting for the provided value of scrollY. + * + * @param scrollY the current scroll offset to apply to rect + * @param requestBounds defines the local coordinate space of rect, within the container + * @param requestRect the rectangle to transform to container-local coordinates + * @return the same rectangle mapped to container bounds + */ + public static Rect transformFromRequestToContainer(int scrollY, Rect requestBounds, + Rect requestRect) { + Rect requestedContainerBounds = new Rect(requestRect); + requestedContainerBounds.offset(0, -scrollY); + requestedContainerBounds.offset(requestBounds.left, requestBounds.top); + return requestedContainerBounds; + } + + /** + * Maps a rect in container-local coordinate space to request space (relative to + * requestBounds), accounting for the provided value of scrollY. + * + * @param scrollY the current scroll offset of the container + * @param requestBounds defines the local coordinate space of rect, within the container + * @param containerRect the rectangle within the container local coordinate space + * @return the same rectangle mapped to within request bounds + */ + public static Rect transformFromContainerToRequest(int scrollY, Rect requestBounds, + Rect containerRect) { + Rect requestRect = new Rect(containerRect); + requestRect.offset(-requestBounds.left, -requestBounds.top); + requestRect.offset(0, scrollY); + return requestRect; + } + + /** + * Implements the core contract of requestRectangleOnScreen. Given a bounding rect and + * another rectangle, return the minimum scroll distance that will maximize the visible area + * of the requested rectangle. + * + * @param parentVisibleBounds the visible area + * @param requested the requested area + */ + public static int computeScrollAmount(Rect parentVisibleBounds, Rect requested) { + final int height = parentVisibleBounds.height(); + final int top = parentVisibleBounds.top; + final int bottom = parentVisibleBounds.bottom; + int scrollYDelta = 0; + + if (requested.bottom > bottom && requested.top > top) { + // need to scroll DOWN (move views up) to get it in view: + // move just enough so that the entire rectangle is in view + // (or at least the first screen size chunk). + + if (requested.height() > height) { + // just enough to get screen size chunk on + scrollYDelta += (requested.top - top); + } else { + // entire rect at bottom + scrollYDelta += (requested.bottom - bottom); + } + } else if (requested.top < top && requested.bottom < bottom) { + // need to scroll UP (move views down) to get it in view: + // move just enough so that entire rectangle is in view + // (or at least the first screen size chunk of it). + + if (requested.height() > height) { + // screen size chunk + scrollYDelta -= (bottom - requested.bottom); + } else { + // entire rect at top + scrollYDelta -= (top - requested.top); + } + } + return scrollYDelta; + } + + /** + * Locate a view to use as a reference, given an anticipated scrolling movement. + * <p> + * This view will be used to measure the actual movement of child views after scrolling. + * When scrolling down, the last (max(y)) view is used, otherwise the first (min(y) + * view. This helps to avoid recycling the reference view as a side effect of scrolling. + * + * @param parent the scrolling container + * @param expectedScrollDistance the amount of scrolling to perform + */ + public static View findScrollingReferenceView(ViewGroup parent, int expectedScrollDistance) { + View selected = null; + Rect parentLocalVisible = new Rect(); + parent.getLocalVisibleRect(parentLocalVisible); + + final int childCount = parent.getChildCount(); + for (int i = 0; i < childCount; i++) { + View child = parent.getChildAt(i); + if (selected == null) { + selected = child; + } else if (expectedScrollDistance < 0) { + if (child.getTop() < selected.getTop()) { + selected = child; + } + } else if (child.getBottom() > selected.getBottom()) { + selected = child; + } + } + return selected; + } + @Override public final void onScrollCaptureSearch(CancellationSignal signal, Consumer<Rect> onReady) { if (signal.isCanceled()) { diff --git a/core/java/com/android/internal/widget/CachingIconView.java b/core/java/com/android/internal/widget/CachingIconView.java index 4a70f7416075..299cbe12b4d1 100644 --- a/core/java/com/android/internal/widget/CachingIconView.java +++ b/core/java/com/android/internal/widget/CachingIconView.java @@ -257,7 +257,7 @@ public class CachingIconView extends ImageView { boolean hasColor = color != ColoredIconHelper.COLOR_INVALID; if (background == null) { // This is the pre-S style -- colored icon with no background. - if (hasColor) { + if (hasColor && icon != null) { icon.mutate().setColorFilter(color, PorterDuff.Mode.SRC_ATOP); } } else { @@ -265,7 +265,9 @@ public class CachingIconView extends ImageView { // colorize the icon itself with the background color, creating an inverted effect. if (hasColor) { background.mutate().setColorFilter(color, PorterDuff.Mode.SRC_ATOP); - icon.mutate().setColorFilter(mBackgroundColor, PorterDuff.Mode.SRC_ATOP); + if (icon != null) { + icon.mutate().setColorFilter(mBackgroundColor, PorterDuff.Mode.SRC_ATOP); + } } else { background.mutate().setColorFilter(mBackgroundColor, PorterDuff.Mode.SRC_ATOP); } diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java index 3d054a5e773c..02ffe8c5268e 100644 --- a/core/java/com/android/internal/widget/EditableInputConnection.java +++ b/core/java/com/android/internal/widget/EditableInputConnection.java @@ -99,6 +99,12 @@ public class EditableInputConnection extends BaseInputConnection } @Override + public void endComposingRegionEditInternal() { + // The ContentCapture service is interested in Composing-state changes. + mTextView.notifyContentCaptureTextChanged(); + } + + @Override public void closeConnection() { super.closeConnection(); synchronized(this) { diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java index 73c5460755b1..3f756d757706 100644 --- a/core/java/com/android/internal/widget/LockPatternView.java +++ b/core/java/com/android/internal/widget/LockPatternView.java @@ -1524,7 +1524,9 @@ public class LockPatternView extends View { if (virtualViewId != ExploreByTouchHelper.INVALID_ID) { int row = (virtualViewId - VIRTUAL_BASE_VIEW_ID) / 3; int col = (virtualViewId - VIRTUAL_BASE_VIEW_ID) % 3; - return !mPatternDrawLookup[row][col]; + if (row < 3) { + return !mPatternDrawLookup[row][col]; + } } return false; } @@ -1570,7 +1572,6 @@ public class LockPatternView extends View { final Rect bounds = mTempRect; final int row = ordinal / 3; final int col = ordinal % 3; - final CellState cell = mCellStates[row][col]; float centerX = getCenterXForColumn(col); float centerY = getCenterYForRow(row); float cellheight = mSquareHeight * mHitFactor * 0.5f; diff --git a/core/java/com/android/server/AppWidgetBackupBridge.java b/core/java/com/android/server/AppWidgetBackupBridge.java index 7d82d355e3eb..8e834a87784d 100644 --- a/core/java/com/android/server/AppWidgetBackupBridge.java +++ b/core/java/com/android/server/AppWidgetBackupBridge.java @@ -47,9 +47,9 @@ public class AppWidgetBackupBridge { : null; } - public static void restoreStarting(int userId) { + public static void systemRestoreStarting(int userId) { if (sAppWidgetService != null) { - sAppWidgetService.restoreStarting(userId); + sAppWidgetService.systemRestoreStarting(userId); } } @@ -59,9 +59,9 @@ public class AppWidgetBackupBridge { } } - public static void restoreFinished(int userId) { + public static void systemRestoreFinished(int userId) { if (sAppWidgetService != null) { - sAppWidgetService.restoreFinished(userId); + sAppWidgetService.systemRestoreFinished(userId); } } } diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java index 6976ace36c11..a8dcbaffeeb5 100644 --- a/core/java/com/android/server/SystemConfig.java +++ b/core/java/com/android/server/SystemConfig.java @@ -86,6 +86,7 @@ public class SystemConfig { // and "allow-ignore-location-settings". private static final int ALLOW_OVERRIDE_APP_RESTRICTIONS = 0x100; private static final int ALLOW_IMPLICIT_BROADCASTS = 0x200; + private static final int ALLOW_VENDOR_APEX = 0x400; private static final int ALLOW_ALL = ~0; // property for runtime configuration differentiation @@ -240,7 +241,7 @@ public class SystemConfig { private final ArraySet<String> mRollbackWhitelistedPackages = new ArraySet<>(); private final ArraySet<String> mWhitelistedStagedInstallers = new ArraySet<>(); - private final ArraySet<String> mAllowedPartnerApexes = new ArraySet<>(); + private final ArraySet<String> mAllowedVendorApexes = new ArraySet<>(); /** * Map of system pre-defined, uniquely named actors; keys are namespace, @@ -411,8 +412,8 @@ public class SystemConfig { return mWhitelistedStagedInstallers; } - public Set<String> getAllowedPartnerApexes() { - return mAllowedPartnerApexes; + public Set<String> getAllowedVendorApexes() { + return mAllowedVendorApexes; } public ArraySet<String> getAppDataIsolationWhitelistedApps() { @@ -489,7 +490,7 @@ public class SystemConfig { // Vendors are only allowed to customize these int vendorPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PRIVAPP_PERMISSIONS - | ALLOW_ASSOCIATIONS; + | ALLOW_ASSOCIATIONS | ALLOW_VENDOR_APEX; if (Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.O_MR1) { // For backward compatibility vendorPermissionFlag |= (ALLOW_PERMISSIONS | ALLOW_APP_CONFIGS); @@ -530,7 +531,8 @@ public class SystemConfig { } // Allow OEM to customize these - int oemPermissionFlag = ALLOW_FEATURES | ALLOW_OEM_PERMISSIONS | ALLOW_ASSOCIATIONS; + int oemPermissionFlag = ALLOW_FEATURES | ALLOW_OEM_PERMISSIONS | ALLOW_ASSOCIATIONS + | ALLOW_VENDOR_APEX; readPermissions(Environment.buildPath( Environment.getOemDirectory(), "etc", "sysconfig"), oemPermissionFlag); readPermissions(Environment.buildPath( @@ -541,7 +543,8 @@ public class SystemConfig { // the use of hidden APIs from the product partition. int productPermissionFlag = ALLOW_FEATURES | ALLOW_LIBS | ALLOW_PERMISSIONS | ALLOW_APP_CONFIGS | ALLOW_PRIVAPP_PERMISSIONS | ALLOW_HIDDENAPI_WHITELISTING - | ALLOW_ASSOCIATIONS | ALLOW_OVERRIDE_APP_RESTRICTIONS | ALLOW_IMPLICIT_BROADCASTS; + | ALLOW_ASSOCIATIONS | ALLOW_OVERRIDE_APP_RESTRICTIONS | ALLOW_IMPLICIT_BROADCASTS + | ALLOW_VENDOR_APEX; if (Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.R) { // TODO(b/157393157): This must check product interface enforcement instead of // DEVICE_INITIAL_SDK_INT for the devices without product interface enforcement. @@ -668,6 +671,7 @@ public class SystemConfig { (permissionFlag & ALLOW_OVERRIDE_APP_RESTRICTIONS) != 0; final boolean allowImplicitBroadcasts = (permissionFlag & ALLOW_IMPLICIT_BROADCASTS) != 0; + final boolean allowVendorApex = (permissionFlag & ALLOW_VENDOR_APEX) != 0; while (true) { XmlUtils.nextElement(parser); if (parser.getEventType() == XmlPullParser.END_DOCUMENT) { @@ -1217,15 +1221,14 @@ public class SystemConfig { } XmlUtils.skipCurrentTag(parser); } break; - case "allowed-partner-apex": { - // TODO(b/189274479): should this be allowOemPermissions instead? - if (allowAppConfigs) { + case "allowed-vendor-apex": { + if (allowVendorApex) { String pkgName = parser.getAttributeValue(null, "package"); if (pkgName == null) { Slog.w(TAG, "<" + name + "> without package in " + permFile + " at " + parser.getPositionDescription()); } else { - mAllowedPartnerApexes.add(pkgName); + mAllowedVendorApexes.add(pkgName); } } else { logNotAllowedInPartition(name, permFile, parser); diff --git a/core/java/com/android/server/WidgetBackupProvider.java b/core/java/com/android/server/WidgetBackupProvider.java index a2efbdd6f2f8..5453c4de6986 100644 --- a/core/java/com/android/server/WidgetBackupProvider.java +++ b/core/java/com/android/server/WidgetBackupProvider.java @@ -28,7 +28,7 @@ import java.util.List; public interface WidgetBackupProvider { public List<String> getWidgetParticipants(int userId); public byte[] getWidgetState(String packageName, int userId); - public void restoreStarting(int userId); + public void systemRestoreStarting(int userId); public void restoreWidgetState(String packageName, byte[] restoredState, int userId); - public void restoreFinished(int userId); + public void systemRestoreFinished(int userId); } diff --git a/core/java/com/android/server/backup/AccountManagerBackupHelper.java b/core/java/com/android/server/backup/AccountManagerBackupHelper.java index 39b18c0f2c16..f76dd095de29 100644 --- a/core/java/com/android/server/backup/AccountManagerBackupHelper.java +++ b/core/java/com/android/server/backup/AccountManagerBackupHelper.java @@ -56,7 +56,7 @@ public class AccountManagerBackupHelper extends BlobBackupHelper { } } } catch (Exception e) { - Slog.e(TAG, "Unable to store payload " + key); + Slog.e(TAG, "Unable to store payload " + key, e); } return new byte[0]; @@ -79,7 +79,7 @@ public class AccountManagerBackupHelper extends BlobBackupHelper { } } } catch (Exception e) { - Slog.w(TAG, "Unable to restore key " + key); + Slog.e(TAG, "Unable to restore key " + key, e); } } } diff --git a/core/java/com/android/server/backup/NotificationBackupHelper.java b/core/java/com/android/server/backup/NotificationBackupHelper.java index 7d4f8f79aa63..faa0509086fc 100644 --- a/core/java/com/android/server/backup/NotificationBackupHelper.java +++ b/core/java/com/android/server/backup/NotificationBackupHelper.java @@ -49,7 +49,7 @@ public class NotificationBackupHelper extends BlobBackupHelper { newPayload = nm.getBackupPayload(mUserId); } catch (Exception e) { // Treat as no data - Slog.e(TAG, "Couldn't communicate with notification manager"); + Slog.e(TAG, "Couldn't communicate with notification manager", e); newPayload = null; } } @@ -68,7 +68,7 @@ public class NotificationBackupHelper extends BlobBackupHelper { ServiceManager.getService("notification")); nm.applyRestore(payload, mUserId); } catch (Exception e) { - Slog.e(TAG, "Couldn't communicate with notification manager"); + Slog.e(TAG, "Couldn't communicate with notification manager", e); } } } diff --git a/core/java/com/android/server/backup/PermissionBackupHelper.java b/core/java/com/android/server/backup/PermissionBackupHelper.java index 4d1949e3e3d7..ec5e25189d64 100644 --- a/core/java/com/android/server/backup/PermissionBackupHelper.java +++ b/core/java/com/android/server/backup/PermissionBackupHelper.java @@ -59,7 +59,7 @@ public class PermissionBackupHelper extends BlobBackupHelper { Slog.w(TAG, "Unexpected backup key " + key); } } catch (Exception e) { - Slog.e(TAG, "Unable to store payload " + key); + Slog.e(TAG, "Unable to store payload " + key, e); } return null; } @@ -79,7 +79,7 @@ public class PermissionBackupHelper extends BlobBackupHelper { Slog.w(TAG, "Unexpected restore key " + key); } } catch (Exception e) { - Slog.w(TAG, "Unable to restore key " + key); + Slog.e(TAG, "Unable to restore key " + key, e); } } } diff --git a/core/java/com/android/server/backup/PreferredActivityBackupHelper.java b/core/java/com/android/server/backup/PreferredActivityBackupHelper.java index 503c71990adb..47e0c079a9f1 100644 --- a/core/java/com/android/server/backup/PreferredActivityBackupHelper.java +++ b/core/java/com/android/server/backup/PreferredActivityBackupHelper.java @@ -95,7 +95,7 @@ public class PreferredActivityBackupHelper extends BlobBackupHelper { Slog.w(TAG, "Unexpected backup key " + key); } } catch (Exception e) { - Slog.e(TAG, "Unable to store payload " + key); + Slog.e(TAG, "Unable to store payload " + key, e); } return null; } @@ -124,7 +124,7 @@ public class PreferredActivityBackupHelper extends BlobBackupHelper { Slog.w(TAG, "Unexpected restore key " + key); } } catch (Exception e) { - Slog.w(TAG, "Unable to restore key " + key); + Slog.e(TAG, "Unable to restore key " + key, e); } } } diff --git a/core/java/com/android/server/backup/SliceBackupHelper.java b/core/java/com/android/server/backup/SliceBackupHelper.java index 8e5a5eecec89..77517b334aff 100644 --- a/core/java/com/android/server/backup/SliceBackupHelper.java +++ b/core/java/com/android/server/backup/SliceBackupHelper.java @@ -48,7 +48,7 @@ public class SliceBackupHelper extends BlobBackupHelper { newPayload = sm.getBackupPayload(UserHandle.USER_SYSTEM); } catch (Exception e) { // Treat as no data - Slog.e(TAG, "Couldn't communicate with slice manager"); + Slog.e(TAG, "Couldn't communicate with slice manager", e); newPayload = null; } } @@ -66,7 +66,7 @@ public class SliceBackupHelper extends BlobBackupHelper { // TODO: http://b/22388012 sm.applyRestore(payload, UserHandle.USER_SYSTEM); } catch (Exception e) { - Slog.e(TAG, "Couldn't communicate with slice manager"); + Slog.e(TAG, "Couldn't communicate with slice manager", e); } } } diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 4a1a2728b987..64bf47cee6ec 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -27,9 +27,11 @@ #include <sys/types.h> #include <dirent.h> +#include <algorithm> #include <array> #include <atomic> #include <functional> +#include <iterator> #include <list> #include <optional> #include <sstream> @@ -120,6 +122,10 @@ static jclass gZygoteClass; static jmethodID gCallPostForkSystemServerHooks; static jmethodID gCallPostForkChildHooks; +static constexpr const char* kZygoteInitClassName = "com/android/internal/os/ZygoteInit"; +static jclass gZygoteInitClass; +static jmethodID gGetOrCreateSystemServerClassLoader; + static bool gIsSecurityEnforced = true; /** @@ -168,6 +174,7 @@ static constexpr const uint64_t UPPER_HALF_WORD_MASK = 0xFFFF'FFFF'0000'0000; static constexpr const uint64_t LOWER_HALF_WORD_MASK = 0x0000'0000'FFFF'FFFF; static constexpr const char* kCurProfileDirPath = "/data/misc/profiles/cur"; +static constexpr const char* kRefProfileDirPath = "/data/misc/profiles/ref"; /** * The maximum value that the gUSAPPoolSizeMax variable may take. This value @@ -1431,6 +1438,7 @@ static void isolateJitProfile(JNIEnv* env, jobjectArray pkg_data_info_list, // Mount (namespace) tmpfs on profile directory, so apps no longer access // the original profile directory anymore. MountAppDataTmpFs(kCurProfileDirPath, fail_fn); + MountAppDataTmpFs(kRefProfileDirPath, fail_fn); // Create profile directory for this user. std::string actualCurUserProfile = StringPrintf("%s/%d", kCurProfileDirPath, user_id); @@ -1444,14 +1452,24 @@ static void isolateJitProfile(JNIEnv* env, jobjectArray pkg_data_info_list, packageName.c_str()); std::string mirrorCurPackageProfile = StringPrintf("/data_mirror/cur_profiles/%d/%s", user_id, packageName.c_str()); + std::string actualRefPackageProfile = StringPrintf("%s/%s", kRefProfileDirPath, + packageName.c_str()); + std::string mirrorRefPackageProfile = StringPrintf("/data_mirror/ref_profiles/%s", + packageName.c_str()); if (access(mirrorCurPackageProfile.c_str(), F_OK) != 0) { ALOGW("Can't access app profile directory: %s", mirrorCurPackageProfile.c_str()); continue; } + if (access(mirrorRefPackageProfile.c_str(), F_OK) != 0) { + ALOGW("Can't access app profile directory: %s", mirrorRefPackageProfile.c_str()); + continue; + } PrepareDir(actualCurPackageProfile, DEFAULT_DATA_DIR_PERMISSION, uid, uid, fail_fn); BindMount(mirrorCurPackageProfile, actualCurPackageProfile, fail_fn); + PrepareDir(actualRefPackageProfile, DEFAULT_DATA_DIR_PERMISSION, uid, uid, fail_fn); + BindMount(mirrorRefPackageProfile, actualRefPackageProfile, fail_fn); } } @@ -1611,6 +1629,17 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, instruction_set.value().c_str()); } + if (is_system_server) { + // Prefetch the classloader for the system server. This is done early to + // allow a tie-down of the proper system server selinux domain. + env->CallStaticObjectMethod(gZygoteInitClass, gGetOrCreateSystemServerClassLoader); + if (env->ExceptionCheck()) { + // Be robust here. The Java code will attempt to create the classloader + // at a later point (but may not have rights to use AoT artifacts). + env->ExceptionClear(); + } + } + if (setresgid(gid, gid, gid) == -1) { fail_fn(CREATE_ERROR("setresgid(%d) failed: %s", gid, strerror(errno))); } @@ -2005,6 +2034,9 @@ void zygote::ZygoteFailure(JNIEnv* env, __builtin_unreachable(); } +static std::set<int>* gPreloadFds = nullptr; +static bool gPreloadFdsExtracted = false; + // Utility routine to fork a process from the zygote. pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server, const std::vector<int>& fds_to_close, @@ -2030,9 +2062,12 @@ pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server, __android_log_close(); AStatsSocket_close(); - // If this is the first fork for this zygote, create the open FD table. If - // it isn't, we just need to check whether the list of open files has changed - // (and it shouldn't in the normal case). + // If this is the first fork for this zygote, create the open FD table, + // verifying that files are of supported type and allowlisted. Otherwise (not + // the first fork), check that the open files have not changed. Newly open + // files are not expected, and will be disallowed in the future. Currently + // they are allowed if they pass the same checks as in the + // FileDescriptorTable::Create() above. if (gOpenFdTable == nullptr) { gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore, fail_fn); } else { @@ -2128,7 +2163,12 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( fds_to_ignore.push_back(gSystemServerSocketFd); } - pid_t pid = zygote::ForkCommon(env, false, fds_to_close, fds_to_ignore, true); + if (gPreloadFds && gPreloadFdsExtracted) { + fds_to_ignore.insert(fds_to_ignore.end(), gPreloadFds->begin(), gPreloadFds->end()); + } + + pid_t pid = zygote::ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore, + true); if (pid == 0) { SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, capabilities, capabilities, @@ -2265,6 +2305,10 @@ int zygote::forkApp(JNIEnv* env, } fds_to_ignore.push_back(gSystemServerSocketFd); } + if (gPreloadFds && gPreloadFdsExtracted) { + fds_to_ignore.insert(fds_to_ignore.end(), gPreloadFds->begin(), gPreloadFds->end()); + } + return zygote::ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore, is_priority_fork == JNI_TRUE, purge); } @@ -2568,6 +2612,35 @@ static jint com_android_internal_os_Zygote_nativeCurrentTaggingLevel(JNIEnv* env #endif // defined(__aarch64__) } +static void com_android_internal_os_Zygote_nativeMarkOpenedFilesBeforePreload(JNIEnv* env, jclass) { + // Ignore invocations when too early or too late. + if (gPreloadFds) { + return; + } + + // App Zygote Preload starts soon. Save FDs remaining open. After the + // preload finishes newly open files will be determined. + auto fail_fn = std::bind(zygote::ZygoteFailure, env, "zygote", nullptr, _1); + gPreloadFds = GetOpenFds(fail_fn).release(); +} + +static void com_android_internal_os_Zygote_nativeAllowFilesOpenedByPreload(JNIEnv* env, jclass) { + // Ignore invocations when too early or too late. + if (!gPreloadFds || gPreloadFdsExtracted) { + return; + } + + // Find the newly open FDs, if any. + auto fail_fn = std::bind(zygote::ZygoteFailure, env, "zygote", nullptr, _1); + std::unique_ptr<std::set<int>> current_fds = GetOpenFds(fail_fn); + auto difference = std::make_unique<std::set<int>>(); + std::set_difference(current_fds->begin(), current_fds->end(), gPreloadFds->begin(), + gPreloadFds->end(), std::inserter(*difference, difference->end())); + delete gPreloadFds; + gPreloadFds = difference.release(); + gPreloadFdsExtracted = true; +} + static const JNINativeMethod gMethods[] = { {"nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/" @@ -2616,6 +2689,10 @@ static const JNINativeMethod gMethods[] = { (void*)com_android_internal_os_Zygote_nativeSupportsTaggedPointers}, {"nativeCurrentTaggingLevel", "()I", (void*)com_android_internal_os_Zygote_nativeCurrentTaggingLevel}, + {"nativeMarkOpenedFilesBeforePreload", "()V", + (void*)com_android_internal_os_Zygote_nativeMarkOpenedFilesBeforePreload}, + {"nativeAllowFilesOpenedByPreload", "()V", + (void*)com_android_internal_os_Zygote_nativeAllowFilesOpenedByPreload}, }; int register_com_android_internal_os_Zygote(JNIEnv* env) { @@ -2626,6 +2703,13 @@ int register_com_android_internal_os_Zygote(JNIEnv* env) { gCallPostForkChildHooks = GetStaticMethodIDOrDie(env, gZygoteClass, "callPostForkChildHooks", "(IZZLjava/lang/String;)V"); - return RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods)); + gZygoteInitClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, kZygoteInitClassName)); + gGetOrCreateSystemServerClassLoader = + GetStaticMethodIDOrDie(env, gZygoteInitClass, "getOrCreateSystemServerClassLoader", + "()Ljava/lang/ClassLoader;"); + + RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods)); + + return JNI_OK; } } // namespace android diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp index 7fa627b3f809..6f5cc5314d0b 100644 --- a/core/jni/fd_utils.cpp +++ b/core/jni/fd_utils.cpp @@ -52,7 +52,6 @@ static const char* kPathAllowlist[] = { static const char kFdPath[] = "/proc/self/fd"; -// static FileDescriptorAllowlist* FileDescriptorAllowlist::Get() { if (instance_ == nullptr) { instance_ = new FileDescriptorAllowlist(); @@ -169,8 +168,8 @@ class FileDescriptorInfo { // Create a FileDescriptorInfo for a given file descriptor. static FileDescriptorInfo* CreateFromFd(int fd, fail_fn_t fail_fn); - // Checks whether the file descriptor associated with this object - // refers to the same description. + // Checks whether the file descriptor associated with this object refers to + // the same description. bool RefersToSameFile() const; void ReopenOrDetach(fail_fn_t fail_fn) const; @@ -185,8 +184,10 @@ class FileDescriptorInfo { const bool is_sock; private: + // Constructs for sockets. explicit FileDescriptorInfo(int fd); + // Constructs for non-socket file descriptors. FileDescriptorInfo(struct stat stat, const std::string& file_path, int fd, int open_flags, int fd_flags, int fs_flags, off_t offset); @@ -204,7 +205,6 @@ class FileDescriptorInfo { DISALLOW_COPY_AND_ASSIGN(FileDescriptorInfo); }; -// static FileDescriptorInfo* FileDescriptorInfo::CreateFromFd(int fd, fail_fn_t fail_fn) { struct stat f_stat; // This should never happen; the zygote should always have the right set @@ -465,42 +465,24 @@ void FileDescriptorInfo::DetachSocket(fail_fn_t fail_fn) const { } } -// static +// TODO: Move the definitions here and eliminate the forward declarations. They +// temporarily help making code reviews easier. +static int ParseFd(dirent* dir_entry, int dir_fd); +static std::unique_ptr<std::set<int>> GetOpenFdsIgnoring(const std::vector<int>& fds_to_ignore, + fail_fn_t fail_fn); + FileDescriptorTable* FileDescriptorTable::Create(const std::vector<int>& fds_to_ignore, fail_fn_t fail_fn) { - DIR* proc_fd_dir = opendir(kFdPath); - if (proc_fd_dir == nullptr) { - fail_fn(std::string("Unable to open directory ").append(kFdPath)); - } - - int dir_fd = dirfd(proc_fd_dir); - dirent* dir_entry; - + std::unique_ptr<std::set<int>> open_fds = GetOpenFdsIgnoring(fds_to_ignore, fail_fn); std::unordered_map<int, FileDescriptorInfo*> open_fd_map; - while ((dir_entry = readdir(proc_fd_dir)) != nullptr) { - const int fd = ParseFd(dir_entry, dir_fd); - if (fd == -1) { - continue; - } - - if (std::find(fds_to_ignore.begin(), fds_to_ignore.end(), fd) != fds_to_ignore.end()) { - continue; - } - + for (auto fd : *open_fds) { open_fd_map[fd] = FileDescriptorInfo::CreateFromFd(fd, fail_fn); } - - if (closedir(proc_fd_dir) == -1) { - fail_fn("Unable to close directory"); - } - return new FileDescriptorTable(open_fd_map); } -void FileDescriptorTable::Restat(const std::vector<int>& fds_to_ignore, fail_fn_t fail_fn) { - std::set<int> open_fds; - - // First get the list of open descriptors. +static std::unique_ptr<std::set<int>> GetOpenFdsIgnoring(const std::vector<int>& fds_to_ignore, + fail_fn_t fail_fn) { DIR* proc_fd_dir = opendir(kFdPath); if (proc_fd_dir == nullptr) { fail_fn(android::base::StringPrintf("Unable to open directory %s: %s", @@ -508,6 +490,7 @@ void FileDescriptorTable::Restat(const std::vector<int>& fds_to_ignore, fail_fn_ strerror(errno))); } + auto result = std::make_unique<std::set<int>>(); int dir_fd = dirfd(proc_fd_dir); dirent* dir_entry; while ((dir_entry = readdir(proc_fd_dir)) != nullptr) { @@ -520,14 +503,26 @@ void FileDescriptorTable::Restat(const std::vector<int>& fds_to_ignore, fail_fn_ continue; } - open_fds.insert(fd); + result->insert(fd); } if (closedir(proc_fd_dir) == -1) { fail_fn(android::base::StringPrintf("Unable to close directory: %s", strerror(errno))); } + return result; +} + +std::unique_ptr<std::set<int>> GetOpenFds(fail_fn_t fail_fn) { + const std::vector<int> nothing_to_ignore; + return GetOpenFdsIgnoring(nothing_to_ignore, fail_fn); +} + +void FileDescriptorTable::Restat(const std::vector<int>& fds_to_ignore, fail_fn_t fail_fn) { + std::unique_ptr<std::set<int>> open_fds = GetOpenFdsIgnoring(fds_to_ignore, fail_fn); - RestatInternal(open_fds, fail_fn); + // Check that the files did not change, and leave only newly opened FDs in + // |open_fds|. + RestatInternal(*open_fds, fail_fn); } // Reopens all file descriptors that are contained in the table. @@ -548,6 +543,12 @@ FileDescriptorTable::FileDescriptorTable( : open_fd_map_(map) { } +FileDescriptorTable::~FileDescriptorTable() { + for (auto& it : open_fd_map_) { + delete it.second; + } +} + void FileDescriptorTable::RestatInternal(std::set<int>& open_fds, fail_fn_t fail_fn) { // ART creates a file through memfd for optimization purposes. We make sure // there is at most one being created. @@ -618,8 +619,7 @@ void FileDescriptorTable::RestatInternal(std::set<int>& open_fds, fail_fn_t fail } } -// static -int FileDescriptorTable::ParseFd(dirent* dir_entry, int dir_fd) { +static int ParseFd(dirent* dir_entry, int dir_fd) { char* end; const int fd = strtol(dir_entry->d_name, &end, 10); if ((*end) != '\0') { diff --git a/core/jni/fd_utils.h b/core/jni/fd_utils.h index 14c318e8e84a..a28ebf17d334 100644 --- a/core/jni/fd_utils.h +++ b/core/jni/fd_utils.h @@ -69,6 +69,9 @@ private: DISALLOW_COPY_AND_ASSIGN(FileDescriptorAllowlist); }; +// Returns the set of file descriptors currently open by the process. +std::unique_ptr<std::set<int>> GetOpenFds(fail_fn_t fail_fn); + // A FileDescriptorTable is a collection of FileDescriptorInfo objects // keyed by their FDs. class FileDescriptorTable { @@ -79,6 +82,14 @@ class FileDescriptorTable { static FileDescriptorTable* Create(const std::vector<int>& fds_to_ignore, fail_fn_t fail_fn); + ~FileDescriptorTable(); + + // Checks that the currently open FDs did not change their metadata from + // stat(2), readlink(2) etc. Ignores FDs from |fds_to_ignore|. + // + // Temporary: allows newly open FDs if they pass the same checks as in + // Create(). This will be further restricted. See TODOs in the + // implementation. void Restat(const std::vector<int>& fds_to_ignore, fail_fn_t fail_fn); // Reopens all file descriptors that are contained in the table. Returns true @@ -91,8 +102,6 @@ class FileDescriptorTable { void RestatInternal(std::set<int>& open_fds, fail_fn_t fail_fn); - static int ParseFd(dirent* e, int dir_fd); - // Invariant: All values in this unordered_map are non-NULL. std::unordered_map<int, FileDescriptorInfo*> open_fd_map_; diff --git a/core/proto/android/server/apphibernationservice.proto b/core/proto/android/server/apphibernationservice.proto index d341c4b2f0a8..64c2a322548f 100644 --- a/core/proto/android/server/apphibernationservice.proto +++ b/core/proto/android/server/apphibernationservice.proto @@ -39,4 +39,5 @@ message GlobalLevelHibernationStatesProto { message GlobalLevelHibernationStateProto { optional string package_name = 1; optional bool hibernated = 2; + optional int64 saved_byte = 3; }
\ No newline at end of file diff --git a/core/res/res/drawable/chooser_direct_share_icon_placeholder.xml b/core/res/res/drawable/chooser_direct_share_icon_placeholder.xml index 838cb49ca79e..bd8dba866dd2 100644 --- a/core/res/res/drawable/chooser_direct_share_icon_placeholder.xml +++ b/core/res/res/drawable/chooser_direct_share_icon_placeholder.xml @@ -26,7 +26,7 @@ <group android:name="background"> <path android:pathData="M0,0 L 64,0 64,64 0,64 z" - android:fillColor="@color/chooser_gradient_background"/> + android:fillColor="@android:color/transparent"/> </group> <!-- Gradient starts offscreen so it is not visible in the first frame before start --> @@ -44,7 +44,7 @@ android:color="@android:color/transparent" android:offset="0.0" /> <item - android:color="@color/chooser_gradient_highlight" + android:color="@android:color/transparent" android:offset="0.5" /> <item android:color="@android:color/transparent" @@ -58,7 +58,7 @@ shadow. Using clip-path is a more elegant solution but leaves awful jaggies around the path's shape. --> <group android:name="cover"> - <path android:fillColor="?attr/colorBackgroundFloating" + <path android:fillColor="@android:color/transparent" android:pathData="M0,0 L64,0 L64,64 L0,64 L0,0 Z M59.0587325,42.453601 C60.3124932,39.2104785 61,35.6855272 61,32 C61,15.9837423 48.0162577,3 32,3 C15.9837423,3 3,15.9837423 3,32 C3,48.0162577 15.9837423,61 32,61 C35.6855272,61 39.2104785,60.3124932 42.453601,59.0587325 C44.3362195,60.2864794 46.5847839,61 49,61 C55.627417,61 61,55.627417 61,49 C61,46.5847839 60.2864794,44.3362195 59.0587325,42.453601 Z"/> </group> </vector> diff --git a/core/res/res/layout/splash_screen_view.xml b/core/res/res/layout/splash_screen_view.xml index e6d724f1ecb2..0b7b49cdea83 100644 --- a/core/res/res/layout/splash_screen_view.xml +++ b/core/res/res/layout/splash_screen_view.xml @@ -18,12 +18,15 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="match_parent" android:layout_width="match_parent" + android:padding="0dp" android:orientation="vertical"> <View android:id="@+id/splashscreen_icon_view" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_gravity="center" + android:padding="0dp" + android:background="@null" android:contentDescription="@string/splash_screen_view_icon_description"/> <View android:id="@+id/splashscreen_branding_view" @@ -31,6 +34,8 @@ android:layout_width="wrap_content" android:layout_gravity="center_horizontal|bottom" android:layout_marginBottom="60dp" + android:padding="0dp" + android:background="@null" android:contentDescription="@string/splash_screen_view_branding_description"/> </android.window.SplashScreenView>
\ No newline at end of file diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index cd893185b4f6..8af85dd662d8 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Probeer \'n ander vingerafdruk"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Te helder"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Probeer om dit te verstel"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Verander elke keer die posisie van jou vinger so effens"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Vingerafdruk is gestaaf"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Geen vingerafdrukke is geregistreer nie."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Kan nie vingerafdruksensor gebruik nie. Besoek \'n verskaffer wat herstelwerk doen"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Vingerafdrukikoon"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Gesigslot"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Skryf jou gesig weer in"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Skryf asseblief jou gesig weer in om herkenning te verbeter"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Kwessie met Gesigslot"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Tik om jou gesigmodel uit te vee en voeg jou gesig dan weer by"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Stel Gesigslot op"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Ontsluit jou foon deur daarna te kyk"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Stel meer maniere op om te ontsluit"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Tik om \'n vingerafdruk by te voeg"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Vingerafdrukslot"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Kan nie vingerafdruksensor gebruik nie"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Besoek \'n verskaffer wat herstelwerk doen."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Kon nie gesigdata akkuraat vasvang nie. Probeer weer."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Te helder. Probeer sagter beligting."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Te donker. Probeer helderder beligting."</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index b261c461cd5e..d1c7c49ac051 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ሌላ የጣት አሻራ ይሞክሩ"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"በጣም ብርሃናማ"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ለማስተካከል ይሞክሩ"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"በእያንዳንዱ ጊዜ የጣትዎን ቦታ በትንሹ ይለዋውጡ"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"የጣት አሻራ ትክክለኛነት ተረጋግጧል"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ምንም የጣት አሻራዎች አልተመዘገቡም።"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ይህ መሣሪያ የጣት አሻራ ዳሳሽ የለውም።"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ዳሳሽ ለጊዜው ተሰናክሏል።"</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"የጣት አሻራ ዳሳሽን መጠቀም አይቻልም። የጥገና አገልግሎት ሰጪን ይጎብኙ"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ጣት <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"የጣት አሻራ ይጠቀሙ"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"የጣት አሻራ ወይም የማያ ገጽ መቆለፊያ ይጠቀሙ"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"የጣት አሻራ አዶ"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"በመልክ መክፈት"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"የእርስዎን ፊት ዳግመኛ ያስመዝግቡ"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"ማንነትን ለይቶ ማወቅን ለማሻሻል፣ እባክዎ የእርስዎን ፊት ዳግም ያስመዝግቡ"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"ከመልክ መክፈት ጋር በተያያዘ ችግር"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"የእርስዎ የመልክ ሞዴል ለመሰረዝ መታ ያድርጉ፣ ከዚያ መልክዎን እንደገና ያክሉ"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"በመልክ መክፈትን ያዋቅሩ"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"ስልክዎን በመመልከት ያስከፍቱት"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"የሚከፍቱባቸው ተጨማሪ መንገዶችን ያቀናብሩ"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"የጣት አሻራን ለማከል መታ ያድርጉ"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"በጣት አሻራ መክፈቻ"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"የጣት አሻራ ዳሳሽን መጠቀም አይቻልም"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"የጥገና አገልግሎት ሰጪን ይጎብኙ።"</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"ትክክለኛ የፊት ውሂብ ማንሳት አልተቻለም። እንደገና ይሞክሩ።"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"ከልክ በላይ ፈካ ያለ። ይበልጥ ረጋ ያለ ብርሃን አጠቃቀምን ይሞክሩ።"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"ከልክ በላይ ጨለማ ነው። ከዚህ ፈካ ያለ ብርሃን አጠቃቀምን ይሞክሩ።"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index b38bf9f93d73..39e3021c128e 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -146,7 +146,7 @@ <string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string> <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"الاتصال عبر WiFi"</string> <string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string> - <string name="wifi_calling_off_summary" msgid="5626710010766902560">"إيقاف"</string> + <string name="wifi_calling_off_summary" msgid="5626710010766902560">"غير مفعّل"</string> <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"الاتصال عبر Wi-Fi"</string> <string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"الاتصال عبر شبكة الجوّال"</string> <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wi-Fi فقط"</string> @@ -597,6 +597,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"يمكنك تجربة بصمة إصبع أخرى."</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"الصورة ساطعة للغاية."</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"حاوِل تعديل بصمة الإصبع."</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"غيِّر موضع إصبعك قليلاً في كل مرة."</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"تم مصادقة بصمة الإصبع"</string> @@ -613,7 +614,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ليست هناك بصمات إصبع مسجَّلة."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"لا يحتوي هذا الجهاز على مستشعِر بصمات إصبع."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"تم إيقاف جهاز الاستشعار مؤقتًا."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"الإصبع <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استخدام بصمة الإصبع"</string> @@ -624,12 +625,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"رمز بصمة الإصبع"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"فتح الجهاز بالتعرف على الوجه"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"إعادة تسجيل وجهك"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"لتحسين قدرة الجهاز على معرفة وجهك، يُرجى إعادة تسجيل الوجه."</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"مشكلة متعلّقة بميزة \"فتح الجهاز بالتعرف على الوجه\""</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"انقر لحذف نموذج الوجه ثم أضِف نموذجًا لوجهك مرة أخرى."</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"إعداد ميزة \"فتح الجهاز بالتعرف على الوجه\""</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"يمكنك فتح قفل هاتفك بمجرّد النظر إلى الشاشة."</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"إعداد المزيد من الطرق لفتح قفل الجهاز"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"انقر لإضافة بصمة إصبع."</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"تعذّر تسجيل بيانات دقيقة للوجه. حاول مرة أخرى."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"ساطع للغاية. تجربة مستوى سطوع أقلّ."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"الصورة معتمة للغاية. يُرجى زيادة السطوع."</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 846fb2c31d1f..ad3d74697e70 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"অন্য এটা ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰি চাওক"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"অতি উজ্জ্বল"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"মিলাই চাওক"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"প্ৰতিবাৰতে আপোনাৰ আঙুলিটোৰ স্থান সামান্য সলনি কৰক"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ফিংগাৰপ্ৰিণ্টৰ সত্যাপন কৰা হ’ল"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"কোনো ফিংগাৰপ্ৰিণ্ট যোগ কৰা নহ\'ল।"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই।"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ছেন্সৰটো সাময়িকভাৱে অক্ষম হৈ আছে।"</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> আঙুলি"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string> @@ -612,12 +613,20 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ফিংগাৰপ্ৰিণ্ট আইকন"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"মুখাৱয়বৰ দ্বাৰা আনলক কৰাৰ সুবিধা"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"আপোনাৰ মুখমণ্ডল পুনৰ পঞ্জীয়ণ কৰক"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"চিনাক্তকৰণৰ সুবিধাটো উন্নত কৰিবলৈ, অনুগ্ৰহ কৰি আপোনাৰ মুখমণ্ডল পুনৰ পঞ্জীয়ন কৰক"</string> + <!-- no translation found for face_recalibrate_notification_title (2524791952735579082) --> + <skip /> + <!-- no translation found for face_recalibrate_notification_content (3064513770251355594) --> + <skip /> <string name="face_setup_notification_title" msgid="8843461561970741790">"মুখাৱয়বৰে আনলক কৰাৰ সুবিধাটো ছেট আপ কৰক"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"আপোনাৰ ফ’নটোলৈ চাই সেইটো আনলক কৰক"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"আনলক কৰাৰ অধিক উপায় ছেট আপ কৰক"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"এটা ফিংগাৰপ্ৰিণ্ট যোগ দিবলৈ টিপক"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"সঠিক মুখমণ্ডলৰ ডেটা কেপচাৰ নহ’ল। আকৌ চেষ্টা কৰক।"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"অতি উজ্জ্বল। ইয়াতকৈ কম পোহৰৰ উৎস ব্যৱহাৰ কৰক।"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"অতি আন্ধাৰ। উজ্জ্বল লাইট ব্যৱহাৰ কৰক।"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 6b4736f71696..85f1b4708080 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Başqa bir barmaq izini sınayın"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Çox işıqlıdır"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Tənzimləməyə çalışın"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Hər dəfə barmağınızın yerini bir az dəyişdirin"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Barmaq izi doğrulandı"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Barmaq izi qeydə alınmayıb."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"Barmaq <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmaq izini istifadə edin"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Barmaq izi ikonası"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Üz ilə kiliddən çıxarma"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Üzünüzü yenidən qeydiyyatdan keçirin"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Tanınmanı təkmilləşdirmək üçün üzünüzü yenidən qeydiyyatdan keçirin"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Üz ilə kiliddən çıxarma problemi"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Üz modelinizi silmək üçün toxunun, sonra yenidən üzünüzü əlavə edin"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Üz ilə kiliddən çıxarmanı ayarlayın"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Telefona baxaraq onu kiliddən çıxarın"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Kiliddən çıxarmağın daha çox yolunu ayarlayın"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Barmaq izi əlavə etmək üçün toxunun"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Dəqiq üz datası əldə edilmədi. Yenidən cəhd edin."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Çox işıqlıdır. Daha az işıqlı şəkli sınayın."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Çox qaranlıqdır. Parlaq işıqdan istifadə edin."</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 5fcd2df25a78..a763cf3a12b0 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -352,7 +352,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Dozvoljava aplikaciji da proširuje ili skuplja statusnu traku."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"prikazuje obaveštenja kao aktivnosti preko celog ekrana na zaključanom uređaju"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Omogućava aplikaciji da na zaključanom uređaju prikazuje obaveštenja kao aktivnosti preko celog ekrana."</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"instaliranje prečica"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instaliranje prečica"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Omogućava aplikaciji da dodaje prečice na početni ekran bez intervencije korisnika."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"deinstaliranje prečica"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Omogućava aplikaciji da uklanja prečice sa početnog ekrana bez intervencije korisnika."</string> @@ -588,6 +588,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Probajte sa drugim otiskom prsta"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Previše je svetlo"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Probajte da prilagodite"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put lagano promenite položaj prsta"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisak prsta je potvrđen"</string> @@ -604,8 +605,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije registrovan nijedan otisak prsta."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ne možete da koristite senzor za otisak prsta. Posetite dobavljača za popravke"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -615,12 +615,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona otiska prsta"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Otključavanje licem"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Ponovo registrujte lice"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Da biste poboljšali prepoznavanje, ponovo registrujte lice"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problem sa otključavanje licem"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Dodirnite da biste izbrisali model lica, pa ponovo dodajte svoje lice"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Podesite otključavanje licem"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Otključajte telefon tako što ćete ga pogledati"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Podesite još načina za otključavanje"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Dodirnite da biste dodali otisak prsta"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Otključavanje otiskom prsta"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Ne možete da koristite senzor za otisak prsta"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Posetite dobavljača za popravke."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Snimanje lica nije uspelo. Probajte ponovo."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Previše je svetlo. Probajte sa slabijim osvetljenjem."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Pretamno je. Probajte sa jačim osvetljenjem."</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 1af3ddd3b7fc..003b5e560d78 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -355,7 +355,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Дазваляе прыкладанню разгортваць ці згортваць радок стану."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"паказваць апавяшчэнні ў поўнаэкранным рэжыме на заблакіраванай прыладзе"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Дазваляе праграме паказваць апавяшчэнні ў поўнаэкранным рэжыме на заблакіраванай прыладзе"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"усталёўваць ярлыкі"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Стварэнне ярлыкоў"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Дазваляе праграме дадаваць ярлыкі на Галоўны экран без умяшання карыстальніка."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"выдаляць ярлыкі"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Дазваляе праграме выдаляць ярлыкі з Галоўнага экрана без умяшання карыстальніка."</string> @@ -591,6 +591,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Паспрабуйце іншы адбітак пальца"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Занадта светла"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Паспрабуйце наладзіць"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Кожны раз крыху мяняйце пазіцыю пальца"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Адбітак пальца распазнаны"</string> @@ -607,7 +608,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Адбіткі пальцаў не зарэгістраваны."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На гэтай прыладзе няма сканера адбіткаў пальцаў."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчык часова выключаны."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Выкарыстоўваць адбітак пальца"</string> @@ -618,12 +619,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Значок адбіткаў пальцаў"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Распазнаванне твару"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Паўтарыце рэгістрацыю твару"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Каб палепшыць распазнавальнасць, яшчэ раз выканайце рэгістрацыю твару"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Праблема з распазнаваннем твару"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Націсніце, каб выдаліць мадэль твару, пасля дадайце твар яшчэ раз"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Наладзьце распазнаванне твару"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Разблакіруйце свой тэлефон, паглядзеўшы на яго"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Наладзьце дадатковыя спосабы разблакіроўкі"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Націсніце, каб дадаць адбітак пальца"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Не атрымалася распазнаць твар. Паўтарыце спробу."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Занадта светла. Прыглушыце асвятленне."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Занадта цёмна. Павялічце асвятленне."</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index b3722abd908b..b72e780a4f8a 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Разрешава на приложението да разгъва или свива лентата на състоянието."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"показване на известия като активности на цял екран на заключено устройство"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Дава възможност на приложението да показва известия като активности на цял екран на заключено устройство"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"инсталиране на преки пътища"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Инсталиране на преки пътища"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Разрешава на приложението да добавя към началния екран преки пътища без намеса на потребителя."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"деинсталиране на преки пътища"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Разрешава на приложението да премахва преки пътища от началния екран без намеса на потребителя."</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Опитайте с друг отпечатък"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Твърде светло е"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Опитайте да коригирате"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Всеки път променяйте леко позицията на пръста си"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечатъкът е удостоверен"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Няма регистрирани отпечатъци."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Това устройство няма сензор за отпечатъци."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорът е временно деактивиран."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Сензорът за отпечатъци не може да се използва. Посетете оторизиран сервиз."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Пръст <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Използване на отпечатък"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Използване на отпечатък или опцията за заключване на екрана"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Икона за отпечатък"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Отключване с лице"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Регистрирайте отново лицето си"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"С цел подобряване на разпознаването регистрирайте отново лицето си"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Проблем с отключването с лице"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Докоснете, за да изтриете модела на лицето си, след което добавете лицето си отново"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Настройване на отключването с лице"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Отключвайте телефона си, като го погледнете"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Настройване на още начини за отключване на телефона"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Докоснете, за да добавите отпечатък"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Отключване с отпечатък"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Сензорът за отпечатъци не може да се използва"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Посетете оторизиран сервиз."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Лицето не бе заснето точно. Опитайте отново."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Твърде светло е. Опитайте при по-слабо осветление."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Твърде тъмно е. Опитайте при по-силно осветление."</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 69ddbb4f1f46..718eef00d159 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"অন্য আঙ্গুলের ছাপ দিয়ে চেষ্টা করুন"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"অত্যন্ত উজ্জ্বল"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"অ্যাডজাস্ট করার চেষ্টা করুন"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"প্রতিবার আঙ্গুলের ছাপ সেটআপ করার সময় আপনার আঙ্গুলের অবস্থান সামান্য পরিবর্তন করুন"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"আঙ্গুলের ছাপ যাচাই করা হয়েছে"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"কোনও আঙ্গুলের ছাপ নথিভুক্ত করা হয়নি।"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইসে আঙ্গুলের ছাপ নেওয়ার সেন্সর নেই।"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"সেন্সর অস্থায়ীভাবে বন্ধ করা আছে।"</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"আঙ্গুল <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"আঙ্গুলের ছাপ ব্যবহার করুন"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"আঙ্গুলের ছাপ আইকন"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"\'ফেস আনলক\'"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"আপনার ফেস আবার এনরোল করুন"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"শনাক্তকরণের উন্নতি করতে আপনার ফেস আবার এনরোল করুন"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"\'ফেস আনলক\' ফিচার ব্যবহার করার ক্ষেত্রে হওয়া সমস্যা"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"আপনার ফেস মডেল মুছে দেওয়ার জন্য ট্যাপ করুন এবং তারপরে আবার ফেস যোগ করুন"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"\'ফেস আনলক\' সেট আপ করুন"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"আপনার ফোনের দিকে তাকিয়ে এটিকে আনলক করুন"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"আনলক করার জন্য বিভিন্ন উপায়ে সেট আপ করুন"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"একটি আঙ্গুলের ছাপ যোগ করতে ট্যাপ করুন"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"মুখের সঠিক ডেটা পাওয়া যায়নি। আবার চেষ্টা করুন।"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"খুব উজ্জ্বল। আলো কমিয়ে চেষ্টা করে দেখুন।"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"খুব অন্ধকার। আরও উজ্জ্বল আলো ব্যবহার করে দেখুন।"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 74da24a6bfc4..59d03d9b0e4f 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -352,7 +352,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Dozvoljava aplikaciji proširivanje ili sužavanje statusne trake."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"prikaz obavještenja kao aktivnosti preko cijelog ekrana na zaključanom uređaju"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Dozvoljava aplikaciji da prikazuje obavještenja kao aktivnosti preko cijelog ekrana na zaključanom uređaju"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"instaliranje prečica"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instaliranje prečica"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Omogućava aplikaciji dodavanje prečice za početni ekran bez intervencije korisnika."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"uklanjanje prečica"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Omogućava aplikaciji uklanjanje prečice početnog ekrana bez intervencije korisnika."</string> @@ -588,6 +588,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Pokušajte s drugim otiskom prsta"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Presvijetlo"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Pokušajte podesiti"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put blago promijenite položaj prsta"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisak prsta je potvrđen"</string> @@ -604,8 +605,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije prijavljen nijedan otisak prsta."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nije moguće koristiti senzor za otisak prsta. Posjetite pružaoca usluga za popravke"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -615,12 +615,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona za otisak prsta"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Otključavanje licem"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Ponovo registrirajte lice"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Ponovo registrirajte lice da poboljšate prepoznavanje"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problem s otključavanjem licem"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Dodirnite da izbrišete model lica, a zatim ponovo dodajte lice"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Postavite otključavanje licem"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Otključajte telefon gledajući u njega"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Postavite više načina otključavanja"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Dodirnite da dodate otisak prsta"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Otključavanje otiskom prsta"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Nije moguće koristiti senzor za otisak prsta"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Posjetite pružaoca usluga za popravke."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Lice nije snimljeno precizno. Pokušajte ponovo."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Previše svijetlo. Probajte s blažim osvjetljenjem."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Previše je tamno. Pokušajte s jačim osvjetljenjem."</string> @@ -1894,7 +1897,7 @@ <string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao je vaš administrator"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Uredu"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ušteda baterije uključuje tamnu temu i ograničava ili isključuje aktivnost u pozadini, određene vizuelne efekte i funkcije te neke mrežne veze."</string> - <string name="battery_saver_description" msgid="8518809702138617167">"Ušteda baterije uključuje Tamnu temu i ograničava ili isključuje aktivnost u pozadini, određene vizuelne efekte i funkcije i neke mrežne veze."</string> + <string name="battery_saver_description" msgid="8518809702138617167">"Ušteda baterije uključuje Tamnu temu i ograničava ili isključuje aktivnost u pozadini, određene vizuelne efekte i funkcije te neke mrežne veze."</string> <string name="data_saver_description" msgid="4995164271550590517">"Radi smanjenja prijenosa podataka, Ušteda podataka sprečava da neke aplikacije šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može pristupiti podacima, ali će to činiti rjeđe. Naprimjer, to može značiti da se slike ne prikazuju dok ih ne dodirnete."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Uključiti Uštedu podataka?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Uključi"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 03e7ef2e904b..e06cc3724161 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permet que l\'aplicació desplegui o replegui la barra d\'estat."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"mostrar notificacions com a activitats de pantalla completa en un dispositiu bloquejat"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permet a l\'aplicació mostrar notificacions com a activitats de pantalla completa en un dispositiu bloquejat"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"instal·lar dreceres"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instal·lar dreceres"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permet que una aplicació afegeixi dreceres a la pantalla d\'inici sense la intervenció de l\'usuari."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"desinstal·la dreceres"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permet que l\'aplicació suprimeixi les dreceres de la pantalla d\'inici sense la intervenció de l\'usuari."</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prova una altra empremta digital"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Hi ha massa llum"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prova d\'ajustar l\'empremta digital"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Canvia lleugerament la posició del dit en cada intent"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"L\'empremta digital s\'ha autenticat"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No s\'ha registrat cap empremta digital."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aquest dispositiu no té sensor d\'empremtes digitals."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor està desactivat temporalment."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"No es pot utilitzar el sensor d\'empremtes digitals. Visita un proveïdor de reparacions."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dit <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icona d\'empremta digital"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Desbloqueig facial"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Torna a registrar la cara"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Per millorar el reconeixement, torna a registrar la cara"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problema amb Desbloqueig facial"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Toca per suprimir el teu model facial i, a continuació, torna a afegir la teva cara"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Configura Desbloqueig facial"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Mira el telèfon per desbloquejar-lo"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configura més maneres de desbloquejar el dispositiu"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Toca per afegir una empremta digital"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Desbloqueig amb empremta digital"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"No es pot utilitzar el sensor d\'empremtes digitals"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visita un proveïdor de reparacions."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"No es reconeix la teva cara. Torna-ho a provar."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Massa brillant Prova una il·luminació més suau."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Massa fosc. Prova una il·luminació més brillant."</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index bfd56343d674..1ec443e53a96 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -355,7 +355,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Umožňuje aplikaci rozbalit či sbalit stavový řádek."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"zobrazovat oznámení na celé obrazovce zamčeného zařízení"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Umožňuje aplikaci zobrazovat oznámení na celé obrazovce zamčeného zařízení"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalace zástupců"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instalace zástupců"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Umožňuje aplikaci přidat zástupce na plochu bez zásahu uživatele."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"odinstalace zástupců"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Umožňuje aplikaci odebrat zástupce z plochy bez zásahu uživatele."</string> @@ -591,6 +591,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Zkuste jiný otisk prstu"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Je příliš světlo"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Zkuste provést úpravu"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Pokaždé lehce změňte polohu prstu"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisk byl ověřen"</string> @@ -607,8 +608,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nejsou zaregistrovány žádné otisky prstů."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Snímač otisků prstů nelze použít. Navštivte servis"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -618,12 +618,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona otisku prstů"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Odemknutí obličejem"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Zaznamenejte obličej znovu"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Chcete-li rozpoznání zdokonalit, zaznamenejte obličej znovu"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problém s odemykáním obličejem"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Klepnutím svůj model obličeje smažte a potom ho přidejte znovu"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Nastavte odemknutí obličejem"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Telefon odemknete pohledem"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Nastavte si více způsobů odemykání"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Klepnutím přidáte otisk prstu"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Odemknutí otiskem prstu"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Snímač otisků prstů nelze použít"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Navštivte servis"</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Obličej se nepodařilo zachytit. Zkuste to znovu."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Je příliš světlo. Zmírněte osvětlení."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Je moc velká tma. Přejděte na světlo."</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 4231048bccea..e0bfb592bb25 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prøv med et andet fingeraftryk"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Der er for lyst"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prøv at justere den"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Flyt fingeren en smule hver gang"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeraftrykket blev godkendt"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Der er ikke registreret nogen fingeraftryk."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Fingeraftrykslæseren kan ikke bruges. Få den repareret"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Fingeraftryk <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon for fingeraftryk"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Ansigtslås"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Registrer dit ansigt igen"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Registrer dit ansigt igen for at forbedre genkendelsen af det"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Der er et problem med Ansigtslås"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Tryk for at slette din ansigtsmodel, og tilføj derefter dit ansigt igen"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Konfigurer ansigtslås"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Lås din telefon op ved at kigge på den"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Konfigurer flere måder at låse op på"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Tryk for at tilføje et fingeraftryk"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Oplåsning med fingeraftryk"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Fingeraftrykslæseren kan ikke bruges"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Få den repareret."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Der blev ikke registreret ansigtsdata. Prøv igen."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Der er for lyst. Prøv en mere dæmpet belysning."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"For mørkt. Prøv med mere belysning."</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 7a75eea2181c..5af538dc703e 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Anderen Fingerabdruck verwenden"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Zu hell"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Versuche, den Finger anders aufzulegen"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ändere jedes Mal die Position deines Fingers"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerabdruck wurde authentifiziert"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Keine Fingerabdrücke erfasst."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Fingerabdruck verwenden"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerabdruck-Symbol"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Entsperrung per Gesichtserkennung"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Gesicht neu scannen lassen"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Für bessere Erkennung Gesicht neu scannen lassen"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problem bei der Entsperrung per Gesichtserkennung"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Tippe, um dein Gesichtsmodell zu löschen, und füge es dann noch einmal hinzu"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Entsperrung per Gesichtserkennung einrichten"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Entsperre dein Smartphone, indem du es ansiehst"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Weitere Möglichkeiten zum Entsperren einrichten"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Tippe, um einen Fingerabdruck hinzuzufügen"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Gesichtsdaten nicht gut erfasst. Erneut versuchen."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Zu hell. Schwächere Beleuchtung ausprobieren."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Zu dunkel. Probier eine hellere Beleuchtung aus."</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 523cde133638..3f14d04ad073 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Δοκιμάστε άλλο δακτυλικό αποτύπωμα"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Υπερβολικά έντονος φωτισμός"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Δοκιμάστε να το προσαρμόσετε"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Αλλάζετε ελαφρώς τη θέση του δακτύλου σας κάθε φορά."</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Η ταυτότητα του δακτυλικού αποτυπώματος ελέγχθηκε"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Δεν έχουν καταχωριστεί δακτυλικά αποτυπώματα."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Αυτή η συσκευή δεν διαθέτει αισθητήρα δακτυλικού αποτυπώματος."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Ο αισθητήρας απενεργοποιήθηκε προσωρινά."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Δεν είναι δυνατή η χρήση του αισθητήρα δακτυλικών αποτυπωμάτων. Επισκεφτείτε έναν πάροχο υπηρεσιών επισκευής."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Δάχτυλο <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Χρήση δακτυλικού αποτυπώματος"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Χρήση δακτυλικού αποτυπώματος ή κλειδώματος οθόνης"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Εικονίδιο δακτυλικών αποτυπωμάτων"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Ξεκλείδωμα με το πρόσωπο"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Εγγράψτε ξανά το πρόσωπό σας"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Για να βελτιώσετε την αναγνώριση, εγγράψτε ξανά το πρόσωπό σας"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Πρόβλημα με το Ξεκλείδωμα με το πρόσωπο"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Πατήστε για να διαγράψετε το μοντέλο προσώπου και, στη συνέχεια, προσθέστε το πρόσωπό σας ξανά."</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Ρύθμιση της λειτουργίας Ξεκλείδωμα με το πρόσωπο"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Ξεκλειδώστε το τηλέφωνό σας απλώς κοιτώντας το"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Ρυθμίστε περισσότερους τρόπους ξεκλειδώματος"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Πατήστε για να προσθέσετε δακτυλικό αποτύπωμα"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Ξεκλείδωμα με δακτυλικό αποτύπωμα"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Δεν είναι δυνατή η χρήση του αισθητήρα δακτυλικών αποτυπωμάτων"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Επισκεφτείτε έναν πάροχο υπηρεσιών επισκευής."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Αδύνατη λήψη ακριβών δεδομ. προσώπου. Επανάληψη."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Υπερβολικά έντονος φωτισμός. Δοκιμάστε πιο ήπιο."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Πολύ σκοτεινό περιβάλλον. Φροντίστε τον φωτισμό."</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index b2eaab053b46..253de2c9fa40 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Change the position of your finger slightly each time"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Face Unlock"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Re-enrol your face"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"To improve recognition, please re-enrol your face"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Issue with Face Unlock"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Tap to delete your face model, then add your face again"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Set up Face Unlock"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Unlock your phone by looking at it"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Set up more ways to unlock"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Tap to add a fingerprint"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Fingerprint Unlock"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Can’t use fingerprint sensor"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visit a repair provider."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Couldn’t capture accurate face data. Try again."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Too bright. Try gentler lighting."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Too dark. Try brighter lighting."</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 0a257f429b76..10e683109adc 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Change the position of your finger slightly each time"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Face Unlock"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Re-enrol your face"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"To improve recognition, please re-enrol your face"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Issue with Face Unlock"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Tap to delete your face model, then add your face again"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Set up Face Unlock"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Unlock your phone by looking at it"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Set up more ways to unlock"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Tap to add a fingerprint"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Fingerprint Unlock"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Can’t use fingerprint sensor"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visit a repair provider."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Couldn’t capture accurate face data. Try again."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Too bright. Try gentler lighting."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Too dark. Try brighter lighting."</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 5eca8a68a12f..7aea9a73121d 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Change the position of your finger slightly each time"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Face Unlock"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Re-enrol your face"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"To improve recognition, please re-enrol your face"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Issue with Face Unlock"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Tap to delete your face model, then add your face again"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Set up Face Unlock"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Unlock your phone by looking at it"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Set up more ways to unlock"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Tap to add a fingerprint"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Fingerprint Unlock"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Can’t use fingerprint sensor"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visit a repair provider."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Couldn’t capture accurate face data. Try again."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Too bright. Try gentler lighting."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Too dark. Try brighter lighting."</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 74d32d4a1075..257f403179de 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Change the position of your finger slightly each time"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Face Unlock"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Re-enrol your face"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"To improve recognition, please re-enrol your face"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Issue with Face Unlock"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Tap to delete your face model, then add your face again"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Set up Face Unlock"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Unlock your phone by looking at it"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Set up more ways to unlock"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Tap to add a fingerprint"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Fingerprint Unlock"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Can’t use fingerprint sensor"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visit a repair provider."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Couldn’t capture accurate face data. Try again."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Too bright. Try gentler lighting."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Too dark. Try brighter lighting."</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index 385608faaf28..df52af899d74 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Try another fingerprint"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Too bright"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Try adjusting"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Change the position of your finger slightly each time"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerprint authenticated"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string> <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_error_bad_calibration" msgid="374406495079531135">"Sensor needs calibration"</string> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Can’t use fingerprint sensor. Visit a repair provider"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -611,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Face Unlock"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Re-enroll your face"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"To improve recognition, please re-enroll your face"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Issue with Face Unlock"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Tap to delete your face model, then add your face again"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Set up Face Unlock"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Unlock your phone by looking at it"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Set up more ways to unlock"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Tap to add a fingerprint"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Fingerprint Unlock"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Can’t use fingerprint sensor"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visit a repair provider."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Couldn’t capture accurate face data. Try again."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Too bright. Try gentler lighting."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Too dark. Try brighter lighting."</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index fafb766c0dba..5cc92a0739a0 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permite que la aplicación muestre y oculte la barra de estado."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"mostrar notificaciones como actividades de pantalla completa en un dispositivo bloqueado"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permite que la app muestre notificaciones como actividades de pantalla completa en un dispositivo bloqueado"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalar accesos directos"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instalar accesos directos"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permite que una aplicación agregue accesos directos a la pantalla principal sin que el usuario intervenga."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"desinstalar accesos directos"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permite que la aplicación elimine accesos directos de la pantalla principal sin que el usuario intervenga."</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prueba con otra huella dactilar"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Demasiada luz"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prueba ajustarla"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Cambia un poco la posición del dedo cada vez"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Se autenticó la huella dactilar"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No se registraron huellas digitales."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"No se puede usar el sensor de huellas dactilares. Consulta a un proveedor de reparaciones."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícono de huella dactilar"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Desbloqueo facial"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Vuelve a registrar tu rostro"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Para mejorar el reconocimiento, vuelve a registrar tu rostro"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problema con el Desbloqueo facial"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Presiona para borrar el modelo de rostro y, luego, vuelve a agregar tu rostro"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Configura Desbloqueo facial"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Desbloquea el teléfono con solo mirarlo"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configura más formas de desbloquear el dispositivo"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Presiona para agregar una huella dactilar"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Desbloqueo con huellas dactilares"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"No se puede usar el sensor de huellas dactilares"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Consulta a un proveedor de reparaciones."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Datos faciales imprecisos. Vuelve a intentarlo."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Demasiado brillante. Prueba con menos iluminación."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Demasiado oscuro. Prueba con más iluminación."</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 3468da5db15a..1d7c4a393b7b 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prueba con otra huella digital"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Demasiada luz"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prueba a mover el dedo"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Cambia ligeramente el dedo de posición cada vez"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Se ha autenticado la huella digital"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No se ha registrado ninguna huella digital."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"No se puede usar el sensor de huellas digitales. Visita un proveedor de reparaciones."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icono de huella digital"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Desbloqueo facial"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Volver a registrar la cara"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Para mejorar el reconocimiento, vuelve a registrar tu cara"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problema con Desbloqueo facial"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Toca para eliminar tu modelo facial y luego añade de nuevo tu cara"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Configura Desbloqueo facial"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Desbloquea el teléfono con solo mirarlo"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configura más formas de desbloqueo"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Toca para añadir una huella digital"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Desbloqueo con Huella Digital"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"No se puede usar el sensor de huellas digitales"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visita un proveedor de reparaciones."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Datos faciales no reconocidos. Vuelve a intentarlo."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Hay demasiada luz. Busca un sitio menos iluminado."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Demasiado oscuro. Prueba en un lugar con más luz."</string> @@ -1870,8 +1873,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Actualizado por el administrador"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminado por el administrador"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string> - <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"El modo Ahorro de batería activa el tema oscuro y limita o desactiva la actividad en segundo plano, algunos efectos visuales, ciertas funciones y algunas conexiones de red."</string> - <string name="battery_saver_description" msgid="8518809702138617167">"El modo Ahorro de batería activa el tema oscuro y limita o desactiva la actividad en segundo plano, algunos efectos visuales, ciertas funciones y algunas conexiones de red."</string> + <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ahorro de batería activa el tema oscuro y limita o desactiva la actividad en segundo plano, algunos efectos visuales, ciertas funciones y algunas conexiones de red."</string> + <string name="battery_saver_description" msgid="8518809702138617167">"Ahorro de batería activa el tema oscuro y limita o desactiva la actividad en segundo plano, algunos efectos visuales, ciertas funciones y algunas conexiones de red."</string> <string name="data_saver_description" msgid="4995164271550590517">"Ahorro de datos evita que algunas aplicaciones envíen o reciban datos en segundo plano, lo que puede reducir el uso de datos. Una aplicación activa puede acceder a los datos, aunque con menos frecuencia. Esto significa que es posible que, por ejemplo, algunas imágenes no se muestren hasta que las toques."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"¿Activar Ahorro de datos?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Activar"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 0a60d66cd2e2..cbcee5995f31 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Võimaldab rakendusel laiendada või ahendada olekuriba."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"Kuva märguanded lukustatud seadmes täisekraantegevustena"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Lubab rakendusel märguandeid lukustatud seadmes täisekraantegevustena kuvada"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"otseteede installimine"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Otseteede installimine"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Lubab rakendusel lisada avakuva otseteid ilma kasutaja sekkumiseta."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"otseteede desinstallimine"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Lubab rakendusel eemaldada avakuva otseteid ilma kasutaja sekkumiseta."</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Proovige teist sõrmejälge"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Liiga ere"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Proovige kohandada"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Muutke iga kord pisut oma sõrme asendit"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Sõrmejälg autenditi"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ühtegi sõrmejälge pole registreeritud."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Sõrmejäljeandurit ei saa kasutada. Külastage remonditeenuse pakkujat"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Sõrmejälg <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Sõrmejälje ikoon"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Näoga avamine"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Registreerige oma nägu uuesti"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Tuvastamise parandamiseks registreerige oma nägu uuesti"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Probleem funktsiooniga Näoga avamine"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Puudutage näomudeli kustutamiseks, seejärel lisage oma nägu uuesti"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Näoga avamise seadistamine"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Avage telefon seda vaadates"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Seadistage rohkem viise avamiseks"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Puudutage sõrmejälje lisamiseks"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Sõrmejäljega avamine"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Sõrmejäljeandurit ei saa kasutada"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Külastage remonditeenuse pakkujat."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Näoandmeid ei saanud jäädvustada. Proovige uuesti."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Liiga ere. Proovige hämaramat valgust."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Liiga pime. Proovige parema valgustusega kohas."</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index e36cc324aed9..c3172a6c3589 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Egoera-barra zabaltzeko edo tolesteko baimena ematen die aplikazioei."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"blokeatutako gailu batean jakinarazpenak pantaila osoko jarduera gisa bistaratzea"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Blokeatutako gailu batean jakinarazpenak pantaila osoko jarduera gisa bistaratzeko baimena ematen die aplikazioei"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalatu lasterbideak"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instalatu lasterbideak"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Erabiltzaileak ezer egin gabe hasierako pantailan lasterbideak gehitzeko aukera ematen die aplikazioei."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"desinstalatu lasterbideak"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Erabiltzaileak ezer egin gabe hasierako pantailako lasterbideak kentzeko aukera ematen die aplikazioei."</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Erabili beste hatz-marka bat"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Argi gehiegi dago"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Saiatu doituta"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Aldi bakoitzean, aldatu hatzaren posizioa apur bat"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Autentifikatu da hatz-marka"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ez da erregistratu hatz-markarik."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ezin da erabili hatz-marken sentsorea. Jo konponketak egiten dituen hornitzaile batenera."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. hatza"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Hatz-markaren ikonoa"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Aurpegi bidez desblokeatzeko eginbidea"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Erregistratu aurpegia berriro"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Ezagutzea hobetzeko, erregistratu aurpegia berriro"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Arazoak ditugu aurpegi bidez desblokeatzeko eginbidearekin"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Sakatu hau aurpegi-eredua ezabatzeko eta, gero, gehitu aurpegia berriro"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Konfiguratu aurpegi bidez desblokeatzeko eginbidea"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Telefonoa desblokeatzeko, begira iezaiozu"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Konfiguratu telefonoa desblokeatzeko modu gehiago"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Sakatu hau hatz-marka bat gehitzeko"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Hatz-marka bidez desblokeatzea"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Ezin da erabili hatz-marken sentsorea"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Jo konponketak egiten dituen hornitzaile batenera."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Ezin izan dira bildu argazkiaren datu zehatzak. Saiatu berriro."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Argi gehiegi dago. Joan toki ilunago batera."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Ilunegi dago. Erabili argi gehiago."</string> @@ -1055,8 +1058,8 @@ <string name="last_month" msgid="1528906781083518683">"Azken hilabetea"</string> <string name="older" msgid="1645159827884647400">"Zaharragoa"</string> <string name="preposition_for_date" msgid="2780767868832729599">"<xliff:g id="DATE">%s</xliff:g>"</string> - <string name="preposition_for_time" msgid="4336835286453822053">"ordua: <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="preposition_for_year" msgid="3149809685340130039">"urtea: <xliff:g id="YEAR">%s</xliff:g>"</string> + <string name="preposition_for_time" msgid="4336835286453822053">"<xliff:g id="TIME">%s</xliff:g>"</string> + <string name="preposition_for_year" msgid="3149809685340130039">"<xliff:g id="YEAR">%s</xliff:g>"</string> <string name="day" msgid="8394717255950176156">"egun"</string> <string name="days" msgid="4570879797423034973">"egun"</string> <string name="hour" msgid="7796325297097314653">"ordu"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index add623a593f9..4105e266b96d 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"اثر انگشت دیگری را امتحان کنید"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"خیلی روشن است"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"اثر انگشت را تنظیم کنید"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"هربار موقعیت انگشتتان را کمی تغییر دهید"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"اثر انگشت اصالتسنجی شد"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"اثر انگشتی ثبت نشده است."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"این دستگاه حسگر اثر انگشت ندارد."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"حسگر بهطور موقت غیرفعال است."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"امکان استفاده از حسگر اثر انگشت وجود ندارد. به ارائهدهنده خدمات تعمیر مراجعه کنید"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"انگشت <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استفاده از اثر انگشت"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استفاده از اثر انگشت یا قفل صفحه"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"نماد اثر انگشت"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"قفلگشایی با چهره"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"ثبت مجدد چهره"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"برای بهبود تشخیص، لطفاً چهرهتان را دوباره ثبت کنید"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"مشکل در «قفلگشایی با چهره»"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"برای حذف مدل چهرهتان ضربه بزنید، سپس چهرهتان را دوباره اضافه کنید"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"راهاندازی «قفلگشایی با چهره»"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"برای باز کردن قفل تلفن خود به آن نگاه کنید"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"راهاندازی روشهای بیشتر برای باز کردن قفل"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"برای افزودن اثر انگشت، ضربه بزنید"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"قفلگشایی با اثر انگشت"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"امکان استفاده از حسگر اثر انگشت وجود ندارد"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"به ارائهدهنده خدمات تعمیر مراجعه کنید."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"دادههای دقیق چهره ضبط نشد. دوباره امتحان کنید."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"خیلی روشن است. روشناییاش را ملایمتر کنید."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"خیلی تاریک است. تصویر را روشنتر کنید."</string> @@ -908,12 +911,12 @@ <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"لطفاً به راهنمای کاربر مراجعه کرده یا با مرکز پشتیبانی از مشتریان تماس بگیرید."</string> <string name="lockscreen_sim_locked_message" msgid="3160196135801185938">"سیم کارت قفل شد."</string> <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"بازگشایی قفل سیم کارت…"</string> - <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string> + <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. \n\nپساز <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string> <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"گذرواژهٔ خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه تایپ کردهاید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string> <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"پین را<xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه تایپ کردهاید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string> - <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. بعد از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که برای بازگشایی قفل رایانهٔ لوحی خود به Google وارد شوید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string> - <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"<xliff:g id="NUMBER_0">%1$d</xliff:g> بار الگوی بازگشاییتان را اشتباه کشیدهاید. اگر <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر داشته باشید، از شما خواسته میشود با اطلاعات ورود به سیستم Google خود، قفل دستگاه Android TV را باز کنید.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دیگر دوباره امتحان کنید."</string> - <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"الگوی قفلگشایی را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر از شما خواسته میشود که برای بازگشایی قفل گوشی خود به برنامه Google وارد شوید.\n\n پس از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string> + <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. بعداز <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که برای بازگشایی قفل رایانهٔ لوحیتان به Google وارد شوید.\n\n لطفاً پساز <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string> + <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. اگر <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر داشته باشید، از شما خواسته میشود با اطلاعات ورود به سیستم Google خود، قفل دستگاه Android TV را باز کنید.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دیگر دوباره امتحان کنید."</string> + <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. پساز <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، از شما خواسته میشود که برای بازگشایی قفل گوشی به برنامه Google وارد شوید.\n\n پساز <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string> <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"شما به اشتباه <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اقدام به باز کردن قفل رایانهٔ لوحی کردهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، رایانهٔ لوحی به پیشفرض کارخانه بازنشانی میشود و تمام دادههای کاربر از دست خواهد رفت."</string> <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"<xliff:g id="NUMBER_0">%1$d</xliff:g> تلاش ناموفق برای باز کردن قفل Android TV خود داشتهاید. اگر <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر داشته باشید، دستگاه Android TV شما به تنظیمات پیشفرض کارخانه بازنشانی خواهد شد و همه دادههای کاربر ازدست خواهد رفت."</string> <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"شما به اشتباه <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اقدام به باز کردن قفل تلفن کردهاید. پس از<xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، تلفن به پیشفرض کارخانه بازنشانی میشود و تمام دادههای کاربر از دست خواهد رفت."</string> @@ -1021,7 +1024,7 @@ <string name="text_copied" msgid="2531420577879738860">"متن در بریدهدان کپی شد."</string> <string name="copied" msgid="4675902854553014676">"کپی شد"</string> <string name="pasted_from_app" msgid="5627698450808256545">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> از <xliff:g id="SOURCE_APP_NAME">%2$s</xliff:g> جایگذاری کرد"</string> - <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> از بریدهدان جایگذاری کرد"</string> + <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> از بریدهدان جایگذاری کرد"</string> <string name="pasted_text" msgid="4298871641549173733">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> نوشتاری را که کپی کردید جایگذاری کرد"</string> <string name="pasted_image" msgid="4729097394781491022">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> تصویری را که کپی کردید جایگذاری کرد"</string> <string name="pasted_content" msgid="646276353060777131">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> محتوایی را که کپی کردید جایگذاری کرد"</string> @@ -1671,16 +1674,16 @@ <string name="kg_login_checking_password" msgid="4676010303243317253">"درحال بررسی حساب..."</string> <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"پین خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه تایپ کردید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string> <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"گذرواژه خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه تایپ کردید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string> - <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدید. \n\nلطفاً پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string> + <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. \n\nلطفاً پساز <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string> <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"شما به اشتباه <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اقدام به باز کردن قفل رایانه لوحی کردهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، رایانهٔ لوحی به پیشفرض کارخانه بازنشانی میشود و تمام دادههای کاربر از دست خواهد رفت."</string> <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"<xliff:g id="NUMBER_0">%1$d</xliff:g> تلاش ناموفق برای باز کردن قفل Android TV خود داشتهاید. اگر <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر داشته باشید، دستگاه Android TV شما به تنظیمات پیشفرض کارخانه بازنشانی خواهد شد و همه دادههای کاربر ازدست خواهد رفت."</string> <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"شما به اشتباه <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اقدام به باز کردن قفل تلفن کردهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، تلفن به پیشفرض کارخانه بازنشانی میشود و تمام دادههای کاربر از دست خواهد رفت."</string> <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"شما به اشتباه <xliff:g id="NUMBER">%d</xliff:g> بار اقدام به باز کردن قفل رایانه لوحی کردهاید. رایانه لوحی اکنون به پیشفرض کارخانه بازنشانی میشود."</string> <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل Android TV خود داشتهاید. اکنون دستگاه Android TV شما به تنظیمات پیشفرض کارخانه بازنشانی میشود."</string> <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"شما به اشتباه <xliff:g id="NUMBER">%d</xliff:g> بار اقدام به باز کردن قفل تلفن کردهاید. این تلفن اکنون به پیشفرض کارخانه بازنشانی میشود."</string> - <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. بعد از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که با استفاده از یک حساب ایمیل قفل رایانه لوحی خود را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string> - <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"<xliff:g id="NUMBER_0">%1$d</xliff:g> بار الگوی بازگشاییتان را اشتباه کشیدهاید. اگر <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر داشته باشید، از شما خواسته میشود بااستفاده از حساب ایمیل خود، قفل دستگاه Android TV را باز کنید.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دیگر دوباره امتحان کنید."</string> - <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که با استفاده از یک حساب ایمیل قفل تلفن خود را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string> + <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. بعداز <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که بااستفاده از یک حساب ایمیل قفل رایانه لوحیتان را باز کنید.\n\n لطفاً پساز <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string> + <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. اگر <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر داشته باشید، از شما خواسته میشود بااستفاده از حساب ایمیلتان، قفل دستگاه Android TV را باز کنید.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دیگر دوباره امتحان کنید."</string> + <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. پساز <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که بااستفاده از یک حساب ایمیل قفل تلفنتان را باز کنید.\n\n لطفاً پساز <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string> <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string> <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"حذف"</string> <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"میزان صدا را به بالاتر از حد توصیه شده افزایش میدهید؟\n\nگوش دادن به صداهای بلند برای مدت طولانی میتواند به شنواییتان آسیب وارد کند."</string> @@ -1714,7 +1717,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"استفاده از میانبر"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"وارونگی رنگ"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"تصحیح رنگ"</string> - <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"حالت تکحرکت"</string> + <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"حالت یکدستی"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"بسیار کمنور"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> روشن شد."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> خاموش شد."</string> @@ -1864,7 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"کار دوم <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"کار سوم <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"درخواست کد پین قبل از برداشتن پین"</string> - <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"درخواست الگوی باز کردن قفل قبل از برداشتن سنجاق"</string> + <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"درخواست الگوی بازگشایی قفل قبلاز برداشتن سنجاق"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"درخواست گذرواژه قبل از برداشتن سنجاق"</string> <string name="package_installed_device_owner" msgid="7035926868974878525">"توسط سرپرست سیستم نصب شد"</string> <string name="package_updated_device_owner" msgid="7560272363805506941">"توسط سرپرست سیستم بهروزرسانی شد"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 5b4caa7b71fe..f5bc75b055a2 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Antaa sovelluksen laajentaa tai tiivistää tilarivin."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"näyttää ilmoituksia koko näytön tapahtumina lukitulla laitteella"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Sallii sovelluksen näyttää ilmoituksia koko näytön tapahtumina lukitulla laitteella"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"asentaa pikakuvakkeita"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Pikakuvakkeiden asentaminen"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Antaa sovelluksen lisätä aloitusruudun pikakuvakkeita ilman käyttäjän toimia."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"poista pikakuvakkeita"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Antaa sovelluksen poistaa aloitusruudun pikakuvakkeita ilman käyttäjän toimia."</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Kokeile toista sormenjälkeä"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Liian kirkas"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Kokeile muuttaa asentoa"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Liikuta sormeasi hieman joka kerralla"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Sormenjälki tunnistettu"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Sormenjälkiä ei ole otettu käyttöön."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Sormenjälkitunnistinta ei voi käyttää. Käy korjausliikkeessä"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Sormi <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Sormenjälkikuvake"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Kasvojentunnistusavaus"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Lisää kasvot uudelleen"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Lisää kasvosi uudelleen tunnistamisen parantamiseksi"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Face Unlockiin liittyvä ongelma"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Poista kasvomalli napauttamalla ja lisää sitten kasvosi uudelleen"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Ota kasvojentunnistusavaus käyttöön"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Avaa puhelimesi lukitus katsomalla laitetta"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Ota käyttöön lisää tapoja avata lukitus"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Napauta lisätäksesi sormenjälki"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Sormenjälkiavaus"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Sormenjälkitunnistinta ei voi käyttää"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Käy korjausliikkeessä."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Tarkan kasvodatan tallennus epäonnistui. Yritä uudelleen."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Liian kirkasta. Kokeile pehmeämpää valaistusta."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Liian pimeää. Kokeile kirkkaampaa valaistusta."</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 29c9698479fa..cbf8d690c370 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Essayez une autre empreinte digitale"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Trop lumineux"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Essayez de l\'ajuster"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Modifiez légèrement la position de votre doigt chaque fois"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Empreinte digitale authentifiée"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Aucune empreinte digitale enregistrée."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Impossible utiliser capteur empreinte digitale. Consultez un fournisseur de services de réparation"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icône d\'empreinte digitale"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Déverrouillage par reconnaissance faciale"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Inscrivez votre visage à nouveau"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Pour améliorer la reconnaissance, veuillez enregistrer à nouveau votre visage"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problème avec la fonctionnalité de déverrouillage par reconnaissance faciale"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Touchez pour supprimer votre modèle facial, puis ajoutez votre visage de nouveau"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Configurer le déverrouillage par reconnaissance faciale"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Déverrouillez votre téléphone en le regardant"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configurer d\'autres méthodes de déverrouillage"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Touchez pour ajouter une empreinte digitale"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Déverrouillage par empreinte digitale"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Impossible d\'utiliser le capteur d\'empreintes digitales"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Consultez un fournisseur de services de réparation."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Imposs. capt. données visage précises. Réessayez."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Trop lumineux. Essayez un éclairage plus faible."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Trop sombre. Essayez avec un éclairage plus fort."</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 23e599e1d948..69daf30ff2fa 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Essayez une autre empreinte"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Trop de lumière"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Essayez de repositionner le doigt"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Changez légèrement de position chaque fois"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Empreinte digitale authentifiée"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Aucune empreinte digitale enregistrée."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icône d\'empreinte digitale"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Déverrouillage par reconnaissance faciale"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Enregistrer à nouveau votre visage"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Pour améliorer la reconnaissance, veuillez enregistrer à nouveau votre visage"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problème lié au déverrouillage par reconnaissance faciale"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Appuyez pour supprimer votre empreinte faciale, puis ajoutez de nouveau votre visage"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Configurer le déverrouillage facial"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Déverrouillez votre téléphone en le regardant"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configurer d\'autres méthodes de déverrouillage"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Appuyez pour ajouter une empreinte digitale"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Capture du visage impossible. Réessayez."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Trop lumineux. Essayez de baisser la lumière."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Trop sombre. Essayez une éclairage plus lumineux."</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 70f703a34648..157f01f7cfda 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Proba con outra impresión dixital"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Hai demasiada luz"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Proba a axustar a impresión dixital"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Cambia lixeiramente a posición do dedo en cada intento"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Autenticouse a impresión dixital"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Non se rexistraron impresións dixitais."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Non se puido usar o sensor de impresión dixital. Visita un provedor de reparacións"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icona de impresión dixital"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Desbloqueo facial"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Volve inscribir a túa cara"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Para mellorar o recoñecemento, inscribe de novo a túa cara"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Produciuse un problema co desbloqueo facial"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Toca para eliminar o teu modelo facial e despois engade de novo a cara"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Configurar o desbloqueo facial"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Mira o teléfono para desbloquealo"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configura máis maneiras de desbloquear o dispositivo"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Toca para engadir unha impresión dixital"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Desbloqueo mediante impresión dixital"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Non se puido usar o sensor de impresión dixital"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visita un provedor de reparacións."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Sen datos faciais exactos. Téntao de novo."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Hai demasiada iluminación. Proba cunha máis suave."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Hai demasiada escuridade. Proba con máis luz."</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 4d27b1086f61..6dcb8ef5ed0d 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"ઍપ્લિકેશનને સ્ટેટસ બાર વિસ્તૃત કરવાની અને સંકુચિત કરવાની મંજૂરી આપે છે."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"લૉક કરેલા ડિવાઇસ પર પૂર્ણ સ્ક્રીન પરની પ્રવૃતિઓની જેમ નોટિફિકેશન બતાવો"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"ઍપને લૉક કરેલા ડિવાઇસ પર પૂર્ણ સ્ક્રીન પરની પ્રવૃતિઓની જેમ નોટિફિકેશન બતાવવાની મંજૂરી આપે છે"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"શોર્ટકટ્સ ઇન્સ્ટોલ કરો"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"શૉર્ટકટ ઇન્સ્ટૉલ કરો"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"એપ્લિકેશનને વપરાશકર્તા હસ્તક્ષેપ વગર હોમસ્ક્રીન શોર્ટકટ્સ ઉમેરવાની મંજૂરી આપે છે."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"શોર્ટકટ્સ અનઇન્સ્ટોલ કરો"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"એપ્લિકેશનને વપરાશકર્તા હસ્તક્ષેપ વગર હોમસ્ક્રીન શોર્ટકટ્સ દૂર કરવાની મંજૂરી આપે છે."</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"અન્ય ફિંગરપ્રિન્ટ અજમાવી જુઓ"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"અતિશય પ્રકાશિત"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ગોઠવણી કરી જુઓ"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"દરેક વખતે સ્કૅનર પર તમારી આંગળીની સ્થિતિ સહેજ બદલતા રહો"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ફિંગરપ્રિન્ટ પ્રમાણિત કરી"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"કોઈ ફિંગરપ્રિન્ટની નોંધણી કરવામાં આવી નથી."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"આ ડિવાઇસમાં કોઈ ફિંગરપ્રિન્ટ સેન્સર નથી."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"સેન્સર હંગામી રૂપે બંધ કર્યું છે."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"આંગળી <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string> @@ -612,12 +613,20 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ફિંગરપ્રિન્ટ આયકન"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ફેસ અનલૉક"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"તમારા ચહેરાની ફરી નોંધણી કરાવો"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"ઓળખવાની પ્રક્રિયાને બહેતર બનાવવા માટે કૃપા કરીને તમારા ચહેરાની ફરી નોંધણી કરાવો"</string> + <!-- no translation found for face_recalibrate_notification_title (2524791952735579082) --> + <skip /> + <!-- no translation found for face_recalibrate_notification_content (3064513770251355594) --> + <skip /> <string name="face_setup_notification_title" msgid="8843461561970741790">"ફેસ અનલૉક સુવિધાનું સેટઅપ કરો"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"તમારા ફોનની તરફ જોઈને તેને અનલૉક કરો"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"અનલૉક કરવાની બીજી રીતોનું સેટઅપ કરો"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ફિંગરપ્રિન્ટ ઉમેરવા માટે ટૅપ કરો"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"ચહેરાનો સચોટ ડેટા કૅપ્ચર ન થયો. ફરી પ્રયાસ કરો."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"અતિશય પ્રકાશિત. થોડો હળવો પ્રકાશ અજમાવી જુઓ."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"અતિશય ઘેરી. વધુ ઝળહળતો પ્રકાશ અજમાવો"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 74f4f4612d24..9a205dd2ab1c 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -309,7 +309,7 @@ <string name="permgroupdesc_location" msgid="1995955142118450685">"इस डिवाइस की जगह तक पहुंचने दें"</string> <string name="permgrouplab_calendar" msgid="6426860926123033230">"कैलेंडर"</string> <string name="permgroupdesc_calendar" msgid="6762751063361489379">"अपने कैलेंडर को ऐक्सेस करने"</string> - <string name="permgrouplab_sms" msgid="795737735126084874">"एसएमएस"</string> + <string name="permgrouplab_sms" msgid="795737735126084874">"मैसेज (एसएमएस)"</string> <string name="permgroupdesc_sms" msgid="5726462398070064542">"मैसेज (एसएमएस) भेजें और देखें"</string> <string name="permgrouplab_storage" msgid="1938416135375282333">"फ़ाइलें और मीडिया"</string> <string name="permgroupdesc_storage" msgid="6351503740613026600">"अपने डिवाइस पर मौजूद फ़ोटो, मीडिया और फ़ाइलें ऐक्सेस करने की"</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"किसी दूसरे फ़िंगरप्रिंट से कोशिश करें"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"बहुत रोशनी है"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"सेंसर पर सही तरीके से उंगली लगाने की कोशिश करें"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"फ़िंगरप्रिंट सेट अप करते समय, अपनी उंगली को हर बार थोड़ी अलग स्थिति में रखें"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"फ़िंगरप्रिंट की पुष्टि हो गई"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कोई फ़िंगरप्रिंट रजिस्टर नहीं किया गया है."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"इस डिवाइस में फ़िंगरप्रिंट सेंसर नहीं है."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"फ़िंगरप्रिंट <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फ़िंगरप्रिंट इस्तेमाल करें"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फ़िंगरप्रिंट आइकॉन"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"फ़ेस अनलॉक"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"अपना चेहरा फिर से दर्ज करें"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"कृपया अपना चेहरा फिर से दर्ज करें ताकि आपको बेहतर तरीके से पहचाना जा सके"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"फ़ेस अनलॉक के साथ कोई समस्या है"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"अपने चेहरे का मॉडल मिटाने के लिए टैप करें. इसके बाद, अपना चेहरा फिर से रजिस्टर करें"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"फे़स अनलॉक की सुविधा सेट अप करें"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"अपने फ़ोन की तरफ़ देखकर उसे अनलॉक करें"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"फ़ोन को अनलॉक करने के दूसरे तरीके सेट अप करें"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"फ़िंगरप्रिंट जोड़ने के लिए टैप करें"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"चेहरे से जुड़ा सटीक डेटा कैप्चर नहीं किया जा सका. फिर से कोशिश करें."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"बहुत रोशनी है. हल्की रोशनी आज़माएं."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"बहुत अंधेरा है. बेहतर रोशनी में आज़माएं."</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 13a7c450f6d3..06812bb02dc7 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -588,6 +588,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Isprobajte drugi otisak prsta"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Presvijetlo"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Pokušajte ga prilagoditi"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put lagano promijenite položaj prsta"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Autentificirano otiskom prsta"</string> @@ -604,8 +605,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije registriran nijedan otisak prsta."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Senzor otiska prsta ne može se koristiti. Posjetite davatelja usluga popravaka"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -615,12 +615,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona otiska prsta"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Otključavanje licem"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Ponovo registrirajte svoje lice"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Za poboljšanje prepoznavanja ponovo registrirajte svoje lice"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Poteškoće s otključavanjem licem"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Dodirnite da biste izbrisali model lica, a zatim ponovo dodajte svoje lice"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Postavite otključavanje licem"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Otključajte telefon gledajući u njega"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Postavite više načina otključavanja"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Dodirnite da biste dodali otisak prsta"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Otključavanje otiskom prsta"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Senzor otiska prsta ne može se koristiti"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Posjetite davatelja usluga popravaka."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Podaci o licu nisu točni. Pokušajte ponovo."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Presvijetlo je. Pokušajte sa slabijim svjetlom."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Pretamno je. Pokušajte s jačim osvjetljenjem."</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index a478e6763a41..1a4723c8612a 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Próbálkozzon másik ujjlenyomattal"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Túl világos"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Próbálja beállítani"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Módosítsa minden alkalommal kis mértékben ujja helyzetét."</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Ujjlenyomat hitelesítve"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nincsenek regisztrált ujjlenyomatok."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nem lehet használni az ujjlenyomat-érzékelőt. Keresse fel a szervizt."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. ujj"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ujjlenyomat ikon"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Arcalapú feloldás"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Rögzítsen újra képet az arcáról"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"A felismerés javítása érdekében rögzítsen újra az arcáról készített képet"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Arcalapú feloldással kapcsolatos problémák"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Koppintson arcmodellje törléséhez, majd készítsen újat"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Az Arcalapú feloldás beállítása"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Feloldhatja a zárolást úgy, hogy ránéz a telefonra"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"További feloldási módszerek beállítása"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Koppintson ide ujjlenyomat hozzáadásához"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Feloldás ujjlenyomattal"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Nem lehet használni az ujjlenyomat-érzékelőt"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Keresse fel a szervizt."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Sikertelen az arc pontos rögzítése. Próbálja újra."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Túl világos. Próbálja kevésbé erős világítással."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Túl sötét. Próbálja jobb megvilágítás mellett."</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index e42eccb58cb6..211050b84831 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Թույլ է տալիս ծրագրին ընդլայնել կամ հետ ծալել կարգավիճակի գոտին:"</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"ցուցադրել ծանուցումներ կողպված սարքի էկրանին լիաէկրան ռեժիմում"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Թույլ է տալիս հավելվածին ծանուցումներ ցուցադրել կողպված սարքի էկրանին լիաէկրան ռեժիմում"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"տեղադրել դյուրանցումներ"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Դյուրանցումների տեղադրում"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Հավելվածին թույլ է տալիս ավելացնել գլխավոր էկրանի դյուրանցումներ՝ առանց օգտագործողի միջամտության:"</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"ապատեղադրել դյուրանցումները"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Հավելվածին թույլ է տալիս հեռացնել գլխավոր էկրանի դյուրանցումները՝ առանց օգտագործողի միջամտության:"</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Փորձեք մեկ այլ մատնահետք"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Շատ լուսավոր է"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Փորձեք փոխել մատի դիրքը"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ամեն անգամ թեթևակի փոխեք մատի դիրքը"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Մատնահետքը նույնականացվեց"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Գրանցված մատնահետք չկա:"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Այս սարքը չունի մատնահետքերի սկաներ։"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Տվիչը ժամանակավորապես անջատված է:"</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Մատնահետքերի սկաները հնարավոր չէ օգտագործել։ Այցելեք սպասարկման կենտրոն։"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Մատնահետք <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Օգտագործել մատնահետք"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Օգտագործել մատնահետք կամ էկրանի կողպում"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Մատնահետքի պատկերակ"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Դեմքով ապակողպում"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Նորից գրանցեք ձեր դեմքը"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Ճանաչումը լավացնելու համար նորից գրանցեք ձեր դեմքը"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Դեմքով ապակողպման հետ կապված խնդիր"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Հպեք՝ ձեր դեմքի նմուշը ջնջելու համար, այնուհետև նորից ավելացրեք այն:"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Կարգավորեք դեմքով ապակողպումը"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Ապակողպելու համար պարզապես նայեք հեռախոսին"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Կարգավորեք ապակողպելու այլ եղանակներ"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Հպեք՝ մատնահետք ավելացնելու համար"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Մատնահետքով ապակողպում"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Մատնահետքերի սկաները հնարավոր չէ օգտագործել"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Այցելեք սպասարկման կենտրոն։"</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Չհաջողվեց գրանցել դեմքի ճշգրիտ տվյալները։ Կրկնեք։"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Շատ լուսավոր է։ Փորձեք ավելի թեթև լուսավորություն։"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Շատ մութ է։ Փորձեք ավելի պայծառ լուսավորություն։"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index f50c4707f02a..3429d8b323b8 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Coba sidik jari lain"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Terlalu terang"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Coba sesuaikan"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ubah sedikit posisi jari di setiap percobaan"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Sidik jari diautentikasi"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Tidak ada sidik jari yang terdaftar."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Tidak dapat menggunakan sensor sidik jari. Kunjungi penyedia reparasi"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon sidik jari"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Face Unlock"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Daftarkan kembali wajah Anda"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Untuk menyempurnakan pengenalan wajah, daftarkan kembali wajah Anda"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Masalah pada Face Unlock"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Ketuk untuk menghapus model wajah, lalu tambahkan wajah Anda lagi"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Siapkan Face Unlock"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Buka kunci ponsel dengan melihat ke ponsel"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Siapkan lebih banyak cara untuk membuka kunci"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Ketuk untuk menambahkan sidik jari"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Fingerprint Unlock"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Tidak dapat menggunakan sensor sidik jari"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Kunjungi penyedia reparasi."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Tidak bisa mengambil data wajah akurat. Coba lagi."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Terlalu terang. Coba cahaya yang lebih lembut."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Terlalu gelap. Coba pencahayaan yang lebih cerah."</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index bfc747668692..1f5559f2e43d 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prófaðu annað fingrafar"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Of bjart"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prófaðu að breyta stöðu fingursins"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Breyttu stöðu fingursins örlítið í hvert skipti"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingrafar staðfest"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Engin fingraför hafa verið skráð."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ekki er hægt að nota fingrafaralesara. Þú verður að fara með hann á verkstæði"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Fingur <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -611,13 +611,16 @@ <string-array name="fingerprint_error_vendor"> </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingrafaratákn"</string> - <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Andlitsopnun"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Skráðu andlitið þitt aftur"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Skráðu andlitið þitt til að bæta kennsl"</string> - <string name="face_setup_notification_title" msgid="8843461561970741790">"Setja upp andlitsopnun"</string> + <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Andlitskenni"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Vandamál varðandi andlitskenni"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Ýttu til að eyða andlitslíkaninu og skráðu svo andlitið aftur"</string> + <string name="face_setup_notification_title" msgid="8843461561970741790">"Setja upp andlitskenni"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Taktu símann úr lás með því að horfa á hann"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Settu upp fleiri leiðir til að taka úr lás"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Ýttu til að bæta við fingrafari"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Fingrafarskenni"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Ekki er hægt að nota fingrafaralesara"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Þú verður að fara á verkstæði."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Nákvæm andlitsgögn fengust ekki. Reyndu aftur."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Of bjart. Prófaðu mýkri lýsingu."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Of dimmt. Prófaðu sterkari lýsingu."</string> @@ -641,19 +644,19 @@ <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="5085202213036026288">"Andlit ekki staðfest. Vélbúnaður er ekki tiltækur."</string> - <string name="face_error_timeout" msgid="2598544068593889762">"Prófaðu andlitsopnun aftur."</string> + <string name="face_error_timeout" msgid="2598544068593889762">"Prófaðu andlitskenni aftur."</string> <string name="face_error_no_space" msgid="5649264057026021723">"Ekki er hægt að vista ný andlitsgögn. Eyddu gömlu fyrst."</string> <string name="face_error_canceled" msgid="2164434737103802131">"Hætt við andlitsgreiningu."</string> - <string name="face_error_user_canceled" msgid="5766472033202928373">"Notandi hætti við andlitsopnun."</string> + <string name="face_error_user_canceled" msgid="5766472033202928373">"Notandi hætti við andlitskenni."</string> <string name="face_error_lockout" msgid="7864408714994529437">"Of margar tilraunir. Reyndu aftur síðar."</string> - <string name="face_error_lockout_permanent" msgid="3277134834042995260">"Of margar tilraunir. Slökkt á andlitsopnun."</string> + <string name="face_error_lockout_permanent" msgid="3277134834042995260">"Of margar tilraunir. Slökkt á andlitskenni."</string> <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Of margar tilraunir. Sláðu inn skjálásinn í staðinn."</string> <string name="face_error_unable_to_process" msgid="5723292697366130070">"Ekki tókst að staðfesta andlit. Reyndu aftur."</string> - <string name="face_error_not_enrolled" msgid="1134739108536328412">"Þú hefur ekki sett upp andlitsopnun."</string> - <string name="face_error_hw_not_present" msgid="7940978724978763011">"Þetta tæki styður ekki andlitsopnun"</string> + <string name="face_error_not_enrolled" msgid="1134739108536328412">"Þú hefur ekki sett upp andlitskenni."</string> + <string name="face_error_hw_not_present" msgid="7940978724978763011">"Þetta tæki styður ekki andlitskenni"</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> - <string name="face_app_setting_name" msgid="5854024256907828015">"Nota andlitsopnun"</string> + <string name="face_app_setting_name" msgid="5854024256907828015">"Nota andlitskenni"</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="6620492813371195429">"Notaðu andlitið þitt til að halda áfram"</string> <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Notaðu andlitið eða skjálás til að halda áfram"</string> @@ -956,7 +959,7 @@ <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"Stækka opnunarsvæði."</string> <string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"Opnun með stroku."</string> <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"Opnun með mynstri."</string> - <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Andlitsopnun."</string> + <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Andlitskenni."</string> <string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"Opnun með PIN-númeri."</string> <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"Taka PIN-númer SIM-korts úr lás."</string> <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"Taka PUK-númer SIM-korts úr lás."</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 708841dafac8..798acc06a255 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prova con un\'altra impronta"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Troppa luce"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prova a regolare"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Cambia leggermente la posizione del dito ogni volta"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Impronta autenticata"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nessuna impronta digitale registrata."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Impossibile usare il sensore di impronte digitali. Contatta un fornitore di servizi di riparazione"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icona dell\'impronta"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Sblocco con il volto"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Registra di nuovo il volto"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Per migliorare il riconoscimento, registra di nuovo il tuo volto"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problema con Sblocco con il volto"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Tocca per eliminare il tuo modello del volto e poi riaggiungi il tuo volto"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Configura lo sblocco con il volto"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Sblocca il telefono guardandolo"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configura altri modi per sbloccare"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Tocca per aggiungere un\'impronta"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Sblocco con l\'impronta"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Impossibile utilizzare il sensore di impronte digitali"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Contatta un fornitore di servizi di riparazione."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Impossibile acquisire dati viso accurati. Riprova."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Troppa luce. Prova con una luce più soft."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Troppo buio. Prova con più luce."</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index fabffbf34abf..5aacfa719213 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -591,6 +591,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"יש להשתמש בטביעת אצבע אחרת"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"בהיר מדי"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"יש לנסות ולשנות את תנוחת האצבע"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"צריך לשנות מעט את תנוחת האצבע בכל פעם"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"טביעת האצבע אומתה"</string> @@ -607,7 +608,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"לא נסרקו טביעות אצבע."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"במכשיר הזה אין חיישן טביעות אצבע."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"החיישן מושבת באופן זמני."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"שימוש בטביעת אצבע"</string> @@ -618,12 +619,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"סמל טביעת אצבע"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"פתיחה ע\"י זיהוי הפנים"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"יש לבצע סריקה חוזרת של הפנים שלך"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"לשיפור הזיהוי יש לסרוק מחדש את הפנים שלך"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"בעיה בפתיחה ע\"י זיהוי הפנים"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"יש להקיש כדי למחוק את התבנית לזיהוי הפנים, ואז להוסיף תבנית חדשה לזיהוי הפנים"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"הגדרת התכונה \'פתיחה ע\"י זיהוי הפנים\'"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"יש להביט בטלפון כדי לבטל את נעילתו"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"אפשר להגדיר דרכים נוספות לביטול נעילה"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"יש להקיש כדי להוסיף טביעת אצבע"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"לא ניתן היה לקלוט את הפנים במדויק. יש לנסות שוב."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"בהירה מדי. צריך תאורה עדינה יותר."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"התמונה חשוכה מדי. צריך תאורה חזקה יותר."</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index e275df037597..609c5a9403c3 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -297,7 +297,7 @@ <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"ユーザー補助の使用"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」が電池を使用しています"</string> <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> 個のアプリが電池を使用しています"</string> - <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"タップして電池やデータの使用量を確認"</string> + <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"タップしてバッテリーやデータの使用量を確認"</string> <string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>、<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string> <string name="safeMode" msgid="8974401416068943888">"セーフモード"</string> <string name="android_system_label" msgid="5974767339591067210">"Android システム"</string> @@ -438,7 +438,7 @@ <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"位置情報提供者の追加コマンドアクセス"</string> <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"位置情報提供元の追加のコマンドにアクセスすることをアプリに許可します。許可すると、アプリがGPSなどの位置情報源の動作を妨害する恐れがあります。"</string> <string name="permlab_accessFineLocation" msgid="6426318438195622966">"フォアグラウンドでのみ正確な位置情報にアクセス"</string> - <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"このアプリは、使用中に、位置情報サービスからデバイスの正確な位置情報を取得できます。アプリが位置情報を取得するには、デバイスで位置情報サービスがオンになっている必要があります。この場合、電池使用量が増えることがあります。"</string> + <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"このアプリは、使用中に、位置情報サービスからデバイスの正確な位置情報を取得できます。アプリが位置情報を取得するには、デバイスで位置情報サービスがオンになっている必要があります。この場合、バッテリー使用量が増えることがあります。"</string> <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"フォアグラウンドでのみおおよその位置情報にアクセス"</string> <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"このアプリは、使用中に、位置情報サービスからデバイスのおおよその位置情報を取得できます。アプリが位置情報を取得するには、デバイスで位置情報サービスがオンになっている必要があります。"</string> <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"バックグラウンドでの位置情報へのアクセス"</string> @@ -517,9 +517,9 @@ <string name="permlab_changeWifiState" msgid="7947824109713181554">"Wi-Fiからの接続と切断"</string> <string name="permdesc_changeWifiState" msgid="7170350070554505384">"Wi-Fiアクセスポイントへの接続/切断、Wi-Fiネットワークのデバイス設定の変更をアプリに許可します。"</string> <string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"Wi-Fiマルチキャストの受信を許可する"</string> - <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"マルチキャストアドレスを使用して、このタブレットだけでなくWi-Fiネットワーク上のすべてのデバイスに送信されたパケットを受信することをアプリに許可します。マルチキャスト以外のモードよりも電池の消費量が大きくなります。"</string> - <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"マルチキャスト アドレスを使用して、この Android TV デバイスだけでなく Wi-Fi ネットワーク上のすべてのデバイスに送信されたパケットを受信することをアプリに許可します。マルチキャスト以外のモードよりも電池の消費量が大きくなります。"</string> - <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"マルチキャストアドレスを使用して、このモバイル デバイスだけでなくWi-Fiネットワーク上のすべてのデバイスに送信されたパケットを受信することをアプリに許可します。マルチキャスト以外のモードよりも電池の消費量が大きくなります。"</string> + <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"マルチキャスト アドレスを使用して、このタブレットだけでなく Wi-Fi ネットワーク上のすべてのデバイスに送信されたパケットを受信することをアプリに許可します。マルチキャスト以外のモードよりもバッテリーの消費量が大きくなります。"</string> + <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"マルチキャスト アドレスを使用して、この Android TV デバイスだけでなく Wi-Fi ネットワーク上のすべてのデバイスに送信されたパケットを受信することをアプリに許可します。マルチキャスト以外のモードよりもバッテリーの消費量が大きくなります。"</string> + <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"マルチキャスト アドレスを使用して、このモバイル デバイスだけでなく Wi-Fi ネットワーク上のすべてのデバイスに送信されたパケットを受信することをアプリに許可します。マルチキャスト以外のモードよりもバッテリーの消費量が大きくなります。"</string> <string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"Bluetoothの設定へのアクセス"</string> <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"ローカルのBluetoothタブレットを設定することと、リモートデバイスを検出してペアに設定することをアプリに許可します。"</string> <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Android TV デバイスで Bluetooth を設定することと、リモート デバイスを検出してペアに設定することをアプリに許可します。"</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"別の指紋をお試しください"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"明るすぎます"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"調整してみてください"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"毎回、指を置く位置を少し変えてください"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"指紋認証を完了しました"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"指紋が登録されていません。"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"このデバイスには指紋認証センサーがありません。"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"センサーが一時的に無効になっています。"</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"指紋認証センサーを使用できません。修理業者に調整を依頼してください"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"指紋 <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"指紋の使用"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"指紋または画面ロックの使用"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指紋アイコン"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"顔認証"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"顔の再登録"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"認識を改善するには、顔を再登録してください"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"顔認証に関する問題"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"タップして顔モデルを削除してから、改めて顔を追加してください"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"顔認証の設定"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"スマートフォンに顔を向けるとロックが解除されます"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"その他のロック解除方法の設定"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"タップすると指紋が追加されます"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"指紋認証"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"指紋認証センサーを使用できません"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"修理業者に調整を依頼してください。"</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"顔を認識できませんでした。もう一度お試しください。"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"明るすぎます。もっと暗い場所でお試しください。"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"暗すぎます。もっと明るい場所でお試しください。"</string> @@ -1870,8 +1873,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"管理者により更新されています"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"管理者により削除されています"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string> - <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"バッテリー セーバーを有効にすると、ダークテーマが ON になり、バックグラウンド アクティビティ、一部の視覚効果、特定の機能、一部のネットワーク接続が制限されるか OFF になります。"</string> - <string name="battery_saver_description" msgid="8518809702138617167">"バッテリー セーバーを有効にすると、ダークテーマが ON になり、バックグラウンド アクティビティ、一部の視覚効果、特定の機能、一部のネットワーク接続が制限されるか OFF になります。"</string> + <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"バッテリー セーバーを有効にすると、ダークモードが ON になり、バックグラウンド アクティビティ、一部の視覚効果、特定の機能、一部のネットワーク接続が制限されるか OFF になります。"</string> + <string name="battery_saver_description" msgid="8518809702138617167">"バッテリー セーバーを有効にすると、ダークモードが ON になり、バックグラウンド アクティビティ、一部の視覚効果、特定の機能、一部のネットワーク接続が制限されるか OFF になります。"</string> <string name="data_saver_description" msgid="4995164271550590517">"データセーバーは、一部のアプリによるバックグラウンドでのデータ送受信を停止することでデータ使用量を抑制します。使用中のアプリからデータを送受信することはできますが、その頻度は低くなる場合があります。この影響として、たとえば画像はタップしないと表示されないようになります。"</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"データセーバーを ON にしますか?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ON にする"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index bd85e614ce07..8a68fb923e87 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ცადეთ სხვა თითის ანაბეჭდი"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ზედმეტად ნათელია"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ცადეთ დარეგულირება"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ოდნავ შეცვალეთ თითის დაჭერის ადგილი ყოველ ჯერზე"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"თითის ანაბეჭდი ავტორიზებულია"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"თითის ანაბეჭდები რეგისტრირებული არ არის."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ამ მოწყობილობას არ აქვს თითის ანაბეჭდის სენსორი."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"სენსორი დროებით გათიშულია."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"გამოიყენეთ თითის ანაბეჭდი"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"თითის ანაბეჭდის ხატულა"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"განბლოკვა სახით"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"დაარეგისტრირეთ თქვენი სახე ხელახლა"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"ამოცნობის გასაუმჯობესებლად, გთხოვთ, ხელახლა დაარეგისტრიროთ თქვენი სახე"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"პრობლემა სახით განბლოკვასთან დაკავშირებით"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"შეეხეთ თქვენი სახის მოდელის წასაშლელად, შემდეგ დაამატეთ სახე ხელახლა"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"სახით განბლოკვის პარამეტრების დაყენება"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"განბლოკეთ თქვენი ტელეფონი შეხედვით"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"დააყენეთ განბლოკვის სხვა ხერხები"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"შეეხეთ თითის ანაბეჭდის დასამატებლად"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"სახის ზუსტი მონაცემები არ აღიბეჭდა. ცადეთ ხელახლა."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"მეტისმეტად ნათელია. ცადეთ უფრო სუსტი განათება."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"მეტისმეტად ბნელია. ცადეთ უფრო ძლიერი განათება."</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 16da28fc28d9..df6a2aafe4e3 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Қолданбаға статус жолағын жаюға емесе тасалауға рұқсат береді."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"құлыпталған құрылғыда хабарландыруларды толық экрандағы әрекеттер түрінде көрсету"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Қолданбаның құлыпталған құрылғыда хабарландыруларды толық экрандағы әрекеттер түрінде көрсетуіне рұқсат береді."</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"төте пернелерді орнату"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"таңбаша орнату"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Қолданбаға Негізгі экранның төте пернелерін пайдаланушының қатысуынсыз қосу мүмкіндігін береді."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"төте пернелерді алып тастау"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Қолданбаға Негізгі экранның төте пернелерін пайдаланушының қатысуынсыз алып тастау мүмкіндігін береді."</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Басқа саусақ ізін байқап көріңіз."</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Тым жарық."</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Дұрыстап қойып көріңіз."</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Саусағыңыздың қалпын аздап өзгертіп тұрыңыз."</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Саусақ ізі аутентификацияланды"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Саусақ іздері тіркелмеген."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бұл құрылғыда саусақ ізін оқу сканері жоқ."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик уақытша өшірулі."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-саусақ"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Саусақ ізін пайдалану"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Саусақ ізі белгішесі"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Бет тану"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Бетті қайта тіркеу"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Құрылғы жүзіңізді жақсырақ тануы үшін, бетіңізді қайта тіркеңіз."</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Face Unlock функциясына қатысты мәселе шықты"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Бет үлгісін жою үшін түртіңіз, содан соң жаңа бет үлгісін қосыңыз."</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Бет тану функциясын реттеу"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Телефоныңызға қарап, оның құлпын ашыңыз."</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Құлыпты ашудың басқа тәсілдерін реттеу"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Саусақ ізін қосу үшін түртіңіз."</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Бет деректері дұрыс алынбады. Әрекетті қайталаңыз."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Тым ашық. Күңгірттеу жарық керек."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Тым қараңғы. Молырақ жарық керек."</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index e72db139ae61..edbd547371ce 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"សាកល្បងប្រើស្នាមម្រាមដៃផ្សេងទៀត"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ភ្លឺពេក"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"សាកល្បងកែតម្រូវ"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ប្ដូរទីតាំងម្រាមដៃរបស់អ្នកតិចៗគ្រប់ពេល"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"បានផ្ទៀងផ្ទាត់ស្នាមម្រាមដៃ"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"មិនមានការចុះឈ្មោះស្នាមម្រាមដៃទេ។"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ឧបករណ៍នេះមិនមានឧបករណ៍ចាប់ស្នាមម្រាមដៃទេ។"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"បានបិទឧបករណ៍ចាប់សញ្ញាជាបណ្តោះអាសន្ន។"</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"មិនអាចប្រើឧបករណ៍ចាប់ស្នាមម្រាមដៃបានទេ។ សូមទាក់ទងក្រុមហ៊ុនផ្ដល់ការជួសជុល"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ម្រាមដៃ <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ប្រើស្នាមម្រាមដៃ"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ប្រើស្នាមម្រាមដៃ ឬការចាក់សោអេក្រង់"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"រូបស្នាមម្រាមដៃ"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ដោះសោតាមទម្រង់មុខ"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"ស្កេនបញ្ចូលមុខរបស់អ្នកម្ដងទៀត"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"ដើម្បីធ្វើឱ្យការសម្គាល់មុខប្រសើរជាងមុន សូមស្កេនបញ្ចូលមុខរបស់អ្នកម្ដងទៀត"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"មានបញ្ហាពាក់ព័ន្ធនឹងមុខងារដោះសោតាមទម្រង់មុខ"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"ចុចដើម្បីលុបគំរូមុខរបស់អ្នក រួចបញ្ចូលមុខរបស់អ្នកម្ដងទៀត"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"រៀបចំការដោះសោតាមទម្រង់មុខ"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"ដោះសោទូរសព្ទរបស់អ្នកដោយសម្លឹងមើលវា"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"រៀបចំវិធីច្រើនទៀតដើម្បីដោះសោ"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ចុចដើម្បីបញ្ចូលស្នាមម្រាមដៃ"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ការដោះសោដោយប្រើស្នាមម្រាមដៃ"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"មិនអាចប្រើឧបករណ៍ចាប់ស្នាមម្រាមដៃបានទេ"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ទាក់ទងក្រុមហ៊ុនផ្ដល់ការជួសជុល។"</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"មិនអាចថតទិន្នន័យទម្រង់មុខបានត្រឹមត្រូវទេ។ សូមព្យាយាមម្ដងទៀត។"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"ភ្លឺពេក។ សូមសាកល្បងប្រើពន្លឺស្រាលជាងនេះ។"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"ងងឹតជ្រុល។ សូមសាកល្បងប្រើពន្លឺភ្លឺជាងនេះ។"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 8858d0b8896d..17b550db04ed 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ಮತ್ತೊಂದು ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಪ್ರಯತ್ನಿಸಿ"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ತುಂಬಾ ಪ್ರಕಾಶಮಾನವಾಗಿದೆ"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ಹೊಂದಿಸಲು ಪ್ರಯತ್ನಿಸಿ"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ಪ್ರತಿ ಬಾರಿಯೂ ನಿಮ್ಮ ಬೆರಳಿನ ಸ್ಥಾನವನ್ನು ಸ್ವಲ್ಪ ಮಟ್ಟಿಗೆ ಬದಲಾಯಿಸಿ"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಅನ್ನು ಪ್ರಮಾಣೀಕರಣ ಮಾಡಲಾಗಿದೆ"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ಯಾವುದೇ ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಅನ್ನು ನೋಂದಣಿ ಮಾಡಿಲ್ಲ."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ಈ ಸಾಧನವು ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಹೊಂದಿಲ್ಲ."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ಸೆನ್ಸಾರ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"ಫಿಂಗರ್ <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಬಳಸಿ"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಐಕಾನ್"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ಫೇಸ್ ಅನ್ಲಾಕ್"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"ನಿಮ್ಮ ಮುಖವನ್ನು ಮರುನೋಂದಣಿ ಮಾಡಿ"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"ಗುರುತಿಸುವಿಕೆಯನ್ನು ಹೆಚ್ಚಿಸಲು ನಿಮ್ಮ ಮುಖವನ್ನು ಮರುನೋಂದಣಿ ಮಾಡಿ"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"ಫೇಸ್ ಅನ್ಲಾಕ್ ಕುರಿತು ಸಮಸ್ಯೆ ಇದೆ"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"ನಿಮ್ಮ ಫೇಸ್ ಮಾಡೆಲ್ ಅನ್ನು ಅಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ, ನಂತರ ನಿಮ್ಮ ಫೇಸ್ ಮಾಡೆಲ್ ಅನ್ನು ಪುನಃ ಸೇರಿಸಿ"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"ಫೇಸ್ ಅನ್ಲಾಕ್ ಅನ್ನು ಸೆಟಪ್ ಮಾಡಿ"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"ಫೋನ್ ಅನ್ನು ನೋಡುವ ಮೂಲಕ ಅನ್ಲಾಕ್ ಮಾಡಿ"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಹೆಚ್ಚಿನ ಮಾರ್ಗಗಳನ್ನು ಹೊಂದಿಸಿ"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಸೇರಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"ಸರಿಯಾಗಿ ಮುಖ ಕ್ಯಾಪ್ಚರ್ ಮಾಡಲಾಗಲಿಲ್ಲ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"ತುಂಬಾ ಪ್ರಕಾಶಮಾನವಾಗಿದೆ ಮಂದ ಪ್ರಕಾಶಮಾನವಿರುವ ಲೈಟ್ ಬಳಸಿ"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"ತುಂಬಾ ಕಪ್ಪು ಛಾಯೆಯಿದೆ. ಪ್ರಕಾಶಮಾನವಾದ ಲೈಟಿಂಗ್ ಬಳಸಿ."</string> @@ -1395,7 +1402,7 @@ <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ಭಾಷೆ ಮತ್ತು ವಿನ್ಯಾಸವನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> - <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"ಇತರ ಅಪ್ಲಿಕೇಶನ್ ಮೇಲೆ ಡಿಸ್ಪ್ಲೇ"</string> + <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"ಇತರ ಆ್ಯಪ್ಗಳ ಮೇಲೆ ಪ್ರದರ್ಶಿಸುವಿಕೆ"</string> <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> ಇತರೆ ಆ್ಯಪ್ಗಳ ಮೇಲೆ ಡಿಸ್ಪ್ಲೇ ಆಗುತ್ತದೆ"</string> <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> ಇತರೆ ಆ್ಯಪ್ಗಳ ಮೇಲೆ ಡಿಸ್ಪ್ಲೇ ಆಗುತ್ತದೆ"</string> <string name="alert_windows_notification_message" msgid="6538171456970725333">"<xliff:g id="NAME">%s</xliff:g> ಈ ವೈಶಿಷ್ಟ್ಯ ಬಳಸುವುದನ್ನು ನೀವು ಬಯಸದಿದ್ದರೆ, ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೆರೆಯಲು ಮತ್ತು ಅದನ್ನು ಆಫ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index e9d0fc5a3326..9df09b494099 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"다른 지문으로 시도"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"너무 밝음"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"조정 시도"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"지문을 등록할 때마다 손가락을 조금씩 이동하세요."</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"지문이 인증됨"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"등록된 지문이 없습니다."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"기기에 지문 센서가 없습니다."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"센서가 일시적으로 사용 중지되었습니다."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"지문 센서를 사용할 수 없습니다. 수리업체에 방문하세요."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"손가락 <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"지문 사용"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"지문 또는 화면 잠금 사용"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"지문 아이콘"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"얼굴 인식 잠금 해제"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"얼굴 재등록 필요"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"인식률을 개선하려면 얼굴을 다시 등록하세요."</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"얼굴 인식 잠금 해제 문제"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"탭하여 얼굴 모델을 삭제한 후 다시 얼굴을 추가하세요"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"얼굴 인식 잠금 해제 설정"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"휴대전화의 화면을 응시하여 잠금 해제할 수 있습니다."</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"다른 잠금 해제 방법 설정"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"지문을 추가하려면 탭하세요."</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"지문 잠금 해제"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"지문 센서를 사용할 수 없음"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"수리업체에 방문하세요."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"정확한 얼굴 데이터를 캡처하지 못했습니다. 다시 시도하세요."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"너무 밝습니다. 조명 밝기를 조금 낮춰보세요."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"너무 어둡습니다. 조명을 밝게 해 보세요."</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index c1961db3c757..820a79cbe4ef 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Колдонмого абал тилкесин жайып көрсөтүү же жыйнап коюу мүмкүнчүлүгүн берет."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"билдирмелерди кулпуланган түзмөктүн толук экранында көрсөтүү"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Колдонмого билдирмелерди кулпуланган түзмөктүн толук экранында көрсөтүүгө уруксат берет"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"тез чакырма орнотуу"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Ыкчам баскыч түзүү"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Колдонмого үй экранга колдонуучунун катышуусусуз тез чакырма кошууга мүмкүнчүлүк берет."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"тез чакыргычтарды жок кылуу"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Колдонмого колдонуучунун катышуусусуз үй экранынын тез чакырмаларын жок кылуу мүмкүнчүлүгүн берет."</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Башка манжа изин байкап көрүңүз"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Өтө жарык"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Тууралап көрүңүз"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Манжаңыздын абалын ар жолкусунда бир аз өзгөртүп туруңуз"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Манжа изи текшерилди"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Бир да манжа изи катталган эмес."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бул түзмөктө манжа изинин сенсору жок."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сенсор убактылуу өчүрүлгөн."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-манжа"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Манжа изин колдонуу"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Манжа изинин сүрөтчөсү"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Жүзүнөн таанып ачуу"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Жүзүңүздү кайра таанытыңыз."</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Мыкты таануу үчүн, жүзүңүздү кайра таанытыңыз"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Жүзүнөн таанып ачуу функциясында маселе келип чыкты"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Жүзүңүздүн үлгүсүн өчүрүү үчүн басып, жаңы үлгүнү кошуңуз"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Жүзүнөн таанып ачууну жөндөө"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Телефонуңузду карап туруп эле кулпусун ачып алыңыз"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Кулпусун ачуунун көбүрөөк жолдорун жөндөңүз"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Манжа изин кошуу үчүн басыңыз"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Жүзүңүз жакшы тартылган жок. Кайталап көрүңүз."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Өтө жарык. Жарыктыкты азайтып көрүңүз."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Өтө караңгы. Жарыгыраак жерден тартып көрүңүз."</string> @@ -1870,8 +1877,8 @@ <string name="package_updated_device_owner" msgid="7560272363805506941">"Администраторуңуз жаңыртып койгон"</string> <string name="package_deleted_device_owner" msgid="2292335928930293023">"Администраторуңуз жок кылып салган"</string> <string name="confirm_battery_saver" msgid="5247976246208245754">"ЖАРАЙТ"</string> - <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Батареяны үнөмдөгүч режиминде Караңгы тема күйгүзүлүп, фондогу аракеттер, айрым визуалдык эффекттер, белгилүү бир функциялар жана айрым тармакка туташуулар чектелип же өчүрүлөт."</string> - <string name="battery_saver_description" msgid="8518809702138617167">"Батареяны үнөмдөгүч режиминде Караңгы тема күйгүзүлүп, фондогу аракеттер, айрым визуалдык эффекттер, белгилүү бир функциялар жана айрым тармакка туташуулар чектелип же өчүрүлөт."</string> + <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Батареяны үнөмдөөчү режимде Караңгы тема күйгүзүлүп, фондогу аракеттер, айрым визуалдык эффекттер, белгилүү бир функциялар жана айрым тармакка туташуулар чектелип же өчүрүлөт."</string> + <string name="battery_saver_description" msgid="8518809702138617167">"Батареяны үнөмдөөчү режимде Караңгы тема күйгүзүлүп, фондогу аракеттер, айрым визуалдык эффекттер, белгилүү бир функциялар жана айрым тармакка туташуулар чектелип же өчүрүлөт."</string> <string name="data_saver_description" msgid="4995164271550590517">"Трафикти үнөмдөө режиминде айрым колдонмолор маалыматтарды фондо өткөрө алышпайт. Учурда сиз пайдаланып жаткан колдонмо маалыматтарды жөнөтүп/ала алат, бирок адаттагыдан азыраак өткөргөндүктөн, анын айрым функциялары талаптагыдай иштебей коюшу мүмкүн. Мисалы, сүрөттөр басылмайынча жүктөлбөйт."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"Трафикти үнөмдөө режимин иштетесизби?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"Күйгүзүү"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 65643c35bd8f..982845c60f46 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ລອງໃຊ້ລາຍນິ້ວມືອື່ນ"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ແຈ້ງເກີນໄປ"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ກະລຸນາລອງປັບແກ້"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ປ່ຽນຕຳແໜ່ງຂອງນິ້ວມືຂອງທ່ານເລັກນ້ອຍໃນແຕ່ລະເທື່ອ"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ພິສູດຢືນຢັນລາຍນິ້ວມືແລ້ວ"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ບໍ່ມີການລົງທະບຽນລາຍນິ້ວມື."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ອຸປະກອນນີ້ບໍ່ມີເຊັນເຊີລາຍນິ້ວມື."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ປິດການເຮັດວຽກຂອງເຊັນເຊີໄວ້ຊົ່ວຄາວແລ້ວ."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ບໍ່ສາມາດໃຊ້ເຊັນເຊີລາຍນິ້ວມືໄດ້. ກະລຸນາໄປຫາຜູ້ໃຫ້ບໍລິການສ້ອມແປງ"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ນີ້ວມື <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ໃຊ້ລາຍນິ້ວມື"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ໃຊ້ລາຍນິ້ວມື ຫຼື ການລັອກໜ້າຈໍ"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ໄອຄອນລາຍນິ້ວມື"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ປົດລັອກດ້ວຍໜ້າ"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"ລົງທະບຽນໃບໜ້າຂອງທ່ານຄືນໃໝ່"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"ເພື່ອປັບປຸງການຈຳແນກ, ກະລຸນາລົງທະບຽນໃບໜ້າຂອງທ່ານຄືນໃໝ່."</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"ເກີດບັນຫາກັບການປົດລັອກດ້ວຍໜ້າ"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"ແຕະເພື່ອລຶບຮູບແບບໃບໜ້າຂອງທ່ານ, ຈາກນັ້ນເພີ່ມໃບໜ້າຂອງທ່ານໃສ່ໃໝ່"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"ຕັ້ງຄ່າການປົດລັອກດ້ວຍໜ້າ"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"ປົດລັອກໂທລະສັບຂອງທ່ານໂດຍການເບິ່ງມັນ"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ຕັ້ງຄ່າວິທີເພີ່ມເຕີມເພື່ອປົດລັອກ"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ແຕະເພື່ອເພີ່ມລາຍນິ້ວມື"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ປົດລັອກດ້ວຍລາຍນິ້ວມື"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"ບໍ່ສາມາດໃຊ້ເຊັນເຊີລາຍນິ້ວມືໄດ້"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ກະລຸນາໄປຫາຜູ້ໃຫ້ບໍລິການສ້ອມແປງ."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"ບໍ່ສາມາດບັນທຶກຂໍ້ມູນໃບໜ້າທີ່ຖືກຕ້ອງໄດ້. ກະລຸນາລອງໃໝ່."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"ແຈ້ງເກີນໄປ. ລອງຄ່ອຍແສງໄຟລົງ."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"ມືດເກີນ. ກະລຸນາລອງໃຊ້ສະພາບແສງທີ່ແຈ້ງຂຶ້ນ."</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 9849124541bd..c76c8119f1a3 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -591,6 +591,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Pabandykite kitą kontrolinį kodą"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Per šviesu"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Pabandykite koreguoti"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Kaskart šiek tiek pakeiskite piršto poziciją"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Piršto antspaudas autentifikuotas"</string> @@ -607,8 +608,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Neužregistruota jokių kontrolinių kodų."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Negalima naudoti kontrolinio kodo jutiklio. Apsilankykite pas taisymo paslaugos teikėją"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> pirštas"</string> <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> @@ -618,12 +618,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Piršto antspaudo piktograma"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Atrakinimas pagal veidą"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Pakartotinis veido registravimas"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Kad patobulintumėte atpažinimą, iš naujo užregistruokite veidą"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Su atrakinimu pagal veidą susijusi problema"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Palieskite, kad ištrintumėte veido modelį, tada iš naujo pridėkite veidą"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Atrakinimo pagal veidą nustatymas"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Atrakinkite telefoną pažiūrėję į jį"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Daugiau atrakinimo metodų nustatymas"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Palieskite, kad pridėtumėte kontrolinį kodą"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Atrakinimas kontroliniu kodu"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Negalima naudoti kontrolinio kodo jutiklio"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Apsilankykite pas taisymo paslaugos teikėją."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Neužfiks. tikslūs veido duom. Bandykite dar kartą."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Per šviesu. Išbandykite mažesnį apšvietimą."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Per tamsu. Išbandykite šviesesnį apšvietimą."</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 8407622b0614..c787e508702a 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -588,6 +588,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Izmēģiniet citu pirksta nospiedumu"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Pārāk spilgts"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Mēģiniet mainīt pozīciju"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Katru reizi mazliet mainiet pirksta pozīciju."</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Pirksta nospiedums tika autentificēts."</string> @@ -604,8 +605,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nav reģistrēts neviens pirksta nospiedums."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nevar izmantot pirksta nospieduma sensoru. Sazinieties ar remonta pakalpojumu sniedzēju."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. pirksts"</string> <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> @@ -615,12 +615,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Pirksta nospieduma ikona"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Autorizācija pēc sejas"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Atkārtoti reģistrējiet seju"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Lai uzlabotu atpazīšanu, lūdzu, atkārtoti reģistrējiet savu seju"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problēma ar autorizāciju pēc sejas"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Pieskarieties, lai izdzēstu sejas modeli, un pēc tam vēlreiz pievienojiet seju"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Autorizācijas pēc sejas iestatīšana"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Atbloķējiet tālruni, skatoties uz to"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Citi atbloķēšanas veidi"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Pieskarieties, lai pievienotu pirksta nospiedumu"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Autorizācija ar pirksta nospiedumu"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Nevar izmantot pirksta nospieduma sensoru"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Sazinieties ar remonta pakalpojumu sniedzēju."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Neizdevās tvert sejas datus. Mēģiniet vēlreiz."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Pārāk spilgts. Izmēģiniet maigāku apgaismojumu."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Pārāk tumšs. Izmēģiniet spožāku apgaismojumu."</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 42a55c20a190..fbda7b435e0d 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Пробајте со друг отпечаток"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Премногу светло"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Пробајте да го приспособите прстот"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Менувајте ја положбата на прстот по малку секој пат"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечатокот е проверен"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Не се запишани отпечатоци."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Уредов нема сензор за отпечатоци."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорот е привремено оневозможен."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не може да се користи сензорот за отпечатоци. Однесете го на поправка"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користи отпечаток"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користи отпечаток или заклучување екран"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Икона за отпечатоци"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Отклучување со лик"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Повторно регистрирајте го ликот"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"За да се подобри препознавањето, повторно регистрирајте го ликот"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Проблем со „Отклучување со лик“"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Допрете за да го избришете вашиот модел на лице, а потоа повторно додајте го лицето"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Поставете „Отклучување со лик“"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Отклучете го телефонот со гледање во него"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Поставете уште начини за отклучување"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Допрете за да додадете отпечаток"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Отклучување со отпечаток"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Не може да се користи сензорот за отпечатоци"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Однесете го на поправка."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Не се сними прецизна слика. Обидете се повторно."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Премногу светла. Пробајте со послабо осветлување."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Премногу темна. Пробајте со посилно осветлување."</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index f4a79e317e0c..2274cda930f0 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"നില ബാർ വിപുലീകരിക്കുന്നതിനോ ചുരുക്കുന്നതിനോ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"ലോക്ക് ചെയ്ത ഒരു ഉപകരണത്തിൽ പൂർണ്ണ സ്ക്രീൻ ആക്റ്റിവിറ്റികളായി അറിയിപ്പുകൾ പ്രദർശിപ്പിക്കുക"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"ലോക്ക് ചെയ്ത ഒരു ഉപകരണത്തിൽ പൂർണ്ണ സ്ക്രീൻ ആക്റ്റിവിറ്റികളായി അറിയിപ്പുകൾ പ്രദർശിപ്പിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"കുറുക്കുവഴികൾ ഇൻസ്റ്റാളുചെയ്യുക"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"കുറുക്കുവഴികൾ ഇൻസ്റ്റാൾ ചെയ്യുക"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"ഉപയോക്തൃ ഇടപെടലില്ലാതെ ഹോംസ്ക്രീൻ കുറുക്കുവഴികൾ ചേർക്കാൻ ഒരു അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"കുറുക്കുവഴികൾ അൺഇൻസ്റ്റാളുചെയ്യുക"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"ഉപയോക്തൃ ഇടപെടലില്ലാതെ ഹോംസ്ക്രീൻ കുറുക്കുവഴികൾ നീക്കംചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"മറ്റൊരു ഫിംഗർപ്രിന്റ് ഉപയോഗിച്ച് നോക്കുക"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"തെളിച്ചം വളരെയധികമാണ്"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"അൽപ്പം നീക്കി നോക്കൂ"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ഓരോ തവണയും നിങ്ങളുടെ വിരലിന്റെ സ്ഥാനം ചെറുതായി മാറ്റുക"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ഫിംഗർപ്രിന്റ് പരിശോധിച്ചുറപ്പിച്ചു"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"വിരലടയാളങ്ങൾ എൻറോൾ ചെയ്തിട്ടില്ല."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ഈ ഉപകരണത്തിൽ ഫിംഗർപ്രിന്റ് സെൻസറില്ല."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"സെൻസർ താൽക്കാലികമായി പ്രവർത്തനരഹിതമാക്കി."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"വിരലടയാള സെൻസർ ഉപയോഗിക്കാനാകുന്നില്ല. റിപ്പയർ കേന്ദ്രം സന്ദർശിക്കുക"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ഫിംഗർ <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ഫിംഗർപ്രിന്റ് അല്ലെങ്കിൽ സ്ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ഫിംഗർപ്രിന്റ് ഐക്കൺ"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ഫെയ്സ് അൺലോക്ക്"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"നിങ്ങളുടെ മുഖം വീണ്ടും എൻറോൾ ചെയ്യൂ"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"തിരിച്ചറിയൽ മെച്ചപ്പെടുത്താൻ, നിങ്ങളുടെ മുഖം ദയവായി വീണ്ടും എൻറോൾ ചെയ്യൂ"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"ഫെയ്സ് അൺലോക്കുമായി ബന്ധപ്പെട്ട പ്രശ്നം"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"നിങ്ങളുടെ മുഖ മോഡൽ ഇല്ലാതാക്കാൻ ടാപ്പ് ചെയ്യുക, തുടർന്ന് അത് വീണ്ടും ചേർക്കുക"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"ഫെയ്സ് അൺലോക്ക് സജ്ജീകരിക്കുക"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"ഫോണിലേക്ക് നോക്കി അത് അൺലോക്ക് ചെയ്യുക"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"അൺലോക്ക് ചെയ്യുന്നതിനുള്ള കൂടുതൽ വഴികൾ സജ്ജീകരിക്കുക"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ഫിംഗർപ്രിന്റ് ചേർക്കാൻ ടാപ്പ് ചെയ്യുക"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ഫിംഗർപ്രിന്റ് അൺലോക്ക്"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"വിരലടയാള സെൻസർ ഉപയോഗിക്കാനാകുന്നില്ല"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"റിപ്പയർ കേന്ദ്രം സന്ദർശിക്കുക."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"കൃത്യ മുഖ ഡാറ്റ എടുക്കാനായില്ല. വീണ്ടും ശ്രമിക്കൂ."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"വളരെയധികം തെളിച്ചം. സൗമ്യതയേറിയ പ്രകാശം ശ്രമിക്കൂ."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"വളരെ ഇരുണ്ടത്. തിളക്കമേറിയ ലൈറ്റിംഗ് പരീക്ഷിക്കുക."</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 7d0a64345db5..3936541a2cc6 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Өөр хурууны хээ туршина уу"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Хэт гэрэлтэй байна"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Тохируулж үзнэ үү"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Хурууныхаа байрлалыг тухай бүрд бага зэрэг өөрчилнө үү"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Хурууны хээг нотолсон"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Бүртгүүлсэн хурууны хээ алга."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Энэ төхөөрөмжид хурууны хээ мэдрэгч алга."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Мэдрэгчийг түр хугацаанд идэвхгүй болгосон."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Хурууны хээ мэдрэгч ашиглах боломжгүй. Засварын үйлчилгээ үзүүлэгчид зочилно уу"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Хурууны хээ <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Хурууны хээ ашиглах"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Хурууны хээ эсвэл дэлгэцийн түгжээ ашиглах"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Хурууны хээний дүрс"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Царайгаар түгжээ тайлах"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Царайгаа дахин бүртгүүлнэ үү"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Танилтыг сайжруулахын тулд царайгаа дахин бүртгүүлнэ үү"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Царайгаар түгжээ тайлахтай холбоотой асуудал"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Нүүрний загвараа устгахын тулд товшоод, дараа нь царайгаа дахин нэмнэ үү"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Царайгаар түгжээ тайлахыг тохируулах"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Утас руугаа харж түгжээг нь тайлна уу"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Түгжээ тайлах илүү олон арга тохируулна уу"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Хурууны хээ нэмэхийн тулд товшино уу"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Хурууны хээгээр түгжээ тайлах"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Хурууны хээ мэдрэгч ашиглах боломжгүй"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Засварын үйлчилгээ үзүүлэгчид зочилно уу."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Царайн өгөгдлийг зөв авч чадсангүй. Дахин оролдоно уу."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Хэт цайвар байна. Гэрэл багатай газар оролдоно уу."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Хэт харанхуй байна. Гэрэлтэй орчинд туршина уу."</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 3933bf358d8f..1d2f96a02e9e 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -248,15 +248,15 @@ <string name="global_action_power_options" msgid="1185286119330160073">"पॉवर"</string> <string name="global_action_restart" msgid="4678451019561687074">"रीस्टार्ट करा"</string> <string name="global_action_emergency" msgid="1387617624177105088">"आणीबाणी"</string> - <string name="global_action_bug_report" msgid="5127867163044170003">"बग रीपोर्ट"</string> + <string name="global_action_bug_report" msgid="5127867163044170003">"बग रिपोर्ट"</string> <string name="global_action_logout" msgid="6093581310002476511">"सेशन समाप्त करा"</string> <string name="global_action_screenshot" msgid="2610053466156478564">"स्क्रीनशॉट"</string> <string name="bugreport_title" msgid="8549990811777373050">"बग रिपोर्ट"</string> - <string name="bugreport_message" msgid="5212529146119624326">"ई-मेल मेसेज म्हणून पाठविण्यासाठी, हे तुमच्या सद्य डिव्हाइस स्थितीविषयी माहिती संकलित करेल. बग रीपोर्ट सुरू करण्यापासून तो पाठविण्यापर्यंत थोडा वेळ लागेल; कृपया धीर धरा."</string> + <string name="bugreport_message" msgid="5212529146119624326">"ईमेल मेसेज म्हणून पाठविण्यासाठी, हे तुमच्या सध्याच्या डिव्हाइस स्थितीविषयी माहिती संकलित करेल. बग रिपोर्ट सुरू करण्यापासून तो पाठवण्यापर्यंत थोडा वेळ लागेल; कृपया धीर धरा."</string> <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"परस्परसंवादी अहवाल"</string> <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"बहुतांश प्रसंगांमध्ये याचा वापर करा. ते तुम्हाला अहवालाच्या प्रगतीचा मागोवा घेण्याची, समस्येविषयी आणखी तपाशील एंटर करण्याची आणि स्क्रीनशॉट घेण्याची अनुमती देते. ते कदाचित अहवाल देण्यासाठी बराच वेळ घेणारे कमी-वापरलेले विभाग वगळू शकते."</string> <string name="bugreport_option_full_title" msgid="7681035745950045690">"संपूर्ण अहवाल"</string> - <string name="bugreport_option_full_summary" msgid="1975130009258435885">"तुमचे डिव्हाइस प्रतिसाद देत नाही किंवा खूप धीमे असते किंवा तुम्हाला सर्व अहवाल विभागांची आवश्यकता असते तेव्हा कमीतकमी सिस्टम हस्तक्षेपासाठी या पर्यायाचा वापर करा. तुम्हाला आणखी तपशील एंटर करण्याची किंवा अतिरिक्त स्क्रीनशॉट घेण्याची अनुमती देत नाही."</string> + <string name="bugreport_option_full_summary" msgid="1975130009258435885">"तुमचे डिव्हाइस प्रतिसाद देत नाही किंवा खूप धीमे असते अथवा तुम्हाला सर्व अहवाल विभागांची आवश्यकता असते तेव्हा कमीतकमी सिस्टम हस्तक्षेपासाठी या पर्यायाचा वापर करा. तुम्हाला आणखी तपशील एंटर करण्याची किंवा अतिरिक्त स्क्रीनशॉट घेण्याची अनुमती देत नाही."</string> <plurals name="bugreport_countdown" formatted="false" msgid="3906120379260059206"> <item quantity="other">दोष अहवालासाठी <xliff:g id="NUMBER_1">%d</xliff:g> सेकंदांमध्ये स्क्रीनशॉट घेत आहे.</item> <item quantity="one">दोष अहवालासाठी <xliff:g id="NUMBER_0">%d</xliff:g> सेकंदामध्ये स्क्रीनशॉट घेत आहे.</item> @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"स्टेटस बार विस्तृत करण्यासाठी किंवा संक्षिप्त करण्यासाठी अॅप ला अनुमती देते."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"लॉक केलेल्या डिव्हाइसवर फुल स्क्रीन अॅक्टिव्हिटी म्हणून सूचना प्रदर्शित करणे"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"लॉक केलेल्या डिव्हाइसवर फुल स्क्रीन अॅक्टिव्हिटी म्हणून सूचना प्रदर्शित करण्यासाठी ॲपला अनुमती द्या"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"शॉर्टकट स्थापित करा"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"शॉर्टकट इंस्टॉल करा"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"अनुप्रयोगाला वापरकर्ता हस्तक्षेपाशिवाय मुख्यस्क्रीन शॉर्टकट जोडण्याची अनुमती देते."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"शॉर्टकट विस्थापित करा"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"अनुप्रयोगाला वापरकर्ता हस्तक्षेपाशिवाय मुख्यस्क्रीन शॉर्टकट काढण्याची अनुमती देते."</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"दुसरी फिंगरप्रिंट वापरून पाहा"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"खूप प्रखर"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"अॅडजस्ट करण्याचा प्रयत्न करा"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"तुमच्या बोटाची स्थिती प्रत्येक वेळी थोडीशी बदला"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"फिंगरप्रिंट ऑथेंटिकेट केली आहे"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कोणत्याही फिंगरप्रिंटची नोंद झाली नाही"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"या डिव्हाइसमध्ये फिंगरप्रिंट सेन्सर नाही."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेन्सर तात्पुरता बंद केला आहे."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"फिंगरप्रिंट सेन्सर वापरू शकत नाही. दुरुस्तीच्या सेवा पुरवठादाराला भेट द्या"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> बोट"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिंट वापरा"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फिंगरप्रिंट किंवा स्क्रीन लॉक वापरा"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फिंगरप्रिंट आयकन"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"फेस अनलॉक"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"तुमच्या चेहऱ्याची पुन्हा नोंदणी करा"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"ओळखण्यामध्ये सुधारणा करण्यासाठी, कृपया तुमच्या चेहऱ्याची पुन्हा नोंदणी करा"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"फेस अनलॉकसंबंधित समस्या"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"फेस मॉडेल हटवण्यासाठी टॅप करा, त्यानंतर तुमचा चेहरा पुन्हा जोडा"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"फेस अनलॉक सेट करा"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"तुमच्या फोनकडे पाहून तो अनलॉक करा"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"अनलॉक करण्याच्या आणखी पद्धती सेट करा"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"फिंगरप्रिंट जोडण्यासाठी टॅप करा"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"फिंगरप्रिंट अनलॉक"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"फिंगरप्रिंट सेन्सर वापरू शकत नाही"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"दुरुस्तीच्या सेवा पुरवठादाराला भेट द्या."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"अचूक फेस डेटा कॅप्चर करता आला नाही. पुन्हा करा."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"खूप प्रखर. आणखी सौम्य प्रकाश वापरून पहा."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"खूप गडद. आणखी प्रखर प्रकाश वापरून पहा."</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 2ad6baf06138..095c3d320d59 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Cuba cap jari lain"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Terlalu terang"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Cuba selaraskan"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Tukar sedikit kedudukan jari anda setiap kali pergerakan dilakukan"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Cap jari disahkan"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Tiada cap jari didaftarkan."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Tidak boleh menggunakan penderia cap jari. Lawati penyedia pembaikan"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon cap jari"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Buka Kunci Wajah"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Daftarkan semula wajah anda"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Untuk meningkatkan pengecaman, sila daftarkan semula wajah anda"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Isu dengan Buka Kunci Wajah"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Ketik untuk memadamkan model wajah anda, kemudian tambahkan wajah anda semula"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Sediakan Buka Kunci Wajah"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Buka kunci telefon anda dengan melihat telefon anda"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Sediakan lebih banyak cara untuk membuka kunci"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Ketik untuk menambahkan cap jari"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Buka Kunci Cap Jari"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Tidak boleh menggunakan penderia cap jari"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Lawati penyedia pembaikan."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Gagal menangkap data wajah dgn tepat. Cuba lagi."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Terlalu terang. Cuba pencahayaan yang lebih lembut."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Terlalu gelap. Cuba pencahayaan yang lebih cerah."</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 3543be0fb9e4..bcd4ace5bad8 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"အက်ပ်အား အခြေအနေပြ ဘားကို ချဲ့ခွင့် သို့မဟုတ် ခေါက်သိမ်းခွင့် ပြုသည်။"</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"လော့ခ်ချထားသော စက်ပစ္စည်းပေါ်တွင် အကြောင်းကြားချက်များကို ဖန်သားပြင်အပြည့် လုပ်ဆောင်ချက်များအဖြစ် ပြခြင်း"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"လော့ခ်ချထားသော စက်ပစ္စည်းပေါ်တွင် အကြောင်းကြားချက်များကို ဖန်သားပြင်အပြည့် လုပ်ဆောင်ချက်များအဖြစ် ပြရန် အက်ပ်ကို ခွင့်ပြုသည်"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"အတိုကောက်များအား ထည့်သွင်းခြင်း"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"ဖြတ်လမ်းလင့်ခ်များ ထည့်သွင်းခြင်း"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"အပလီကေးရှင်းအား အသုံးပြုသူ လုပ်ဆောင်ခြင်း မပါပဲ ပင်မ မြင်ကွင်းအား ပြောင်းလဲခွင့် ပေးခြင်း"</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"အတိုကောက်များ ဖယ်ထုတ်ခြင်း"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"အပလီကေးရှင်းအား အသုံးပြုသူ လုပ်ဆောင်ခြင်း မပါပဲ ပင်မ မြင်ကွင်းအား ဖယ်ရှားခွင့် ပေးခြင်း"</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"အခြားလက်ဗွေဖြင့် စမ်းကြည့်ပါ"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"အလွန် လင်းသည်"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ပြင်ဆင်ကြည့်ပါ"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"အကြိမ်တိုင်း သင့်လက်ချောင်း၏တည်နေရာကို အနည်းငယ်ပြောင်းပါ"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"လက်ဗွေကို အထောက်အထား စိစစ်ပြီးပါပြီ"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"မည်သည့် လက်ဗွေကိုမျှ ထည့်သွင်းမထားပါ။"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ဤစက်တွင် လက်ဗွေအာရုံခံကိရိယာ မရှိပါ။"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"အာရုံခံကိရိယာကို ယာယီပိတ်ထားသည်။"</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"လက်ဗွေ အာရုံခံကိရိယာကို အသုံးပြု၍ မရပါ။ ပြုပြင်ရေး ဝန်ဆောင်မှုပေးသူထံသို့ သွားပါ"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"လက်ချောင်း <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"လက်ဗွေ သုံးခြင်း"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"လက်ဗွေ (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"လက်ဗွေ သင်္ကေတ"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"မျက်နှာပြ လော့ခ်ဖွင့်ခြင်း"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"သင့်မျက်နှာကို စာရင်းပြန်သွင်းပါ"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"ပိုမှတ်မိစေရန် သင့်မျက်နှာကို စာရင်းပြန်သွင်းပါ"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"‘မျက်နှာပြ လော့ခ်ဖွင့်ခြင်း’ ဆိုင်ရာ ပြဿနာ"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"သင်၏မျက်နှာနမူနာကို ဖျက်ရန် တို့ပါ။ ထို့နောက် သင့်မျက်နှာကို ထပ်ထည့်ပါ"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"မျက်နှာပြ လော့ခ်ဖွင့်ခြင်းကို ထည့်သွင်းပါ"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"သင့်ဖုန်းကိုကြည့်၍ သော့ဖွင့်ပါ"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"သော့ဖွင့်ရန် နောက်ထပ်နည်းလမ်းများကို စနစ်ထည့်သွင်းပါ"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"လက်ဗွေထည့်ရန် တို့ပါ"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"လက်ဗွေသုံး လော့ခ်ဖွင့်ခြင်း"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"လက်ဗွေ အာရုံခံကိရိယာကို အသုံးပြု၍ မရပါ"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ပြုပြင်ရေး ဝန်ဆောင်မှုပေးသူထံသို့ သွားပါ။"</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"မျက်နှာဒေတာ အမှန် မရိုက်ယူနိုင်ပါ၊ ထပ်စမ်းကြည့်ပါ။"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"အလွန် လင်းသည်။ အလင်းလျှော့ကြည့်ပါ။"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"အလွန်မှောင်သည်။ ပိုလင်းအောင် လုပ်ကြည့်ပါ။"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 9ed34e026e80..c71b69023424 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prøv et annet fingeravtrykk"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"For lyst"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prøv å justere"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Endre posisjonen til fingeren litt hver gang"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeravtrykket er godkjent"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ingen fingeravtrykk er registrert."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Kan ikke bruke fingeravtrykkssensoren. Gå til en reparasjonsleverandør"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon for fingeravtrykk"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Ansiktslås"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Registrer ansiktet ditt på nytt"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"For å forbedre gjenkjennelse, registrer ansiktet ditt på nytt"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problem med ansiktslås"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Trykk for å slette ansiktsmodellen din, og legg deretter til ansiktet på nytt"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Konfigurer ansiktslås"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Lås opp telefonen ved å se på den"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Konfigurer flere måter å låse opp på"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Trykk for å legge til et fingeravtrykk"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Opplåsing med fingeravtrykk"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Kan ikke bruke fingeravtrykkssensoren"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Gå til en reparasjonsleverandør."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Kunne ikke ta opp nøyaktige ansiktsdata Prøv igjen"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"For lyst. Prøv svakere belysning."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"For mørkt. Prøv sterkere belysning."</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 25f59c27e077..929d032edc27 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"एपलाई स्थिति पट्टि विस्तार वा संकुचन गर्न अनुमति दिन्छ।"</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"लक गरिएको डिभाइसमा स्क्रिनभरि देखिने सूचनाहरू देखाइयोस्"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"यो अनुमति दिइएमा एपले लक गरिएको डिभाइसमा स्क्रिनभरि देखिने सूचनाहरू देखाउन सक्छ"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"सर्टकट स्थापना गर्नुहोस्"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"सर्टकट इन्स्टल गर्ने"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा एपलाई सर्टकटमा थप्नको लागि अनुमति दिन्छ।"</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"सर्टकटहरूको स्थापन रद्द गर्नुहोस्"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा एपलाई सर्टकटमा हटाउनको लागि अनुमति दिन्छ।"</string> @@ -438,9 +438,9 @@ <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"अधिक स्थान प्रदायक आदेशहरू पहुँच गर्नुहोस्"</string> <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"एपलाई अतिरिक्त स्थान प्रदायक आदेशहरू पहुँच गर्न अनुमति दिन्छ। यो एपलाई GPS वा अन्य स्थान स्रोतहरूको संचालन साथै हस्तक्षेप गर्न अनुमति दिन सक्छ।"</string> <string name="permlab_accessFineLocation" msgid="6426318438195622966">"अग्रभूमिमा मात्र सटीक स्थानमाथि पहुँच राख्नुहोस्"</string> - <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"यो एप चलाएका बेला यसले लोकेसनमा आधारित सेवाहरूबाट तपाईंको स्थानको सटीक जानकारी प्राप्त गर्न सक्छ। तपाईंको डिभाइसमा लोकेसनमा आधारित सेवाहरू सक्रिय गरिएको छ भने मात्र यो एपले स्थानको जानकारी प्राप्त गर्न सक्छ। यसले ब्याट्रीको उपयोग बढाउन सक्छ।"</string> + <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"यो एप चलाएका बेला यसले लोकेसन सर्भिसबाट तपाईंको स्थानको सटीक जानकारी प्राप्त गर्न सक्छ। तपाईंको डिभाइसमा लोकेसन सर्भिस सक्रिय गरिएको छ भने मात्र यो एपले स्थानको जानकारी प्राप्त गर्न सक्छ। यसले ब्याट्रीको उपयोग बढाउन सक्छ।"</string> <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"अग्रभागमा मात्र अनुमानित स्थानमाथि पहुँच राख्नुहोस्"</string> - <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"यो एप चलाएका बेला यसले लोकेसनमा आधारित सेवाहरूबाट तपाईंको स्थानको अनुमानित जानकारी प्राप्त गर्न सक्छ। तपाईंको डिभाइसमा लोकेसनमा आधारित सेवाहरू सक्रिय गरिएको छ भने मात्र यो एपले स्थानको जानकारी प्राप्त गर्न सक्छ।"</string> + <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"यो एप चलाएका बेला यसले लोकेसन सर्भिसबाट तपाईंको स्थानको अनुमानित जानकारी प्राप्त गर्न सक्छ। तपाईंको डिभाइसमा लोकेसन सर्भिस सक्रिय गरिएको छ भने मात्र यो एपले स्थानको जानकारी प्राप्त गर्न सक्छ।"</string> <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"पृष्ठभूमिमा स्थानसम्बन्धी पहुँच"</string> <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"यो एपले जुनसुकै बेला (एप नचलाएका बेलामा पनि) स्थानमाथि पहुँच राख्न सक्छ।"</string> <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"तपाईँका अडियो सेटिङहरू परिवर्तन गर्नुहोस्"</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"अर्को फिंगरप्रिन्ट प्रयोग गरी हेर्नुहोस्"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ज्यादै उज्यालो छ"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"सेन्सरमा सही तरिकाले औँला राखेर हेर्नुहोस्"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"हरेक पटक आफ्नो औँला थोरै यताउता सार्नुहोस्"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"फिंगरप्रिन्ट प्रमाणीकरण गरियो"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कुनै पनि फिंगरप्रिन्ट दर्ता गरिएको छैन।"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"यो डिभाइसमा कुनै पनि फिंगरप्रिन्ट सेन्सर छैन।"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"केही समयका लागि सेन्सर असक्षम पारियो।"</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"औंला <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string> @@ -612,12 +613,20 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फिंगरप्रिन्ट आइकन"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"फेस अनलक"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"आफ्नो अनुहार पुनः दर्ता गर्नुहोस्"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"अनुहार पहिचानको गुणस्तर सुधार गर्न कृपया आफ्नो अनुहार पुनः दर्ता गर्नुहोस्"</string> + <!-- no translation found for face_recalibrate_notification_title (2524791952735579082) --> + <skip /> + <!-- no translation found for face_recalibrate_notification_content (3064513770251355594) --> + <skip /> <string name="face_setup_notification_title" msgid="8843461561970741790">"फेस अनलक सेटअप गर्नुहोस्"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"फोनमा हेरेकै भरमा फोन अनलक गर्नुहोस्"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"अनलक गर्ने अन्य तरिकाहरू सेटअप गर्नुहोस्"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"फिंगरप्रिन्ट हाल्न ट्याप गर्नुहोस्"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"अनुहारको सटीक डेटा खिच्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"ज्यादै चम्किलो। अझ मधुरो प्रकाश प्रयोग गरी हेर्नु…"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"ज्यादै अँध्यारो छ। अझ बढी प्रकाशमा गई हेर्नुहोस्"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 307c125c41ca..74012129e2b4 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Probeer een andere vingerafdruk"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Te veel licht"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Verplaats je vinger"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Verander de positie van je vinger steeds een beetje"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Vingerafdruk geverifieerd"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Geen vingerafdrukken geregistreerd."</string> <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 staat tijdelijk uit."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Kan vingerafdruksensor niet gebruiken. Ga naar een reparateur."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Vingerafdruk-icoon"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Ontgrendelen via gezicht"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Je gezicht opnieuw registreren"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Registreer je gezicht opnieuw om de herkenning te verbeteren"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Probleem met Ontgrendelen via gezichtsherkenning"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Tik om je gezichtsmodel te verwijderen en voeg je gezicht opnieuw toe"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Ontgrendeling via gezichtsherkenning instellen"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Ontgrendel je telefoon door ernaar te kijken"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Stel meer manieren in om te ontgrendelen"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Tik om een vingerafdruk toe te voegen"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Ontgrendelen met vingerafdruk"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Kan vingerafdruksensor niet gebruiken"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Ga naar een reparateur."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Geen accurate gegevens. Probeer het nog eens."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Overbelicht. Probeer een minder felle belichting."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Te donker. Probeer een fellere verlichting."</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index 1e6eb37d0132..7885f672c8ed 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"ଷ୍ଟାଟସ୍ ବାର୍କୁ ବଡ଼ କିମ୍ବା ଛୋଟ କରିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"ଏକ ଲକ୍ ହୋଇଥିବା ଡିଭାଇସରେ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ୍ କାର୍ଯ୍ୟକଳାପ ଭାବେ ଦେଖାନ୍ତୁ"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"ଏକ ଲକ୍ ହୋଇଥିବା ଡିଭାଇସରେ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ୍ କାର୍ଯ୍ୟକଳାପ ଭାବେ ଦେଖାଇବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"ଶର୍ଟକଟ୍ ଇନଷ୍ଟଲ୍ କରନ୍ତୁ"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"ସର୍ଟକଟ୍ ଇନଷ୍ଟଲ୍ କରନ୍ତୁ"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"ୟୁଜର୍ଙ୍କ ବିନା ବାଧାରେ ହୋମ୍ସ୍କ୍ରୀନ୍ ସର୍ଟକଟ୍ ଯୋଡ଼ିବାକୁ ଏକ ଆପ୍ଲିକେଶନ୍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"ଶର୍ଟକଟ୍ ଅନଇନଷ୍ଟଲ୍ କରନ୍ତୁ"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"ୟୁଜର୍ଙ୍କ ବିନା ବାଧାରେ ହୋମ୍ସ୍କ୍ରୀନ୍ର ଶର୍ଟକଟ୍ ବାହାର କରିବା ପାଇଁ ଗୋଟିଏ ଆପ୍ଲିକେଶନ୍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ଅନ୍ୟ ଏକ ଟିପଚିହ୍ନ ବ୍ୟବହାର କରି ଦେଖନ୍ତୁ"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ବହୁତ ଉଜ୍ଜ୍ୱଳ"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ଆଡଜଷ୍ଟ କରି ଦେଖନ୍ତୁ"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ପ୍ରତି ଥର ଆପଣଙ୍କ ଆଙ୍ଗୁଠିର ସ୍ଥାନ ସାମାନ୍ୟ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ଟିପଚିହ୍ନ ପ୍ରମାଣିତ ହେଲା"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"କୌଣସି ଆଙ୍ଗୁଠି ଚିହ୍ନ ପଞ୍ଜୀକୃତ ହୋଇନାହିଁ।"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ଏହି ଡିଭାଇସ୍ରେ ଟିପଚିହ୍ନ ସେନ୍ସର୍ ନାହିଁ।"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ସେନ୍ସରକୁ ଅସ୍ଥାୟୀ ଭାବେ ଅକ୍ଷମ କରାଯାଇଛି।"</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"ଆଙ୍ଗୁଠି <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ଟିପଚିହ୍ନ ଆଇକନ୍"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ଫେସ୍ ଅନଲକ୍"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"ଆପଣଙ୍କର ମୁହଁ ପୁଣି-ଏନ୍ରୋଲ୍ କରନ୍ତୁ"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"ଚିହ୍ନଟକରଣକୁ ଉନ୍ନତ କରିବା ପାଇଁ, ଦୟାକରି ଆପଣଙ୍କର ମୁହଁ ପୁଣି-ଏନ୍ରୋଲ୍ କରନ୍ତୁ।"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"ଫେସ୍ ଅନଲକ୍ ସହ ସମସ୍ୟା"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"ଆପଣଙ୍କ ଫେସ୍ ମଡେଲକୁ ଡିଲିଟ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ, ତା\'ପରେ ପୁଣି ଆପଣଙ୍କ ଫେସ୍ ଯୋଗ କରନ୍ତୁ"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"ଫେସ୍ ଅନଲକ୍ ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"ଫୋନକୁ ଦେଖି ଏହାକୁ ଅନଲକ୍ କରନ୍ତୁ"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ଅନଲକ୍ କରିବା ପାଇଁ ଆହୁରି ଅଧିକ ଉପାୟ ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ଏକ ଟିପଚିହ୍ନ ଯୋଗ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"ମୁହଁର ଡାଟା କ୍ୟାପଚର୍ ହେଲାନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"ଅତ୍ୟଧିକ ଉଜ୍ଵଳ। କମ୍ ଉଜ୍ବଳକରଣରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"ଅତ୍ୟଧିକ ଅନ୍ଧକାର। ଉଜ୍ବଳ ଲାଇଟ୍ ବ୍ୟବହାର କରନ୍ତୁ।"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index fbccb257569e..f5f8a5548abc 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ਕੋਈ ਹੋਰ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤ ਕੇ ਦੇਖੋ"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਚਮਕ"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ਵਿਵਸਥਿਤ ਕਰਕੇ ਦੇਖੋ"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ਹਰ ਵਾਰ ਆਪਣੀ ਉਂਗਲ ਨੂੰ ਥੋੜ੍ਹਾ ਹਿਲਾਓ"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਪ੍ਰਮਾਣਿਤ ਹੋਇਆ"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ਕੋਈ ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਰਜ ਨਹੀਂ ਕੀਤੇ ਗਏ।"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨਹੀਂ ਹੈ।"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ਸੈਂਸਰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"ਉਂਗਲ <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string> @@ -612,12 +613,20 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਪ੍ਰਤੀਕ"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ਫ਼ੇਸ ਅਣਲਾਕ"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"ਆਪਣਾ ਚਿਹਰਾ ਮੁੜ-ਦਰਜ ਕਰੋ"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"ਪਛਾਣ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ ਚਿਹਰੇ ਨੂੰ ਮੁੜ-ਦਰਜ ਕਰੋ"</string> + <!-- no translation found for face_recalibrate_notification_title (2524791952735579082) --> + <skip /> + <!-- no translation found for face_recalibrate_notification_content (3064513770251355594) --> + <skip /> <string name="face_setup_notification_title" msgid="8843461561970741790">"ਫ਼ੇਸ ਅਣਲਾਕ ਦਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"ਆਪਣੇ ਫ਼ੋਨ ਵੱਲ ਦੇਖ ਕੇ ਇਸਨੂੰ ਅਣਲਾਕ ਕਰੋ"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ਅਣਲਾਕ ਕਰਨ ਦੇ ਹੋਰ ਤਰੀਕਿਆਂ ਦਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"ਸਟੀਕ ਚਿਹਰਾ ਡਾਟਾ ਕੈਪਚਰ ਨਹੀਂ ਹੋਇਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਚਮਕ। ਹਲਕੀ ਚਮਕ ਵਰਤ ਕੇ ਦੇਖੋ।"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"ਬਹੁਤ ਗੂੜ੍ਹਾ। ਤੇਜ਼ ਰੋਸ਼ਨੀ ਕਰਕੇ ਦੇਖੋ।"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 0671787fc470..8e0f2b4ceb97 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -355,7 +355,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Pozwala aplikacji na rozwijanie lub zwijanie paska stanu."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"wyświetlaj powiadomienia w trybie pełnoekranowym na zablokowanym urządzeniu"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Zezwala na wyświetlanie przez aplikacje powiadomień w trybie pełnoekranowym na zablokowanym urządzeniu"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalowanie skrótów"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instalowanie skrótów"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Pozwala aplikacji dodawać skróty na ekranie głównym bez interwencji użytkownika."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"odinstalowywanie skrótów"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Pozwala aplikacji usuwać skróty z ekranu głównego bez interwencji użytkownika."</string> @@ -591,6 +591,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Użyj odcisku innego palca"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Zbyt jasno"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Popraw"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Za każdym razem lekko zmieniaj ułożenie palca"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Uwierzytelniono odciskiem palca"</string> @@ -607,8 +608,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nie zarejestrowano odcisków palców."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Nie można użyć czytnika linii papilarnych. Odwiedź serwis."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Odcisk palca <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -618,12 +618,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona odcisku palca"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Rozpoznawanie twarzy"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Zarejestruj swoją twarz ponownie"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Aby poprawić rozpoznawanie, ponownie zarejestruj swoją twarz"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problem z rozpoznawaniem twarzy"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Kliknij, aby usunąć model twarzy, a następnie ponownie dodaj skan twarzy"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Skonfiguruj rozpoznawanie twarzy"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Popatrz na ekran telefonu, aby go odblokować"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Skonfiguruj więcej sposobów odblokowywania"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Kliknij, aby dodać odcisk palca"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Odblokowywanie odciskiem palca"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Nie można użyć czytnika linii papilarnych"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Odwiedź serwis."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Nie udało się zarejestrować danych twarzy. Spróbuj ponownie."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Zbyt jasno. Spróbuj przy słabszym świetle."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Zbyt ciemno. Spróbuj w jaśniejszym świetle."</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 8c6b146c408e..f0be5ec24e90 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -305,7 +305,7 @@ <string name="managed_profile_label" msgid="7316778766973512382">"Perfil de trabalho"</string> <string name="permgrouplab_contacts" msgid="4254143639307316920">"Contatos"</string> <string name="permgroupdesc_contacts" msgid="9163927941244182567">"acesse seus contatos"</string> - <string name="permgrouplab_location" msgid="1858277002233964394">"Local"</string> + <string name="permgrouplab_location" msgid="1858277002233964394">"Localização"</string> <string name="permgroupdesc_location" msgid="1995955142118450685">"acesse o local do dispositivo"</string> <string name="permgrouplab_calendar" msgid="6426860926123033230">"Agenda"</string> <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acesse sua agenda"</string> @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permite que o app expanda ou recolha a barra de status."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"exibir notificações como atividades em tela cheia em um dispositivo bloqueado"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permite que o app exiba notificações como atividades em tela cheia em um dispositivo bloqueado"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalar atalhos"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instalar atalhos"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permite que um app adicione atalhos da tela inicial sem a intervenção do usuário."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"desinstalar atalhos"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permite que o app remova atalhos da tela inicial sem a intervenção do usuário."</string> @@ -438,9 +438,9 @@ <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"acessar comandos extras do provedor de localização"</string> <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permite que o app acesse comandos do provedor não relacionados à localização. Isso pode permitir que o app interfira no funcionamento do GPS ou de outras fontes de localização."</string> <string name="permlab_accessFineLocation" msgid="6426318438195622966">"acessar localização precisa apenas em primeiro plano"</string> - <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Esse app poderá acessar seu local exato por meio dos Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local. Isso pode aumentar o uso da bateria."</string> + <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Esse app poderá acessar sua localização exata com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local. Isso pode aumentar o uso da bateria."</string> <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"acessar local aproximado apenas em primeiro plano"</string> - <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Esse app poderá acessar seu local aproximado por meio dos Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local."</string> + <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Esse app poderá acessar sua localização aproximada com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local."</string> <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"acessar a localização em segundo plano"</string> <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Esse app poderá acessar o local a qualquer momento, mesmo quando não estiver sendo usado."</string> <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"alterar as suas configurações de áudio"</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Use outra impressão digital"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Claro demais"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Ajuste a posição do dedo"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Mude a posição do dedo ligeiramente a cada momento"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Impressão digital autenticada"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registrada."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Não foi possível usar o sensor de impressão digital. Entre em contato com uma assistência técnica"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícone de impressão digital"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Desbloqueio facial"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Registre seu rosto novamente"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Para melhorar o reconhecimento, registre seu rosto novamente"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problema com o desbloqueio facial"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Toque para excluir seu modelo de rosto e crie um novo"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Configurar o desbloqueio facial"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Desbloqueie o smartphone olhando para ele"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configure mais formas de desbloquear a tela"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Toque para adicionar uma impressão digital"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Desbloqueio por impressão digital"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Não foi possível usar o sensor de impressão digital"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Entre em contato com uma assistência técnica."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Dados precisos não capturados. Tente novamente."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Muito iluminado. Diminua a iluminação."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Muito escuro. Use uma iluminação mais clara."</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 0fa0e50de0cb..d721932516a6 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Experimente outra impressão digital"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Está demasiado claro"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Experimente ajustar"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Altere a posição do seu dedo ligeiramente de cada vez"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"A impressão digital foi autenticada."</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registada."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Não é possível usar o sensor de impressões digitais. Visite um fornecedor de serviços de reparação"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícone de impressão digital"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Desbloqueio facial"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Volte a inscrever o seu rosto"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Para melhorar o reconhecimento, volte a inscrever o seu rosto."</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problema com o Desbloqueio facial"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Toque para eliminar o seu modelo de rosto e, em seguida, adicione o seu rosto novamente"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Configure o Desbloqueio facial"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Desbloqueie o telemóvel ao olhar para ele"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configure mais formas de desbloquear"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Toque para adicionar uma impressão digital"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Desbloqueio por impressão digital"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Não é possível utilizar o sensor de impressões digitais"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Visite um fornecedor de serviços de reparação."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Imp. capt. dados rosto precisos. Tente novamente."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Demasiado clara. Experimente uma luz mais suave."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Demasiado escura. Experimente local com mais luz."</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 8c6b146c408e..f0be5ec24e90 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -305,7 +305,7 @@ <string name="managed_profile_label" msgid="7316778766973512382">"Perfil de trabalho"</string> <string name="permgrouplab_contacts" msgid="4254143639307316920">"Contatos"</string> <string name="permgroupdesc_contacts" msgid="9163927941244182567">"acesse seus contatos"</string> - <string name="permgrouplab_location" msgid="1858277002233964394">"Local"</string> + <string name="permgrouplab_location" msgid="1858277002233964394">"Localização"</string> <string name="permgroupdesc_location" msgid="1995955142118450685">"acesse o local do dispositivo"</string> <string name="permgrouplab_calendar" msgid="6426860926123033230">"Agenda"</string> <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acesse sua agenda"</string> @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permite que o app expanda ou recolha a barra de status."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"exibir notificações como atividades em tela cheia em um dispositivo bloqueado"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permite que o app exiba notificações como atividades em tela cheia em um dispositivo bloqueado"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalar atalhos"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instalar atalhos"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permite que um app adicione atalhos da tela inicial sem a intervenção do usuário."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"desinstalar atalhos"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permite que o app remova atalhos da tela inicial sem a intervenção do usuário."</string> @@ -438,9 +438,9 @@ <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"acessar comandos extras do provedor de localização"</string> <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permite que o app acesse comandos do provedor não relacionados à localização. Isso pode permitir que o app interfira no funcionamento do GPS ou de outras fontes de localização."</string> <string name="permlab_accessFineLocation" msgid="6426318438195622966">"acessar localização precisa apenas em primeiro plano"</string> - <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Esse app poderá acessar seu local exato por meio dos Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local. Isso pode aumentar o uso da bateria."</string> + <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Esse app poderá acessar sua localização exata com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local. Isso pode aumentar o uso da bateria."</string> <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"acessar local aproximado apenas em primeiro plano"</string> - <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Esse app poderá acessar seu local aproximado por meio dos Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local."</string> + <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Esse app poderá acessar sua localização aproximada com os Serviços de localização enquanto estiver sendo usado. Os Serviços de localização do dispositivo precisam estar ativados para que o app possa acessar o local."</string> <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"acessar a localização em segundo plano"</string> <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Esse app poderá acessar o local a qualquer momento, mesmo quando não estiver sendo usado."</string> <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"alterar as suas configurações de áudio"</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Use outra impressão digital"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Claro demais"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Ajuste a posição do dedo"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Mude a posição do dedo ligeiramente a cada momento"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Impressão digital autenticada"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registrada."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Não foi possível usar o sensor de impressão digital. Entre em contato com uma assistência técnica"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícone de impressão digital"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Desbloqueio facial"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Registre seu rosto novamente"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Para melhorar o reconhecimento, registre seu rosto novamente"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problema com o desbloqueio facial"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Toque para excluir seu modelo de rosto e crie um novo"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Configurar o desbloqueio facial"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Desbloqueie o smartphone olhando para ele"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configure mais formas de desbloquear a tela"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Toque para adicionar uma impressão digital"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Desbloqueio por impressão digital"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Não foi possível usar o sensor de impressão digital"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Entre em contato com uma assistência técnica."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Dados precisos não capturados. Tente novamente."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Muito iluminado. Diminua a iluminação."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Muito escuro. Use uma iluminação mais clara."</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 7bbf3e1dd913..5a37821f8a2c 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -352,7 +352,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permite aplicației să extindă sau să restrângă bara de stare."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"să afișeze notificări ca activități pe ecran complet pe un dispozitiv blocat"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permite aplicației să afișeze notificări ca activități pe ecran complet pe un dispozitiv blocat"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalează comenzi rapide"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Instalarea de comenzi rapide"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permite unei aplicații să adauge comenzi rapide pe ecranul de pornire, fără intervenția utilizatorului."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"dezinstalează comenzi rapide"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permite aplicației să elimine comenzi rapide de pe ecranul de pornire, fără intervenția utilizatorului."</string> @@ -588,6 +588,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Încercați altă amprentă"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Prea luminos"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Încercați să ajustați"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Schimbați ușor poziția degetului de fiecare dată"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Amprentă autentificată"</string> @@ -604,7 +605,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nu au fost înregistrate amprente."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Folosiți amprenta"</string> @@ -615,12 +616,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Pictograma amprentă"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Deblocare facială"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Reînregistrați-vă chipul"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Pentru a îmbunătăți recunoașterea, reînregistrați-vă chipul"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problemă cu Deblocarea facială"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Atingeți pentru a șterge modelul facial, apoi adăugați din nou fața"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Configurați Deblocarea facială"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Deblocați-vă telefonul uitându-vă la acesta"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Configurați mai multe moduri de deblocare"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Atingeți ca să adăugați o amprentă"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Nu s-a putut fotografia fața cu precizie. Încercați din nou."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Prea luminos. Încercați o lumină mai slabă."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Prea întunecat. Încercați o lumină mai puternică."</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index ebe46e8124e5..6820452f85a8 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -591,6 +591,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Попробуйте сохранить отпечаток другого пальца."</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Слишком светло."</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Попробуйте изменить положение пальца."</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Каждый раз немного меняйте положение пальца."</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечаток пальца проверен"</string> @@ -607,8 +608,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Нет отсканированных отпечатков пальцев"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На этом устройстве нет сканера отпечатков пальцев."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сканер отпечатков пальцев временно отключен."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Невозможно использовать сканер отпечатков пальцев. Обратитесь в сервисный центр."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Отпечаток <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Использовать отпечаток пальца"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Использовать отпечаток пальца или блокировку экрана"</string> @@ -618,12 +618,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Значок отпечатка пальца"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Фейсконтроль"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Зарегистрируйте лицо ещё раз"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Чтобы улучшить распознавание лица, зарегистрируйте его ещё раз"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Ошибка фейсконтроля"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Нажмите, чтобы удалить модель лица, а затем добавьте ее снова."</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Настройка фейсконтроля"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Вы сможете разблокировать телефон, просто посмотрев на него."</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Настройте другие способы разблокировки"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Нажмите, чтобы добавить отпечаток пальца."</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Разблокировка по отпечатку пальца"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Невозможно использовать сканер отпечатков пальцев"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Обратитесь в сервисный центр."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Не удалось собрать данные. Повторите попытку."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Слишком светло. Сделайте освещение менее ярким."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Слишком темно. Сделайте освещение ярче."</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index eea259472033..d17dd4463729 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"තවත් ඇඟිලි සලකුණක් උත්සාහ කරන්න"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"දීප්තිය වැඩියි"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"සීරුමාරු කිරීම උත්සාහ කරන්න"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"එක් එක් අවස්ථාවේ ඔබගේ ඇඟිල්ලේ පිහිටීම මදක් වෙනස් කරන්න"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ඇඟිලි සලකුණ සත්යාපනය කරන ලදී"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ඇඟිලි සලකුණු ඇතුළත් කර නොමැත."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"මෙම උපාංගයේ ඇඟිලි සලකුණු සංවේදකයක් නොමැත."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"සංවේදකය තාවකාලිකව අබල කර ඇත."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"ඇඟිලි සලකුණු සංවේදකය භාවිත කළ නොහැකිය. අළුත්වැඩියා සැපයුම්කරුවෙකු බලන්න"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"ඇඟිලි <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ඇඟිලි සලකුණ භාවිත කරන්න"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ඇඟිලි සලකුණ හෝ තිර අගුල භාවිත කරන්න"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ඇඟිලි සලකුණු නිරූපකය"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"මුහුණෙන් අගුළු ඇරීම"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"ඔබේ මුහුණ යළි ලියාපදිංචි කරන්න"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"හඳුනා ගැනීම වැඩිදියුණු කිරීමට, ඔබේ මුහුණ යළි-ලියාපදිංචි කරන්න"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"මුහුණෙන් අගුලු හැරීම සම්බන්ධව ගැටලුවකි"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"ඔබගේ මුහුණත ආකෘතිය මැකීමට තට්ටු කරන්න, අනතුරුව ඔබගේ මුහුණ නැවත එක් කරන්න"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"මුහුණෙන් අගුළු ඇරීම පිහිටුවන්න"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"ඔබගේ දුරකථනය දෙස බැලීමෙන් එහි අගුලු හරින්න"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"අගුලු හැරීමට තවත් ක්රම සකසන්න"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ඇඟිලි සලකුණක් එක් කිරීමට තට්ටු කරන්න"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ඇඟිලි සලකුණු අගුළු ඇරීම"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"ඇඟිලි සලකුණු සංවේදකය භාවිත කළ නොහැකිය"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"අළුත්වැඩියා සැපයුම්කරුවෙකු බලන්න."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"නිරවද්ය මුහුණු දත්ත ගත නොහැකි විය. නැවත උත්සාහ කරන්න."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"දීප්තිය වැඩියි. තවත් මඳ ආලෝකය උත්සාහ කරන්න."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"ඉතා අඳුරුයි. තවත් දීප්තිමත් ආලෝකය උත්සාහ කරන්න."</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 234e3a86f54f..f44c8d864937 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -591,6 +591,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Vyskúšajte iný odtlačok prsta"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Príliš jasno"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Vyskúšajte upraviť"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Zakaždým trocha zmeňte pozíciu prsta"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Odtlačok prsta bol overený"</string> @@ -607,8 +608,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Neregistrovali ste žiadne odtlačky prstov."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Senzor odtlačkov prstov nie je možné používať. Navštívte poskytovateľa opráv."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst: <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -618,12 +618,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona odtlačku prsta"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Odomknutie tvárou"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Znova zaregistrujte svoju tvár"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Znova zaregistrujte svoju tvár, aby sa zlepšilo rozpoznávanie"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problém s odomknutím tvárou"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Klepnutím odstráňte model tváre a potom znova pridajte svoju tvár"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Nastavte odomknutie tvárou"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Odomykajte telefón tak, že sa naň pozriete"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Nastavte viac spôsobov odomknutia"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Klepnutím pridajte odtlačok prsta"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Odomknutie odtlačkom prsta"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Senzor odtlačkov prstov nie je možné používať"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Navštívte poskytovateľa opráv."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Nepodarilo sa nasnímať presné údaje o tvári. Skúste to znova."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Príliš veľa svetla. Skúste jemnejšie osvetlenie."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Príliš veľká tma. Skúste lepšie osvetlenie."</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 19c443444d89..0f79fb61f4ec 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -591,6 +591,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Poskusite z drugim prstnim odtisom."</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Presvetlo je."</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Poskusite popraviti položaj prsta."</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Vsakič nekoliko spremenite položaj prsta."</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Pristnost prstnega odtisa je preverjena"</string> @@ -607,8 +608,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ni registriranih prstnih odtisov."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Tipala prstnih odtisov ni mogoče uporabiti. Obiščite ponudnika popravil."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -618,12 +618,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona prstnih odtisov"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Odklepanje z obrazom"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Znova registrirajte obraz"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Za izboljšanje prepoznavanja znova registrirajte svoj obraz"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Težava z odklepanjem z obrazom"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Dotaknite se, da izbrišete model obraza, in nato znova dodajte obraz."</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Nastavitev odklepanja z obrazom"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Odklenite telefon tako, da ga pogledate."</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Nastavite več načinov odklepanja"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Dotaknite se, da dodate prstni odtis."</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Odklepanje s prstnim odtisom"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Tipala prstnih odtisov ni mogoče uporabiti"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Obiščite ponudnika popravil."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Točnih podatkov o obrazu ni bilo mogoče zajeti. Poskusite znova."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Presvetlo. Poskusite z blažjo osvetlitvijo."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Pretemno. Poskusite z močnejšo osvetlitvijo."</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 7934473206b5..57c1297cae0d 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Lejon aplikacionin të zgjerojë ose shpalosë shiritin e statusit."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"shfaq njoftimet si aktivitete në ekran të plotë në një pajisje të kyçur"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Lejon që aplikacioni t\'i shfaqë njoftimet si aktivitete në ekran të plotë në një pajisje të kyçur"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalo shkurtore"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"instalimi i shkurtoreve"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Lejon një aplikacion për të shtuar shkurtore në ekranin bazë pa ndërhyrjen e përdoruesit."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"çinstalo shkurtore"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Lejon aplikacionin të heqë shkurtore në ekranin bazë, pa ndërhyrjen e përdoruesit."</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Provo një gjurmë gishti tjetër"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Me shumë ndriçim"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Provo ta rregullosh"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ndrysho pak pozicionin e gishtit çdo herë"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Gjurma e gishtit u vërtetua"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nuk ka asnjë gjurmë gishti të regjistruar."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Përdor gjurmën e gishtit"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona e gjurmës së gishtit"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Shkyçja me fytyrë"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Regjistro përsëri fytyrën tënde"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Për të përmirësuar njohjen, regjistro përsëri fytyrën tënde"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Lëshoje me \"Shkyçjen me fytyrë\""</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Trokit për të fshirë modelin tënd të fytyrës, pastaj shtoje përsëri fytyrën tënde"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Konfiguro \"Shkyçjen me fytyrë\""</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Shkyçe telefonin duke parë tek ai"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Konfiguri më shumë mënyra për të shkyçur"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Trokit për të shtuar një gjurmë gishti"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"S\'mund të regjistroheshin të dhëna të sakta të fytyrës. Provo përsëri."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Me shumë ndriçim. Provo një ndriçim më të butë."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Shumë i errët. Provo një ndriçim më të fortë."</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index a0ae389e428b..8c7c5fe2fa9e 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -352,7 +352,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Дозвољава апликацији да проширује или скупља статусну траку."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"приказује обавештења као активности преко целог екрана на закључаном уређају"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Омогућава апликацији да на закључаном уређају приказује обавештења као активности преко целог екрана."</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"инсталирање пречица"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Инсталирање пречица"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Омогућава апликацији да додаје пречице на почетни екран без интервенције корисника."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"деинсталирање пречица"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Омогућава апликацији да уклања пречице са почетног екрана без интервенције корисника."</string> @@ -588,6 +588,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Пробајте са другим отиском прста"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Превише је светло"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Пробајте да прилагодите"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Сваки пут лагано промените положај прста"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отисак прста је потврђен"</string> @@ -604,8 +605,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Није регистрован ниједан отисак прста."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Овај уређај нема сензор за отисак прста."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензор је привремено онемогућен."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не можете да користите сензор за отисак прста. Посетите добављача за поправке"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користите отисак прста"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користите отисак прста или закључавање екрана"</string> @@ -615,12 +615,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Икона отиска прста"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Откључавање лицем"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Поново региструјте лице"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Да бисте побољшали препознавање, поново региструјте лице"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Проблем са откључавање лицем"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Додирните да бисте избрисали модел лица, па поново додајте своје лице"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Подесите откључавање лицем"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Откључајте телефон тако што ћете га погледати"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Подесите још начина за откључавање"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Додирните да бисте додали отисак прста"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Откључавање отиском прста"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Не можете да користите сензор за отисак прста"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Посетите добављача за поправке."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Снимање лица није успело. Пробајте поново."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Превише је светло. Пробајте са слабијим осветљењем."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Претамно је. Пробајте са јачим осветљењем."</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 34d5e2c08ff7..b45a94a3955a 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Testa ett annat fingeravtryck"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Det är för ljust"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Testa att justera fingeravtrycket"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Flytta fingret lite varje gång"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeravtrycket har autentiserats"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Inga fingeravtryck har registrerats."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Det går inte att använda fingeravtryckssensorn. Besök ett reparationsställe"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon för fingeravtryck"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Ansiktslås"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Registrera ansiktet på nytt"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Gör om registreringen av ansiktet så att ansiktsigenkänningen ska fungera bättre"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problem med ansiktslås"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Tryck för att radera ansiktsmodellen och lägg sedan till ansiktet igen"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Konfigurera ansiktslås"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Lås upp telefonen genom att titta på den"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Konfigurera fler sätt att låsa upp"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Tryck för att lägga till ett fingeravtryck"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Fingeravtryckslås"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Det går inte att använda fingeravtryckssensorn"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Besök ett reparationsställe."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Det gick inte att fånga ansiktsdata. Försök igen."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Det är för ljust. Testa lägre belysning."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Det är för mörkt. Testa med bättre belysning."</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index cc8d644ebc0c..163ad5363d01 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Jaribu alama nyingine ya kidole"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Inang\'aa mno"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Jaribu kurekebisha"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Badilisha mkao wa kidole chako kiasi kila wakati"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Imethibitisha alama ya kidole"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Hakuna alama za vidole zilizojumuishwa."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Imeshindwa kutumia kitambua alama ya kidole. Tembelea mtoa huduma za urekebishaji"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Kidole cha <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Aikoni ya alama ya kidole"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Kufungua kwa uso"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Sajili uso wako tena"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Ili kuimarisha utambuzi, tafadhali sajili uso wako tena"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Hitilafu imetokea kwenye kipengele cha Kufungua kwa uso"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Gusa ili ufute muundo wa uso wako, kisha uweke uso wako tena"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Weka mipangilio ya Kufungua kwa uso"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Fungua simu yako kwa kuiangalia"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Weka mipangilio ya mbinu zaidi za kufungua"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Gusa ili uweke alama ya kidole"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Kufungua kwa Alama ya Kidole"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Imeshindwa kutumia kitambua alama ya kidole"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Tembelea mtoa huduma za urekebishaji."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Imeshindwa kunasa data sahihi ya uso. Jaribu tena."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Inang\'aa mno. Jaribu mwangaza hafifu"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Hakuna mwangaza wa kutosha. Jaribu kuongeza mwangaza."</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 0d2815164b81..26fa15bdd625 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -47,7 +47,7 @@ <string name="mismatchPin" msgid="2929611853228707473">"உள்ளிட்ட பின்கள் பொருந்தவில்லை."</string> <string name="invalidPin" msgid="7542498253319440408">"4 இலிருந்து 8 எண்கள் வரையுள்ள பின் ஐத் தட்டச்சு செய்யவும்."</string> <string name="invalidPuk" msgid="8831151490931907083">"8 அல்லது அதற்கு மேல் எண்கள் உள்ள PUK ஐத் தட்டச்சு செய்யவும்."</string> - <string name="needPuk" msgid="7321876090152422918">"உங்கள் சிம் கார்டு PUK பூட்டுதல் செய்யப்பட்டுள்ளது. அதைத் திறக்க PUK குறியீட்டைத் உள்ளிடவும்."</string> + <string name="needPuk" msgid="7321876090152422918">"உங்கள் சிம் கார்டு PUK பூட்டுதல் செய்யப்பட்டுள்ளது. அதை அன்லாக் செய்ய PUK குறியீட்டை உள்ளிடவும்."</string> <string name="needPuk2" msgid="7032612093451537186">"சிம் கார்டைத் தடுப்பு நீக்க PUK2 ஐ உள்ளிடவும்."</string> <string name="enablePin" msgid="2543771964137091212">"தோல்வி, சிம்/RUIM பூட்டை இயக்கவும்."</string> <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584"> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"வேறு கைரேகையை முயலவும்"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"அதிக வெளிச்சமாக உள்ளது"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"விரலைச் சரியாக வைக்கவும்"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ஒவ்வொரு முறையும் விரலின் நிலையைச் சிறிதளவு மாற்றுங்கள்"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"கைரேகை அங்கீகரிக்கப்பட்டது"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"கைரேகைப் பதிவுகள் எதுவும் இல்லை."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"இந்தச் சாதனத்தில் கைரேகை சென்சார் இல்லை."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"சென்சார் தற்காலிகமாக முடக்கப்பட்டுள்ளது."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"கைரேகையைப் பயன்படுத்து"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"கைரேகை ஐகான்"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"முகம் காட்டித் திறத்தல்"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"முகத்தை மீண்டும் பதிவுசெய்யவும்"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"அடையாளத்தை மேம்படுத்த முகத்தை மீண்டும் பதிவுசெய்யவும்"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"முகம் காட்டித் திறத்தல் அம்சத்தில் சிக்கல்"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"முகத் தோற்றப் பதிவைத் தட்டி நீக்கிவிட்டு உங்கள் முகத்தை மீண்டும் சேர்க்கவும்"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"\'முகம் காட்டித் திறத்தல்\' அம்சத்தை அமைத்தல்"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"மொபைலைப் பார்ப்பதன் மூலம் அதைத் திறக்கலாம்"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"திறக்க, மேலும் பல வழிகளை அமையுங்கள்"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"கைரேகையைச் சேர்க்கத் தட்டுங்கள்"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"முகம் தெளிவாகப் பதிவாகவில்லை. மீண்டும் முயலவும்."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"அதிக ஒளிர்வு. மிதமான ஒளியில் முயலவும்."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"இருட்டாக உள்ளது. பிரகாசமான ஒளியில் முயலவும்."</string> @@ -885,7 +892,7 @@ <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"சரி!"</string> <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"மீண்டும் முயற்சிக்கவும்"</string> <string name="lockscreen_password_wrong" msgid="8605355913868947490">"மீண்டும் முயற்சிக்கவும்"</string> - <string name="lockscreen_storage_locked" msgid="634993789186443380">"எல்லா அம்சங்கள் & தரவை பெற, சாதனத்தை திறக்கவும்"</string> + <string name="lockscreen_storage_locked" msgid="634993789186443380">"எல்லா அம்சங்கள் & தரவை பெற, சாதனத்தை அன்லாக் செய்யவும்"</string> <string name="faceunlock_multiple_failures" msgid="681991538434031708">"முகம் காட்டித் திறத்தல் அம்சத்தை அதிகமுறை பயன்படுத்துவிட்டீர்கள்"</string> <string name="lockscreen_missing_sim_message_short" msgid="1248431165144893792">"சிம் கார்டு இல்லை"</string> <string name="lockscreen_missing_sim_message" product="tablet" msgid="8596805728510570760">"டேப்லெட்டில் சிம் கார்டு இல்லை."</string> @@ -911,10 +918,10 @@ <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"திறப்பதற்கான வடிவத்தை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string> <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"உங்கள் கடவுச்சொல்லை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக உள்ளிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string> <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"உங்கள் பின்னை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக உள்ளிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string> - <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"திறப்பதற்கான வடிவத்தை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக வரைந்தால், உங்கள் Google உள்நுழைவைப் பயன்படுத்தி டேப்லெட்டைத் திறக்குமாறு கேட்கப்படுவீர்கள். \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string> - <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"திறப்பதற்கான பேட்டர்னை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக வரைந்தால் உங்கள் Google உள்நுழைவைப் பயன்படுத்தி Android TVயைத் திறக்குமாறு கேட்கப்படுவீர்கள். \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string> - <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"திறப்பதற்கான வடிவத்தை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக வரைந்தால், உங்கள் Google உள்நுழைவைப் பயன்படுத்தி மொபைலைத் திறக்குமாறு கேட்கப்படுவீர்கள். \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string> - <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"டேப்லெட்டைத் தடைநீக்க <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு, டேப்லெட்டானது ஆரம்ப இயல்புநிலைக்கு மீட்டமைக்கப்பட்டு, எல்லா பயனர் தரவும் இழக்கப்படும்."</string> + <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"அன்லாக் வடிவத்தை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக வரைந்தால், உங்கள் Google உள்நுழைவைப் பயன்படுத்தி டேப்லெட்டை அன்லாக் செய்யுமாறு கேட்கப்படுவீர்கள். \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string> + <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"அன்லாக் பேட்டர்னை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக வரைந்தால் உங்கள் Google உள்நுழைவைப் பயன்படுத்தி Android TVயை அன்லாக் செய்யுமாறு கேட்கப்படுவீர்கள். \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string> + <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"அன்லாக் பேட்டர்னை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக வரைந்தால், உங்கள் Google உள்நுழைவைப் பயன்படுத்தி மொபைலை அன்லாக் செய்யுமாறு கேட்கப்படுவீர்கள். \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string> + <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"டேப்லெட்டை அன்லாக் செய்ய <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு, டேப்லெட்டானது ஆரம்ப இயல்புநிலைக்கு மீட்டமைக்கப்பட்டு, எல்லா பயனர் தரவும் இழக்கப்படும்."</string> <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"உங்கள் Android TVயில் <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறான கடவுச்சொல்லை உள்ளிட்டுத் திறக்க முயன்றுள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறான கடவுச்சொல்லை உள்ளிட்டு முயன்றால் உங்கள் Android TV ஆரம்ப நிலைக்கு மீட்டமைக்கப்படுவதுடன் பயனரின் அனைத்துத் தரவையும் இழக்க நேரிடும்."</string> <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"தொலைபேசியைத் தடைநீக்க <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு, தொலைபேசியானது ஆரம்ப இயல்புநிலைக்கு மீட்டமைக்கப்பட்டு, எல்லா பயனர் தரவும் இழக்கப்படும்."</string> <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"நீங்கள் டேப்லெட்டைத் தடைநீக்க <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். டேப்லெட் இப்போது ஆரம்ப இயல்புநிலைக்கு மீட்டமைக்கப்படும்."</string> @@ -922,7 +929,7 @@ <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"நீங்கள் தொலைபேசியைத் தடைநீக்க <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். தொலைபேசி இப்போது ஆரம்ப இயல்புநிலைக்கு மீட்டமைக்கப்படும்."</string> <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"<xliff:g id="NUMBER">%d</xliff:g> வினாடிகள் கழித்து மீண்டும் முயற்சிக்கவும்."</string> <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"வடிவத்தை மறந்துவிட்டீர்களா?"</string> - <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"கணக்கைத் திற"</string> + <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"கணக்கை அன்லாக் செய்"</string> <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"அதிகமான வடிவ முயற்சிகள்"</string> <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"திறக்க, Google கணக்கு மூலம் உள்நுழையவும்."</string> <string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"பயனர்பெயர் (மின்னஞ்சல் முகவரி)"</string> @@ -944,7 +951,7 @@ <string name="keyguard_accessibility_add_widget" msgid="8245795023551343672">"விட்ஜெட்டைச் சேர்க்கவும்."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="544239307077644480">"காலியானது"</string> <string name="keyguard_accessibility_unlock_area_expanded" msgid="7768634718706488951">"திறக்கும் பகுதி விரிவாக்கப்பட்டது."</string> - <string name="keyguard_accessibility_unlock_area_collapsed" msgid="4729922043778400434">"திறக்கும் பகுதி சுருக்கப்பட்டது."</string> + <string name="keyguard_accessibility_unlock_area_collapsed" msgid="4729922043778400434">"அன்லாக் செய்வதற்கான பகுதி சுருக்கப்பட்டது."</string> <string name="keyguard_accessibility_widget" msgid="6776892679715699875">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> விட்ஜெட்."</string> <string name="keyguard_accessibility_user_selector" msgid="1466067610235696600">"பயனர் தேர்வி"</string> <string name="keyguard_accessibility_status" msgid="6792745049712397237">"நிலை"</string> @@ -953,12 +960,12 @@ <string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"விட்ஜெட்டை மீண்டும் வரிசைப்படுத்துவது தொடங்கியது."</string> <string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"விட்ஜெட்டை மீண்டும் வரிசைப்படுத்துவது முடிந்தது."</string> <string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"விட்ஜெட் <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> நீக்கப்பட்டது."</string> - <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"திறப்பதற்கான பகுதியை விவரிக்கவும்."</string> + <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"அன்லாக் செய்வதற்கான பகுதியை விரிவாக்கவும்"</string> <string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"ஸ்லைடு மூலம் திறத்தல்."</string> <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"பேட்டர்ன் மூலம் திறத்தல்."</string> <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"முகம் காட்டித் திறத்தல்."</string> <string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"Pin மூலம் திறத்தல்."</string> - <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"சிம்மைத் திறக்கும் பின்."</string> + <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"சிம் பின் அன்லாக்."</string> <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"சிம்மைத் திறக்கும் Puk."</string> <string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"கடவுச்சொல் மூலம் திறத்தல்."</string> <string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"வடிவப் பகுதி."</string> @@ -1565,7 +1572,7 @@ <string name="shareactionprovider_share_with" msgid="2753089758467748982">"இவர்களுடன் பகிர்"</string> <string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> உடன் பகிர்"</string> <string name="content_description_sliding_handle" msgid="982510275422590757">"ஸ்லைடிங் ஹேன்டில். தொட்டுப் பிடிக்கவும்."</string> - <string name="description_target_unlock_tablet" msgid="7431571180065859551">"திறக்க ஸ்வைப் செய்யவும்."</string> + <string name="description_target_unlock_tablet" msgid="7431571180065859551">"அன்லாக் செய்ய ஸ்வைப் செய்யவும்."</string> <string name="action_bar_home_description" msgid="1501655419158631974">"முகப்பிற்கு வழிசெலுத்து"</string> <string name="action_bar_up_description" msgid="6611579697195026932">"மேலே வழிசெலுத்து"</string> <string name="action_menu_overflow_description" msgid="4579536843510088170">"மேலும் விருப்பங்கள்"</string> @@ -1662,7 +1669,7 @@ <string name="kg_invalid_puk" msgid="4809502818518963344">"சரியான PUK குறியீட்டை மீண்டும் உள்ளிடவும். தொடர் முயற்சிகள் சிம் ஐ நிரந்தரமாக முடக்கிவிடும்."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"பின் குறியீடுகள் பொருந்தவில்லை"</string> <string name="kg_login_too_many_attempts" msgid="699292728290654121">"அதிகமான வடிவ முயற்சிகள்"</string> - <string name="kg_login_instructions" msgid="3619844310339066827">"திறக்க, உங்கள் Google கணக்கு மூலம் உள்நுழையவும்."</string> + <string name="kg_login_instructions" msgid="3619844310339066827">"அன்லாக் செய்ய உங்கள் Google கணக்கு மூலம் உள்நுழையவும்."</string> <string name="kg_login_username_hint" msgid="1765453775467133251">"பயனர்பெயர் (மின்னஞ்சல்)"</string> <string name="kg_login_password_hint" msgid="3330530727273164402">"கடவுச்சொல்"</string> <string name="kg_login_submit_button" msgid="893611277617096870">"உள்நுழைக"</string> @@ -1675,12 +1682,12 @@ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"டேப்லெட்டைத் திறக்க <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு, டேப்லெட்டானது ஆரம்பநிலைக்கு மீட்டமைக்கப்பட்டு, எல்லா பயனர் தரவையும் இழப்பீர்கள்."</string> <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"உங்கள் Android TVயில் <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறான கடவுச்சொல்லை உள்ளிட்டுத் திறக்க முயன்றுள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறான கடவுச்சொல்லை உள்ளிட்டு முயன்றால் உங்கள் Android TV ஆரம்ப நிலைக்கு மீட்டமைக்கப்படுவதுடன் பயனரின் அனைத்துத் தரவையும் இழக்க நேரிடும்."</string> <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"மொபைலைத் திறக்க <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு,மொபைலானது ஆரம்பநிலைக்கு மீட்டமைக்கப்பட்டு, எல்லா பயனர் தரவையும் இழப்பீர்கள்."</string> - <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"டேப்லெட்டைத் திறக்க <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். டேப்லெட் இப்போது ஆரம்பநிலைக்கு மீட்டமைக்கப்படும்."</string> + <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"டேப்லெட்டை அன்லாக் செய்ய <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். டேப்லெட் இப்போது ஆரம்பநிலைக்கு மீட்டமைக்கப்படும்."</string> <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"உங்கள் Android TVயில் <xliff:g id="NUMBER">%d</xliff:g> முறை தவறான கடவுச்சொல்லை உள்ளிட்டுத் திறக்க முயன்றுள்ளீர்கள். இப்போது உங்கள் Android TV ஆரம்ப நிலைக்கு மீட்டமைக்கப்படும்."</string> <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"மொபைலைத் திறக்க <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயற்சித்துள்ளீர்கள். மொபைல் இப்போது ஆரம்பநிலைக்கு மீட்டமைக்கப்படும்."</string> <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"திறப்பதற்கான வடிவத்தை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். மேலும் <xliff:g id="NUMBER_1">%2$d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு, மின்னஞ்சல் கணக்கைப் பயன்படுத்தி உங்கள் டேப்லெட்டைத் திறக்க கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகளில் மீண்டும் முயற்சிக்கவும்."</string> <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"திறப்பதற்கான பேட்டர்னை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக வரைந்தால் மின்னஞ்சல் கணக்கைப் பயன்படுத்தி Android TVயைத் திறக்கும்படி கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string> - <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"திறப்பதற்கான வடிவத்தை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். மேலும் <xliff:g id="NUMBER_1">%2$d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு, மின்னஞ்சல் கணக்கைப் பயன்படுத்தி உங்கள் மொபைலைத் திறக்கக் கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string> + <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"அன்லாக் வடிவத்தை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துள்ளீர்கள். மேலும் <xliff:g id="NUMBER_1">%2$d</xliff:g> தோல்வி முயற்சிகளுக்குப் பிறகு, மின்னஞ்சல் கணக்கைப் பயன்படுத்தி உங்கள் மொபைலை அன்லாக் செய்யக் கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகள் கழித்து முயற்சிக்கவும்."</string> <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string> <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"அகற்று"</string> <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"பரிந்துரைத்த அளவை விட ஒலியை அதிகரிக்கவா?\n\nநீண்ட நேரத்திற்கு அதிகளவில் ஒலி கேட்பது கேட்கும் திறனைப் பாதிக்கலாம்."</string> @@ -1985,7 +1992,7 @@ <string name="new_sms_notification_content" msgid="3197949934153460639">"பார்க்க, SMS பயன்பாட்டைத் திறக்கவும்"</string> <string name="profile_encrypted_title" msgid="9001208667521266472">"சில செயலுக்கு கட்டுப்பாடு இருக்கலாம்"</string> <string name="profile_encrypted_detail" msgid="5279730442756849055">"பணிக் கணக்கு பூட்டியுள்ளது"</string> - <string name="profile_encrypted_message" msgid="1128512616293157802">"பணிக் கணக்கை திறக்க, தட்டுக"</string> + <string name="profile_encrypted_message" msgid="1128512616293157802">"பணிக் கணக்கை அன்லாக் செய்யத் தட்டுக"</string> <string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> உடன் இணைக்கப்பட்டது"</string> <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"கோப்புகளைப் பார்க்க, தட்டவும்"</string> <string name="pin_target" msgid="8036028973110156895">"பின் செய்"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 936b758a1db5..6c9226810361 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"మరొక వేలిముద్రను ట్రై చేయండి"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"వెలుతురు అధికంగా ఉంది"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"సర్దుబాటు చేయడానికి ట్రై చేయండి"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ప్రతిసారీ మీ వేళ్ల స్థానాన్ని కొద్దిగా మార్చండి"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"వేలిముద్ర ప్రమాణీకరించబడింది"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"వేలిముద్రలు నమోదు చేయబడలేదు."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ఈ పరికరంలో వేలిముద్ర సెన్సార్ ఎంపిక లేదు."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"సెన్సార్ తాత్కాలికంగా డిజేబుల్ చేయబడింది."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"వేలు <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"వేలిముద్రను ఉపయోగించండి"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"వేలిముద్ర చిహ్నం"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ఫేస్ అన్లాక్"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"మీ ముఖాన్ని తిరిగి నమోదు చేయండి"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"గుర్తింపును మెరుగుపరచడానికి, దయచేసి మీ ముఖంను తిరిగి నమోదు చేసుకోండి"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"ఫేస్ అన్లాక్తో సమస్య"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"ఫేస్ మోడల్ను తొలగించడానికి నొక్కండి, ఆపై మీ ముఖాన్ని మళ్లీ జోడించండి"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"ఫేస్ అన్లాక్ను సెటప్ చేయండి"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"మీ ఫోన్ను చూడటం ద్వారా దాన్ని అన్లాక్ చేయండి"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"అన్లాక్ చేయడానికి మరిన్ని మార్గాలను సెటప్ చేయండి"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"వేలిముద్రను జోడించడానికి ట్యాప్ చేయండి"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"ముఖం డేటా సరిగ్గా రాలేదు. మళ్లీ ప్రయత్నించండి."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"వెలుతురు అధికంగా ఉంది. తక్కువ ఉండేలా చూడండి."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"చాలా చీకటిగా ఉంది. బాగా వెలుతురులో ప్రయత్నించండి."</string> diff --git a/core/res/res/values-television/config.xml b/core/res/res/values-television/config.xml index 3ecb1dddd916..55e5685b95e5 100644 --- a/core/res/res/values-television/config.xml +++ b/core/res/res/values-television/config.xml @@ -42,4 +42,8 @@ <!-- Allow SystemUI to show the shutdown dialog --> <bool name="config_showSysuiShutdown">true</bool> + + <!-- Component name of the activity used to inform a user about a sensory being blocked because + of privacy settings. --> + <string name="config_sensorUseStartedActivity">com.android.systemui/com.android.systemui.sensorprivacy.television.TvUnblockSensorActivity</string> </resources> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 9b2966f8586b..b35ddabd3c10 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ลองลายนิ้วมืออื่น"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"สว่างเกินไป"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ลองปรับการวางนิ้ว"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"เปลี่ยนตำแหน่งของนิ้วเล็กน้อยไปเรื่อยๆ ทุกครั้ง"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"ตรวจสอบสิทธิ์ลายนิ้วมือแล้ว"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ไม่มีลายนิ้วมือที่ลงทะเบียน"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ลายนิ้วมือ"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ปิดใช้เซ็นเซอร์ชั่วคราวแล้ว"</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"นิ้ว <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ใช้ลายนิ้วมือ"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ไอคอนลายนิ้วมือ"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"การปลดล็อกด้วยใบหน้า"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"ลงทะเบียนใบหน้าอีกครั้ง"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"โปรดลงทะเบียนใบหน้าอีกครั้งเพื่อปรับปรุงการจดจำ"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"มีปัญหาเกี่ยวกับฟีเจอร์ปลดล็อกด้วยใบหน้า"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"แตะเพื่อลบรูปแบบใบหน้า แล้วเพิ่มใบหน้าอีกครั้ง"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"ตั้งค่าการปลดล็อกด้วยใบหน้า"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"ปลดล็อกโทรศัพท์โดยมองไปที่โทรศัพท์"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"ตั้งค่าการปลดล็อกด้วยวิธีอื่น"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"แตะเพื่อเพิ่มลายนิ้วมือ"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"บันทึกข้อมูลใบหน้าที่ถูกต้องไม่ได้ ลองอีกครั้ง"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"สว่างเกินไป ลองหาตำแหน่งที่แสงน้อยกว่านี้"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"มืดเกินไป ลองหาตำแหน่งที่สว่างขึ้น"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index a34ac289dab9..d28a73dc1d19 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Sumubok ng ibang fingerprint"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Masyadong maliwanag"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Subukang isaayos"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Bahagyang baguhin ang posisyon ng iyong daliri sa bawat pagkakataon"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Na-authenticate ang fingerprint"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Walang naka-enroll na fingerprint."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Hindi magamit ang sensor para sa fingerprint. Bumisita sa provider ng pag-aayos"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Daliri <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icon ng fingerprint"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Pag-unlock Gamit ang Mukha"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"I-enroll ulit ang iyong mukha"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Para mapahusay ang pagkilala, paki-enroll ulit ang iyong mukha"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Isyu sa Pag-unlock Gamit ang Mukha"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"I-tap para i-delete ang iyong face model, pagkatapos ay idagdag ulit ang mukha mo"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"I-set up ang Pag-unlock Gamit ang Mukha"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"I-unlock ang iyong telepono sa pamamagitan ng pagtingin dito"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Mag-set up ng higit pang paraan para mag-unlock"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"I-tap para magdagdag ng fingerprint"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Pag-unlock Gamit ang Fingerprint"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Hindi magamit ang sensor para sa fingerprint"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Bumisita sa provider ng pag-aayos."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Hindi makakuha ng tamang face data. Subukang muli."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Masyadong maliwanag. Subukang bawasan ang liwanag."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Masyadong madilim. Subukan sa mas maliwanag."</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index a08dcb23a6fc..b7afbdeced7f 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Başka bir parmak izi deneyin"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Çok parlak"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Ayarlamayı deneyin"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Her defasında parmağınızın konumunu biraz değiştirin"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Parmak izi kimlik doğrulaması yapıldı"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Parmak izi kaydedilmedi."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Parmak izi sensörü kullanılamıyor. Bir onarım hizmeti sağlayıcıyı ziyaret edin"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. parmak"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Parmak izi simgesi"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Yüz Tanıma Kilidi"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Yüzünüzü yeniden kaydedin"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Daha iyi tanınmasını sağlamak için lütfen yüzünüzü yeniden kaydedin"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Yüz Tanıma Kilidi sorunu"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Yüz modelinizi silmek için dokunup ardından yüzünüzü yeniden ekleyin"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Yüz Tanıma Kilidi\'ni kurma"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Telefonunuza bakarak kilidini açın"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Kilidi açmak için daha fazla yöntem ayarlayın"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Parmak izi eklemek için dokunun"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Parmak İzi Kilidi"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Parmak izi sensörü kullanılamıyor"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Bir onarım hizmeti sağlayıcıyı ziyaret edin."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Doğru yüz verileri yakalanamadı. Tekrar deneyin."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Çok parlak. Parlaklığı daha az bir ışıklandırma deneyin."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Çok karanlık. Daha parlak ışıkta deneyin."</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 8be7da682be7..10b51ed4acd7 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -591,6 +591,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Спробуйте інший відбиток пальця"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Надто яскраво"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Спробуйте відкоригувати відбиток пальця"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Щоразу трохи змінюйте положення пальця"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Відбиток пальця автентифіковано"</string> @@ -607,8 +608,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Відбитки пальців не зареєстровано."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На цьому пристрої немає сканера відбитків пальців."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик тимчасово вимкнено."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Не вдається скористатися сканером відбитків пальців. Зверніться до постачальника послуг із ремонту."</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Відбиток пальця <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Доступ за відбитком пальця"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Використовувати відбиток пальця або дані для розблокування екрана"</string> @@ -618,12 +618,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Значок відбитка пальця"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Фейсконтроль"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Повторно проскануйте обличчя"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Повторно проскануйте обличчя для ефективнішого розпізнавання"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Сталася помилка з фейсконтролем"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Натисніть, щоб видалити свою модель обличчя, а потім знову додайте її"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Налаштування фейсконтролю"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Ви зможете розблоковувати телефон, подивившись на нього"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Налаштуйте більше способів розблокування"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Натисніть, щоб додати відбиток пальця"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Розблокування відбитком пальця"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Не вдається скористатися сканером відбитків пальців"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Зверніться до постачальника послуг із ремонту."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Не вдалося чітко зняти обличчя. Повторіть спробу."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Занадто яскраво. Потрібно менше світла."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Занадто темно. Потрібно більше світла."</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index e0344e05a756..a00b051eece5 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"دوسرا فنگر پرنٹ آزمائیں"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"کافی روشنی ہے"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ایڈجسٹ کرنے کی کوشش کریں"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ہر بار اپنی انگلی کی پوزیشن کو تھوڑا تبدیل کریں"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"فنگر پرنٹ کی تصدیق ہو گئی"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"کوئی فنگر پرنٹ مندرج شدہ نہیں ہے۔"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"اس آلہ میں فنگر پرنٹ سینسر نہیں ہے۔"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"سینسر عارضی طور غیر فعال ہے۔"</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"فنگر پرنٹ استعمال کریں"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"فنگر پرنٹ آئیکن"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"فیس اَنلاک"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"اپنے چہرے کو دوبارہ مندرج کریں"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"شناخت کو بہتر بنانے کے لیے براہ کرم اپنے چہرے کو دوبارہ مندرج کریں"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"فیس اَنلاک میں مسئلہ"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"اپنے چہرے کا ماڈل حذف کرنے کے لیے تھپتھپائیں پھر اپنا چہرہ دوبارہ شامل کریں"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"فیس اَنلاک سیٹ اپ کریں"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"اپنے فون کی طرف دیکھ کر اسے غیر مقفل کریں"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"غیر مقفل کرنے کے مزید طریقے سیٹ اپ کریں"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"فنگر پرنٹ شامل کرنے کیلئے تھپتھپائیں"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"چہرے کا درست ڈيٹا کیپچر نہیں ہو سکا۔ پھر آزمائيں۔"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"کافی روشنی ہے۔ ہلکی روشنی میں آزمائیں۔"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"کافی اندھیرا ہے۔ تیز روشنی میں آزمائیں۔"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index 25a6a1aed415..045c62db29d4 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Boshqa barmoq izi bilan urining"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Juda yorqin"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Moslashga urining"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Barmoqni har safar biroz surib joylang"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Barmoq izi tekshirildi"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Hech qanday barmoq izi qayd qilinmagan."</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu qurilmada barmoq izi skaneri mavjud emas."</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor vaqtincha faol emas."</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"Barmoq izi <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmoq izi ishlatish"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Barmoq izi belgisi"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Yuz bilan ochish"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Yuzingizni yana qayd qiling"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Yuzingiz yanada yaxshiroq aniqlanishi uchun uni yana bir marta qayd qiling"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Yuz bilan ochishda muammo bor"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Yuz modelini oʻchirish uchun bosing va keyin yana yuzni qoʻshing"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Yuz bilan ochishni sozlash"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Telefoningizni yuz tekshiruvi yordamida qulfdan chiqaring"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Qulfdan chiqarishning boshqa usullarini sozlang"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Barmoq izi kiritish uchun bosing"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Yuz ravshan suratga olinmadi. Qaytadan urining."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Juda yorqin. Biroz soyaroq joy tanlang."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Juda qorongʻi. Atrofingizni yoriting."</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index a5cfbaf9a3d9..050eb96a07b7 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -349,7 +349,7 @@ <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Cho phép ứng dụng mở rộng hoặc thu gọn thanh trạng thái."</string> <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"hiển thị thông báo dưới dạng các hoạt động ở chế độ toàn màn hình trên thiết bị ở trạng thái khóa"</string> <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Cho phép ứng dụng hiển thị thông báo dưới dạng các hoạt động ở chế độ toàn màn hình trên thiết bị ở trạng thái khóa"</string> - <string name="permlab_install_shortcut" msgid="7451554307502256221">"cài đặt lối tắt"</string> + <string name="permlab_install_shortcut" msgid="7451554307502256221">"Cài đặt lối tắt"</string> <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Cho phép ứng dụng thêm lối tắt trên Màn hình chính mà không cần sự can thiệp của người dùng."</string> <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"gỡ cài đặt lối tắt"</string> <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Cho phép ứng dụng xóa lối tắt trên Màn hình chính mà không cần sự can thiệp của người dùng."</string> @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Hãy thử một vân tay khác"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Quá sáng"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Hãy thử điều chỉnh"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Mỗi lần, hãy thay đổi vị trí ngón tay một chút"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Đã xác thực vân tay"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Chưa đăng ký vân tay."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Không thể dùng cảm biến vân tay. Hãy liên hệ với một nhà cung cấp dịch vụ sửa chữa"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Ngón tay <xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Biểu tượng vân tay"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Mở khóa bằng khuôn mặt"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Đăng ký lại khuôn mặt của bạn"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Để cải thiện khả năng nhận dạng, hãy đăng ký lại khuôn mặt của bạn"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Vấn đề với tính năng Mở khóa bằng khuôn mặt"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Nhấn để xóa mẫu khuôn mặt, sau đó thêm lại khuôn mặt của bạn"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Thiết lập tính năng Mở khóa bằng khuôn mặt"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Mở khóa điện thoại bằng cách nhìn vào điện thoại"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Thiết lập thêm những cách mở khóa khác"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Nhấn để thêm vân tay"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Mở khóa bằng vân tay"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Không thể dùng cảm biến vân tay"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Hãy liên hệ với một nhà cung cấp dịch vụ sửa chữa."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Không thể ghi lại đúng dữ liệu mặt. Hãy thử lại."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Quá sáng. Hãy thử giảm độ sáng."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Quá tối. Hãy thử tăng độ sáng."</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 23832eb16ab6..eb231303c91c 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"请试试其他指纹"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"光线太亮"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"请尝试调整指纹"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"请在每次放手指时略微更改手指的位置"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"已验证指纹"</string> @@ -601,7 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未注册任何指纹。"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此设备没有指纹传感器。"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"传感器已暂时停用。"</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> + <!-- no translation found for fingerprint_error_bad_calibration (4385512597740168120) --> <skip /> <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指纹"</string> @@ -612,12 +613,18 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指纹图标"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"人脸解锁"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"重新注册您的面孔"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"要提升识别精确度,请重新注册您的面孔"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"人脸解锁存在问题"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"请点按以删除您的脸部模型,然后再添加您的脸部模型"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"设置人脸解锁"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"脸部对准手机即可将其解锁"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"设置更多解锁方式"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"点按即可添加指纹"</string> + <!-- no translation found for fingerprint_recalibrate_notification_name (1414578431898579354) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_title (2406561052064558497) --> + <skip /> + <!-- no translation found for fingerprint_recalibrate_notification_content (8519935717822194943) --> + <skip /> <string name="face_acquired_insufficient" msgid="2150805835949162453">"无法捕获准确的人脸数据,请重试。"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"亮度过高,请尝试使用较柔和的亮度。"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"亮度不足,请尝试将光线调亮。"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 0b59e5255baa..c2bce4677083 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"改用其他指紋"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"太亮"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"嘗試調整"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"每次掃瞄時請稍微變更手指的位置"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"驗證咗指紋"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未註冊任何指紋"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此裝置沒有指紋感應器。"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"指紋感應器無法使用,請洽詢維修供應商"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋鎖定"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指紋圖示"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"面孔解鎖"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"重新註冊臉孔"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"如要提高識別能力,請重新註冊您的臉孔"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"「面孔解鎖」功能發生問題"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"請輕按這裡刪除面部模型,然後再重新新增"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"設定「面孔解鎖」"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"直望手機即可解鎖"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"設定更多解鎖方法"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"輕按即可新增指紋"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"指紋解鎖"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"指紋感應器無法使用"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"請洽詢維修供應商。"</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"無法擷取準確的臉容資料。請再試一次。"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"影像太亮。請嘗試在更暗的環境下使用。"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"影像太暗。請嘗試在更明亮的環境下使用。"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 8f81d83a46e5..0dae86f859a4 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"改用其他指紋"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"太亮"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"請試著調整"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"每次掃描時請稍微變更手指的位置"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"指紋驗證成功"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未登錄任何指紋。"</string> <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"這個裝置沒有指紋感應器。"</string> <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"指紋感應器無法使用,請洽詢維修供應商"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定功能"</string> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指紋圖示"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"人臉解鎖"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"請重新註冊你的臉孔"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"為提升辨識精準度,請重新註冊你的臉孔"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"人臉解鎖功能發生問題"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"請輕觸這裡刪除臉部模型,然後再重新新增"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"設定人臉解鎖功能"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"看著手機就能解鎖"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"設定更多解鎖方式"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"輕觸即可新增指紋"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"指紋解鎖"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"指紋感應器無法使用"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"請洽詢維修供應商。"</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"無法擷取精準臉孔資料,請再試一次。"</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"亮度過高,請嘗試使用較柔和的照明方式。"</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"亮度不足,請嘗試使用較明亮的照明方式。"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index c5c781840ce5..7ff6bb330dea 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -585,6 +585,7 @@ <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Zama ezinye izigxivizo zeminwe"</string> <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Kukhanya kakhulu"</string> <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Zama ukulungisa"</string> + <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Shintsha indawo yomunwe wakho kancane isikhathi ngasinye"</string> <string-array name="fingerprint_acquired_vendor"> </string-array> <string name="fingerprint_authenticated" msgid="2024862866860283100">"Izigxivizo zeminwe zigunyaziwe"</string> @@ -601,8 +602,7 @@ <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Azikho izigxivizo zeminwe ezibhalisiwe."</string> <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> - <!-- no translation found for fingerprint_error_bad_calibration (374406495079531135) --> - <skip /> + <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"Ayikwazi ukusebenzisa inzwa yesigxivizo somunwe. Vakashela umhlinzeki wokulungisa"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"Umunwe ongu-<xliff:g id="FINGERID">%d</xliff:g>"</string> <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> @@ -612,12 +612,15 @@ </string-array> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Isithonjana sezigxivizo zeminwe"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Ukuvula ubuso"</string> - <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Phinda ubhalise ubuso bakho"</string> - <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Ukuze uthuthukise ukubonwa, sicela uphinde ubhalise ubuso bakho"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Inkinga Ngokuvula ngobuso"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Thepha ukuze usule imodeli yakho yobuso, bese wengeza futhi ubuso"</string> <string name="face_setup_notification_title" msgid="8843461561970741790">"Setha Ukuvula ngobuso"</string> <string name="face_setup_notification_content" msgid="5463999831057751676">"Vula ifoni yakho ngokuyibheka"</string> <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Setha izindlela eziningi zokuvula"</string> <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Thepha ukuze ungeze izigxivizo zomunwe"</string> + <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Ukuvula ngesigxivizo somunwe"</string> + <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Ayikwazi ukusebenzisa inzwa yesigxivizo somunwe"</string> + <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Vakashela umhlinzeki wokulungisa."</string> <string name="face_acquired_insufficient" msgid="2150805835949162453">"Ayikwazanga ukuthwebula idatha enembile yobuso. Zama futhi."</string> <string name="face_acquired_too_bright" msgid="8070756048978079164">"Kukhanya kakhulu. Zama ukukhanya okuthambile."</string> <string name="face_acquired_too_dark" msgid="252573548464426546">"Kumnyama kakhulu Zama ukukhanyisa okukhanyayo."</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index f4aff9467cee..646fbd3978fd 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1706,6 +1706,10 @@ config_enableFusedLocationOverlay is false. --> <string name="config_fusedLocationProviderPackageName" translatable="false">com.android.location.fused</string> + <!-- Default value for the ADAS GNSS Location Enabled setting if this setting has never been + set before. --> + <bool name="config_defaultAdasGnssLocationEnabled" translatable="false">false</bool> + <string-array name="config_locationExtraPackageNames" translatable="false"></string-array> <!-- The package name of the default network recommendation app. @@ -1890,6 +1894,9 @@ STREAM_MUSIC as if it's on TV platform. --> <bool name="config_single_volume">false</bool> + <!-- Flag indicating whether the volume panel should show remote sessions. --> + <bool name="config_volumeShowRemoteSessions">true</bool> + <!-- Flag indicating that an outbound call must have a call capable phone account that has declared it can process the call's handle. --> <bool name="config_requireCallCapableAccountForHandle">false</bool> @@ -3580,13 +3587,21 @@ --> <integer name="config_respectsActivityMinWidthHeightMultiWindow">0</integer> - <!-- This value is only used when the device checks activity min width/height to determine if it + <!-- This value is only used when the device checks activity min height to determine if it + can be shown in multi windowing modes. + If the activity min height is greater than this percentage of the display height in + portrait, it will not be allowed to be shown in multi windowing modes. + The value should be between [0 - 1]. + --> + <item name="config_minPercentageMultiWindowSupportHeight" format="float" type="dimen">0.3</item> + + <!-- This value is only used when the device checks activity min width to determine if it can be shown in multi windowing modes. - If the activity min width/height is greater than this percentage of the display smallest - width, it will not be allowed to be shown in multi windowing modes. + If the activity min width is greater than this percentage of the display width in + landscape, it will not be allowed to be shown in multi windowing modes. The value should be between [0 - 1]. --> - <item name="config_minPercentageMultiWindowSupportWidth" format="float" type="dimen">0.3</item> + <item name="config_minPercentageMultiWindowSupportWidth" format="float" type="dimen">0.5</item> <!-- If the display smallest screen width is greater or equal to this value, we will treat it as a large screen device, which will have some multi window features enabled by default. @@ -4628,6 +4643,15 @@ <!-- The package name for the default bug report handler app from power menu short press. This app must be allowlisted. --> <string name="config_defaultBugReportHandlerApp" translatable="false"></string> + <!-- When true, enables the allowlisted app to upload profcollect reports. --> + <bool name="config_profcollectReportUploaderEnabled">false</bool> + + <!-- The package name for the default profcollect report uploader app. This app must be allowlisted. --> + <string name="config_defaultProfcollectReportUploaderApp" translatable="false"></string> + + <!-- The action name for the default profcollect report uploader app. --> + <string name="config_defaultProfcollectReportUploaderAction" translatable="false"></string> + <!-- The default value used for RawContacts.ACCOUNT_NAME when contacts are inserted without this column set. These contacts are stored locally on the device and will not be removed even if no android.account.Account with this name exists. A null string will be used if the @@ -5007,6 +5031,10 @@ <!-- Default value for Settings.ASSIST_TOUCH_GESTURE_ENABLED --> <bool name="config_assistTouchGestureEnabledDefault">true</bool> + <!-- The maximum byte size of the information contained in the bundle of + HotwordDetectedResult. --> + <integer translatable="false" name="config_hotwordDetectedResultMaxBundleSize">0</integer> + <!-- The amount of dimming to apply to wallpapers with mid range luminance. 0 displays the wallpaper at full brightness. 1 displays the wallpaper as fully black. --> <item name="config_wallpaperDimAmount" format="float" type="dimen">0.05</item> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 302bd94c1973..d1a5cc49be9f 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1638,8 +1638,8 @@ <string name="fingerprint_error_hw_not_present">This device does not have a fingerprint sensor.</string> <!-- Generic error message shown when fingerprint is not available due to a security vulnerability. [CHAR LIMIT=50] --> <string name="fingerprint_error_security_update_required">Sensor temporarily disabled.</string> - <!-- Generic error message shown when fingerprint needs calibration [CHAR LIMIT=50] --> - <string name="fingerprint_error_bad_calibration">Sensor needs calibration</string> + <!-- Generic error message shown when fingerprint needs calibration [CHAR LIMIT=150] --> + <string name="fingerprint_error_bad_calibration">Can\u2019t use fingerprint sensor. Visit a repair provider</string> <!-- Template to be used to name enrolled fingerprints by default. --> <string name="fingerprint_name_template">Finger <xliff:g id="fingerId" example="1">%d</xliff:g></string> @@ -1663,9 +1663,9 @@ <!-- Notification name shown when the system requires the user to re-enroll their face. [CHAR LIMIT=NONE] --> <string name="face_recalibrate_notification_name">Face Unlock</string> <!-- Notification title shown when the system requires the user to re-enroll their face. [CHAR LIMIT=NONE] --> - <string name="face_recalibrate_notification_title">Re-enroll your face</string> + <string name="face_recalibrate_notification_title">Issue with Face Unlock</string> <!-- Notification content shown when the system requires the user to re-enroll their face. [CHAR LIMIT=NONE] --> - <string name="face_recalibrate_notification_content">To improve recognition, please re-enroll your face</string> + <string name="face_recalibrate_notification_content">Tap to delete your face model, then add your face again</string> <!-- Title of a notification that directs the user to set up Face Unlock by enrolling their face. [CHAR LIMIT=NONE] --> <string name="face_setup_notification_title">Set up Face Unlock</string> <!-- Contents of a notification that directs the user to set up face unlock by enrolling their face. [CHAR LIMIT=NONE] --> @@ -1675,6 +1675,13 @@ <!-- Contents of a notification that directs the user to enroll a fingerprint. [CHAR LIMIT=NONE] --> <string name="fingerprint_setup_notification_content">Tap to add a fingerprint</string> + <!-- Notification name shown when the system requires the user to re-calibrate their fingerprint. [CHAR LIMIT=NONE] --> + <string name="fingerprint_recalibrate_notification_name">Fingerprint Unlock</string> + <!-- Notification title shown when the system requires the user to re-calibrate their fingerprint. [CHAR LIMIT=NONE] --> + <string name="fingerprint_recalibrate_notification_title">Can\u2019t use fingerprint sensor</string> + <!-- Notification content shown when the system requires the user to re-calibrate their fingerprint. [CHAR LIMIT=NONE] --> + <string name="fingerprint_recalibrate_notification_content">Visit a repair provider.</string> + <!-- Message shown during face acquisition when the face cannot be recognized [CHAR LIMIT=50] --> <string name="face_acquired_insufficient">Couldn\u2019t capture accurate face data. Try again.</string> <!-- Message shown during face acquisition when the image is too bright [CHAR LIMIT=50] --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 5f849b4e1eb0..c05adfd4ba2e 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -395,6 +395,7 @@ <java-symbol type="bool" name="config_supportsMultiDisplay" /> <java-symbol type="integer" name="config_supportsNonResizableMultiWindow" /> <java-symbol type="integer" name="config_respectsActivityMinWidthHeightMultiWindow" /> + <java-symbol type="dimen" name="config_minPercentageMultiWindowSupportHeight" /> <java-symbol type="dimen" name="config_minPercentageMultiWindowSupportWidth" /> <java-symbol type="integer" name="config_largeScreenSmallestScreenWidthDp" /> <java-symbol type="bool" name="config_useLegacySplit" /> @@ -1918,6 +1919,7 @@ <java-symbol type="bool" name="config_tintNotificationActionButtons" /> <java-symbol type="bool" name="config_dozeAfterScreenOffByDefault" /> <java-symbol type="bool" name="config_enableActivityRecognitionHardwareOverlay" /> + <java-symbol type="bool" name="config_defaultAdasGnssLocationEnabled" /> <java-symbol type="bool" name="config_enableFusedLocationOverlay" /> <java-symbol type="bool" name="config_enableGeocoderOverlay" /> <java-symbol type="bool" name="config_enableGeofenceOverlay" /> @@ -2540,6 +2542,9 @@ <java-symbol type="string" name="fingerprint_error_security_update_required" /> <java-symbol type="string" name="fingerprint_error_bad_calibration" /> <java-symbol type="string" name="fingerprint_acquired_immobile" /> + <java-symbol type="string" name="fingerprint_recalibrate_notification_name" /> + <java-symbol type="string" name="fingerprint_recalibrate_notification_title" /> + <java-symbol type="string" name="fingerprint_recalibrate_notification_content" /> <!-- Fingerprint config --> <java-symbol type="integer" name="config_fingerprintMaxTemplatesPerUser"/> @@ -4018,6 +4023,11 @@ <java-symbol type="bool" name="config_bugReportHandlerEnabled" /> <java-symbol type="string" name="config_defaultBugReportHandlerApp" /> + <!-- For profcollect report uploader --> + <java-symbol type="bool" name="config_profcollectReportUploaderEnabled" /> + <java-symbol type="string" name="config_defaultProfcollectReportUploaderApp" /> + <java-symbol type="string" name="config_defaultProfcollectReportUploaderAction" /> + <java-symbol type="string" name="usb_device_resolve_prompt_warn" /> <!-- For Accessibility system actions --> @@ -4404,5 +4414,9 @@ <java-symbol type="bool" name="config_assistLongPressHomeEnabledDefault" /> <java-symbol type="bool" name="config_assistTouchGestureEnabledDefault" /> + <java-symbol type="integer" name="config_hotwordDetectedResultMaxBundleSize" /> + <java-symbol type="dimen" name="config_wallpaperDimAmount" /> + + <java-symbol type="bool" name="config_volumeShowRemoteSessions" /> </resources> diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp index 93e4a294a2cb..8fae80d602d9 100644 --- a/core/tests/coretests/Android.bp +++ b/core/tests/coretests/Android.bp @@ -121,6 +121,8 @@ java_genrule { ":FrameworksCoreTests_keyset_splat_api", ":FrameworksCoreTests_locales", ":FrameworksCoreTests_overlay_config", + ":FrameworksCoreTests_res_version_after", + ":FrameworksCoreTests_res_version_before", ":FrameworksCoreTests_version_1", ":FrameworksCoreTests_version_1_diff", ":FrameworksCoreTests_version_1_nosys", diff --git a/core/tests/coretests/apks/res_upgrade/Android.bp b/core/tests/coretests/apks/res_upgrade/Android.bp new file mode 100644 index 000000000000..c58614f2c946 --- /dev/null +++ b/core/tests/coretests/apks/res_upgrade/Android.bp @@ -0,0 +1,22 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +android_test_helper_app { + name: "FrameworksCoreTests_res_version_before", + defaults: ["FrameworksCoreTests_apks_defaults"], + resource_dirs: ["res_before"], + certificate: ":FrameworksCoreTests_unit_test_cert", +} + +android_test_helper_app { + name: "FrameworksCoreTests_res_version_after", + defaults: ["FrameworksCoreTests_apks_defaults"], + resource_dirs: ["res_after"], + certificate: ":FrameworksCoreTests_unit_test_cert", +} diff --git a/core/tests/coretests/apks/res_upgrade/AndroidManifest.xml b/core/tests/coretests/apks/res_upgrade/AndroidManifest.xml new file mode 100644 index 000000000000..1c607c9fd249 --- /dev/null +++ b/core/tests/coretests/apks/res_upgrade/AndroidManifest.xml @@ -0,0 +1,20 @@ +<?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 xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.frameworks.coretests.res_version"> + <application android:hasCode="false"/> +</manifest> diff --git a/core/tests/coretests/apks/res_upgrade/res_after/values/values.xml b/core/tests/coretests/apks/res_upgrade/res_after/values/values.xml new file mode 100644 index 000000000000..db4fd54c7aee --- /dev/null +++ b/core/tests/coretests/apks/res_upgrade/res_after/values/values.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> + <string name="version">after</string> + <public type="string" name="version" id="0x7f010000"/> +</resources> diff --git a/core/tests/coretests/apks/res_upgrade/res_before/values/values.xml b/core/tests/coretests/apks/res_upgrade/res_before/values/values.xml new file mode 100644 index 000000000000..63fc79020e3f --- /dev/null +++ b/core/tests/coretests/apks/res_upgrade/res_before/values/values.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> + <string name="version">before</string> + <public type="string" name="version" id="0x7f010000"/> +</resources> diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/PutDocumentsRequestTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/PutDocumentsRequestTest.java deleted file mode 100644 index 6fad4b8dcdac..000000000000 --- a/core/tests/coretests/src/android/app/appsearch/external/app/PutDocumentsRequestTest.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch; - - -import static com.google.common.truth.Truth.assertThat; - -import com.android.server.appsearch.testing.AppSearchEmail; - -import com.google.common.collect.ImmutableSet; - -import org.junit.Test; - -import java.util.Set; - -public class PutDocumentsRequestTest { - - @Test - public void addGenericDocument_byCollection() { - Set<AppSearchEmail> emails = - ImmutableSet.of( - new AppSearchEmail.Builder("namespace", "test1").build(), - new AppSearchEmail.Builder("namespace", "test2").build()); - PutDocumentsRequest request = - new PutDocumentsRequest.Builder().addGenericDocuments(emails).build(); - - assertThat(request.getGenericDocuments().get(0).getId()).isEqualTo("test1"); - assertThat(request.getGenericDocuments().get(1).getId()).isEqualTo("test2"); - } -} diff --git a/core/tests/coretests/src/android/app/appsearch/external/util/IndentingStringBuilderTest.java b/core/tests/coretests/src/android/app/appsearch/external/util/IndentingStringBuilderTest.java new file mode 100644 index 000000000000..057ecbd9dfe9 --- /dev/null +++ b/core/tests/coretests/src/android/app/appsearch/external/util/IndentingStringBuilderTest.java @@ -0,0 +1,89 @@ +/* + * 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. + */ + +package android.app.appsearch.util; + +import static com.google.common.truth.Truth.assertThat; + +import static org.junit.Assert.assertThrows; + +import org.junit.Test; + +public class IndentingStringBuilderTest { + @Test + public void testAppendIndentedStrings() { + IndentingStringBuilder stringBuilder = new IndentingStringBuilder(); + stringBuilder + .increaseIndentLevel() + .append("\nIndentLevel1\nIndentLevel1\n") + .decreaseIndentLevel() + .append("IndentLevel0,\n"); + + String str = stringBuilder.toString(); + String expectedString = "\n IndentLevel1\n IndentLevel1\nIndentLevel0,\n"; + + assertThat(str).isEqualTo(expectedString); + } + + @Test + public void testDecreaseIndentLevel_throwsException() { + IndentingStringBuilder stringBuilder = new IndentingStringBuilder(); + + Exception e = + assertThrows( + IllegalStateException.class, () -> stringBuilder.decreaseIndentLevel()); + assertThat(e).hasMessageThat().contains("Cannot set indent level below 0."); + } + + @Test + public void testAppendIndentedObjects() { + IndentingStringBuilder stringBuilder = new IndentingStringBuilder(); + Object stringProperty = "String"; + Object longProperty = 1L; + Object booleanProperty = true; + + stringBuilder + .append(stringProperty) + .append("\n") + .increaseIndentLevel() + .append(longProperty) + .append("\n") + .decreaseIndentLevel() + .append(booleanProperty); + + String str = stringBuilder.toString(); + String expectedString = "String\n 1\ntrue"; + + assertThat(str).isEqualTo(expectedString); + } + + @Test + public void testAppendIndentedStrings_doesNotIndentLineBreak() { + IndentingStringBuilder stringBuilder = new IndentingStringBuilder(); + + stringBuilder + .append("\n") + .increaseIndentLevel() + .append("\n\n") + .decreaseIndentLevel() + .append("\n"); + + String str = stringBuilder.toString(); + String expectedString = "\n\n\n\n"; + + assertThat(str).isEqualTo(expectedString); + } +} diff --git a/core/tests/coretests/src/android/content/ContextTest.java b/core/tests/coretests/src/android/content/ContextTest.java index d1776fb7e5c1..8488a84dbe01 100644 --- a/core/tests/coretests/src/android/content/ContextTest.java +++ b/core/tests/coretests/src/android/content/ContextTest.java @@ -25,15 +25,23 @@ 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; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import android.app.ActivityThread; +import android.app.PendingIntent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInstaller; +import android.content.pm.PackageManager; import android.content.res.Configuration; +import android.content.res.Resources; import android.graphics.PixelFormat; import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.inputmethodservice.InputMethodService; import android.media.ImageReader; +import android.os.FileUtils; import android.os.UserHandle; import android.view.Display; @@ -42,12 +50,20 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; +import com.android.compatibility.common.util.ShellIdentityUtils; +import com.android.frameworks.coretests.R; + import org.junit.Test; import org.junit.runner.RunWith; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.TimeUnit; + /** - * Build/Install/Run: - * atest FrameworksCoreTests:ContextTest + * Build/Install/Run: + * atest FrameworksCoreTests:ContextTest */ @SmallTest @RunWith(AndroidJUnit4.class) @@ -216,6 +232,132 @@ public class ContextTest { assertFalse(context.isUiContext()); } + private static class TestReceiver extends BroadcastReceiver implements AutoCloseable { + private static final String INTENT_ACTION = "com.android.server.pm.test.test_app.action"; + private final ArrayBlockingQueue<Intent> mResults = new ArrayBlockingQueue<>(1); + + public IntentSender makeIntentSender() { + return PendingIntent.getBroadcast(getContext(), 0, new Intent(INTENT_ACTION), + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED) + .getIntentSender(); + } + + public void waitForIntent() throws InterruptedException { + assertNotNull(mResults.poll(30, TimeUnit.SECONDS)); + } + + @Override + public void onReceive(Context context, Intent intent) { + mResults.add(intent); + } + + public void register() { + getContext().registerReceiver(this, new IntentFilter(INTENT_ACTION)); + } + + @Override + public void close() throws Exception { + getContext().unregisterReceiver(this); + } + + private Context getContext() { + return InstrumentationRegistry.getInstrumentation().getContext(); + } + } + + @Test + public void applicationContextBeforeAndAfterUpgrade() throws Exception { + final Context context = InstrumentationRegistry.getInstrumentation().getContext(); + final String testPackageName = "com.android.frameworks.coretests.res_version"; + try { + final PackageManager pm = context.getPackageManager(); + final int versionRes = 0x7f010000; + + final Context appContext = ApplicationProvider.getApplicationContext(); + installApk(appContext, R.raw.res_version_before); + + ApplicationInfo info = pm.getApplicationInfo(testPackageName, 0); + final Context beforeContext = appContext.createApplicationContext(info, 0); + assertEquals("before", beforeContext.getResources().getString(versionRes)); + + installApk(appContext, R.raw.res_version_after); + + info = pm.getApplicationInfo(testPackageName, 0); + final Context afterContext = appContext.createApplicationContext(info, 0); + assertEquals("before", beforeContext.createConfigurationContext(Configuration.EMPTY) + .getResources().getString(versionRes)); + assertEquals("after", afterContext.createConfigurationContext(Configuration.EMPTY) + .getResources().getString(versionRes)); + assertNotEquals(beforeContext.getPackageResourcePath(), + afterContext.getPackageResourcePath()); + } finally { + uninstallPackage(context, testPackageName); + } + } + + @Test + public void packageContextBeforeAndAfterUpgrade() throws Exception { + final Context context = InstrumentationRegistry.getInstrumentation().getContext(); + final String testPackageName = "com.android.frameworks.coretests.res_version"; + try { + final int versionRes = 0x7f010000; + final Context appContext = ApplicationProvider.getApplicationContext(); + installApk(appContext, R.raw.res_version_before); + + final Context beforeContext = appContext.createPackageContext(testPackageName, 0); + assertEquals("before", beforeContext.getResources().getString(versionRes)); + + installApk(appContext, R.raw.res_version_after); + + final Context afterContext = appContext.createPackageContext(testPackageName, 0); + assertEquals("before", beforeContext.createConfigurationContext(Configuration.EMPTY) + .getResources().getString(versionRes)); + assertEquals("after", afterContext.createConfigurationContext(Configuration.EMPTY) + .getResources().getString(versionRes)); + assertNotEquals(beforeContext.getPackageResourcePath(), + afterContext.getPackageResourcePath()); + } finally { + uninstallPackage(context, testPackageName); + } + } + + private void installApk(Context context, int rawApkResId) throws Exception { + final PackageManager pm = context.getPackageManager(); + final PackageInstaller pi = pm.getPackageInstaller(); + final PackageInstaller.SessionParams params = new PackageInstaller.SessionParams( + PackageInstaller.SessionParams.MODE_FULL_INSTALL); + final int sessionId = pi.createSession(params); + + try (PackageInstaller.Session session = pi.openSession(sessionId)) { + // Copy the apk to the install session. + final Resources resources = context.getResources(); + try (InputStream is = resources.openRawResource(rawApkResId); + OutputStream sessionOs = session.openWrite("base", 0, -1)) { + FileUtils.copy(is, sessionOs); + } + + // Wait for the installation to finish + try (TestReceiver receiver = new TestReceiver()) { + receiver.register(); + ShellIdentityUtils.invokeMethodWithShellPermissions(session, + (s) -> { + s.commit(receiver.makeIntentSender()); + return true; + }); + receiver.waitForIntent(); + } + } + } + + private void uninstallPackage(Context context, String packageName) throws Exception { + try (TestReceiver receiver = new TestReceiver()) { + receiver.register(); + final PackageInstaller pi = context.getPackageManager().getPackageInstaller(); + pi.uninstall(packageName, receiver.makeIntentSender()); + receiver.waitForIntent(); + } + } + private Context createUiContext() { final Context appContext = ApplicationProvider.getApplicationContext(); final DisplayManager displayManager = appContext.getSystemService(DisplayManager.class); diff --git a/core/tests/coretests/src/android/os/VibratorTest.java b/core/tests/coretests/src/android/os/VibratorTest.java index 8f9168b58184..0ece793c8125 100644 --- a/core/tests/coretests/src/android/os/VibratorTest.java +++ b/core/tests/coretests/src/android/os/VibratorTest.java @@ -16,6 +16,8 @@ package android.os; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; import static junit.framework.TestCase.assertEquals; import static org.mockito.ArgumentMatchers.any; @@ -26,6 +28,7 @@ import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import android.hardware.vibrator.IVibrator; import android.media.AudioAttributes; import android.platform.test.annotations.Presubmit; @@ -70,6 +73,54 @@ public class VibratorTest { } @Test + public void areEffectsSupported_noVibrator_returnsAlwaysNo() { + SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo( + new VibratorInfo[0]); + assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_NO, + info.isEffectSupported(VibrationEffect.EFFECT_CLICK)); + } + + @Test + public void areEffectsSupported_unsupportedInOneVibrator_returnsNo() { + VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1) + .setSupportedEffects(VibrationEffect.EFFECT_CLICK) + .build(); + VibratorInfo unsupportedVibrator = new VibratorInfo.Builder(/* id= */ 2) + .setSupportedEffects(new int[0]) + .build(); + SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo( + new VibratorInfo[]{supportedVibrator, unsupportedVibrator}); + assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_NO, + info.isEffectSupported(VibrationEffect.EFFECT_CLICK)); + } + + @Test + public void areEffectsSupported_unknownInOneVibrator_returnsUnknown() { + VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1) + .setSupportedEffects(VibrationEffect.EFFECT_CLICK) + .build(); + VibratorInfo unknownSupportVibrator = VibratorInfo.EMPTY_VIBRATOR_INFO; + SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo( + new VibratorInfo[]{supportedVibrator, unknownSupportVibrator}); + assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_UNKNOWN, + info.isEffectSupported(VibrationEffect.EFFECT_CLICK)); + } + + @Test + public void arePrimitivesSupported_supportedInAllVibrators_returnsYes() { + VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1) + .setSupportedEffects(VibrationEffect.EFFECT_CLICK) + .build(); + VibratorInfo secondVibrator = new VibratorInfo.Builder(/* id= */ 2) + .setSupportedEffects(VibrationEffect.EFFECT_CLICK) + .build(); + SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo( + new VibratorInfo[]{firstVibrator, secondVibrator}); + assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_YES, + info.isEffectSupported(VibrationEffect.EFFECT_CLICK)); + } + + @Test public void arePrimitivesSupported_returnsArrayOfSameSize() { assertEquals(0, mVibratorSpy.arePrimitivesSupported(new int[0]).length); assertEquals(1, mVibratorSpy.arePrimitivesSupported( @@ -80,6 +131,40 @@ public class VibratorTest { } @Test + public void arePrimitivesSupported_noVibrator_returnsAlwaysFalse() { + SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo( + new VibratorInfo[0]); + assertFalse(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK)); + } + + @Test + public void arePrimitivesSupported_unsupportedInOneVibrator_returnsFalse() { + VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1) + .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS) + .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10) + .build(); + VibratorInfo unsupportedVibrator = VibratorInfo.EMPTY_VIBRATOR_INFO; + SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo( + new VibratorInfo[]{supportedVibrator, unsupportedVibrator}); + assertFalse(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK)); + } + + @Test + public void arePrimitivesSupported_supportedInAllVibrators_returnsTrue() { + VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1) + .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS) + .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 5) + .build(); + VibratorInfo secondVibrator = new VibratorInfo.Builder(/* id= */ 2) + .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS) + .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 15) + .build(); + SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo( + new VibratorInfo[]{firstVibrator, secondVibrator}); + assertTrue(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK)); + } + + @Test public void getPrimitivesDurations_returnsArrayOfSameSize() { assertEquals(0, mVibratorSpy.getPrimitiveDurations(new int[0]).length); assertEquals(1, mVibratorSpy.getPrimitiveDurations( @@ -90,6 +175,40 @@ public class VibratorTest { } @Test + public void getPrimitivesDurations_noVibrator_returnsAlwaysZero() { + SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo( + new VibratorInfo[0]); + assertEquals(0, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK)); + } + + @Test + public void getPrimitivesDurations_unsupportedInOneVibrator_returnsZero() { + VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1) + .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS) + .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10) + .build(); + VibratorInfo unsupportedVibrator = VibratorInfo.EMPTY_VIBRATOR_INFO; + SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo( + new VibratorInfo[]{supportedVibrator, unsupportedVibrator}); + assertEquals(0, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK)); + } + + @Test + public void getPrimitivesDurations_supportedInAllVibrators_returnsMaxDuration() { + VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1) + .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS) + .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10) + .build(); + VibratorInfo secondVibrator = new VibratorInfo.Builder(/* id= */ 2) + .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS) + .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 20) + .build(); + SystemVibrator.AllVibratorsInfo info = new SystemVibrator.AllVibratorsInfo( + new VibratorInfo[]{firstVibrator, secondVibrator}); + assertEquals(20, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK)); + } + + @Test public void vibrate_withAudioAttributes_createsVibrationAttributesWithSameUsage() { VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK); AudioAttributes audioAttributes = new AudioAttributes.Builder().setUsage( diff --git a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java index 45b63e03c27e..652622db66c2 100644 --- a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java +++ b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java @@ -304,11 +304,6 @@ public class ForwardDeleteTest { forwardDelete(state, 0); state.assertEquals("|"); - // Regional indicator symbol + COMBINING ENCLOSING KEYCAP - state.setByString("| U+1F1FA U+20E3"); - forwardDelete(state, 0); - state.assertEquals("|"); - // COMBINING ENCLOSING KEYCAP + emoji modifier state.setByString("| '1' U+20E3 U+1F3FB"); forwardDelete(state, 0); @@ -408,11 +403,6 @@ public class ForwardDeleteTest { // forwardDelete(state, 0); // state.assertEquals("|"); - // Regional indicator symbol + emoji modifier - state.setByString("| U+1F1FA U+1F3FB"); - forwardDelete(state, 0); - state.assertEquals("|"); - // Emoji modifier + regional indicator symbol state.setByString("| U+1F466 U+1F3FB U+1F1FA"); forwardDelete(state, 0); diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java index 55943a0dc319..82b2bf4185e6 100644 --- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java @@ -19,6 +19,7 @@ package com.android.internal.os; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -969,11 +970,61 @@ public class BinderCallsStatsTest { } @Test + public void testLatencyCollectionActiveEvenWithoutDeviceState() { + TestBinderCallsStats bcs = new TestBinderCallsStats(null); + bcs.setCollectLatencyData(true); + + Binder binder = new Binder(); + CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID); + assertNotEquals(null, callSession); + + bcs.time += 10; + bcs.elapsedTime += 20; + bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID); + + assertEquals(1, bcs.getLatencyObserver().getLatencyHistograms().size()); + } + + @Test public void testLatencyCollectionEnabledByDefault() { TestBinderCallsStats bcs = new TestBinderCallsStats(); assertEquals(true, bcs.getCollectLatencyData()); } + @Test + public void testProcessSource() { + BinderCallsStats defaultCallsStats = new BinderCallsStats( + new BinderCallsStats.Injector()); + + BinderCallsStats systemServerCallsStats = new BinderCallsStats( + new BinderCallsStats.Injector(), + com.android.internal.os.BinderLatencyProto.Dims.SYSTEM_SERVER); + + BinderCallsStats telephonyCallsStats = new BinderCallsStats( + new BinderCallsStats.Injector(), + com.android.internal.os.BinderLatencyProto.Dims.TELEPHONY); + + BinderCallsStats bluetoothCallsStats = new BinderCallsStats( + new BinderCallsStats.Injector(), + com.android.internal.os.BinderLatencyProto.Dims.BLUETOOTH); + + assertEquals( + com.android.internal.os.BinderLatencyProto.Dims.SYSTEM_SERVER, + defaultCallsStats.getLatencyObserver().getProcessSource()); + + assertEquals( + com.android.internal.os.BinderLatencyProto.Dims.SYSTEM_SERVER, + systemServerCallsStats.getLatencyObserver().getProcessSource()); + + assertEquals( + com.android.internal.os.BinderLatencyProto.Dims.TELEPHONY, + telephonyCallsStats.getLatencyObserver().getProcessSource()); + + assertEquals( + com.android.internal.os.BinderLatencyProto.Dims.BLUETOOTH, + bluetoothCallsStats.getLatencyObserver().getProcessSource()); + } + private static class TestHandler extends Handler { ArrayList<Runnable> mRunnables = new ArrayList<>(); diff --git a/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java b/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java index 3f9e62e7b180..952721320c90 100644 --- a/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java @@ -29,6 +29,8 @@ import android.util.Log; import com.android.internal.util.FileRotator.Reader; import com.android.internal.util.FileRotator.Writer; +import com.android.internal.util.test.FsUtil; + import com.google.android.collect.Lists; import java.io.DataInputStream; @@ -38,15 +40,10 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.ProtocolException; import java.util.ArrayList; import java.util.Arrays; import java.util.Random; -import junit.framework.Assert; - -import libcore.io.IoUtils; - /** * Tests for {@link FileRotator}. */ @@ -67,7 +64,7 @@ public class FileRotatorTest extends AndroidTestCase { super.setUp(); mBasePath = getContext().getFilesDir(); - IoUtils.deleteContents(mBasePath); + FsUtil.deleteContents(mBasePath); } public void testEmpty() throws Exception { diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 04291e3dcc5c..6385952fe884 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -428,6 +428,8 @@ applications that come with the platform <!-- Permissions required for CTS test - TVInputManagerTest --> <permission name="android.permission.ACCESS_TUNED_INFO" /> <permission name="android.permission.TV_INPUT_HARDWARE" /> + <permission name="com.android.providers.tv.permission.ACCESS_WATCHED_PROGRAMS" /> + <permission name="com.android.providers.tv.permission.WRITE_EPG_DATA"/> <!-- Permission required for CTS test - PrivilegedLocationPermissionTest --> <permission name="android.permission.LOCATION_HARDWARE" /> <!-- Permissions required for GTS test - GtsDialerAudioTestCases --> @@ -494,6 +496,8 @@ applications that come with the platform <permission name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS" /> <!-- Permission required for CTS test - CtsAlarmManagerTestCases --> <permission name="android.permission.UPDATE_DEVICE_STATS" /> + <!-- Permission required for GTS test - PendingSystemUpdateTest --> + <permission name="android.permission.NOTIFY_PENDING_SYSTEM_UPDATE" /> </privapp-permissions> <privapp-permissions package="com.android.statementservice"> diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml index d757a8c75a80..4ae0fc4ae6ed 100644 --- a/data/fonts/fonts.xml +++ b/data/fonts/fonts.xml @@ -1331,6 +1331,9 @@ <family lang="und-Zsye"> <font weight="400" style="normal">NotoColorEmoji.ttf</font> </family> + <family lang="und-Zsye"> + <font weight="400" style="normal">NotoColorEmojiFlags.ttf</font> + </family> <family lang="und-Zsym"> <font weight="400" style="normal">NotoSansSymbols-Regular-Subsetted2.ttf</font> </family> diff --git a/data/keyboards/Vendor_0a5c_Product_8502.kl b/data/keyboards/idroid_con.kl index 6d4a163d9f0b..6d4a163d9f0b 100644 --- a/data/keyboards/Vendor_0a5c_Product_8502.kl +++ b/data/keyboards/idroid_con.kl diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java index 4534d36342db..6c1c2ee1ee57 100644 --- a/graphics/java/android/graphics/BLASTBufferQueue.java +++ b/graphics/java/android/graphics/BLASTBufferQueue.java @@ -131,4 +131,12 @@ public final class BLASTBufferQueue { nativeMergeWithNextTransaction(mNativeObject, t.mNativeObject, frameNumber); } + /** + * Merge the transaction passed in to the next transaction in BlastBufferQueue. + * @param nativeTransaction native handle passed from native c/c++ code. + */ + public void mergeWithNextTransaction(long nativeTransaction, long frameNumber) { + nativeMergeWithNextTransaction(mNativeObject, nativeTransaction, frameNumber); + } + } diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java index e141d5178570..30d1e0fdb9d8 100644 --- a/graphics/java/android/graphics/HardwareRenderer.java +++ b/graphics/java/android/graphics/HardwareRenderer.java @@ -912,7 +912,7 @@ public class HardwareRenderer { * @param aSurfaceControlNativeObj ASurfaceControl native object handle * @param frame The id of the frame being drawn. */ - void onMergeTransaction(long aSurfaceTranactionNativeObj, + boolean onMergeTransaction(long aSurfaceTranactionNativeObj, long aSurfaceControlNativeObj, long frame); } diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index 8aba87ba3c8f..b994ad20320b 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -184,7 +184,6 @@ public class RippleDrawable extends LayerDrawable { private PorterDuffColorFilter mMaskColorFilter; private PorterDuffColorFilter mFocusColorFilter; private boolean mHasValidMask; - private int mComputedRadius = -1; /** The current ripple. May be actively animating or pending entry. */ private RippleForeground mRipple; @@ -390,8 +389,6 @@ public class RippleDrawable extends LayerDrawable { if (mRipple != null) { mRipple.onBoundsChange(); } - - mComputedRadius = Math.round(computeRadius()); invalidateSelf(); } @@ -750,7 +747,7 @@ public class RippleDrawable extends LayerDrawable { if (mBackground != null) { mBackground.onHotspotBoundsChanged(); } - float newRadius = Math.round(computeRadius()); + float newRadius = Math.round(getComputedRadius()); for (int i = 0; i < mRunningAnimations.size(); i++) { RippleAnimationSession s = mRunningAnimations.get(i); s.setRadius(newRadius); @@ -939,14 +936,13 @@ public class RippleDrawable extends LayerDrawable { } private float computeRadius() { - Rect b = getDirtyBounds(); - float radius = (float) Math.sqrt(b.width() * b.width() + b.height() * b.height()) / 2; - return radius; + final float halfWidth = mHotspotBounds.width() / 2.0f; + final float halfHeight = mHotspotBounds.height() / 2.0f; + return (float) Math.sqrt(halfWidth * halfWidth + halfHeight * halfHeight); } private int getComputedRadius() { if (mState.mMaxRadius >= 0) return mState.mMaxRadius; - if (mComputedRadius >= 0) return mComputedRadius; return (int) computeRadius(); } diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java index 89d2b743a619..72a145fa6a05 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java @@ -151,7 +151,7 @@ public class AndroidKeyStoreProvider extends Provider { * Gets the {@link KeyStore} operation handle corresponding to the provided JCA crypto * primitive. * - * <p>The following primitives are supported: {@link Cipher} and {@link Mac}. + * <p>The following primitives are supported: {@link Cipher}, {@link Signature} and {@link Mac}. * * @return KeyStore operation handle or {@code 0} if the provided primitive's KeyStore operation * is not in progress. diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml index ca7d077e0ef0..f646039df1f8 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings.xml @@ -45,7 +45,7 @@ <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"٪۵۰ بالا"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"٪۳۰ بالا"</string> <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"تمامصفحه پایین"</string> - <string name="one_handed_tutorial_title" msgid="4583241688067426350">"استفاده از «حالت تک حرکت»"</string> + <string name="one_handed_tutorial_title" msgid="4583241688067426350">"استفاده از حالت یکدستی"</string> <string name="one_handed_tutorial_description" msgid="3486582858591353067">"برای خارج شدن، از پایین صفحهنمایش تند بهطرف بالا بکشید یا در هر جایی از بالای برنامه که میخواهید ضربه بزنید"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"آغاز «حالت تک حرکت»"</string> <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"خروج از «حالت تک حرکت»"</string> diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index 70f03d234a56..f28ee820eb35 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -117,7 +117,9 @@ <!-- This should be at least the size of bubble_expanded_view_padding; it is used to include a slight touch slop around the expanded view. --> <dimen name="bubble_expanded_view_slop">8dp</dimen> - <!-- Default (and minimum) height of the expanded view shown when the bubble is expanded --> + <!-- Default (and minimum) height of the expanded view shown when the bubble is expanded. + If this value changes then R.dimen.bubble_expanded_view_min_height in CtsVerifier + should also be updated. --> <dimen name="bubble_expanded_default_height">180dp</dimen> <!-- On large screens the width of the expanded view is restricted to this size. --> <dimen name="bubble_expanded_view_tablet_width">412dp</dimen> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java index b2ac61cf3f6e..cb27ad9f58f5 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java @@ -249,6 +249,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged !activeControl.getSurfacePosition().equals(lastSurfacePosition); final boolean leashChanged = !haveSameLeash(mImeSourceControl, activeControl); + final InsetsSourceControl lastImeControl = mImeSourceControl; mImeSourceControl = activeControl; if (mAnimation != null) { if (positionChanged) { @@ -262,6 +263,9 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged removeImeSurface(); } } + if (lastImeControl != null) { + lastImeControl.release(SurfaceControl::release); + } } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java index 53dd391a01af..75a1ddeccb22 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java @@ -19,8 +19,8 @@ package com.android.wm.shell.hidedisplaycutout; import static android.view.Display.DEFAULT_DISPLAY; import android.content.Context; +import android.content.res.Configuration; import android.graphics.Insets; -import android.graphics.Point; import android.graphics.Rect; import android.util.ArrayMap; import android.util.Log; @@ -40,13 +40,12 @@ import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import com.android.internal.R; -import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; import java.io.PrintWriter; import java.util.List; -import java.util.concurrent.Executor; /** * Manages the display areas of hide display cutout feature. @@ -76,19 +75,29 @@ class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer { @VisibleForTesting int mRotation; - /** - * Handles rotation based on OnDisplayChangingListener callback. - */ - private final DisplayChangeController.OnDisplayChangingListener mRotationController = - (display, fromRotation, toRotation, wct) -> { - mRotation = toRotation; - updateBoundsAndOffsets(true /* enable */); - final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); - applyAllBoundsAndOffsets(wct, t); - // Only apply t here since the server will do the wct.apply when the method - // finishes. - t.apply(); - }; + private final DisplayController.OnDisplaysChangedListener mListener = + new DisplayController.OnDisplaysChangedListener() { + @Override + public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) { + if (displayId != DEFAULT_DISPLAY) { + return; + } + DisplayLayout displayLayout = + mDisplayController.getDisplayLayout(DEFAULT_DISPLAY); + if (displayLayout == null) { + return; + } + final boolean rotationChanged = mRotation != displayLayout.rotation(); + mRotation = displayLayout.rotation(); + if (rotationChanged || isDisplayBoundsChanged()) { + updateBoundsAndOffsets(true /* enabled */); + final WindowContainerTransaction wct = new WindowContainerTransaction(); + final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); + applyAllBoundsAndOffsets(wct, t); + applyTransaction(wct, t); + } + } + }; HideDisplayCutoutOrganizer(Context context, DisplayController displayController, ShellExecutor mainExecutor) { @@ -154,10 +163,10 @@ class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer { * Enables hide display cutout. */ void enableHideDisplayCutout() { - mDisplayController.addDisplayChangingController(mRotationController); - final Display display = mDisplayController.getDisplay(DEFAULT_DISPLAY); - if (display != null) { - mRotation = display.getRotation(); + mDisplayController.addDisplayWindowListener(mListener); + final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(DEFAULT_DISPLAY); + if (displayLayout != null) { + mRotation = displayLayout.rotation(); } final List<DisplayAreaAppearedInfo> displayAreaInfos = registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT); @@ -174,7 +183,7 @@ class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer { */ void disableHideDisplayCutout() { updateBoundsAndOffsets(false /* enabled */); - mDisplayController.removeDisplayChangingController(mRotationController); + mDisplayController.removeDisplayWindowListener(mListener); unregisterOrganizer(); } @@ -193,23 +202,35 @@ class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer { @VisibleForTesting Rect getDisplayBoundsOfNaturalOrientation() { - Point realSize = new Point(0, 0); - final Display display = mDisplayController.getDisplay(DEFAULT_DISPLAY); - if (display != null) { - display.getRealSize(realSize); + final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(DEFAULT_DISPLAY); + if (displayLayout == null) { + return new Rect(); } final boolean isDisplaySizeFlipped = isDisplaySizeFlipped(); return new Rect( 0, 0, - isDisplaySizeFlipped ? realSize.y : realSize.x, - isDisplaySizeFlipped ? realSize.x : realSize.y); + isDisplaySizeFlipped ? displayLayout.height() : displayLayout.width(), + isDisplaySizeFlipped ? displayLayout.width() : displayLayout.height()); } private boolean isDisplaySizeFlipped() { return mRotation == Surface.ROTATION_90 || mRotation == Surface.ROTATION_270; } + private boolean isDisplayBoundsChanged() { + final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(DEFAULT_DISPLAY); + if (displayLayout == null) { + return false; + } + final boolean isDisplaySizeFlipped = isDisplaySizeFlipped(); + final int width = isDisplaySizeFlipped ? displayLayout.height() : displayLayout.width(); + final int height = isDisplaySizeFlipped ? displayLayout.width() : displayLayout.height(); + return mDefaultDisplayBounds.isEmpty() + || mDefaultDisplayBounds.width() != width + || mDefaultDisplayBounds.height() != height; + } + /** * Updates bounds and offsets according to current state. * @@ -237,7 +258,6 @@ class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer { mCurrentDisplayBounds.right); } mCurrentDisplayBounds.inset(mCurrentCutoutInsets); - // Replace the top bound with the max(status bar height, cutout height) if there is // cutout on the top side. mStatusBarHeight = getStatusBarHeight(); @@ -256,7 +276,7 @@ class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer { } private void initDefaultValuesIfNeeded() { - if (!mDefaultDisplayBounds.isEmpty()) { + if (!isDisplayBoundsChanged()) { return; } mDefaultDisplayBounds.set(getDisplayBoundsOfNaturalOrientation()); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java index 7e4010d5fa6f..362b40f33e89 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java @@ -408,7 +408,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, } boolean isHidden() { - return mSurfaceHidden; + return getVisibility() != View.VISIBLE || mSurfaceHidden; } /** Starts dragging the divider bar. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java index 261ff2f8de83..ea2fc1aae290 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java @@ -146,10 +146,8 @@ public class LegacySplitScreenController implements DisplayController.OnDisplays new LegacySplitDisplayLayout(mContext, displayLayout, mSplits); sdl.rotateTo(toRotation); mRotateSplitLayout = sdl; - final int position = isDividerVisible() - ? (mMinimized ? mView.mSnapTargetBeforeMinimized.position - : mView.getCurrentPosition()) - // snap resets to middle target when not in split-mode + // snap resets to middle target when not minimized and rotation changed. + final int position = mMinimized ? mView.mSnapTargetBeforeMinimized.position : sdl.getSnapAlgorithm().getMiddleTarget().position; DividerSnapAlgorithm snap = sdl.getSnapAlgorithm(); final DividerSnapAlgorithm.SnapTarget target = diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java index b5c54023c492..1cc7ed3afcf7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java @@ -95,7 +95,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController> private final OneHandedTouchHandler mTouchHandler; private final OneHandedState mState; private final OneHandedTutorialHandler mTutorialHandler; - private final OneHandedUiEventLogger mOneHandedUiEventLogger; private final TaskStackListenerImpl mTaskStackListener; private final IOverlayManager mOverlayManager; private final ShellExecutor mMainExecutor; @@ -105,6 +104,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController> private OneHandedEventCallback mEventCallback; private OneHandedDisplayAreaOrganizer mDisplayAreaOrganizer; private OneHandedBackgroundPanelOrganizer mBackgroundPanelOrganizer; + private OneHandedUiEventLogger mOneHandedUiEventLogger; /** * Handle rotation based on OnDisplayChangingListener callback @@ -115,6 +115,8 @@ public class OneHandedController implements RemoteCallable<OneHandedController> return; } mDisplayAreaOrganizer.onRotateDisplay(mContext, toRotation, wct); + mOneHandedUiEventLogger.writeEvent( + OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_ROTATION_OUT); }; private final DisplayController.OnDisplaysChangedListener mDisplaysChangedListener = @@ -498,6 +500,11 @@ public class OneHandedController implements RemoteCallable<OneHandedController> @VisibleForTesting void onActivatedActionChanged() { + if (!isShortcutEnabled()) { + Slog.w(TAG, "Shortcut not enabled, skip onActivatedActionChanged()"); + return; + } + if (!isOneHandedEnabled()) { final boolean success = mOneHandedSettingsUtil.setOneHandedModeEnabled( mContext.getContentResolver(), 1 /* Enabled for shortcut */, mUserId); @@ -586,6 +593,10 @@ public class OneHandedController implements RemoteCallable<OneHandedController> mContext.getContentResolver(), mUserId); setSwipeToNotificationEnabled(enabled); + mOneHandedUiEventLogger.writeEvent(enabled + ? OneHandedUiEventLogger.EVENT_ONE_HANDED_SETTINGS_SHOW_NOTIFICATION_ENABLED_ON + : OneHandedUiEventLogger.EVENT_ONE_HANDED_SETTINGS_SHOW_NOTIFICATION_ENABLED_OFF); + // Also checks one handed mode settings since they all need gesture overlay. setEnabledGesturalOverlay( enabled || mOneHandedSettingsUtil.getSettingsOneHandedModeEnabled( @@ -608,6 +619,11 @@ public class OneHandedController implements RemoteCallable<OneHandedController> } @VisibleForTesting + boolean isShortcutEnabled() { + return mOneHandedSettingsUtil.getShortcutEnabled(mContext.getContentResolver(), mUserId); + } + + @VisibleForTesting boolean isSwipeToNotificationEnabled() { return mIsSwipeToNotificationEnabled; } @@ -617,8 +633,11 @@ public class OneHandedController implements RemoteCallable<OneHandedController> mMainExecutor.execute(() -> stopOneHanded()); } - // Reset and align shortcut one_handed_mode_activated status with current mState - notifyShortcutState(mState.getState()); + // If setting is pull screen, notify shortcut one_handed_mode_activated to reset + // and align status with current mState when function enabled. + if (isOneHandedEnabled() && !isSwipeToNotificationEnabled()) { + notifyShortcutState(mState.getState()); + } mTouchHandler.onOneHandedEnabled(mIsOneHandedEnabled); @@ -717,6 +736,8 @@ public class OneHandedController implements RemoteCallable<OneHandedController> pw.println(mLockedDisabled); pw.print(innerPrefix + "mUserId="); pw.println(mUserId); + pw.print(innerPrefix + "isShortcutEnabled="); + pw.println(isShortcutEnabled()); if (mBackgroundPanelOrganizer != null) { mBackgroundPanelOrganizer.dump(pw); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java index da53b359a304..3baa69f0033a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java @@ -16,6 +16,8 @@ package com.android.wm.shell.onehanded; +import static com.android.internal.accessibility.AccessibilityShortcutController.ONE_HANDED_COMPONENT_NAME; + import android.annotation.IntDef; import android.content.ContentResolver; import android.database.ContentObserver; @@ -34,6 +36,9 @@ import java.lang.annotation.RetentionPolicy; public final class OneHandedSettingsUtil { private static final String TAG = "OneHandedSettingsUtil"; + private static final String ONE_HANDED_MODE_TARGET_NAME = + ONE_HANDED_COMPONENT_NAME.getShortClassName(); + @IntDef(prefix = {"ONE_HANDED_TIMEOUT_"}, value = { ONE_HANDED_TIMEOUT_NEVER, ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS, @@ -158,6 +163,17 @@ public final class OneHandedSettingsUtil { } /** + * Queries one-handed mode shortcut enabled in settings or not. + * + * @return true if user enabled one-handed shortcut in settings, false otherwise. + */ + public boolean getShortcutEnabled(ContentResolver resolver, int userId) { + final String targets = Settings.Secure.getStringForUser(resolver, + Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, userId); + return targets != null ? targets.contains(ONE_HANDED_MODE_TARGET_NAME) : false; + } + + /** * Sets tutorial shown counts. * * @return true if the value was set, false on database errors. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedUiEventLogger.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedUiEventLogger.java index 38ffb07aa5a4..4e610fad05ae 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedUiEventLogger.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedUiEventLogger.java @@ -50,6 +50,8 @@ public class OneHandedUiEventLogger { public static final int EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_4 = 15; public static final int EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_8 = 16; public static final int EVENT_ONE_HANDED_SETTINGS_TIMEOUT_SECONDS_12 = 17; + public static final int EVENT_ONE_HANDED_SETTINGS_SHOW_NOTIFICATION_ENABLED_ON = 18; + public static final int EVENT_ONE_HANDED_SETTINGS_SHOW_NOTIFICATION_ENABLED_OFF = 19; private static final String[] EVENT_TAGS = { "one_handed_trigger_gesture_in", @@ -69,7 +71,9 @@ public class OneHandedUiEventLogger { "one_handed_settings_timeout_seconds_never", "one_handed_settings_timeout_seconds_4", "one_handed_settings_timeout_seconds_8", - "one_handed_settings_timeout_seconds_12" + "one_handed_settings_timeout_seconds_12", + "one_handed_settings_show_notification_enabled_on", + "one_handed_settings_show_notification_enabled_off" }; public OneHandedUiEventLogger(UiEventLogger uiEventLogger) { @@ -152,7 +156,13 @@ public class OneHandedUiEventLogger { ONE_HANDED_SETTINGS_TOGGLES_TIMEOUT_SECONDS_8(364), @UiEvent(doc = "One-Handed mode timeout value changed to 12 seconds") - ONE_HANDED_SETTINGS_TOGGLES_TIMEOUT_SECONDS_12(365); + ONE_HANDED_SETTINGS_TOGGLES_TIMEOUT_SECONDS_12(365), + + @UiEvent(doc = "One-Handed mode show notification toggle on") + ONE_HANDED_SETTINGS_TOGGLES_SHOW_NOTIFICATION_ENABLED_ON(847), + + @UiEvent(doc = "One-Handed mode show notification toggle off") + ONE_HANDED_SETTINGS_TOGGLES_SHOW_NOTIFICATION_ENABLED_OFF(848); private final int mId; @@ -247,6 +257,14 @@ public class OneHandedUiEventLogger { mUiEventLogger.log(OneHandedSettingsTogglesEvent .ONE_HANDED_SETTINGS_TOGGLES_TIMEOUT_SECONDS_12); break; + case EVENT_ONE_HANDED_SETTINGS_SHOW_NOTIFICATION_ENABLED_ON: + mUiEventLogger.log(OneHandedSettingsTogglesEvent + .ONE_HANDED_SETTINGS_TOGGLES_SHOW_NOTIFICATION_ENABLED_ON); + break; + case EVENT_ONE_HANDED_SETTINGS_SHOW_NOTIFICATION_ENABLED_OFF: + mUiEventLogger.log(OneHandedSettingsTogglesEvent + .ONE_HANDED_SETTINGS_TOGGLES_SHOW_NOTIFICATION_ENABLED_OFF); + break; default: // Do nothing break; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java index 9986154b051d..4e477ca104dd 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java @@ -85,7 +85,10 @@ public class SplashScreenExitAnimation implements Animator.AnimatorListener { } View iconView = view.getIconView(); - if (iconView == null || iconView.getBackground() == null) { + + // If the icon and the background are invisible, don't animate it + if (iconView == null || iconView.getLayoutParams().width == 0 + || iconView.getLayoutParams().height == 0) { mIconFadeOutDuration = 0; mIconStartAlpha = 0; mAppRevealDelay = 0; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java index df3fee043419..b09d0d89a6b9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java @@ -77,6 +77,13 @@ public class SplashscreenContentDrawer { // For example, an icon with the foreground 108*108 opaque pixels and it's background // also 108*108 pixels, then do not enlarge this icon if only need to show foreground icon. private static final float ENLARGE_FOREGROUND_ICON_THRESHOLD = (72f * 72f) / (108f * 108f); + + /** + * If the developer doesn't specify a background for the icon, we slightly scale it up. + * + * The background is either manually specified in the theme or the Adaptive Icon + * background is used if it's different from the window background. + */ private static final float NO_BACKGROUND_SCALE = 192f / 160; private final Context mContext; private final IconProvider mIconProvider; @@ -228,7 +235,7 @@ public class SplashscreenContentDrawer { attrs.mWindowBgColor = safeReturnAttrDefault((def) -> typedArray.getColor( R.styleable.Window_windowSplashScreenBackground, def), Color.TRANSPARENT); - attrs.mReplaceIcon = safeReturnAttrDefault((def) -> typedArray.getDrawable( + attrs.mSplashScreenIcon = safeReturnAttrDefault((def) -> typedArray.getDrawable( R.styleable.Window_windowSplashScreenAnimatedIcon), null); attrs.mAnimationDuration = safeReturnAttrDefault((def) -> typedArray.getInt( R.styleable.Window_windowSplashScreenAnimationDuration, def), 0); @@ -241,7 +248,7 @@ public class SplashscreenContentDrawer { if (DEBUG) { Slog.d(TAG, "window attributes color: " + Integer.toHexString(attrs.mWindowBgColor) - + " icon " + attrs.mReplaceIcon + " duration " + attrs.mAnimationDuration + + " icon " + attrs.mSplashScreenIcon + " duration " + attrs.mAnimationDuration + " brandImage " + attrs.mBrandingImage); } } @@ -250,7 +257,7 @@ public class SplashscreenContentDrawer { public static class SplashScreenWindowAttrs { private int mWindowBgResId = 0; private int mWindowBgColor = Color.TRANSPARENT; - private Drawable mReplaceIcon = null; + private Drawable mSplashScreenIcon = null; private Drawable mBrandingImage = null; private int mIconBgColor = Color.TRANSPARENT; private int mAnimationDuration = 0; @@ -287,10 +294,15 @@ public class SplashscreenContentDrawer { // empty splash screen case animationDuration = 0; mFinalIconSize = 0; - } else if (mTmpAttrs.mReplaceIcon != null) { + } else if (mTmpAttrs.mSplashScreenIcon != null) { // replaced icon, don't process - iconDrawable = mTmpAttrs.mReplaceIcon; + iconDrawable = mTmpAttrs.mSplashScreenIcon; animationDuration = mTmpAttrs.mAnimationDuration; + + // There is no background below the icon, so scale the icon up + if (mTmpAttrs.mIconBgColor == Color.TRANSPARENT) { + mFinalIconSize *= NO_BACKGROUND_SCALE; + } createIconDrawable(iconDrawable, false); } else { final float iconScale = (float) mIconSize / (float) mDefaultIconSize; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java index dae7055ede53..211941f44c8e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java @@ -162,6 +162,7 @@ public class SplashscreenIconDrawableFactory { @Override public void draw(Canvas canvas) { + canvas.clipPath(mMaskScaleOnly); if (mMaskScaleOnly != null) { canvas.drawPath(mMaskScaleOnly, mPaint); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java index 46db35a6e29f..670af963230a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java @@ -288,6 +288,7 @@ public class StartingSurfaceDrawer { // create splash screen view finished. final SplashScreenViewSupplier viewSupplier = new SplashScreenViewSupplier(); final FrameLayout rootLayout = new FrameLayout(context); + rootLayout.setPadding(0, 0, 0, 0); final Runnable setViewSynchronized = () -> { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "addSplashScreenView"); // waiting for setContentView before relayoutWindow diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java index acf7f3367d71..382d5806e3c2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java @@ -16,6 +16,7 @@ package com.android.wm.shell.startingsurface; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.graphics.Color.WHITE; import static android.graphics.Color.alpha; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; @@ -63,6 +64,7 @@ import android.graphics.RectF; import android.hardware.HardwareBuffer; import android.os.IBinder; import android.os.RemoteException; +import android.os.SystemClock; import android.os.Trace; import android.util.MergedConfiguration; import android.util.Slog; @@ -116,11 +118,15 @@ public class TaskSnapshotWindow { private static final boolean DEBUG = StartingSurfaceDrawer.DEBUG_TASK_SNAPSHOT; private static final String TITLE_FORMAT = "SnapshotStartingWindow for taskId=%s"; + private static final long DELAY_REMOVAL_TIME_GENERAL = 100; + private static final long DELAY_REMOVAL_TIME_IME_VISIBLE = 350; + //tmp vars for unused relayout params private static final Point TMP_SURFACE_SIZE = new Point(); private final Window mWindow; private final Runnable mClearWindowHandler; + private final long mDelayRemovalTime; private final ShellExecutor mSplashScreenExecutor; private final SurfaceControl mSurfaceControl; private final IWindowSession mSession; @@ -132,8 +138,10 @@ public class TaskSnapshotWindow { private final RectF mTmpDstFrame = new RectF(); private final CharSequence mTitle; private boolean mHasDrawn; + private long mShownTime; private boolean mSizeMismatch; private final Paint mBackgroundPaint = new Paint(); + private final int mActivityType; private final int mStatusBarColor; private final SystemBarBackgroundPainter mSystemBarBackgroundPainter; private final int mOrientationOnCreation; @@ -190,6 +198,7 @@ public class TaskSnapshotWindow { final Point taskSize = snapshot.getTaskSize(); final Rect taskBounds = new Rect(0, 0, taskSize.x, taskSize.y); final int orientation = snapshot.getOrientation(); + final int activityType = runningTaskInfo.topActivityType; final int displayId = runningTaskInfo.displayId; final IWindowSession session = WindowManagerGlobal.getWindowSession(); @@ -207,10 +216,13 @@ public class TaskSnapshotWindow { taskDescription.setBackgroundColor(WHITE); } + final long delayRemovalTime = snapshot.hasImeSurface() ? DELAY_REMOVAL_TIME_IME_VISIBLE + : DELAY_REMOVAL_TIME_GENERAL; + final TaskSnapshotWindow snapshotSurface = new TaskSnapshotWindow( surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, appearance, - windowFlags, windowPrivateFlags, taskBounds, orientation, - topWindowInsetsState, clearWindowHandler, splashScreenExecutor); + windowFlags, windowPrivateFlags, taskBounds, orientation, activityType, + delayRemovalTime, topWindowInsetsState, clearWindowHandler, splashScreenExecutor); final Window window = snapshotSurface.mWindow; final InsetsState mTmpInsetsState = new InsetsState(); @@ -248,7 +260,8 @@ public class TaskSnapshotWindow { public TaskSnapshotWindow(SurfaceControl surfaceControl, TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription, int appearance, int windowFlags, int windowPrivateFlags, Rect taskBounds, - int currentOrientation, InsetsState topWindowInsetsState, Runnable clearWindowHandler, + int currentOrientation, int activityType, long delayRemovalTime, + InsetsState topWindowInsetsState, Runnable clearWindowHandler, ShellExecutor splashScreenExecutor) { mSplashScreenExecutor = splashScreenExecutor; mSession = WindowManagerGlobal.getWindowSession(); @@ -264,6 +277,8 @@ public class TaskSnapshotWindow { windowPrivateFlags, appearance, taskDescription, 1f, topWindowInsetsState); mStatusBarColor = taskDescription.getStatusBarColor(); mOrientationOnCreation = currentOrientation; + mActivityType = activityType; + mDelayRemovalTime = delayRemovalTime; mTransaction = new SurfaceControl.Transaction(); mClearWindowHandler = clearWindowHandler; } @@ -286,6 +301,17 @@ public class TaskSnapshotWindow { } void remove() { + final long now = SystemClock.uptimeMillis(); + if ((now - mShownTime < mDelayRemovalTime) + // Show the latest content as soon as possible for unlocking to home. + && mActivityType != ACTIVITY_TYPE_HOME) { + final long delayTime = mShownTime + mDelayRemovalTime - now; + mSplashScreenExecutor.executeDelayed(() -> remove(), delayTime); + if (DEBUG) { + Slog.d(TAG, "Defer removing snapshot surface in " + delayTime); + } + return; + } try { if (DEBUG) { Slog.d(TAG, "Removing snapshot surface, mHasDrawn: " + mHasDrawn); @@ -326,6 +352,7 @@ public class TaskSnapshotWindow { } else { drawSizeMatchSnapshot(); } + mShownTime = SystemClock.uptimeMillis(); mHasDrawn = true; reportDrawn(); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizerTest.java index 963757045453..3c124bafc18a 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizerTest.java @@ -50,6 +50,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.R; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; import org.junit.Before; @@ -82,6 +83,8 @@ public class HideDisplayCutoutOrganizerTest { @Mock private Display mDisplay; @Mock + private DisplayLayout mDisplayLayout; + @Mock private IWindowContainerToken mMockRealToken; private WindowContainerToken mToken; @@ -95,6 +98,7 @@ public class HideDisplayCutoutOrganizerTest { MockitoAnnotations.initMocks(this); when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay); + when(mMockDisplayController.getDisplayLayout(anyInt())).thenReturn(mDisplayLayout); HideDisplayCutoutOrganizer organizer = new HideDisplayCutoutOrganizer( mContext, mMockDisplayController, mMockMainExecutor); @@ -152,7 +156,7 @@ public class HideDisplayCutoutOrganizerTest { .getDisplayCutoutInsetsOfNaturalOrientation(); mContext.getOrCreateTestableResources().addOverride( R.dimen.status_bar_height_portrait, mFakeStatusBarHeightPortrait); - doReturn(Surface.ROTATION_0).when(mDisplay).getRotation(); + doReturn(Surface.ROTATION_0).when(mDisplayLayout).rotation(); mOrganizer.enableHideDisplayCutout(); verify(mOrganizer).registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT); @@ -171,7 +175,7 @@ public class HideDisplayCutoutOrganizerTest { .getDisplayCutoutInsetsOfNaturalOrientation(); mContext.getOrCreateTestableResources().addOverride( R.dimen.status_bar_height_landscape, mFakeStatusBarHeightLandscape); - doReturn(Surface.ROTATION_90).when(mDisplay).getRotation(); + doReturn(Surface.ROTATION_90).when(mDisplayLayout).rotation(); mOrganizer.enableHideDisplayCutout(); verify(mOrganizer).registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT); @@ -190,7 +194,7 @@ public class HideDisplayCutoutOrganizerTest { .getDisplayCutoutInsetsOfNaturalOrientation(); mContext.getOrCreateTestableResources().addOverride( R.dimen.status_bar_height_landscape, mFakeStatusBarHeightLandscape); - doReturn(Surface.ROTATION_270).when(mDisplay).getRotation(); + doReturn(Surface.ROTATION_270).when(mDisplayLayout).rotation(); mOrganizer.enableHideDisplayCutout(); verify(mOrganizer).registerOrganizer(DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT); @@ -219,4 +223,22 @@ public class HideDisplayCutoutOrganizerTest { assertThat(mOrganizer.mOffsetX).isEqualTo(0); assertThat(mOrganizer.mOffsetY).isEqualTo(0); } + + @Test + public void testDisplaySizeChange() { + doReturn(100).when(mDisplayLayout).width(); + doReturn(200).when(mDisplayLayout).height(); + doReturn(mFakeDefaultCutoutInsets).when(mOrganizer) + .getDisplayCutoutInsetsOfNaturalOrientation(); + mContext.getOrCreateTestableResources().addOverride( + R.dimen.status_bar_height_portrait, mFakeStatusBarHeightPortrait); + doReturn(Surface.ROTATION_0).when(mDisplayLayout).rotation(); + mOrganizer.enableHideDisplayCutout(); + assertThat(mOrganizer.mCurrentDisplayBounds).isEqualTo(new Rect(0, 15, 100, 200)); + + doReturn(200).when(mDisplayLayout).width(); + doReturn(400).when(mDisplayLayout).height(); + mOrganizer.updateBoundsAndOffsets(true); + assertThat(mOrganizer.mCurrentDisplayBounds).isEqualTo(new Rect(0, 15, 200, 400)); + } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java index 950900337918..be786fb55b30 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java @@ -118,6 +118,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { mDefaultTapAppToExitEnabled); when(mMockSettingsUitl.getSettingsSwipeToNotificationEnabled(any(), anyInt())).thenReturn( mDefaultSwipeToNotificationEnabled); + when(mMockSettingsUitl.getShortcutEnabled(any(), anyInt())).thenReturn(false); when(mMockDisplayAreaOrganizer.getLastDisplayBounds()).thenReturn( new Rect(0, 0, mDisplayLayout.width(), mDisplayLayout.height())); @@ -341,6 +342,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { when(mSpiedTransitionState.getState()).thenReturn(STATE_ACTIVE); when(mSpiedTransitionState.isTransitioning()).thenReturn(false); when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(true); + when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true); mSpiedOneHandedController.onActivatedActionChanged(); verify(mSpiedOneHandedController, never()).startOneHanded(); @@ -352,6 +354,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE); when(mSpiedTransitionState.isTransitioning()).thenReturn(false); when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(false); + when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true); mSpiedOneHandedController.onActivatedActionChanged(); verify(mSpiedOneHandedController, never()).startOneHanded(); @@ -363,6 +366,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE); when(mSpiedTransitionState.isTransitioning()).thenReturn(false); when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(true); + when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true); mSpiedOneHandedController.onActivatedActionChanged(); verify(mSpiedOneHandedController).startOneHanded(); @@ -374,6 +378,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { when(mSpiedTransitionState.getState()).thenReturn(STATE_ENTERING); when(mSpiedTransitionState.isTransitioning()).thenReturn(true); when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(true); + when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true); mSpiedOneHandedController.onActivatedActionChanged(); verify(mSpiedTransitionState, never()).setState(STATE_EXITING); @@ -384,6 +389,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { when(mSpiedTransitionState.getState()).thenReturn(STATE_EXITING); when(mSpiedTransitionState.isTransitioning()).thenReturn(true); when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(true); + when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true); mSpiedOneHandedController.onActivatedActionChanged(); verify(mSpiedTransitionState, never()).setState(STATE_ENTERING); @@ -392,6 +398,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { @Test public void testOneHandedDisabled_shortcutTrigger_thenAutoEnabled() { when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(false); + when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true); when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE); when(mSpiedTransitionState.isTransitioning()).thenReturn(false); when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(false); @@ -417,6 +424,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(true); when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE); when(mSpiedTransitionState.isTransitioning()).thenReturn(false); + when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true); when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(true); mSpiedOneHandedController.registerEventCallback(mMockEventCallback); mSpiedOneHandedController.onActivatedActionChanged(); @@ -425,11 +433,11 @@ public class OneHandedControllerTest extends OneHandedTestCase { } @Test - public void testNotifyShortcutState_whenUpdateOneHandedEnabled() { - when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(false); + public void testNotifyShortcutState_whenSetOneHandedEnabled() { + when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(true); when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE); when(mSpiedTransitionState.isTransitioning()).thenReturn(false); - when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(true); + when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(false); mSpiedOneHandedController.registerEventCallback(mMockEventCallback); mSpiedOneHandedController.setOneHandedEnabled(true); @@ -448,4 +456,31 @@ public class OneHandedControllerTest extends OneHandedTestCase { // Verify no NPE crash and mMockShellMainExecutor never be execute. verify(mMockShellMainExecutor, never()).execute(any()); } + + @Test + public void testShortcutEnable_ableToAutoEnableOneHandedMode() { + when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(false); + when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE); + when(mSpiedTransitionState.isTransitioning()).thenReturn(false); + when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true); + when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(false); + when(mMockSettingsUitl.setOneHandedModeEnabled(any(), anyInt(), anyInt())).thenReturn( + false /* To avoid test runner create Toast */); + mSpiedOneHandedController.onActivatedActionChanged(); + + verify(mSpiedOneHandedController).notifyUserConfigChanged(anyBoolean()); + } + + @Test + public void testShortcutDisable_shouldNotAutoEnableOneHandedMode() { + when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(false); + when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE); + when(mSpiedTransitionState.isTransitioning()).thenReturn(false); + when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(false); + when(mMockSettingsUitl.setOneHandedModeEnabled(any(), anyInt(), anyInt())).thenReturn(true); + mSpiedOneHandedController.onActivatedActionChanged(); + + verify(mMockSettingsUitl, never()).setOneHandedModeEnabled(any(), anyInt(), anyInt()); + verify(mSpiedOneHandedController, never()).notifyUserConfigChanged(anyBoolean()); + } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/TaskSnapshotWindowTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/TaskSnapshotWindowTest.java index 5945840a8fa2..a098a6863493 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/TaskSnapshotWindowTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/TaskSnapshotWindowTest.java @@ -16,6 +16,7 @@ package com.android.wm.shell.startingsurface; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; @@ -81,7 +82,8 @@ public class TaskSnapshotWindowTest { mWindow = new TaskSnapshotWindow(new SurfaceControl(), snapshot, "Test", createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), 0 /* appearance */, windowFlags /* windowFlags */, 0 /* privateWindowFlags */, - taskBounds, ORIENTATION_PORTRAIT, new InsetsState(), + taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, + 100 /* delayRemovalTime */, new InsetsState(), null /* clearWindow */, new TestShellExecutor()); } diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h index c770150650e2..45a4f6c9c70d 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -331,6 +331,8 @@ public: mSkiaLayer.reset(); } + mProperties.mutateLayerProperties().mutableStretchEffect().clear(); + mStretchMask.clear(); // Clear out the previous snapshot and the image filter the previous // snapshot was created with whenever the layer changes. mSnapshotResult.snapshot = nullptr; diff --git a/libs/hwui/effects/StretchEffect.cpp b/libs/hwui/effects/StretchEffect.cpp index 43f805d906a5..17cd3ceb577c 100644 --- a/libs/hwui/effects/StretchEffect.cpp +++ b/libs/hwui/effects/StretchEffect.cpp @@ -186,6 +186,7 @@ static const SkString stretchShader = SkString(R"( static const float ZERO = 0.f; static const float INTERPOLATION_STRENGTH_VALUE = 0.7f; +static const char CONTENT_TEXTURE[] = "uContentTexture"; sk_sp<SkShader> StretchEffect::getShader(float width, float height, const sk_sp<SkImage>& snapshotImage, @@ -207,7 +208,7 @@ sk_sp<SkShader> StretchEffect::getShader(float width, float height, mBuilder = std::make_unique<SkRuntimeShaderBuilder>(getStretchEffect()); } - mBuilder->child("uContentTexture") = + mBuilder->child(CONTENT_TEXTURE) = snapshotImage->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, SkSamplingOptions(SkFilterMode::kLinear), matrix); mBuilder->uniform("uInterpolationStrength").set(&INTERPOLATION_STRENGTH_VALUE, 1); @@ -226,7 +227,9 @@ sk_sp<SkShader> StretchEffect::getShader(float width, float height, mBuilder->uniform("viewportWidth").set(&width, 1); mBuilder->uniform("viewportHeight").set(&height, 1); - return mBuilder->makeShader(nullptr, false); + auto result = mBuilder->makeShader(nullptr, false); + mBuilder->child(CONTENT_TEXTURE) = nullptr; + return result; } sk_sp<SkRuntimeEffect> StretchEffect::getStretchEffect() { diff --git a/libs/hwui/effects/StretchEffect.h b/libs/hwui/effects/StretchEffect.h index 25777c278a11..7eb640447f61 100644 --- a/libs/hwui/effects/StretchEffect.h +++ b/libs/hwui/effects/StretchEffect.h @@ -40,9 +40,7 @@ public: StretchEffect() {} - bool isEmpty() const { - return MathUtils::isZero(mStretchDirection.x()) && MathUtils::isZero(mStretchDirection.y()); - } + bool isEmpty() const { return isZero(mStretchDirection.x()) && isZero(mStretchDirection.y()); } void setEmpty() { *this = StretchEffect{}; @@ -113,7 +111,23 @@ public: return !isEmpty(); } + void clear() { + mBuilder = nullptr; + } + private: + // The epsilon for StretchEffect is less than in MathUtils because + // the range is 0-1 for an entire screen and should be significantly + // less than 1 pixel for a smooth stretch animation. + inline static bool isZero(float value) { + // Using fabsf is more performant as ARM computes + // fabsf in a single instruction. + return fabsf(value) <= NON_ZERO_EPSILON; + } + // This should be good for 1/25,000 of a screen and should be good for + // screens with less than ~8000 pixels in one dimension with only 1/4 pixel + // cut-off. + static constexpr float NON_ZERO_EPSILON = 0.00004f; static sk_sp<SkRuntimeEffect> getStretchEffect(); mutable SkVector mStretchDirection{0, 0}; mutable std::unique_ptr<SkRuntimeShaderBuilder> mBuilder; diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp index 9ff2f461d40d..4d31cd90d40f 100644 --- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp +++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp @@ -662,16 +662,18 @@ static void android_view_ThreadedRenderer_setASurfaceTransactionCallback( auto globalCallbackRef = std::make_shared<JWeakGlobalRefHolder>(vm, aSurfaceTransactionCallback); proxy->setASurfaceTransactionCallback( - [globalCallbackRef](int64_t transObj, int64_t scObj, int64_t frameNr) { + [globalCallbackRef](int64_t transObj, int64_t scObj, int64_t frameNr) -> bool { JNIEnv* env = getenv(globalCallbackRef->vm()); jobject localref = env->NewLocalRef(globalCallbackRef->ref()); if (CC_UNLIKELY(!localref)) { - return; + return false; } - env->CallVoidMethod(localref, gASurfaceTransactionCallback.onMergeTransaction, - static_cast<jlong>(transObj), static_cast<jlong>(scObj), - static_cast<jlong>(frameNr)); + jboolean ret = env->CallBooleanMethod( + localref, gASurfaceTransactionCallback.onMergeTransaction, + static_cast<jlong>(transObj), static_cast<jlong>(scObj), + static_cast<jlong>(frameNr)); env->DeleteLocalRef(localref); + return ret; }); } } @@ -1064,7 +1066,7 @@ int register_android_view_ThreadedRenderer(JNIEnv* env) { jclass aSurfaceTransactionCallbackClass = FindClassOrDie(env, "android/graphics/HardwareRenderer$ASurfaceTransactionCallback"); gASurfaceTransactionCallback.onMergeTransaction = - GetMethodIDOrDie(env, aSurfaceTransactionCallbackClass, "onMergeTransaction", "(JJJ)V"); + GetMethodIDOrDie(env, aSurfaceTransactionCallbackClass, "onMergeTransaction", "(JJJ)Z"); jclass prepareSurfaceControlForWebviewCallbackClass = FindClassOrDie( env, "android/graphics/HardwareRenderer$PrepareSurfaceControlForWebviewCallback"); diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 44d0038ad47e..0c9711ba8025 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -910,9 +910,8 @@ CanvasContext* CanvasContext::getActiveContext() { bool CanvasContext::mergeTransaction(ASurfaceTransaction* transaction, ASurfaceControl* control) { if (!mASurfaceTransactionCallback) return false; - std::invoke(mASurfaceTransactionCallback, reinterpret_cast<int64_t>(transaction), - reinterpret_cast<int64_t>(control), getFrameNumber()); - return true; + return std::invoke(mASurfaceTransactionCallback, reinterpret_cast<int64_t>(transaction), + reinterpret_cast<int64_t>(control), getFrameNumber()); } void CanvasContext::prepareSurfaceControlForWebview() { diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index a61c2bfd5c01..3279ccb8e597 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -206,7 +206,7 @@ public: ASurfaceControlStats* stats); void setASurfaceTransactionCallback( - const std::function<void(int64_t, int64_t, int64_t)>& callback) { + const std::function<bool(int64_t, int64_t, int64_t)>& callback) { mASurfaceTransactionCallback = callback; } @@ -317,7 +317,7 @@ private: // If set to true, we expect that callbacks into onSurfaceStatsAvailable bool mExpectSurfaceStats = false; - std::function<void(int64_t, int64_t, int64_t)> mASurfaceTransactionCallback; + std::function<bool(int64_t, int64_t, int64_t)> mASurfaceTransactionCallback; std::function<void()> mPrepareSurfaceControlForWebviewCallback; void cleanupResources(); diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index c47050c31e9a..a77b5b569907 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -314,7 +314,7 @@ void RenderProxy::setPictureCapturedCallback( } void RenderProxy::setASurfaceTransactionCallback( - const std::function<void(int64_t, int64_t, int64_t)>& callback) { + const std::function<bool(int64_t, int64_t, int64_t)>& callback) { mRenderThread.queue().post( [this, cb = callback]() { mContext->setASurfaceTransactionCallback(cb); }); } diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index d575aa77e4ab..1b0f22e75a2d 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -123,7 +123,7 @@ public: void setContentDrawBounds(int left, int top, int right, int bottom); void setPictureCapturedCallback(const std::function<void(sk_sp<SkPicture>&&)>& callback); void setASurfaceTransactionCallback( - const std::function<void(int64_t, int64_t, int64_t)>& callback); + const std::function<bool(int64_t, int64_t, int64_t)>& callback); void setPrepareSurfaceControlForWebviewCallback(const std::function<void()>& callback); void setFrameCallback(std::function<void(int64_t)>&& callback); void setFrameCompleteCallback(std::function<void(int64_t)>&& callback); diff --git a/libs/hwui/renderthread/TimeLord.cpp b/libs/hwui/renderthread/TimeLord.cpp index 406066c92bab..a43fcdc6e202 100644 --- a/libs/hwui/renderthread/TimeLord.cpp +++ b/libs/hwui/renderthread/TimeLord.cpp @@ -15,22 +15,28 @@ */ #include "TimeLord.h" #include <limits> +#include "FrameInfo.h" namespace android { namespace uirenderer { namespace renderthread { -TimeLord::TimeLord() : mFrameIntervalNanos(milliseconds_to_nanoseconds(16)), - mFrameTimeNanos(0), - mFrameIntendedTimeNanos(0), - mFrameVsyncId(-1), - mFrameDeadline(std::numeric_limits<int64_t>::max()){} +TimeLord::TimeLord() + : mFrameIntervalNanos(milliseconds_to_nanoseconds(16)) + , mFrameTimeNanos(0) + , mFrameIntendedTimeNanos(0) + , mFrameVsyncId(UiFrameInfoBuilder::INVALID_VSYNC_ID) + , mFrameDeadline(std::numeric_limits<int64_t>::max()) {} bool TimeLord::vsyncReceived(nsecs_t vsync, nsecs_t intendedVsync, int64_t vsyncId, int64_t frameDeadline, nsecs_t frameInterval) { if (intendedVsync > mFrameIntendedTimeNanos) { mFrameIntendedTimeNanos = intendedVsync; - mFrameVsyncId = vsyncId; + + // The intendedVsync might have been advanced to account for scheduling + // jitter. Since we don't have a way to advance the vsync id we just + // reset it. + mFrameVsyncId = (vsyncId > mFrameVsyncId) ? vsyncId : UiFrameInfoBuilder::INVALID_VSYNC_ID; mFrameDeadline = frameDeadline; if (frameInterval > 0) { mFrameIntervalNanos = frameInterval; diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl index c9e4e0a9cb92..5d5c0fc6265d 100644 --- a/location/java/android/location/ILocationManager.aidl +++ b/location/java/android/location/ILocationManager.aidl @@ -122,6 +122,9 @@ interface ILocationManager boolean isLocationEnabledForUser(int userId); void setLocationEnabledForUser(boolean enabled, int userId); + boolean isAdasGnssLocationEnabledForUser(int userId); + void setAdasGnssLocationEnabledForUser(boolean enabled, int userId); + void addTestProvider(String name, in ProviderProperties properties, in List<String> locationTags, String packageName, @nullable String attributionTag); void removeTestProvider(String provider, String packageName, @nullable String attributionTag); diff --git a/location/java/android/location/LastLocationRequest.java b/location/java/android/location/LastLocationRequest.java index 9ea8048ad476..0970c1c76a36 100644 --- a/location/java/android/location/LastLocationRequest.java +++ b/location/java/android/location/LastLocationRequest.java @@ -34,12 +34,15 @@ import java.util.Objects; public final class LastLocationRequest implements Parcelable { private final boolean mHiddenFromAppOps; + private final boolean mAdasGnssBypass; private final boolean mLocationSettingsIgnored; private LastLocationRequest( boolean hiddenFromAppOps, + boolean adasGnssBypass, boolean locationSettingsIgnored) { mHiddenFromAppOps = hiddenFromAppOps; + mAdasGnssBypass = adasGnssBypass; mLocationSettingsIgnored = locationSettingsIgnored; } @@ -56,6 +59,21 @@ public final class LastLocationRequest implements Parcelable { } /** + * Returns true if this request may access GNSS even if location settings would normally deny + * this, in order to enable automotive safety features. This field is only respected on + * automotive devices, and only if the client is recognized as a legitimate ADAS (Advanced + * Driving Assistance Systems) application. + * + * @return true if all limiting factors will be ignored to satisfy GNSS request + * @hide + */ + // TODO: make this system api + public boolean isAdasGnssBypass() { + return mAdasGnssBypass; + } + + + /** * Returns true if location settings, throttling, background location limits, and any other * possible limiting factors will be ignored in order to satisfy this last location request. * @@ -65,12 +83,22 @@ public final class LastLocationRequest implements Parcelable { return mLocationSettingsIgnored; } + /** + * Returns true if any bypass flag is set on this request. For internal use only. + * + * @hide + */ + public boolean isBypass() { + return mAdasGnssBypass || mLocationSettingsIgnored; + } + public static final @NonNull Parcelable.Creator<LastLocationRequest> CREATOR = new Parcelable.Creator<LastLocationRequest>() { @Override public LastLocationRequest createFromParcel(Parcel in) { return new LastLocationRequest( /* hiddenFromAppOps= */ in.readBoolean(), + /* adasGnssBypass= */ in.readBoolean(), /* locationSettingsIgnored= */ in.readBoolean()); } @Override @@ -86,6 +114,7 @@ public final class LastLocationRequest implements Parcelable { @Override public void writeToParcel(@NonNull Parcel parcel, int flags) { parcel.writeBoolean(mHiddenFromAppOps); + parcel.writeBoolean(mAdasGnssBypass); parcel.writeBoolean(mLocationSettingsIgnored); } @@ -99,12 +128,13 @@ public final class LastLocationRequest implements Parcelable { } LastLocationRequest that = (LastLocationRequest) o; return mHiddenFromAppOps == that.mHiddenFromAppOps + && mAdasGnssBypass == that.mAdasGnssBypass && mLocationSettingsIgnored == that.mLocationSettingsIgnored; } @Override public int hashCode() { - return Objects.hash(mHiddenFromAppOps, mLocationSettingsIgnored); + return Objects.hash(mHiddenFromAppOps, mAdasGnssBypass, mLocationSettingsIgnored); } @NonNull @@ -115,8 +145,11 @@ public final class LastLocationRequest implements Parcelable { if (mHiddenFromAppOps) { s.append("hiddenFromAppOps, "); } + if (mAdasGnssBypass) { + s.append("adasGnssBypass, "); + } if (mLocationSettingsIgnored) { - s.append("locationSettingsIgnored, "); + s.append("settingsBypass, "); } if (s.length() > "LastLocationRequest[".length()) { s.setLength(s.length() - 2); @@ -131,6 +164,7 @@ public final class LastLocationRequest implements Parcelable { public static final class Builder { private boolean mHiddenFromAppOps; + private boolean mAdasGnssBypass; private boolean mLocationSettingsIgnored; /** @@ -138,6 +172,7 @@ public final class LastLocationRequest implements Parcelable { */ public Builder() { mHiddenFromAppOps = false; + mAdasGnssBypass = false; mLocationSettingsIgnored = false; } @@ -146,6 +181,7 @@ public final class LastLocationRequest implements Parcelable { */ public Builder(@NonNull LastLocationRequest lastLocationRequest) { mHiddenFromAppOps = lastLocationRequest.mHiddenFromAppOps; + mAdasGnssBypass = lastLocationRequest.mAdasGnssBypass; mLocationSettingsIgnored = lastLocationRequest.mLocationSettingsIgnored; } @@ -164,6 +200,25 @@ public final class LastLocationRequest implements Parcelable { } /** + * If set to true, indicates that the client is an ADAS (Advanced Driving Assistance + * Systems) client, which requires access to GNSS even if location settings would normally + * deny this, in order to enable auto safety features. This field is only respected on + * automotive devices, and only if the client is recognized as a legitimate ADAS + * application. Defaults to false. + * + * <p>Permissions enforcement occurs when resulting location request is actually used, not + * when this method is invoked. + * + * @hide + */ + // TODO: make this system api + @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) + public @NonNull LastLocationRequest.Builder setAdasGnssBypass(boolean adasGnssBypass) { + mAdasGnssBypass = adasGnssBypass; + return this; + } + + /** * If set to true, indicates that location settings, throttling, background location limits, * and any other possible limiting factors should be ignored in order to satisfy this * last location request. This is only intended for use in user initiated emergency @@ -186,6 +241,7 @@ public final class LastLocationRequest implements Parcelable { public @NonNull LastLocationRequest build() { return new LastLocationRequest( mHiddenFromAppOps, + mAdasGnssBypass, mLocationSettingsIgnored); } } diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index ae44c5e34521..526b84e85e38 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -315,6 +315,33 @@ public class LocationManager { public static final String EXTRA_LOCATION_ENABLED = "android.location.extra.LOCATION_ENABLED"; /** + * Broadcast intent action when the ADAS (Advanced Driving Assistance Systems) GNSS location + * enabled state changes. Includes a boolean intent extra, {@link #EXTRA_ADAS_GNSS_ENABLED}, + * with the enabled state of ADAS GNSS location. This broadcast only has meaning on automotive + * devices. + * + * @see #EXTRA_ADAS_GNSS_ENABLED + * @see #isAdasGnssLocationEnabled() + * + * @hide + */ + // TODO: @SystemApi + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_ADAS_GNSS_ENABLED_CHANGED = + "android.location.action.ADAS_GNSS_ENABLED_CHANGED"; + + /** + * Intent extra included with {@link #ACTION_ADAS_GNSS_ENABLED_CHANGED} broadcasts, containing + * the boolean enabled state of ADAS GNSS location. + * + * @see #ACTION_ADAS_GNSS_ENABLED_CHANGED + * + * @hide + */ + // TODO: @SystemApi + public static final String EXTRA_ADAS_GNSS_ENABLED = "android.location.extra.ADAS_GNSS_ENABLED"; + + /** * Broadcast intent action indicating that a high power location requests * has either started or stopped being active. The current state of * active location requests should be read from AppOpsManager using @@ -621,6 +648,42 @@ public class LocationManager { } /** + * Returns the current enabled/disabled state of ADAS (Advanced Driving Assistance Systems) + * GNSS location access for the given user. This controls safety critical automotive access to + * GNSS location. This only has meaning on automotive devices. + * + * @return true if ADAS location is enabled and false if ADAS location is disabled. + * + * @hide + */ + //TODO: @SystemApi + public boolean isAdasGnssLocationEnabled() { + try { + return mService.isAdasGnssLocationEnabledForUser(mContext.getUser().getIdentifier()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Enables or disables ADAS (Advanced Driving Assistance Systems) GNSS location access for the + * given user. This only has meaning on automotive devices. + * + * @param enabled true to enable ADAS location and false to disable ADAS location. + * + * @hide + */ + // TODO: @SystemApi + @RequiresPermission(WRITE_SECURE_SETTINGS) + public void setAdasGnssLocationEnabled(boolean enabled) { + try { + mService.setAdasGnssLocationEnabledForUser(enabled, mContext.getUser().getIdentifier()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Returns the current enabled/disabled status of the given provider. To listen for changes, see * {@link #PROVIDERS_CHANGED_ACTION}. * diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java index a3842a1ffd0a..b48e59676ac1 100644 --- a/location/java/android/location/LocationRequest.java +++ b/location/java/android/location/LocationRequest.java @@ -194,6 +194,7 @@ public final class LocationRequest implements Parcelable { private float mMinUpdateDistanceMeters; private final long mMaxUpdateDelayMillis; private boolean mHideFromAppOps; + private final boolean mAdasGnssBypass; private boolean mLocationSettingsIgnored; private boolean mLowPower; private @Nullable WorkSource mWorkSource; @@ -236,7 +237,7 @@ public final class LocationRequest implements Parcelable { if (LocationManager.PASSIVE_PROVIDER.equals(provider)) { quality = POWER_NONE; } else if (LocationManager.GPS_PROVIDER.equals(provider)) { - quality = ACCURACY_FINE; + quality = QUALITY_HIGH_ACCURACY; } else { quality = POWER_LOW; } @@ -289,6 +290,7 @@ public final class LocationRequest implements Parcelable { float minUpdateDistanceMeters, long maxUpdateDelayMillis, boolean hiddenFromAppOps, + boolean adasGnssBypass, boolean locationSettingsIgnored, boolean lowPower, WorkSource workSource) { @@ -302,8 +304,9 @@ public final class LocationRequest implements Parcelable { mMinUpdateDistanceMeters = minUpdateDistanceMeters; mMaxUpdateDelayMillis = maxUpdateDelayMillis; mHideFromAppOps = hiddenFromAppOps; - mLowPower = lowPower; + mAdasGnssBypass = adasGnssBypass; mLocationSettingsIgnored = locationSettingsIgnored; + mLowPower = lowPower; mWorkSource = Objects.requireNonNull(workSource); } @@ -339,15 +342,15 @@ public final class LocationRequest implements Parcelable { switch (quality) { case POWER_HIGH: // fall through - case ACCURACY_FINE: + case QUALITY_HIGH_ACCURACY: mQuality = QUALITY_HIGH_ACCURACY; break; - case ACCURACY_BLOCK: + case QUALITY_BALANCED_POWER_ACCURACY: mQuality = QUALITY_BALANCED_POWER_ACCURACY; break; case POWER_LOW: // fall through - case ACCURACY_CITY: + case QUALITY_LOW_POWER: mQuality = QUALITY_LOW_POWER; break; case POWER_NONE: @@ -648,6 +651,21 @@ public final class LocationRequest implements Parcelable { } /** + * Returns true if this request may access GNSS even if location settings would normally deny + * this, in order to enable automotive safety features. This field is only respected on + * automotive devices, and only if the client is recognized as a legitimate ADAS (Advanced + * Driving Assistance Systems) application. + * + * @return true if all limiting factors will be ignored to satisfy GNSS request + * + * @hide + */ + // TODO: @SystemApi + public boolean isAdasGnssBypass() { + return mAdasGnssBypass; + } + + /** * @hide * @deprecated LocationRequests should be treated as immutable. */ @@ -673,6 +691,15 @@ public final class LocationRequest implements Parcelable { } /** + * Returns true if any bypass flag is set on this request. For internal use only. + * + * @hide + */ + public boolean isBypass() { + return mAdasGnssBypass || mLocationSettingsIgnored; + } + + /** * @hide * @deprecated LocationRequests should be treated as immutable. */ @@ -749,6 +776,7 @@ public final class LocationRequest implements Parcelable { /* minUpdateDistanceMeters= */ in.readFloat(), /* maxUpdateDelayMillis= */ in.readLong(), /* hiddenFromAppOps= */ in.readBoolean(), + /* adasGnssBypass= */ in.readBoolean(), /* locationSettingsIgnored= */ in.readBoolean(), /* lowPower= */ in.readBoolean(), /* workSource= */ in.readTypedObject(WorkSource.CREATOR)); @@ -777,6 +805,7 @@ public final class LocationRequest implements Parcelable { parcel.writeFloat(mMinUpdateDistanceMeters); parcel.writeLong(mMaxUpdateDelayMillis); parcel.writeBoolean(mHideFromAppOps); + parcel.writeBoolean(mAdasGnssBypass); parcel.writeBoolean(mLocationSettingsIgnored); parcel.writeBoolean(mLowPower); parcel.writeTypedObject(mWorkSource, 0); @@ -801,6 +830,7 @@ public final class LocationRequest implements Parcelable { && Float.compare(that.mMinUpdateDistanceMeters, mMinUpdateDistanceMeters) == 0 && mMaxUpdateDelayMillis == that.mMaxUpdateDelayMillis && mHideFromAppOps == that.mHideFromAppOps + && mAdasGnssBypass == that.mAdasGnssBypass && mLocationSettingsIgnored == that.mLocationSettingsIgnored && mLowPower == that.mLowPower && Objects.equals(mProvider, that.mProvider) @@ -866,8 +896,11 @@ public final class LocationRequest implements Parcelable { if (mHideFromAppOps) { s.append(", hiddenFromAppOps"); } + if (mAdasGnssBypass) { + s.append(", adasGnssBypass"); + } if (mLocationSettingsIgnored) { - s.append(", locationSettingsIgnored"); + s.append(", settingsBypass"); } if (mWorkSource != null && !mWorkSource.isEmpty()) { s.append(", ").append(mWorkSource); @@ -889,6 +922,7 @@ public final class LocationRequest implements Parcelable { private float mMinUpdateDistanceMeters; private long mMaxUpdateDelayMillis; private boolean mHiddenFromAppOps; + private boolean mAdasGnssBypass; private boolean mLocationSettingsIgnored; private boolean mLowPower; @Nullable private WorkSource mWorkSource; @@ -908,6 +942,7 @@ public final class LocationRequest implements Parcelable { mMinUpdateDistanceMeters = 0; mMaxUpdateDelayMillis = 0; mHiddenFromAppOps = false; + mAdasGnssBypass = false; mLocationSettingsIgnored = false; mLowPower = false; mWorkSource = null; @@ -925,6 +960,7 @@ public final class LocationRequest implements Parcelable { mMinUpdateDistanceMeters = locationRequest.mMinUpdateDistanceMeters; mMaxUpdateDelayMillis = locationRequest.mMaxUpdateDelayMillis; mHiddenFromAppOps = locationRequest.mHideFromAppOps; + mAdasGnssBypass = locationRequest.mAdasGnssBypass; mLocationSettingsIgnored = locationRequest.mLocationSettingsIgnored; mLowPower = locationRequest.mLowPower; mWorkSource = locationRequest.mWorkSource; @@ -977,10 +1013,10 @@ public final class LocationRequest implements Parcelable { public @NonNull Builder setQuality(@NonNull Criteria criteria) { switch (criteria.getAccuracy()) { case Criteria.ACCURACY_COARSE: - mQuality = ACCURACY_BLOCK; + mQuality = QUALITY_BALANCED_POWER_ACCURACY; break; case Criteria.ACCURACY_FINE: - mQuality = ACCURACY_FINE; + mQuality = QUALITY_HIGH_ACCURACY; break; default: { if (criteria.getPowerRequirement() == Criteria.POWER_HIGH) { @@ -1092,6 +1128,25 @@ public final class LocationRequest implements Parcelable { } /** + * If set to true, indicates that the client is an ADAS (Advanced Driving Assistance + * Systems) client, which requires access to GNSS even if location settings would normally + * deny this, in order to enable auto safety features. This field is only respected on + * automotive devices, and only if the client is recognized as a legitimate ADAS + * application. Defaults to false. + * + * <p>Permissions enforcement occurs when resulting location request is actually used, not + * when this method is invoked. + * + * @hide + */ + // TODO: @SystemApi + @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) + public @NonNull Builder setAdasGnssBypass(boolean adasGnssBypass) { + mAdasGnssBypass = adasGnssBypass; + return this; + } + + /** * If set to true, indicates that location settings, throttling, background location limits, * and any other possible limiting factors should be ignored in order to satisfy this * request. This is only intended for use in user initiated emergency situations, and @@ -1171,6 +1226,7 @@ public final class LocationRequest implements Parcelable { mMinUpdateDistanceMeters, mMaxUpdateDelayMillis, mHiddenFromAppOps, + mAdasGnssBypass, mLocationSettingsIgnored, mLowPower, new WorkSource(mWorkSource)); diff --git a/location/java/android/location/provider/ProviderRequest.java b/location/java/android/location/provider/ProviderRequest.java index b72d36519e72..4f33a529a812 100644 --- a/location/java/android/location/provider/ProviderRequest.java +++ b/location/java/android/location/provider/ProviderRequest.java @@ -44,12 +44,19 @@ public final class ProviderRequest implements Parcelable { public static final long INTERVAL_DISABLED = Long.MAX_VALUE; public static final @NonNull ProviderRequest EMPTY_REQUEST = new ProviderRequest( - INTERVAL_DISABLED, QUALITY_BALANCED_POWER_ACCURACY, 0, false, false, new WorkSource()); + INTERVAL_DISABLED, + QUALITY_BALANCED_POWER_ACCURACY, + 0, + false, + false, + false, + new WorkSource()); private final long mIntervalMillis; private final @Quality int mQuality; private final long mMaxUpdateDelayMillis; private final boolean mLowPower; + private final boolean mAdasGnssBypass; private final boolean mLocationSettingsIgnored; private final WorkSource mWorkSource; @@ -72,12 +79,14 @@ public final class ProviderRequest implements Parcelable { @Quality int quality, long maxUpdateDelayMillis, boolean lowPower, + boolean adasGnssBypass, boolean locationSettingsIgnored, @NonNull WorkSource workSource) { mIntervalMillis = intervalMillis; mQuality = quality; mMaxUpdateDelayMillis = maxUpdateDelayMillis; mLowPower = lowPower; + mAdasGnssBypass = adasGnssBypass; mLocationSettingsIgnored = locationSettingsIgnored; mWorkSource = Objects.requireNonNull(workSource); } @@ -126,6 +135,18 @@ public final class ProviderRequest implements Parcelable { } /** + * Returns true if this request may access GNSS even if location settings would normally deny + * this, in order to enable automotive safety features. This field is only respected on + * automotive devices, and only if the client is recognized as a legitimate ADAS (Advanced + * Driving Assistance Systems) application. + * + * @hide + */ + public boolean isAdasGnssBypass() { + return mAdasGnssBypass; + } + + /** * Whether the provider should ignore all location settings, user consents, power restrictions * or any other restricting factors and always satisfy this request to the best of their * ability. This should only be used in case of a user initiated emergency. @@ -135,6 +156,15 @@ public final class ProviderRequest implements Parcelable { } /** + * Returns true if any bypass flag is set on this request. + * + * @hide + */ + public boolean isBypass() { + return mAdasGnssBypass || mLocationSettingsIgnored; + } + + /** * The power blame for this provider request. */ public @NonNull WorkSource getWorkSource() { @@ -153,6 +183,7 @@ public final class ProviderRequest implements Parcelable { /* quality= */ in.readInt(), /* maxUpdateDelayMillis= */ in.readLong(), /* lowPower= */ in.readBoolean(), + /* adasGnssBypass= */ in.readBoolean(), /* locationSettingsIgnored= */ in.readBoolean(), /* workSource= */ in.readTypedObject(WorkSource.CREATOR)); } @@ -176,6 +207,7 @@ public final class ProviderRequest implements Parcelable { parcel.writeInt(mQuality); parcel.writeLong(mMaxUpdateDelayMillis); parcel.writeBoolean(mLowPower); + parcel.writeBoolean(mAdasGnssBypass); parcel.writeBoolean(mLocationSettingsIgnored); parcel.writeTypedObject(mWorkSource, flags); } @@ -198,6 +230,7 @@ public final class ProviderRequest implements Parcelable { && mQuality == that.mQuality && mMaxUpdateDelayMillis == that.mMaxUpdateDelayMillis && mLowPower == that.mLowPower + && mAdasGnssBypass == that.mAdasGnssBypass && mLocationSettingsIgnored == that.mLocationSettingsIgnored && mWorkSource.equals(that.mWorkSource); } @@ -229,8 +262,11 @@ public final class ProviderRequest implements Parcelable { if (mLowPower) { s.append(", lowPower"); } + if (mAdasGnssBypass) { + s.append(", adasGnssBypass"); + } if (mLocationSettingsIgnored) { - s.append(", locationSettingsIgnored"); + s.append(", settingsBypass"); } if (!mWorkSource.isEmpty()) { s.append(", ").append(mWorkSource); @@ -246,10 +282,12 @@ public final class ProviderRequest implements Parcelable { * A Builder for {@link ProviderRequest}s. */ public static final class Builder { + private long mIntervalMillis = INTERVAL_DISABLED; private int mQuality = QUALITY_BALANCED_POWER_ACCURACY; private long mMaxUpdateDelayMillis = 0; private boolean mLowPower; + private boolean mAdasGnssBypass; private boolean mLocationSettingsIgnored; private WorkSource mWorkSource = new WorkSource(); @@ -299,6 +337,16 @@ public final class ProviderRequest implements Parcelable { } /** + * Sets whether this ADAS request should bypass GNSS settings. False by default. + * + * @hide + */ + public @NonNull Builder setAdasGnssBypass(boolean adasGnssBypass) { + this.mAdasGnssBypass = adasGnssBypass; + return this; + } + + /** * Sets whether location settings should be ignored. False by default. */ public @NonNull Builder setLocationSettingsIgnored(boolean locationSettingsIgnored) { @@ -326,6 +374,7 @@ public final class ProviderRequest implements Parcelable { mQuality, mMaxUpdateDelayMillis, mLowPower, + mAdasGnssBypass, mLocationSettingsIgnored, mWorkSource); } diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java index 860d88afe4a2..d8f48c2cf0c6 100755 --- a/media/java/android/mtp/MtpDatabase.java +++ b/media/java/android/mtp/MtpDatabase.java @@ -101,6 +101,8 @@ public class MtpDatabase implements AutoCloseable { private int mBatteryLevel; private int mBatteryScale; private int mDeviceType; + private String mHostType; + private boolean mSkipThumbForHost = false; private MtpServer mServer; private MtpStorageManager mManager; @@ -192,6 +194,7 @@ public class MtpDatabase implements AutoCloseable { MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE, MtpConstants.DEVICE_PROPERTY_BATTERY_LEVEL, MtpConstants.DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE, + MtpConstants.DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO, }; @VisibleForNative @@ -408,6 +411,8 @@ public class MtpDatabase implements AutoCloseable { } context.deleteDatabase(devicePropertiesName); } + mHostType = ""; + mSkipThumbForHost = false; } @VisibleForNative @@ -672,12 +677,24 @@ public class MtpDatabase implements AutoCloseable { @VisibleForNative private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) { + int length; + String value; + switch (property) { case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: // writable string properties kept in shared preferences - String value = mDeviceProperties.getString(Integer.toString(property), ""); - int length = value.length(); + value = mDeviceProperties.getString(Integer.toString(property), ""); + length = value.length(); + if (length > 255) { + length = 255; + } + value.getChars(0, length, outStringValue, 0); + outStringValue[length] = 0; + return MtpConstants.RESPONSE_OK; + case MtpConstants.DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO: + value = mHostType; + length = value.length(); if (length > 255) { length = 255; } @@ -717,6 +734,14 @@ public class MtpDatabase implements AutoCloseable { e.putString(Integer.toString(property), stringValue); return (e.commit() ? MtpConstants.RESPONSE_OK : MtpConstants.RESPONSE_GENERAL_ERROR); + case MtpConstants.DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO: + mHostType = stringValue; + if (stringValue.startsWith("Android/")) { + Log.d(TAG, "setDeviceProperty." + Integer.toHexString(property) + + "=" + stringValue); + mSkipThumbForHost = true; + } + return MtpConstants.RESPONSE_OK; } return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED; @@ -838,6 +863,10 @@ public class MtpDatabase implements AutoCloseable { outLongs[0] = thumbOffsetAndSize != null ? thumbOffsetAndSize[1] : 0; outLongs[1] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_X_DIMENSION, 0); outLongs[2] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_Y_DIMENSION, 0); + if (mSkipThumbForHost) { + Log.d(TAG, "getThumbnailInfo: Skip runtime thumbnail."); + return true; + } if (exif.getThumbnailRange() != null) { if ((outLongs[0] == 0) || (outLongs[1] == 0) || (outLongs[2] == 0)) { Log.d(TAG, "getThumbnailInfo: check thumb info:" @@ -880,6 +909,10 @@ public class MtpDatabase implements AutoCloseable { try { ExifInterface exif = new ExifInterface(path); + if (mSkipThumbForHost) { + Log.d(TAG, "getThumbnailData: Skip runtime thumbnail."); + return exif.getThumbnail(); + } if (exif.getThumbnailRange() != null) return exif.getThumbnail(); } catch (IOException e) { diff --git a/media/java/android/mtp/MtpDevice.java b/media/java/android/mtp/MtpDevice.java index e8b04edb2e1b..ec925918d4e6 100644 --- a/media/java/android/mtp/MtpDevice.java +++ b/media/java/android/mtp/MtpDevice.java @@ -170,6 +170,18 @@ public final class MtpDevice { } /** + * Set device property SESSION_INITIATOR_VERSION_INFO + * + * @param propertyStr string value for device property SESSION_INITIATOR_VERSION_INFO + * @return -1 for error, 0 for success + * + * {@hide} + */ + public int setDevicePropertyInitVersion(@NonNull String propertyStr) { + return native_set_device_property_init_version(propertyStr); + } + + /** * Returns the list of IDs for all storage units on this device * Information about each storage unit can be accessed via {@link #getStorageInfo}. * @@ -421,6 +433,7 @@ public final class MtpDevice { private native boolean native_open(String deviceName, int fd); private native void native_close(); private native MtpDeviceInfo native_get_device_info(); + private native int native_set_device_property_init_version(String propertyStr); private native int[] native_get_storage_ids(); private native MtpStorageInfo native_get_storage_info(int storageId); private native int[] native_get_object_handles(int storageId, int format, int objectHandle); diff --git a/media/java/android/mtp/MtpDeviceInfo.java b/media/java/android/mtp/MtpDeviceInfo.java index 0304ee386ace..88514515eabf 100644 --- a/media/java/android/mtp/MtpDeviceInfo.java +++ b/media/java/android/mtp/MtpDeviceInfo.java @@ -31,6 +31,7 @@ public class MtpDeviceInfo { private String mSerialNumber; private int[] mOperationsSupported; private int[] mEventsSupported; + private int[] mDevicePropertySupported; // only instantiated via JNI private MtpDeviceInfo() { @@ -144,6 +145,21 @@ public class MtpDeviceInfo { } /** + * Returns Device property code supported by the device. + * + * @return supported Device property code. Can be null if device does not provide the property. + * + * @see MtpConstants#DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER + * @see MtpConstants#DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME + * @see MtpConstants#DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO + * + * {@hide} + */ + public final @NonNull int[] getDevicePropertySupported() { + return mDevicePropertySupported; + } + + /** * Returns if the given operation is supported by the device or not. * @param code Operation code. * @return If the given operation is supported by the device or not. @@ -162,6 +178,17 @@ public class MtpDeviceInfo { } /** + * Returns if the given Device property is supported by the device or not. + * @param code Device property code. + * @return If the given Device property is supported by the device or not. + * + * {@hide} + */ + public boolean isDevicePropertySupported(int code) { + return isSupported(mDevicePropertySupported, code); + } + + /** * Returns if the code set contains code. * @hide */ diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp index ffed4747d3ea..a77bc9fe0570 100644 --- a/media/jni/android_mtp_MtpDatabase.cpp +++ b/media/jni/android_mtp_MtpDatabase.cpp @@ -1131,6 +1131,7 @@ static const PropertyTableEntry kDevicePropertyTable[] = { { MTP_DEVICE_PROPERTY_IMAGE_SIZE, MTP_TYPE_STR }, { MTP_DEVICE_PROPERTY_BATTERY_LEVEL, MTP_TYPE_UINT8 }, { MTP_DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE, MTP_TYPE_UINT32 }, + { MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO, MTP_TYPE_STR }, }; bool MtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) { @@ -1289,6 +1290,7 @@ MtpProperty* MtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) { switch (property) { case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: + case MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO: writable = true; // fall through FALLTHROUGH_INTENDED; diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp index 3d2b00fec26c..ac89fecd9150 100644 --- a/media/jni/android_mtp_MtpDevice.cpp +++ b/media/jni/android_mtp_MtpDevice.cpp @@ -72,6 +72,7 @@ static jfieldID field_deviceInfo_version; static jfieldID field_deviceInfo_serialNumber; static jfieldID field_deviceInfo_operationsSupported; static jfieldID field_deviceInfo_eventsSupported; +static jfieldID field_deviceInfo_devicePropertySupported; // MtpStorageInfo fields static jfieldID field_storageInfo_storageId; @@ -129,6 +130,8 @@ static void initializeJavaIDs(JNIEnv* env) { GetFieldIDOrDie(env, clazz_deviceInfo, "mOperationsSupported", "[I"); field_deviceInfo_eventsSupported = GetFieldIDOrDie(env, clazz_deviceInfo, "mEventsSupported", "[I"); + field_deviceInfo_devicePropertySupported = + GetFieldIDOrDie(env, clazz_deviceInfo, "mDevicePropertySupported", "[I"); clazz_storageInfo = (jclass)env->NewGlobalRef(FindClassOrDie(env, "android/mtp/MtpStorageInfo")); @@ -377,9 +380,65 @@ android_mtp_MtpDevice_get_device_info(JNIEnv *env, jobject thiz) } } + assert(deviceInfo->mDeviceProperties); + { + const size_t size = deviceInfo->mDeviceProperties->size(); + ScopedLocalRef<jintArray> events(env, static_cast<jintArray>(env->NewIntArray(size))); + { + ScopedIntArrayRW elements(env, events.get()); + if (elements.get() == NULL) { + ALOGE("Could not create devicePropertySupported element."); + return NULL; + } + for (size_t i = 0; i < size; ++i) { + elements[i] = static_cast<int>(deviceInfo->mDeviceProperties->at(i)); + } + env->SetObjectField(info, field_deviceInfo_devicePropertySupported, events.get()); + } + } + return info; } +static jint +android_mtp_MtpDevice_set_device_property_init_version(JNIEnv *env, jobject thiz, + jstring property_str) { + MtpDevice* const device = get_device_from_object(env, thiz); + + if (!device) { + ALOGD("%s device is null\n", __func__); + env->ThrowNew(clazz_io_exception, "Failed to obtain MtpDevice."); + return -1; + } + + const char *propertyStr = env->GetStringUTFChars(property_str, NULL); + if (propertyStr == NULL) { + return -1; + } + + MtpProperty* property = new MtpProperty(MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO, + MTP_TYPE_STR, true); + if (!property) { + env->ThrowNew(clazz_io_exception, "Failed to obtain property."); + return -1; + } + + if (property->getDataType() != MTP_TYPE_STR) { + env->ThrowNew(clazz_io_exception, "Unexpected property data type."); + return -1; + } + + property->setCurrentValue(propertyStr); + if (!device->setDevicePropValueStr(property)) { + env->ThrowNew(clazz_io_exception, "Failed to obtain property value."); + return -1; + } + + env->ReleaseStringUTFChars(property_str, propertyStr); + + return 0; +} + static jintArray android_mtp_MtpDevice_get_storage_ids(JNIEnv *env, jobject thiz) { @@ -847,6 +906,8 @@ static const JNINativeMethod gMethods[] = { {"native_close", "()V", (void *)android_mtp_MtpDevice_close}, {"native_get_device_info", "()Landroid/mtp/MtpDeviceInfo;", (void *)android_mtp_MtpDevice_get_device_info}, + {"native_set_device_property_init_version", "(Ljava/lang/String;)I", + (void *)android_mtp_MtpDevice_set_device_property_init_version}, {"native_get_storage_ids", "()[I", (void *)android_mtp_MtpDevice_get_storage_ids}, {"native_get_storage_info", "(I)Landroid/mtp/MtpStorageInfo;", (void *)android_mtp_MtpDevice_get_storage_info}, diff --git a/packages/Android.bp b/packages/Android.bp index 00300150e501..810dc565f50d 100644 --- a/packages/Android.bp +++ b/packages/Android.bp @@ -24,8 +24,8 @@ package { java_defaults { name: "platform_app_defaults", - plugins: ["error_prone_android_framework"], errorprone: { + extra_check_modules: ["error_prone_android_framework"], javacflags: [ // We're less worried about performance in app code "-Xep:AndroidFrameworkEfficientCollections:OFF", diff --git a/packages/CompanionDeviceManager/OWNERS b/packages/CompanionDeviceManager/OWNERS index da723b3b67da..734d8b6c5f43 100644 --- a/packages/CompanionDeviceManager/OWNERS +++ b/packages/CompanionDeviceManager/OWNERS @@ -1 +1 @@ -eugenesusla@google.com
\ No newline at end of file +include /core/java/android/companion/OWNERS
\ No newline at end of file diff --git a/packages/PackageInstaller/res/values-as/strings.xml b/packages/PackageInstaller/res/values-as/strings.xml index f355988de604..c050d39c236e 100644 --- a/packages/PackageInstaller/res/values-as/strings.xml +++ b/packages/PackageInstaller/res/values-as/strings.xml @@ -87,7 +87,7 @@ <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"আপোনাৰ টেবলেট আৰু ব্যক্তিগত ডেটা অজ্ঞাত এপৰ আক্ৰমণৰ বলি হোৱাৰ সম্ভাৱনা অধিক। আপুনি এই এপটো ইনষ্টল কৰি এপটোৰ ব্যৱহাৰৰ ফলত আপোনাৰ টিভিত হ\'ব পৰা যিকোনো ক্ষতি বা ডেটা ক্ষয়ৰ বাবে আপুনি নিজে দায়ী হ\'ব বুলি সন্মতি দিয়ে।"</string> <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"আপোনাৰ টিভি আৰু ব্যক্তিগত ডেটা অজ্ঞাত এপৰ আক্ৰমণৰ বলি হোৱাৰ সম্ভাৱনা অধিক। আপুনি এই এপটো ইনষ্টল কৰি এপটোৰ ব্যৱহাৰৰ ফলত আপোনাৰ টিভিত হ\'ব পৰা যিকোনো ক্ষতি বা ডেটা ক্ষয়ৰ বাবে আপুনি নিজে দায়ী হ\'ব বুলি সন্মতি দিয়ে।"</string> <string name="anonymous_source_continue" msgid="4375745439457209366">"অব্যাহত ৰাখক"</string> - <string name="external_sources_settings" msgid="4046964413071713807">"ছেটিংসমূহ"</string> + <string name="external_sources_settings" msgid="4046964413071713807">"ছেটিং"</string> <string name="wear_app_channel" msgid="1960809674709107850">"ৱেৰ এপসমূহ ইনষ্টল/আনইনষ্টল কৰি থকা হৈছে"</string> <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"এপ্ ইনষ্টল কৰাৰ জাননী"</string> <string name="notification_installation_success_message" msgid="6450467996056038442">"সফলতাৰে ইনষ্টল কৰা হ’ল"</string> diff --git a/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml index 22b25a31ae07..95b7e3b8033d 100644 --- a/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml +++ b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml @@ -26,10 +26,54 @@ <issue id="NewApi" message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 21)" - errorLine1=" android:radius="?android:attr/dialogCornerRadius"" + errorLine1=" android:topLeftRadius="?android:attr/dialogCornerRadius"" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location - file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.xml" + file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml" + line="23" + column="9"/> + </issue> + + <issue + id="NewApi" + message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 21)" + errorLine1=" android:bottomLeftRadius="?android:attr/dialogCornerRadius"" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml" + line="25" + column="9"/> + </issue> + + <issue + id="NewApi" + message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 21)" + errorLine1=" android:topRightRadius="?android:attr/dialogCornerRadius"" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml" + line="24" + column="9"/> + </issue> + + <issue + id="NewApi" + message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 21)" + errorLine1=" android:bottomRightRadius="?android:attr/dialogCornerRadius"" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml" + line="26" + column="9"/> + </issue> + + <issue + id="NewApi" + message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 21)" + errorLine1=" android:bottomRightRadius="?android:attr/dialogCornerRadius"" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml" line="23" column="9"/> </issue> diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml new file mode 100644 index 000000000000..16a85d694bf8 --- /dev/null +++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml @@ -0,0 +1,28 @@ +<?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. + --> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:shape="rectangle"> + <solid android:color="?androidprv:attr/colorSurface" /> + <corners + android:topLeftRadius="?android:attr/dialogCornerRadius" + android:topRightRadius="0dp" + android:bottomLeftRadius="?android:attr/dialogCornerRadius" + android:bottomRightRadius="0dp" + /> +</shape>
\ No newline at end of file diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml new file mode 100644 index 000000000000..1b9f68fac850 --- /dev/null +++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml @@ -0,0 +1,28 @@ +<?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. + --> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:shape="rectangle"> + <solid android:color="?androidprv:attr/colorSurface" /> + <corners + android:topLeftRadius="0dp" + android:topRightRadius="?android:attr/dialogCornerRadius" + android:bottomLeftRadius="0dp" + android:bottomRightRadius="?android:attr/dialogCornerRadius" + /> +</shape>
\ No newline at end of file diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/left_rounded_ripple.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/left_rounded_ripple.xml new file mode 100644 index 000000000000..1584b45aabf9 --- /dev/null +++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/left_rounded_ripple.xml @@ -0,0 +1,21 @@ +<?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. + --> + +<ripple xmlns:android="http://schemas.android.com/apk/res/android" + android:color="?android:attr/colorControlHighlight"> + <item android:drawable="@drawable/half_rounded_left_bk"/> +</ripple>
\ No newline at end of file diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/right_rounded_ripple.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/right_rounded_ripple.xml new file mode 100644 index 000000000000..15f2b5cd79d0 --- /dev/null +++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/right_rounded_ripple.xml @@ -0,0 +1,21 @@ +<?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. + --> + +<ripple xmlns:android="http://schemas.android.com/apk/res/android" + android:color="?android:attr/colorControlHighlight"> + <item android:drawable="@drawable/half_rounded_right_bk"/> +</ripple>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml index 93f8724b22a9..a884ef11e835 100644 --- a/packages/SystemUI/res/drawable/tv_rect_shadow_rounded.xml +++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - ~ Copyright (C) 2019 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. @@ -16,10 +16,10 @@ --> <shape xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" android:shape="rectangle"> - - <corners android:radius="20dp"/> - <solid android:color="@color/tv_audio_recording_indicator_icon_background"/> - <stroke android:width="1dp" android:color="@color/tv_audio_recording_indicator_stroke"/> - + <solid android:color="?androidprv:attr/colorSurface" /> + <corners + android:radius="?android:attr/dialogCornerRadius" + /> </shape>
\ No newline at end of file diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_ripple.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_ripple.xml new file mode 100644 index 000000000000..90eefbe9a86e --- /dev/null +++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_ripple.xml @@ -0,0 +1,21 @@ +<?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. + --> + +<ripple xmlns:android="http://schemas.android.com/apk/res/android" + android:color="?android:attr/colorControlHighlight"> + <item android:drawable="@drawable/rounded_bk"/> +</ripple>
\ No newline at end of file diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/square_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/square_bk.xml new file mode 100644 index 000000000000..67b5107576a7 --- /dev/null +++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/square_bk.xml @@ -0,0 +1,25 @@ +<?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. + --> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:shape="rectangle"> + <solid android:color="?androidprv:attr/colorSurface" /> + <corners + android:radius="0dp" + /> +</shape>
\ No newline at end of file diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/square_ripple.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/square_ripple.xml new file mode 100644 index 000000000000..06be00dc2279 --- /dev/null +++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/square_ripple.xml @@ -0,0 +1,21 @@ +<?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. + --> + +<ripple xmlns:android="http://schemas.android.com/apk/res/android" + android:color="?android:attr/colorControlHighlight"> + <item android:drawable="@drawable/square_bk"/> +</ripple>
\ No newline at end of file diff --git a/packages/SettingsLib/ActionButtonsPreference/res/layout-v31/settingslib_action_buttons.xml b/packages/SettingsLib/ActionButtonsPreference/res/layout-v31/settingslib_action_buttons.xml index ba612d76fa57..7c3f5a566bdb 100644 --- a/packages/SettingsLib/ActionButtonsPreference/res/layout-v31/settingslib_action_buttons.xml +++ b/packages/SettingsLib/ActionButtonsPreference/res/layout-v31/settingslib_action_buttons.xml @@ -21,14 +21,13 @@ android:layout_height="wrap_content" android:layout_margin="8dp" android:paddingHorizontal="8dp" - android:orientation="horizontal" - android:background="@drawable/settingslib_rounded_background"> + android:orientation="horizontal"> <Button android:id="@+id/button1" style="@style/SettingsLibActionButton" android:layout_width="0dp" - android:layout_height="wrap_content" + android:layout_height="match_parent" android:layout_weight="1"/> <View @@ -43,7 +42,7 @@ android:id="@+id/button2" style="@style/SettingsLibActionButton" android:layout_width="0dp" - android:layout_height="wrap_content" + android:layout_height="match_parent" android:layout_weight="1"/> <View @@ -58,7 +57,7 @@ android:id="@+id/button3" style="@style/SettingsLibActionButton" android:layout_width="0dp" - android:layout_height="wrap_content" + android:layout_height="match_parent" android:layout_weight="1"/> <View @@ -73,6 +72,6 @@ android:id="@+id/button4" style="@style/SettingsLibActionButton" android:layout_width="0dp" - android:layout_height="wrap_content" + android:layout_height="match_parent" android:layout_weight="1"/> </LinearLayout> diff --git a/packages/SettingsLib/ActionButtonsPreference/res/values/arrays.xml b/packages/SettingsLib/ActionButtonsPreference/res/values/arrays.xml new file mode 100644 index 000000000000..fe88845daa64 --- /dev/null +++ b/packages/SettingsLib/ActionButtonsPreference/res/values/arrays.xml @@ -0,0 +1,44 @@ +<?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:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Do not translate. --> + <integer-array name="background_style1"> + <item>@drawable/rounded_ripple</item> + </integer-array> + + <!-- Do not translate. --> + <integer-array name="background_style2"> + <item>@drawable/left_rounded_ripple</item> + <item>@drawable/right_rounded_ripple</item> + </integer-array> + + <!-- Do not translate. --> + <integer-array name="background_style3"> + <item>@drawable/left_rounded_ripple</item> + <item>@drawable/square_ripple</item> + <item>@drawable/right_rounded_ripple</item> + </integer-array> + + <!-- Do not translate. --> + <integer-array name="background_style4"> + <item>@drawable/left_rounded_ripple</item> + <item>@drawable/square_ripple</item> + <item>@drawable/square_ripple</item> + <item>@drawable/right_rounded_ripple</item> + </integer-array> +</resources>
\ No newline at end of file diff --git a/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java b/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java index 029c9196fa5e..4d3ca945f7e1 100644 --- a/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java +++ b/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java @@ -18,6 +18,7 @@ package com.android.settingslib.widget; import android.content.Context; import android.content.res.Resources; +import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.text.TextUtils; import android.util.AttributeSet; @@ -54,12 +55,21 @@ import java.util.List; public class ActionButtonsPreference extends Preference { private static final String TAG = "ActionButtonPreference"; + private static final boolean mIsAtLeastS = BuildCompatUtils.isAtLeastS(); + private static final int SINGLE_BUTTON_STYLE = 1; + private static final int TWO_BUTTONS_STYLE = 2; + private static final int THREE_BUTTONS_STYLE = 3; + private static final int FOUR_BUTTONS_STYLE = 4; private final ButtonInfo mButton1Info = new ButtonInfo(); private final ButtonInfo mButton2Info = new ButtonInfo(); private final ButtonInfo mButton3Info = new ButtonInfo(); private final ButtonInfo mButton4Info = new ButtonInfo(); private final List<ButtonInfo> mVisibleButtonInfos = new ArrayList<>(4); + private final List<Drawable> mBtnBackgroundStyle1 = new ArrayList<>(1); + private final List<Drawable> mBtnBackgroundStyle2 = new ArrayList<>(2); + private final List<Drawable> mBtnBackgroundStyle3 = new ArrayList<>(3); + private final List<Drawable> mBtnBackgroundStyle4 = new ArrayList<>(4); private View mDivider1; private View mDivider2; @@ -89,15 +99,27 @@ public class ActionButtonsPreference extends Preference { private void init() { setLayoutResource(R.layout.settingslib_action_buttons); setSelectable(false); + + final Resources res = getContext().getResources(); + fetchDrawableArray(mBtnBackgroundStyle1, res.obtainTypedArray(R.array.background_style1)); + fetchDrawableArray(mBtnBackgroundStyle2, res.obtainTypedArray(R.array.background_style2)); + fetchDrawableArray(mBtnBackgroundStyle3, res.obtainTypedArray(R.array.background_style3)); + fetchDrawableArray(mBtnBackgroundStyle4, res.obtainTypedArray(R.array.background_style4)); + } + + private void fetchDrawableArray(List<Drawable> drawableList, TypedArray typedArray) { + for (int i = 0; i < typedArray.length(); i++) { + drawableList.add( + getContext().getDrawable(typedArray.getResourceId(i, 0 /* defValue */))); + } } @Override public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); - final boolean allowedDivider = !BuildCompatUtils.isAtLeastS(); - holder.setDividerAllowedAbove(allowedDivider); - holder.setDividerAllowedBelow(allowedDivider); + holder.setDividerAllowedAbove(!mIsAtLeastS); + holder.setDividerAllowedBelow(!mIsAtLeastS); mButton1Info.mButton = (Button) holder.findViewById(R.id.button1); mButton2Info.mButton = (Button) holder.findViewById(R.id.button2); @@ -113,25 +135,95 @@ public class ActionButtonsPreference extends Preference { mButton3Info.setUpButton(); mButton4Info.setUpButton(); - // Add visible button into list only - if (mButton1Info.isVisible()) { + // Clear info list to avoid duplicate setup. + if (!mVisibleButtonInfos.isEmpty()) { + mVisibleButtonInfos.clear(); + } + updateLayout(); + } + + @Override + protected void notifyChanged() { + super.notifyChanged(); + + // Update buttons background and layout when notified and visible button list exist. + if (!mVisibleButtonInfos.isEmpty()) { + mVisibleButtonInfos.clear(); + updateLayout(); + } + } + + private void updateLayout() { + // Add visible button into list only when platform version is newer than S. + if (mButton1Info.isVisible() && mIsAtLeastS) { mVisibleButtonInfos.add(mButton1Info); } - if (mButton2Info.isVisible()) { + if (mButton2Info.isVisible() && mIsAtLeastS) { mVisibleButtonInfos.add(mButton2Info); } - if (mButton3Info.isVisible()) { + if (mButton3Info.isVisible() && mIsAtLeastS) { mVisibleButtonInfos.add(mButton3Info); } - if (mButton4Info.isVisible()) { + if (mButton4Info.isVisible() && mIsAtLeastS) { mVisibleButtonInfos.add(mButton4Info); } + final boolean isRtl = getContext().getResources().getConfiguration() + .getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; + switch (mVisibleButtonInfos.size()) { + case SINGLE_BUTTON_STYLE : + if (isRtl) { + setupRtlBackgrounds(mVisibleButtonInfos, mBtnBackgroundStyle1); + } else { + setupBackgrounds(mVisibleButtonInfos, mBtnBackgroundStyle1); + } + break; + case TWO_BUTTONS_STYLE : + if (isRtl) { + setupRtlBackgrounds(mVisibleButtonInfos, mBtnBackgroundStyle2); + } else { + setupBackgrounds(mVisibleButtonInfos, mBtnBackgroundStyle2); + } + break; + case THREE_BUTTONS_STYLE : + if (isRtl) { + setupRtlBackgrounds(mVisibleButtonInfos, mBtnBackgroundStyle3); + } else { + setupBackgrounds(mVisibleButtonInfos, mBtnBackgroundStyle3); + } + break; + case FOUR_BUTTONS_STYLE : + if (isRtl) { + setupRtlBackgrounds(mVisibleButtonInfos, mBtnBackgroundStyle4); + } else { + setupBackgrounds(mVisibleButtonInfos, mBtnBackgroundStyle4); + } + break; + default: + Log.e(TAG, "No visible buttons info, skip background settings."); + break; + } + setupDivider1(); setupDivider2(); setupDivider3(); } + private void setupBackgrounds( + List<ButtonInfo> buttonInfoList, List<Drawable> buttonBackgroundStyles) { + for (int i = 0; i < buttonBackgroundStyles.size(); i++) { + buttonInfoList.get(i).mButton.setBackground(buttonBackgroundStyles.get(i)); + } + } + + private void setupRtlBackgrounds( + List<ButtonInfo> buttonInfoList, List<Drawable> buttonBackgroundStyles) { + for (int i = buttonBackgroundStyles.size() - 1; i >= 0; i--) { + buttonInfoList.get(buttonBackgroundStyles.size() - 1 - i) + .mButton.setBackground(buttonBackgroundStyles.get(i)); + } + } + /** * Set the visibility state of button1. */ diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.xml b/packages/SettingsLib/BannerMessagePreference/res/values-gu/strings.xml index ae3834dc0d9d..1fe4c5c0c946 100644 --- a/packages/SettingsLib/ActionButtonsPreference/res/drawable/settingslib_rounded_background.xml +++ b/packages/SettingsLib/BannerMessagePreference/res/values-gu/strings.xml @@ -1,5 +1,5 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?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"); @@ -13,13 +13,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - --> + --> -<shape xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" - android:shape="rectangle"> - <solid android:color="?androidprv:attr/colorSurface" /> - <corners - android:radius="?android:attr/dialogCornerRadius" - /> -</shape>
\ No newline at end of file +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="accessibility_banner_message_dismiss" msgid="5272928723898304168">"છોડી દો"</string> +</resources> diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_disabled_background.xml b/packages/SettingsLib/BannerMessagePreference/res/values-te/strings.xml index 15dfcb70e25e..22a6f59f091c 100644 --- a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_disabled_background.xml +++ b/packages/SettingsLib/BannerMessagePreference/res/values-te/strings.xml @@ -1,5 +1,5 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?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"); @@ -13,14 +13,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - --> + --> -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle" - android:width="@dimen/settingslib_switch_track_width" - android:height="@dimen/settingslib_switch_track_height"> - <solid - android:color="@color/settingslib_track_off_color" - android:alpha="?android:attr/disabledAlpha"/> - <corners android:radius="@dimen/settingslib_switch_track_radius"/> -</shape> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="accessibility_banner_message_dismiss" msgid="5272928723898304168">"విస్మరించు"</string> +</resources> diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_base_layout.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_base_layout.xml index 7d9b4d78ce2a..6acd9ff07965 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_base_layout.xml +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_base_layout.xml @@ -33,7 +33,7 @@ android:background="?android:attr/colorPrimary" android:theme="@style/Theme.CollapsingToolbar.Settings"> - <com.android.settingslib.collapsingtoolbar.AdjustableToolbarLayout + <com.google.android.material.appbar.CollapsingToolbarLayout android:id="@+id/collapsing_toolbar" android:layout_width="match_parent" android:layout_height="@dimen/toolbar_one_line_height" @@ -59,7 +59,7 @@ android:transitionName="shared_element_view" app:layout_collapseMode="pin"/> - </com.android.settingslib.collapsingtoolbar.AdjustableToolbarLayout> + </com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.AppBarLayout> <FrameLayout diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml index 2a72a1ad65db..63d397c69353 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values/styles.xml @@ -17,6 +17,7 @@ <resources> <style name="CollapsingToolbarTitle.Collapsed" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title"> <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item> + <item name="android:textSize">20dp</item> </style> <style name="CollapsingToolbarTitle.Expanded" parent="CollapsingToolbarTitle.Collapsed"> diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/AdjustableToolbarLayout.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/AdjustableToolbarLayout.java deleted file mode 100644 index 0e7e595a3f04..000000000000 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/AdjustableToolbarLayout.java +++ /dev/null @@ -1,80 +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.settingslib.collapsingtoolbar; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.google.android.material.appbar.CollapsingToolbarLayout; - -/** - * A customized version of CollapsingToolbarLayout that can apply different font size based on the - * line count of its title. - */ -public class AdjustableToolbarLayout extends CollapsingToolbarLayout { - - private static final int TOOLBAR_MAX_LINE_NUMBER = 2; - - public AdjustableToolbarLayout(@NonNull Context context) { - this(context, null); - - } - - public AdjustableToolbarLayout(@NonNull Context context, @Nullable AttributeSet attrs) { - this(context, attrs, 0); - } - - public AdjustableToolbarLayout(@NonNull Context context, @Nullable AttributeSet attrs, - int defStyleAttr) { - super(context, attrs, defStyleAttr); - initCollapsingToolbar(); - } - - @SuppressWarnings("RestrictTo") - private void initCollapsingToolbar() { - this.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { - @Override - public void onLayoutChange(View v, int left, int top, int right, int bottom, - int oldLeft, int oldTop, int oldRight, int oldBottom) { - v.removeOnLayoutChangeListener(this); - final int count = getLineCount(); - if (count > TOOLBAR_MAX_LINE_NUMBER) { - final ViewGroup.LayoutParams lp = getLayoutParams(); - lp.height = getResources() - .getDimensionPixelSize(R.dimen.toolbar_three_lines_height); - setScrimVisibleHeightTrigger( - getResources().getDimensionPixelSize( - R.dimen.scrim_visible_height_trigger_three_lines)); - setLayoutParams(lp); - } else if (count == TOOLBAR_MAX_LINE_NUMBER) { - final ViewGroup.LayoutParams lp = getLayoutParams(); - lp.height = getResources() - .getDimensionPixelSize(R.dimen.toolbar_two_lines_height); - setScrimVisibleHeightTrigger( - getResources().getDimensionPixelSize( - R.dimen.scrim_visible_height_trigger_two_lines)); - setLayoutParams(lp); - } - } - }); - } -} diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java index 4ae120ae286d..395a9a716a9b 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java @@ -26,6 +26,7 @@ import android.widget.Toolbar; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.fragment.app.FragmentActivity; import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout; @@ -35,10 +36,19 @@ import com.google.android.material.resources.TextAppearanceConfig; * A base Activity that has a collapsing toolbar layout is used for the activities intending to * enable the collapsing toolbar function. */ -public class CollapsingToolbarBaseActivity extends SettingsTransitionActivity { +public class CollapsingToolbarBaseActivity extends FragmentActivity implements + AppBarLayout.OnOffsetChangedListener { + private static final int TOOLBAR_MAX_LINE_NUMBER = 2; + private static final int FULLY_EXPANDED_OFFSET = 0; + private static final float TOOLBAR_LINE_SPACING_MULTIPLIER = 1.1f; + private static final String KEY_IS_TOOLBAR_COLLAPSED = "is_toolbar_collapsed"; + + @Nullable private CollapsingToolbarLayout mCollapsingToolbarLayout; + @Nullable private AppBarLayout mAppBarLayout; + private boolean mIsToolbarCollapsed; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -48,6 +58,12 @@ public class CollapsingToolbarBaseActivity extends SettingsTransitionActivity { super.setContentView(R.layout.collapsing_toolbar_base_layout); mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar); mAppBarLayout = findViewById(R.id.app_bar); + mAppBarLayout.addOnOffsetChangedListener(this); + if (savedInstanceState != null) { + mIsToolbarCollapsed = savedInstanceState.getBoolean(KEY_IS_TOOLBAR_COLLAPSED); + } + + initCollapsingToolbar(); disableCollapsingToolbarLayoutScrollingBehavior(); final Toolbar toolbar = findViewById(R.id.action_bar); @@ -107,14 +123,43 @@ public class CollapsingToolbarBaseActivity extends SettingsTransitionActivity { return true; } + @Override + public void onOffsetChanged(AppBarLayout appBarLayout, int offset) { + if (offset == FULLY_EXPANDED_OFFSET) { + mIsToolbarCollapsed = false; + } else { + mIsToolbarCollapsed = true; + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + if (isChangingConfigurations()) { + outState.putBoolean(KEY_IS_TOOLBAR_COLLAPSED, mIsToolbarCollapsed); + } + } + /** * Returns an instance of collapsing toolbar. */ + @Nullable public CollapsingToolbarLayout getCollapsingToolbarLayout() { return mCollapsingToolbarLayout; } + /** + * Return an instance of app bar. + */ + @Nullable + public AppBarLayout getAppBarLayout() { + return mAppBarLayout; + } + private void disableCollapsingToolbarLayoutScrollingBehavior() { + if (mAppBarLayout == null) { + return; + } final CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams(); final AppBarLayout.Behavior behavior = new AppBarLayout.Behavior(); @@ -127,4 +172,43 @@ public class CollapsingToolbarBaseActivity extends SettingsTransitionActivity { }); params.setBehavior(behavior); } + + @SuppressWarnings("RestrictTo") + private void initCollapsingToolbar() { + if (mCollapsingToolbarLayout == null || mAppBarLayout == null) { + return; + } + mCollapsingToolbarLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + v.removeOnLayoutChangeListener(this); + if (mIsToolbarCollapsed) { + return; + } + final int count = mCollapsingToolbarLayout.getLineCount(); + if (count > TOOLBAR_MAX_LINE_NUMBER) { + final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams(); + lp.height = getResources() + .getDimensionPixelSize(R.dimen.toolbar_three_lines_height); + mCollapsingToolbarLayout.setScrimVisibleHeightTrigger( + getResources().getDimensionPixelSize( + R.dimen.scrim_visible_height_trigger_three_lines)); + mCollapsingToolbarLayout.setLayoutParams(lp); + mCollapsingToolbarLayout + .setLineSpacingMultiplier(TOOLBAR_LINE_SPACING_MULTIPLIER); + } else if (count == TOOLBAR_MAX_LINE_NUMBER) { + final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams(); + lp.height = getResources() + .getDimensionPixelSize(R.dimen.toolbar_two_lines_height); + mCollapsingToolbarLayout.setScrimVisibleHeightTrigger( + getResources().getDimensionPixelSize( + R.dimen.scrim_visible_height_trigger_two_lines)); + mCollapsingToolbarLayout.setLayoutParams(lp); + mCollapsingToolbarLayout + .setLineSpacingMultiplier(TOOLBAR_LINE_SPACING_MULTIPLIER); + } + } + }); + } } diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseFragment.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseFragment.java index c4c74ffc719b..e7026686d9ff 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseFragment.java +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseFragment.java @@ -25,21 +25,33 @@ import android.widget.Toolbar; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.fragment.app.Fragment; +import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout; /** * A base fragment that has a collapsing toolbar layout for enabling the collapsing toolbar design. */ -public abstract class CollapsingToolbarBaseFragment extends Fragment { +public abstract class CollapsingToolbarBaseFragment extends Fragment implements + AppBarLayout.OnOffsetChangedListener { + private static final int TOOLBAR_MAX_LINE_NUMBER = 2; + private static final int FULLY_EXPANDED_OFFSET = 0; + private static final String KEY_IS_TOOLBAR_COLLAPSED = "is_toolbar_collapsed"; + + @Nullable + private CoordinatorLayout mCoordinatorLayout; @Nullable private CollapsingToolbarLayout mCollapsingToolbarLayout; + @Nullable + private AppBarLayout mAppBarLayout; @NonNull private Toolbar mToolbar; @NonNull private FrameLayout mContentFrameLayout; + private boolean mIsToolbarCollapsed; @Nullable @Override @@ -47,7 +59,17 @@ public abstract class CollapsingToolbarBaseFragment extends Fragment { @Nullable Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.collapsing_toolbar_base_layout, container, false); + mCoordinatorLayout = view.findViewById(R.id.content_parent); mCollapsingToolbarLayout = view.findViewById(R.id.collapsing_toolbar); + mAppBarLayout = view.findViewById(R.id.app_bar); + if (mAppBarLayout != null) { + mAppBarLayout.addOnOffsetChangedListener(this); + } + if (savedInstanceState != null) { + mIsToolbarCollapsed = savedInstanceState.getBoolean(KEY_IS_TOOLBAR_COLLAPSED); + } + initCollapsingToolbar(); + disableCollapsingToolbarLayoutScrollingBehavior(); mToolbar = view.findViewById(R.id.action_bar); mContentFrameLayout = view.findViewById(R.id.content_frame); return view; @@ -60,6 +82,39 @@ public abstract class CollapsingToolbarBaseFragment extends Fragment { requireActivity().setActionBar(mToolbar); } + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + if (getActivity().isChangingConfigurations()) { + outState.putBoolean(KEY_IS_TOOLBAR_COLLAPSED, mIsToolbarCollapsed); + } + } + + @Override + public void onOffsetChanged(AppBarLayout appBarLayout, int offset) { + if (offset == FULLY_EXPANDED_OFFSET) { + mIsToolbarCollapsed = false; + } else { + mIsToolbarCollapsed = true; + } + } + + /** + * Return an instance of CoordinatorLayout. + */ + @Nullable + public CoordinatorLayout getCoordinatorLayout() { + return mCoordinatorLayout; + } + + /** + * Return an instance of app bar. + */ + @Nullable + public AppBarLayout getAppBarLayout() { + return mAppBarLayout; + } + /** * Return the collapsing toolbar layout. */ @@ -75,4 +130,56 @@ public abstract class CollapsingToolbarBaseFragment extends Fragment { public FrameLayout getContentFrameLayout() { return mContentFrameLayout; } + + private void disableCollapsingToolbarLayoutScrollingBehavior() { + if (mAppBarLayout == null) { + return; + } + final CoordinatorLayout.LayoutParams params = + (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams(); + final AppBarLayout.Behavior behavior = new AppBarLayout.Behavior(); + behavior.setDragCallback( + new AppBarLayout.Behavior.DragCallback() { + @Override + public boolean canDrag(@NonNull AppBarLayout appBarLayout) { + return false; + } + }); + params.setBehavior(behavior); + } + + @SuppressWarnings("RestrictTo") + private void initCollapsingToolbar() { + if (mCollapsingToolbarLayout == null || mAppBarLayout == null) { + return; + } + mCollapsingToolbarLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + v.removeOnLayoutChangeListener(this); + if (mIsToolbarCollapsed) { + return; + } + final int count = mCollapsingToolbarLayout.getLineCount(); + if (count > TOOLBAR_MAX_LINE_NUMBER) { + final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams(); + lp.height = getResources() + .getDimensionPixelSize(R.dimen.toolbar_three_lines_height); + mCollapsingToolbarLayout.setScrimVisibleHeightTrigger( + getResources().getDimensionPixelSize( + R.dimen.scrim_visible_height_trigger_three_lines)); + mCollapsingToolbarLayout.setLayoutParams(lp); + } else if (count == TOOLBAR_MAX_LINE_NUMBER) { + final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams(); + lp.height = getResources() + .getDimensionPixelSize(R.dimen.toolbar_two_lines_height); + mCollapsingToolbarLayout.setScrimVisibleHeightTrigger( + getResources().getDimensionPixelSize( + R.dimen.scrim_visible_height_trigger_two_lines)); + mCollapsingToolbarLayout.setLayoutParams(lp); + } + } + }); + } } diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_on_background.xml b/packages/SettingsLib/FooterPreference/res/values-gu/strings.xml index c12d012a0508..54249b88b47e 100644 --- a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_on_background.xml +++ b/packages/SettingsLib/FooterPreference/res/values-gu/strings.xml @@ -1,6 +1,6 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2020 The Android Open Source Project +<?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. @@ -13,12 +13,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - --> + --> -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle" - android:width="@dimen/settingslib_switch_track_width" - android:height="@dimen/settingslib_switch_track_height"> - <solid android:color="@color/settingslib_track_on_color"/> - <corners android:radius="@dimen/settingslib_switch_track_radius"/> -</shape> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="settingslib_learn_more_text" msgid="7385478101223578464">"વધુ જાણો"</string> +</resources> diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_off_background.xml b/packages/SettingsLib/FooterPreference/res/values-te/strings.xml index 4d79a6e20776..6c8d6799754b 100644 --- a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_off_background.xml +++ b/packages/SettingsLib/FooterPreference/res/values-te/strings.xml @@ -1,6 +1,6 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2020 The Android Open Source Project +<?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. @@ -13,12 +13,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - --> + --> -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle" - android:width="@dimen/settingslib_switch_track_width" - android:height="@dimen/settingslib_switch_track_height"> - <solid android:color="@color/settingslib_track_off_color"/> - <corners android:radius="@dimen/settingslib_switch_track_radius"/> -</shape> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="settingslib_learn_more_text" msgid="7385478101223578464">"మరింత తెలుసుకోండి"</string> +</resources> diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_disabled.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_disabled.xml deleted file mode 100644 index b41762f7908e..000000000000 --- a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_disabled.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?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. - --> - -<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> - <item - android:top="@dimen/settingslib_switch_thumb_margin" - android:left="@dimen/settingslib_switch_thumb_margin" - android:right="@dimen/settingslib_switch_thumb_margin" - android:bottom="@dimen/settingslib_switch_thumb_margin"> - <shape android:shape="oval"> - <size - android:height="@dimen/settingslib_switch_thumb_size" - android:width="@dimen/settingslib_switch_thumb_size"/> - <solid - android:color="@color/settingslib_thumb_off_color" - android:alpha="?android:attr/disabledAlpha"/> - </shape> - </item> -</layer-list> diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_off.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_off.xml deleted file mode 100644 index 8b69ad1b2493..000000000000 --- a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_off.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2020 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> - <item - android:top="@dimen/settingslib_switch_thumb_margin" - android:left="@dimen/settingslib_switch_thumb_margin" - android:right="@dimen/settingslib_switch_thumb_margin" - android:bottom="@dimen/settingslib_switch_thumb_margin"> - <shape android:shape="oval"> - <size - android:height="@dimen/settingslib_switch_thumb_size" - android:width="@dimen/settingslib_switch_thumb_size"/> - <solid android:color="@color/settingslib_thumb_off_color"/> - </shape> - </item> -</layer-list> diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_on.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_on.xml deleted file mode 100644 index 0f27fc2f4ad8..000000000000 --- a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_on.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2020 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> - <item - android:top="@dimen/settingslib_switch_thumb_margin" - android:left="@dimen/settingslib_switch_thumb_margin" - android:right="@dimen/settingslib_switch_thumb_margin" - android:bottom="@dimen/settingslib_switch_thumb_margin"> - <shape android:shape="oval"> - <size - android:height="@dimen/settingslib_switch_thumb_size" - android:width="@dimen/settingslib_switch_thumb_size"/> - <solid android:color="@color/settingslib_state_on_color"/> - </shape> - </item> -</layer-list> diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_selector.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_selector.xml deleted file mode 100644 index 06bb779b91ef..000000000000 --- a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_thumb_selector.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2020 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:drawable="@drawable/settingslib_thumb_on" android:state_checked="true"/> - <item android:drawable="@drawable/settingslib_thumb_off" android:state_checked="false"/> - <item android:drawable="@drawable/settingslib_thumb_disabled" android:state_enabled="false"/> -</selector> diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_selector.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_selector.xml deleted file mode 100644 index a38c3b4241a3..000000000000 --- a/packages/SettingsLib/MainSwitchPreference/res/drawable/settingslib_track_selector.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2020 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:drawable="@drawable/settingslib_track_on_background" android:state_checked="true"/> - <item android:drawable="@drawable/settingslib_track_off_background" android:state_checked="false"/> - <item android:drawable="@drawable/settingslib_track_disabled_background" android:state_enabled="false"/> -</selector> diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml index f9e9eabc52ff..2518a6d06255 100644 --- a/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml +++ b/packages/SettingsLib/MainSwitchPreference/res/layout-v31/settingslib_main_switch_bar.xml @@ -60,9 +60,7 @@ android:layout_gravity="center_vertical" android:focusable="false" android:clickable="false" - android:track="@drawable/settingslib_track_selector" - android:thumb="@drawable/settingslib_thumb_selector" - android:theme="@style/MainSwitch.Settingslib"/> + android:theme="@style/Switch.SettingsLib"/> </LinearLayout> </LinearLayout> diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_layout.xml b/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_layout.xml index eccf0c091e49..bef6e352d854 100644 --- a/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_layout.xml +++ b/packages/SettingsLib/MainSwitchPreference/res/layout/settingslib_main_switch_layout.xml @@ -15,9 +15,10 @@ limitations under the License. --> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="wrap_content" - android:layout_width="match_parent" > + android:layout_width="match_parent" + android:importantForAccessibility="no"> <com.android.settingslib.widget.MainSwitchBar android:id="@+id/settingslib_main_switch_bar" @@ -25,6 +26,6 @@ android:layout_height="wrap_content" android:layout_width="match_parent" /> -</LinearLayout> +</FrameLayout> diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml index a1cbcf72c1c6..a386adbafe2a 100644 --- a/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml +++ b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml @@ -41,21 +41,6 @@ <!-- Radius of switch bar --> <dimen name="settingslib_switch_bar_radius">28dp</dimen> - <!-- Margin of switch thumb --> - <dimen name="settingslib_switch_thumb_margin">4dp</dimen> - - <!-- Size of switch thumb --> - <dimen name="settingslib_switch_thumb_size">20dp</dimen> - - <!-- Width of switch track --> - <dimen name="settingslib_switch_track_width">52dp</dimen> - - <!-- Height of switch track --> - <dimen name="settingslib_switch_track_height">28dp</dimen> - - <!-- Radius of switch track --> - <dimen name="settingslib_switch_track_radius">35dp</dimen> - <!-- SwitchBar sub settings margin start / end --> <dimen name="settingslib_switchbar_subsettings_margin_start">72dp</dimen> <dimen name="settingslib_switchbar_subsettings_margin_end">16dp</dimen> diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml b/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml index 472025ab8130..3924e301a2d3 100644 --- a/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml +++ b/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml @@ -23,9 +23,6 @@ <item name="android:textColor">@android:color/black</item> </style> - <style name="MainSwitch.Settingslib" parent="@android:style/Widget.Material.CompoundButton.Switch"> - <item name="android:switchMinWidth">@dimen/settingslib_min_switch_width</item> - </style> <style name="SwitchBar.Switch.Settingslib" parent="@android:style/Widget.Material.CompoundButton.Switch"> <item name="android:trackTint">@color/settingslib_switchbar_switch_track_tint</item> diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/styles.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/styles.xml index 9610c9443184..46f1e030af23 100644 --- a/packages/SettingsLib/SettingsTheme/res/values-v31/styles.xml +++ b/packages/SettingsLib/SettingsTheme/res/values-v31/styles.xml @@ -25,6 +25,7 @@ <style name="Switch.SettingsLib" parent="@android:style/Widget.Material.CompoundButton.Switch"> <item name="android:switchMinWidth">52dp</item> + <item name="android:minHeight">@dimen/settingslib_preferred_minimum_touch_target</item> <item name="android:track">@drawable/settingslib_switch_track</item> <item name="android:thumb">@drawable/settingslib_switch_thumb</item> </style> diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index fa3f34c96ad2..0442ba20f8db 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -568,6 +568,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Verwyder gas"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Stel gassessie terug"</string> <string name="guest_nickname" msgid="6332276931583337261">"Gas"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Stel gassessie terug?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Stel terug"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Stel tans gassessie terug …"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Neem \'n foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Kies \'n prent"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Kies foto"</string> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index 7b4c832fd1d0..42d9eba92360 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"እንግዳን አስወግድ"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"እንግዳን ዳግም አስጀምር"</string> <string name="guest_nickname" msgid="6332276931583337261">"እንግዳ"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"ፎቶ አንሳ"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"ምስል ይምረጡ"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ፎቶ ይምረጡ"</string> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index 525a4978f580..2df9ba72c9a7 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -570,9 +570,14 @@ <string name="user_nickname" msgid="262624187455825083">"اللقب"</string> <string name="guest_new_guest" msgid="3482026122932643557">"إضافة ضيف"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"إزالة جلسة الضيف"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"إعادة ضبط جلسة الضيف"</string> <string name="guest_nickname" msgid="6332276931583337261">"ضيف"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"التقاط صورة"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"اختيار صورة"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"اختيار صورة"</string> diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml index 611f2c44f565..f14dd0bfb099 100644 --- a/packages/SettingsLib/res/values-as/strings.xml +++ b/packages/SettingsLib/res/values-as/strings.xml @@ -79,7 +79,7 @@ <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"সংযোগ কৰা হ’ল (কোনো ফ\'ন বা মিডিয়া নাই), বেটাৰিৰ স্তৰ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"সক্ৰিয়, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰি"</string> <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"সক্ৰিয়, L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> বেটাৰি, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> বেটাৰি"</string> - <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰি"</string> + <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰী"</string> <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> বেটাৰি, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> বেটাৰি"</string> <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"সক্ৰিয়"</string> <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"মিডিয়াৰ অডিঅ’"</string> @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি আঁতৰাওক"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"অতিথিৰ ছেশ্বন ৰিছেট কৰক"</string> <string name="guest_nickname" msgid="6332276931583337261">"অতিথি"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"এখন ফট’ তোলক"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"এখন প্ৰতিচ্ছবি বাছনি কৰক"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ফট’ বাছনি কৰক"</string> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index c50a22d18605..2f75514a14d9 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -454,7 +454,7 @@ <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Tam şarj edilənədək <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - tam şarj edilənədək <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string> - <string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - Şarj müvəqqəti olaraq məhdudlaşdırılıb"</string> + <string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - Şarj müvəqqəti məhdudlaşdırılıb"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Naməlum"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Enerji doldurma"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Sürətlə doldurulur"</string> @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Qonağı silin"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Qonaq sessiyasını sıfırlayın"</string> <string name="guest_nickname" msgid="6332276931583337261">"Qonaq"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Foto çəkin"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Şəkil seçin"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Foto seçin"</string> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index e26d0650c8cc..32a08ad1e3cc 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -569,6 +569,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Resetuj sesiju gosta"</string> <string name="guest_nickname" msgid="6332276931583337261">"Gost"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Želite li da resetujete sesiju gosta?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetuj"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Sesija gosta se resetuje…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Slikaj"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Izaberite sliku"</string> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index 2d1a3629992c..b633841d6865 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -568,9 +568,14 @@ <string name="user_nickname" msgid="262624187455825083">"Псеўданім"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Дадаць госця"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Выдаліць госця"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"Скінуць гасцявы сеанс"</string> <string name="guest_nickname" msgid="6332276931583337261">"Госць"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Зрабіць фота"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Выбраць відарыс"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Выбраць фота"</string> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index 7899fa687ddc..78aea784319c 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -568,6 +568,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Премахване на госта"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Нулиране на сесията като гост"</string> <string name="guest_nickname" msgid="6332276931583337261">"Гост"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Да се нулира ли сесията като гост?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Нулиране"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Сесията като гост се нулира…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Правене на снимка"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Избиране на изображение"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Избиране на снимката"</string> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index 26ad54a6c31e..eca40f96b318 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"বিশেষ নাম"</string> <string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ করুন"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি সরান"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"অতিথি সেশন রিসেট করুন"</string> <string name="guest_nickname" msgid="6332276931583337261">"অতিথি"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"ফটো তুলুন"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"একটি ইমেজ বেছে নিন"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ফটো বেছে নিন"</string> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index 9eb20f90735f..26b2db461e52 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -569,6 +569,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Poništi sesiju gosta"</string> <string name="guest_nickname" msgid="6332276931583337261">"Gost"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Poništiti sesiju gosta?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Poništi"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Poništavanje sesije gosta…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Snimite fotografiju"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberite sliku"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Odabir fotografije"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index d3590bf9e8d2..47b95a557e5c 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -507,7 +507,7 @@ <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmes i recordatoris"</string> <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Permet la configuració d\'alarmes i recordatoris"</string> <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes i recordatoris"</string> - <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permet que aquesta aplicació configuri alarmes i programi accions urgents. Això permet a l\'aplicació executar-se en segon pla i, per tant, és possible que consumeixi més bateria.\n\nSi aquest permís està desactivat, les alarmes i els esdeveniments urgents que ja hagi programat l\'aplicació no funcionaran."</string> + <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permet que aquesta aplicació configuri alarmes i programi accions. Això permet a l\'aplicació executar-se en segon pla i, per tant, és possible que consumeixi més bateria.\n\nSi aquest permís està desactivat, les alarmes i els esdeveniments que ja hagi programat l\'aplicació no funcionaran."</string> <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programació, alarma, recordatori, rellotge"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activa"</string> <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activa el mode No molestis"</string> @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Suprimeix el convidat"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Restableix el convidat"</string> <string name="guest_nickname" msgid="6332276931583337261">"Convidat"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Fes una foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Tria una imatge"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Selecciona una foto"</string> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index 5c664b987101..8a16ae65d76e 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -570,6 +570,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Odstranit hosta"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Resetovat hosta"</string> <string name="guest_nickname" msgid="6332276931583337261">"Host"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Pořídit fotku"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrat obrázek"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Vybrat fotku"</string> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index c169d768cceb..30bf200f38a1 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"Kaldenavn"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Tilføj gæst"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Fjern gæsten"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"Nulstil gæstesession"</string> <string name="guest_nickname" msgid="6332276931583337261">"Gæst"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Tag et billede"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Vælg et billede"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Vælg billede"</string> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index 5808b6ded540..103d23bee5b4 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"Alias"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Gast hinzufügen"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Gast entfernen"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"Gast zurücksetzen"</string> <string name="guest_nickname" msgid="6332276931583337261">"Gast"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Foto machen"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Bild auswählen"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Foto auswählen"</string> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index 59bfab8ddea8..9bf28cbf2684 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -568,6 +568,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Κατάργηση επισκέπτη"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Επαναφορά περιόδου επισκέπτη"</string> <string name="guest_nickname" msgid="6332276931583337261">"Επισκέπτης"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Επαναφορά επισκέπτη;"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Επαναφορά"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Επαναφορά επισκέπτη…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Λήψη φωτογραφίας"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Επιλογή εικόνας"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Επιλογή φωτογραφίας"</string> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index 03004a122616..c1d4ab8410e3 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -568,6 +568,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Reset guest"</string> <string name="guest_nickname" msgid="6332276931583337261">"Guest"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Reset guest?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string> diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml index 42a714d36304..c9fc70dc04b6 100644 --- a/packages/SettingsLib/res/values-en-rCA/strings.xml +++ b/packages/SettingsLib/res/values-en-rCA/strings.xml @@ -568,6 +568,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Reset guest"</string> <string name="guest_nickname" msgid="6332276931583337261">"Guest"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Reset guest?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index 03004a122616..c1d4ab8410e3 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -568,6 +568,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Reset guest"</string> <string name="guest_nickname" msgid="6332276931583337261">"Guest"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Reset guest?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index 03004a122616..c1d4ab8410e3 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -568,6 +568,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Reset guest"</string> <string name="guest_nickname" msgid="6332276931583337261">"Guest"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Reset guest?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string> diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml index fafc76dc67b2..0212719dad91 100644 --- a/packages/SettingsLib/res/values-en-rXC/strings.xml +++ b/packages/SettingsLib/res/values-en-rXC/strings.xml @@ -568,6 +568,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Reset guest"</string> <string name="guest_nickname" msgid="6332276931583337261">"Guest"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Reset guest?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 5d0a61ab2047..7755cb74b04f 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -457,11 +457,11 @@ <string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga limitada temporalmente"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string> - <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rápido"</string> + <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rápidamente"</string> <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Carga lenta"</string> <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Carga inalámbrica"</string> <string name="battery_info_status_discharging" msgid="6962689305413556485">"No se está cargando."</string> - <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Está conectado, pero no se está cargando"</string> + <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Conectado; no se está cargando"</string> <string name="battery_info_status_full" msgid="1339002294876531312">"Cargada"</string> <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlada por el administrador"</string> <string name="disabled" msgid="8017887509554714950">"Inhabilitada"</string> @@ -566,9 +566,11 @@ <string name="user_nickname" msgid="262624187455825083">"Sobrenombre"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Agregar invitado"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Quitar invitado"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"Restablecer perfil de invitado"</string> <string name="guest_nickname" msgid="6332276931583337261">"Invitado"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"¿Quieres restablecer el invitado?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Restablecer"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Restableciendo invitado…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Tomar una foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Elegir una imagen"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index 26c7b2c7a760..3b56ce72aa74 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -457,11 +457,11 @@ <string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga limitada temporalmente"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string> - <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rápidamente"</string> - <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Cargando lentamente"</string> + <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carga rápida"</string> + <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Carga lenta"</string> <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Cargando sin cables"</string> <string name="battery_info_status_discharging" msgid="6962689305413556485">"No se está cargando"</string> - <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Conectado, no se carga"</string> + <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Conectado pero sin cargar"</string> <string name="battery_info_status_full" msgid="1339002294876531312">"Cargada"</string> <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlada por el administrador"</string> <string name="disabled" msgid="8017887509554714950">"Inhabilitada"</string> @@ -507,7 +507,7 @@ <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmas y recordatorios"</string> <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Permitir la programación de alarmas y recordatorios"</string> <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmas y recordatorios"</string> - <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite que esta aplicación programe alarmas y otras acciones de carácter temporal. Este permite sirve para que la aplicación siga activa en segundo plano, lo que puede usar más batería.\n\nSi este permiso está desactivados, no funcionarán las alarmas ni los eventos con carácter temporal programados por esta aplicación."</string> + <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite que esta aplicación programe alarmas y otras acciones que se llevan a cabo a una hora determinada. Esto hace que la aplicación siga activa en segundo plano, lo que puede usar más batería.\n\nSi este permiso está desactivado, no funcionarán las alarmas ni los eventos que se activan a una hora determinada que programe esta aplicación."</string> <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarma, recordatorio, reloj"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activar"</string> <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activar el modo No molestar"</string> @@ -568,6 +568,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Quitar invitado"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Restablecer invitado"</string> <string name="guest_nickname" msgid="6332276931583337261">"Invitado"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"¿Restablecer invitado?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Restablecer"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Restableciendo invitado…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Hacer foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Seleccionar una imagen"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index 194aeaff4b15..d835cb95ed98 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -507,7 +507,7 @@ <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmid ja meeldetuletused"</string> <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Luba alarmide ja meeldetuletuste määramine"</string> <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmid ja meeldetuletused"</string> - <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Lubage sellel rakendusel määrata äratusi ja ajastada kiire tähtajaga toiminguid. See võimaldab rakendusel töötada taustal, mistõttu võib akukasutus olla suurem.\n\nKui see luba on välja lülitatud, siis olemasolevad äratused ja selle rakenduse ajastatud ajapõhised sündmused ei tööta."</string> + <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Lubage sellel rakendusel määrata alarme ja ajastada kiire tähtajaga toiminguid. See võimaldab rakendusel töötada taustal, mistõttu võib akukasutus olla suurem.\n\nKui see luba on välja lülitatud, siis olemasolevad alarmid ja selle rakenduse ajastatud ajapõhised sündmused ei tööta."</string> <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ajakava, äratus, meeldetuletus, kell"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Lülita sisse"</string> <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Valiku Mitte segada sisselülitamine"</string> @@ -568,6 +568,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Eemalda külaline"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Lähtesta külastajaseanss"</string> <string name="guest_nickname" msgid="6332276931583337261">"Külaline"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Kas lähtestada külastajaseanss?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Lähtesta"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Külastajaseansi lähtestamine …"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Pildistage"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Valige pilt"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Valige foto"</string> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 33e2314dd887..08f4fe532701 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Kendu gonbidatua"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Berrezarri gonbidatuentzako saioa"</string> <string name="guest_nickname" msgid="6332276931583337261">"Gonbidatua"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Atera argazki bat"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Aukeratu irudi bat"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Hautatu argazki bat"</string> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index eb68f5fe2bbb..313031be8972 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"نام مستعار"</string> <string name="guest_new_guest" msgid="3482026122932643557">"افزودن مهمان"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"حذف مهمان"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"بازنشانی مهمان"</string> <string name="guest_nickname" msgid="6332276931583337261">"مهمان"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"عکس گرفتن"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"انتخاب تصویر"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"انتخاب عکس"</string> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index a11a00a5f65d..40a3d21cd4a6 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Poista vieras"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Nollaa vieras"</string> <string name="guest_nickname" msgid="6332276931583337261">"Vieras"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Ota kuva"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Valitse kuva"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Valitse kuva"</string> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index 551dc36faac0..e877557aa378 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"Pseudo"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Ajouter un invité"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Supprimer l\'invité"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"Réinitialiser la session Invité"</string> <string name="guest_nickname" msgid="6332276931583337261">"Invité"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Prendre une photo"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Sélectionner une image"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Sélectionnez une photo"</string> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index 5ade70f74e9e..0b0ee65ad1c4 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -461,7 +461,7 @@ <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Charge lente"</string> <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"En charge sans fil"</string> <string name="battery_info_status_discharging" msgid="6962689305413556485">"Pas en charge"</string> - <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connecté, pas en charge"</string> + <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connectée, pas en charge"</string> <string name="battery_info_status_full" msgid="1339002294876531312">"Chargée"</string> <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Contrôlé par l\'administrateur"</string> <string name="disabled" msgid="8017887509554714950">"Désactivée"</string> @@ -507,7 +507,7 @@ <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmes et rappels"</string> <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Autoriser à définir des alarmes et des rappels"</string> <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes et rappels"</string> - <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Autorisez cette appli à définir des alarmes et à planifier des actions soumises à un délai. Cela lui permet de s\'exécuter en arrière-plan, ce qui peut consommer plus de batterie.\n\nSi cette autorisation est désactivée, les alarmes existantes et les événements basés sur l\'heure planifiés par cette appli ne fonctionneront pas."</string> + <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Autorisez cette appli à définir des alarmes et à programmer des actions à certaines heures. Elle s\'exécutera alors en arrière-plan, ce qui peut solliciter davantage la batterie.\n\nSi l\'autorisation est désactivée, les alarmes existantes et les événements programmés par l\'appli ne fonctionneront pas."</string> <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"définir, alarme, rappel, horloge"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activer"</string> <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer le mode Ne pas déranger"</string> @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"Pseudo"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Ajouter un invité"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Supprimer l\'invité"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"Réinitialiser la session Invité"</string> <string name="guest_nickname" msgid="6332276931583337261">"Invité"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Prendre une photo"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Choisir une image"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Sélectionner une photo"</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index dba912ea3920..5cb0d2ad3b79 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Quitar convidado"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Restablecer sesión de convidado"</string> <string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Tirar foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Escoller imaxe"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index b55a5a23493f..d09a8e6bd0d1 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -454,7 +454,7 @@ <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"પૂર્ણ ચાર્જ થવામાં <xliff:g id="TIME">%1$s</xliff:g> બાકી છે"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - પૂર્ણ ચાર્જ થવામાં <xliff:g id="TIME">%2$s</xliff:g> બાકી છે"</string> - <string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - ચાર્જિંગ હંગામી રૂપે પ્રતિબંધિત કરવામાં આવ્યું છે"</string> + <string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - ચાર્જિંગ હંગામીરૂપે પ્રતિબંધિત કરવામાં આવ્યું છે"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"અજાણ્યું"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"ચાર્જ થઈ રહ્યું છે"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ઝડપથી ચાર્જ થાય છે"</string> @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"ઉપનામ"</string> <string name="guest_new_guest" msgid="3482026122932643557">"અતિથિ ઉમેરો"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"અતિથિને કાઢી નાખો"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"અતિથિને રીસેટ કરો"</string> <string name="guest_nickname" msgid="6332276931583337261">"અતિથિ"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"ફોટો લો"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"છબી પસંદ કરો"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ફોટો પસંદ કરો"</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index bc74092efa8d..36cf9f29fb44 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -507,7 +507,7 @@ <string name="alarms_and_reminders_label" msgid="6918395649731424294">"अलार्म और रिमाइंडर"</string> <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"अलार्म और रिमाइंडर सेट करने की अनुमति दें"</string> <string name="alarms_and_reminders_title" msgid="8819933264635406032">"अलार्म और रिमाइंडर"</string> - <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"इस ऐप्लिकेशन को अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर सेट करने की अनुमति दें. ऐसा करने से, ऐप्लिकेशन को बैकग्राउंड में चलने की अनुमति मिलती है. इससे, बैटरी ज़्यादा खर्च होती है.\n\nअगर आप यह अनुमति नहीं देते हैं, तो इस ऐप्लिकेशन की मदद से सेट किए गए अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर काम नहीं करेंगे."</string> + <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"इस ऐप्लिकेशन को अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर सेट करने की अनुमति दें. ऐसा करने से, ऐप्लिकेशन को बैकग्राउंड में चलने की अनुमति मिलती है. इससे बैटरी ज़्यादा खर्च होती है.\n\nअगर आप यह अनुमति नहीं देते हैं, तो इस ऐप्लिकेशन की मदद से सेट किए गए अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर काम नहीं करेंगे."</string> <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"शेड्यूल, अलार्म, रिमाइंडर, घड़ी"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"चालू करें"</string> <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'परेशान न करें\' चालू करें"</string> @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"मेहमान हटाएं"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"मेहमान के तौर पर ब्राउज़ करने का सेशन रीसेट करें"</string> <string name="guest_nickname" msgid="6332276931583337261">"मेहमान"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"फ़ोटो खींचें"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"कोई इमेज चुनें"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"फ़ोटो चुनें"</string> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index d18d34cb0037..51884f398801 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -508,7 +508,7 @@ <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmi i podsjetnici"</string> <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Dopusti postavljanje alarma i podsjetnika"</string> <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmi i podsjetnici"</string> - <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Aplikaciji omogućuje da postavlja alarme i zakazuje vremenski osjetljive radnje. To aplikaciji omogućuje da se izvodi u pozadini, pa je moguće dodatno trošenje baterije.\n\nAko je to dopuštenje isključeno, postojeći alarmi i događaji temeljeni na vremenu koji su zakazani putem ove aplikacije neće funkcionirati."</string> + <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Omogućite toj aplikaciji da postavlja alarme i zakazuje radnje u točno određeno vrijeme. To aplikaciji omogućuje da se izvodi u pozadini, pa je moguća dodatna potrošnja baterije.\n\nAko je to dopuštenje isključeno, postojeći alarmi i događaji zakazani putem te aplikacije neće funkcionirati."</string> <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"raspored, alarm, podsjetnik, sat"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Uključi"</string> <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Uključite opciju Ne uznemiravaj."</string> @@ -569,6 +569,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Uklanjanje gosta"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Poništi gostujuću sesiju"</string> <string name="guest_nickname" msgid="6332276931583337261">"Gost"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Poništiti gostujuću sesiju?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Poništi"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Poništavanje gostujuće sesije…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Fotografiraj"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Odabir slike"</string> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index 3ad3590ca728..fc4592d6c73c 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Vendég munkamenet eltávolítása"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Vendég munkamenet visszaállítása"</string> <string name="guest_nickname" msgid="6332276931583337261">"Vendég"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Fotó készítése"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Kép kiválasztása"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Fotó kiválasztása"</string> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index fcd3c87454e2..766eb383dffa 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -566,9 +566,11 @@ <string name="user_nickname" msgid="262624187455825083">"Կեղծանուն"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Ավելացնել հյուր"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Հեռացնել հյուրին"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"Վերակայել հյուրի աշխատաշրջանը"</string> <string name="guest_nickname" msgid="6332276931583337261">"Հյուր"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Վերակայե՞լ հյուրի աշխատաշրջանը"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Վերակայել"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Հյուրի աշխատաշրջանը վերակայվում է…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Լուսանկարել"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Ընտրել պատկեր"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Ընտրեք լուսանկար"</string> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index f67c068c75c0..b9b5dcb1a94c 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"Nama panggilan"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Tambahkan tamu"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Hapus tamu"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"Reset tamu"</string> <string name="guest_nickname" msgid="6332276931583337261">"Tamu"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Ambil foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Pilih gambar"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Pilih foto"</string> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index da92e7d4517f..0b5a44a335c2 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Fjarlægja gest"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Endurstilla gestastillingu"</string> <string name="guest_nickname" msgid="6332276931583337261">"Gestur"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Taka mynd"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Velja mynd"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Velja mynd"</string> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index 6f7565e3fb02..c07b5107973b 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Rimuovi ospite"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Reimposta sessione Ospite"</string> <string name="guest_nickname" msgid="6332276931583337261">"Ospite"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Scatta una foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Scegli un\'immagine"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Seleziona la foto"</string> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index dc4836213508..11613aa666a0 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -509,7 +509,7 @@ <string name="alarms_and_reminders_label" msgid="6918395649731424294">"שעונים מעוררים ותזכורות"</string> <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"אישור להגדיר שעונים מעוררים ותזכורות"</string> <string name="alarms_and_reminders_title" msgid="8819933264635406032">"שעונים מעוררים ותזכורות"</string> - <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ההגדרה הזו מתירה לאפליקציה להגדיר שעון מעורר ולתזמן פעולות דחופות. האפליקציה תוכל לפעול ברקע ובכך להגביר את צריכת הסוללה.\n\nאם ההרשאה מושבתת, ההתראות והאירועים מבוססי-הזמן שהוגדרו ותוזמנו על ידי האפליקציה לא יפעלו."</string> + <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ההרשאה הזו מתירה לאפליקציה להגדיר שעון מעורר ולתזמן פעולות דחופות. האפליקציה תוכל לפעול ברקע ובכך להגביר את צריכת הסוללה.\n\nאם ההרשאה מושבתת, ההתראות והאירועים מבוססי-הזמן שהוגדרו ותוזמנו על ידי האפליקציה לא יפעלו."</string> <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"תזמון, שעון מעורר, תזכורת, שעון"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"הפעלה"</string> <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"הפעלת מצב נא לא להפריע"</string> @@ -568,9 +568,14 @@ <string name="user_nickname" msgid="262624187455825083">"כינוי"</string> <string name="guest_new_guest" msgid="3482026122932643557">"הוספת אורח"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"הסרת אורח/ת"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"איפוס הגלישה כאורח"</string> <string name="guest_nickname" msgid="6332276931583337261">"אורח"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"צילום תמונה"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"לבחירת תמונה"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"בחירת תמונה"</string> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index 7e9949f72602..dd3b00b71889 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -73,14 +73,14 @@ <string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"接続済み(メディアなし): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_map" msgid="3381860077002724689">"接続済み(メッセージ アクセスなし): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"接続済み(電話、メディアなし): <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string> - <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"接続済み、電池残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"接続済み(電話なし)、電池残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"接続済み(メディアなし)、電池残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> - <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"接続済み(電話、メディアなし)、電池残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> + <string name="bluetooth_connected_battery_level" msgid="5410325759372259950">"接続済み、バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> + <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"接続済み(電話なし)、バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> + <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"接続済み(メディアなし)、バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> + <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"接続済み(電話、メディアなし)、バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>: <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"有効、電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> - <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"有効、L: 電池残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>、R: 電池残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> - <string name="bluetooth_battery_level" msgid="2893696778200201555">"電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> - <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"L: 電池残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>、R: 電池残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> + <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"有効、L: バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>、R: バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> + <string name="bluetooth_battery_level" msgid="2893696778200201555">"バッテリー <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"L: バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>、R: バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"有効"</string> <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"メディアの音声"</string> <string name="bluetooth_profile_headset" msgid="5395952236133499331">"電話"</string> @@ -507,7 +507,7 @@ <string name="alarms_and_reminders_label" msgid="6918395649731424294">"アラームとリマインダー"</string> <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"アラームとリマインダーの設定を許可する"</string> <string name="alarms_and_reminders_title" msgid="8819933264635406032">"アラームとリマインダー"</string> - <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"アラームの設定や時間の制約があるアクションのスケジュールを、このアプリに許可します。これによりアプリがバックグラウンドで実行できるようになるため、バッテリーの使用量が増えることがあります。\n\nこの権限が OFF の場合、このアプリで設定された既存のアラームと時間ベースのイベントは機能しなくなります。"</string> + <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"アラームの設定や時間ベースのアクション設定を、このアプリに許可します。これによりアプリがバックグラウンドで実行できるようになるため、バッテリーの使用量が増えることがあります。\n\nこの権限が OFF の場合、このアプリで設定された既存のアラームと時間ベースのイベントは機能しなくなります。"</string> <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"スケジュール, アラーム, リマインダー, 時計"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ON にする"</string> <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"サイレント モードを ON にする"</string> @@ -566,9 +566,11 @@ <string name="user_nickname" msgid="262624187455825083">"ニックネーム"</string> <string name="guest_new_guest" msgid="3482026122932643557">"ゲストを追加"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"ゲストを削除"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"ゲストをリセット"</string> <string name="guest_nickname" msgid="6332276931583337261">"ゲスト"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"ゲストをリセットしますか?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"リセット"</string> + <string name="guest_resetting" msgid="7822120170191509566">"ゲストをリセットしています…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"写真を撮る"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"画像を選択"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"写真を選択"</string> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index eef252abceeb..821c98a794ef 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"მეტსახელი"</string> <string name="guest_new_guest" msgid="3482026122932643557">"სტუმრის დამატება"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"სტუმრის ამოშლა"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"სტუმრის სესიის გადაყენება"</string> <string name="guest_nickname" msgid="6332276931583337261">"სტუმარი"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"ფოტოს გადაღება"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"აირჩიეთ სურათი"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ფოტოს არჩევა"</string> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index 70dd9e74929b..89556da1f88e 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Қонақты жою"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Қонақ сеансын әдепкі күйге қайтару"</string> <string name="guest_nickname" msgid="6332276931583337261">"Қонақ"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Фотосуретке түсіру"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Сурет таңдау"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Фотосурет таңдау"</string> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index 26595f5cc067..33902beb129a 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -507,7 +507,7 @@ <string name="alarms_and_reminders_label" msgid="6918395649731424294">"ម៉ោងរោទ៍ និងការរំលឹក"</string> <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"អនុញ្ញាតឱ្យកំណត់ម៉ោងរោទ៍ និងការរំលឹក"</string> <string name="alarms_and_reminders_title" msgid="8819933264635406032">"ម៉ោងរោទ៍ និងការរំលឹក"</string> - <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"អនុញ្ញាតឱ្យកម្មវិធីនេះកំណត់ម៉ោងរោទ៍ និងកំណត់កាលវិភាគសកម្មភាពដែលតម្រូវឱ្យទាន់ពេលវេលា។ សកម្មភាពនេះអនុញ្ញាតឱ្យកម្មវិធីនេះដំណើរការនៅផ្ទៃខាងក្រោយ ដែលអាចប្រើថ្មច្រើន។\n\nប្រសិនបើបិទការអនុញ្ញាតនេះ ម៉ោងរោទ៍ដែលមានស្រាប់ និងព្រឹត្តិការណ៍ផ្អែកលើពេលវេលាដែលកម្មវិធីនេះបានកំណត់កាលវិភាគនឹងមិនដំណើរការទេ។"</string> + <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"អនុញ្ញាតឱ្យកម្មវិធីនេះកំណត់ម៉ោងរោទ៍ និងកំណត់កាលវិភាគសកម្មភាពដែលតម្រូវឱ្យទាន់ពេលវេលា។ ការធ្វើបែបនេះអនុញ្ញាតឱ្យកម្មវិធីនេះដំណើរការនៅផ្ទៃខាងក្រោយ ដែលអាចប្រើថ្មច្រើនជាងមុន។\n\nប្រសិនបើបិទការអនុញ្ញាតនេះ ម៉ោងរោទ៍ដែលមានស្រាប់ និងព្រឹត្តិការណ៍ផ្អែកលើពេលវេលាដែលកំណត់ដោយកម្មវិធីនេះនឹងមិនដំណើរការទេ។"</string> <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"កាលវិភាគ ម៉ោងរោទ៍ ការរំលឹក នាឡិកា"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"បើក"</string> <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"បើកមុខងារកុំរំខាន"</string> @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"ដកភ្ញៀវចេញ"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"កំណត់ភ្ញៀវឡើងវិញ"</string> <string name="guest_nickname" msgid="6332276931583337261">"ភ្ញៀវ"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"ថតរូប"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"ជ្រើសរើសរូបភាព"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ជ្រើសរើសរូបថត"</string> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index b36ef8d2a2da..78a67f453e7c 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -452,8 +452,8 @@ <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"ಟ್ಯಾಬ್ಲೆಟ್ ಶೀಘ್ರದಲ್ಲೇ ಶಟ್ ಡೌನ್ ಆಗಬಹುದು (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"ಸಾಧನವು ಶೀಘ್ರದಲ್ಲೇ ಶಟ್ ಡೌನ್ ಆಗಬಹುದು (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"ಭರ್ತಿಯಾಗುವವರೆಗೂ <xliff:g id="TIME">%1$s</xliff:g> - ಉಳಿದಿದೆ"</string> - <string name="power_charging_duration" msgid="6127154952524919719">"ಭರ್ತಿಯಾಗುವವರೆಗೂ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ಉಳಿದಿದೆ"</string> + <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> - ಸಮಯದಲ್ಲಿ ಪೂರ್ತಿ ಚಾರ್ಜ್ ಆಗುತ್ತದೆ"</string> + <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ಸಮಯದಲ್ಲಿ ಪೂರ್ತಿ ಚಾರ್ಜ್ ಆಗುತ್ತದೆ"</string> <string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಚಾರ್ಜಿಂಗ್ ತಾತ್ಕಾಲಿಕವಾಗಿ ಸೀಮಿತವಾಗಿದೆ"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"ಅಪರಿಚಿತ"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string> @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕಿ"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"ಅತಿಥಿಯನ್ನು ಮರುಹೊಂದಿಸಿ"</string> <string name="guest_nickname" msgid="6332276931583337261">"ಅತಿಥಿ"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"ಫೋಟೋ ತೆಗೆದುಕೊಳ್ಳಿ"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"ಚಿತ್ರವನ್ನು ಆರಿಸಿ"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ಫೋಟೋ ಆಯ್ಕೆಮಾಡಿ"</string> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index 592707190eec..68fe19647dc2 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -429,7 +429,7 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"기기에 색상이 표시되는 방식을 조정합니다. 다음과 같은 상황에서 유용합니다.<br/><br/> <ol> <li>&nbsp;색상을 더욱 정확하게 보고 싶을 때</li> <li>&nbsp;집중을 위해 색상을 제거하고 싶을 때</li> </ol>"</string> <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> 우선 적용됨"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>, <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> - <string name="power_remaining_duration_only" msgid="8264199158671531431">"남은 시간 약 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <string name="power_remaining_duration_only" msgid="8264199158671531431">"남은 시간: 약 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"남은 시간 약 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"내 사용량을 기준으로 약 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> 남음"</string> <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"내 사용량(<xliff:g id="LEVEL">%2$s</xliff:g>)을 기준으로 약 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> 남음"</string> @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"닉네임"</string> <string name="guest_new_guest" msgid="3482026122932643557">"게스트 추가"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"게스트 삭제"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"게스트 재설정"</string> <string name="guest_nickname" msgid="6332276931583337261">"게스트"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"사진 찍기"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"이미지 선택"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"사진 선택"</string> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index 618b7db9a988..3fcedb09fe17 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -507,7 +507,7 @@ <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Ойготкучтар жана эстеткичтер"</string> <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Ойготкуч жана эстеткичтерди коюуга уруксат берүү"</string> <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Ойготкучтар жана эстеткичтер"</string> - <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Бул колдонмого ойготкучтарды коюуга жана башка аракеттерди графикке киргизүүгө уруксат берүү. Ушуну менен колдонмо фондо иштеп, батареяны көбүрөөк сарпташы мүмкүн.\n\nЭгер бул уруксат өчүрүлсө, колдонмодогу ойготкучтар жана графикке киргизилген башка аракеттер иштебейт."</string> + <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Бул колдонмого ойготкучтарды коюуга жана башка аракеттерди графикке киргизүүгө уруксат бересиз. Ушуну менен колдонмо фондо иштеп, батареяны көбүрөөк сарпташы мүмкүн.\n\nЭгер бул уруксат өчүрүлсө, колдонмодогу ойготкучтар жана графикке киргизилген башка аракеттер иштебейт."</string> <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"график, ойготкуч, эстеткич, саат"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Күйгүзүү"</string> <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\"Тынчымды алба\" режимин күйгүзүү"</string> @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"Ылакап аты"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Конок кошуу"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Конокту өчүрүү"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"Конок сеансын баштапкы абалга келтирүү"</string> <string name="guest_nickname" msgid="6332276931583337261">"Конок"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Сүрөткө тартуу"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Сүрөт тандаңыз"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Сүрөт тандаңыз"</string> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index bf6c2a32ab7a..462b53f5d5e0 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -566,9 +566,11 @@ <string name="user_nickname" msgid="262624187455825083">"ຊື່ຫຼິ້ນ"</string> <string name="guest_new_guest" msgid="3482026122932643557">"ເພີ່ມແຂກ"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"ລຶບແຂກອອກ"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"ຣີເຊັດແຂກ"</string> <string name="guest_nickname" msgid="6332276931583337261">"ແຂກ"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"ຣີເຊັດແຂກບໍ?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ຣີເຊັດ"</string> + <string name="guest_resetting" msgid="7822120170191509566">"ກຳລັງຣີເຊັດແຂກ…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"ຖ່າຍຮູບ"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"ເລືອກຮູບ"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ເລືອກຮູບ"</string> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index ad0ad1fb28bf..d7d5f24f546f 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -570,6 +570,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Pašalinti svečią"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Iš naujo nustatyti svečią"</string> <string name="guest_nickname" msgid="6332276931583337261">"Svečias"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Fotografuoti"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Pasirinkti vaizdą"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Pasirinkti nuotrauką"</string> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index 586de6fcfdf7..8f9ac01d9ba8 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -569,6 +569,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Noņemt viesi"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Atiestatīt viesa sesiju"</string> <string name="guest_nickname" msgid="6332276931583337261">"Viesis"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Uzņemt fotoattēlu"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Izvēlēties attēlu"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Atlasīt fotoattēlu"</string> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index 0d0f345af7c3..f1f163959d93 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -568,6 +568,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Отстрани гостин"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Ресетирајте го гостинот"</string> <string name="guest_nickname" msgid="6332276931583337261">"Гостин"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Да се ресетира гостинот?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ресетирај"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Се ресетира гостинот…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Фотографирајте"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Одберете слика"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Изберете фотографија"</string> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index 655be1a74c31..134ac9b07841 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"അതിഥിയെ നീക്കം ചെയ്യുക"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"അതിഥിയെ റീസെറ്റ് ചെയ്യുക"</string> <string name="guest_nickname" msgid="6332276931583337261">"അതിഥി"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"ഒരു ഫോട്ടോ എടുക്കുക"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"ഒരു ചിത്രം തിരഞ്ഞെടുക്കുക"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ഫോട്ടോ തിരഞ്ഞെടുക്കുക"</string> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index 07ed369b8d36..5ac22ffbf751 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -568,6 +568,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Зочин хасах"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Зочныг шинэчлэх"</string> <string name="guest_nickname" msgid="6332276931583337261">"Зочин"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Зочныг шинэчлэх үү?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Шинэчлэх"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Зочныг шинэчилж байна…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Зураг авах"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Зураг сонгох"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Зураг сонгох"</string> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index fe8e8375a65a..ea6716595d16 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -568,6 +568,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"अतिथी काढून टाका"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"अतिथी सेशन रीसेट करा"</string> <string name="guest_nickname" msgid="6332276931583337261">"अतिथी"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"अतिथीला रीसेट करायचे आहे का?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"रीसेट करा"</string> + <string name="guest_resetting" msgid="7822120170191509566">"अतिथीला रीसेट करत आहे…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"फोटो काढा"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"इमेज निवडा"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"फोटो निवडा"</string> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index 77006fc1bf1a..34f6343814ab 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"Nama panggilan"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Tambah tetamu"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Alih keluar tetamu"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"Tetapkan semula tetamu"</string> <string name="guest_nickname" msgid="6332276931583337261">"Tetamu"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Ambil foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Pilih imej"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Pilih foto"</string> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index b383ad84cadb..22415ad99330 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"ဧည့်သည်ကို ဖယ်ထုတ်ရန်"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"ဧည့်သည်ကို ပြင်ဆင်သတ်မှတ်ရန်"</string> <string name="guest_nickname" msgid="6332276931583337261">"ဧည့်သည်"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"ဓာတ်ပုံရိုက်ရန်"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"ပုံရွေးရန်"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ဓာတ်ပုံရွေးရန်"</string> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index 84c231faed46..f39c0dccec8b 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -568,6 +568,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Fjern gjesten"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Tilbakestill gjest"</string> <string name="guest_nickname" msgid="6332276931583337261">"Gjest"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Vil du tilbakestille gjesten?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Tilbakestill"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Tilbakestiller gjesten …"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Ta et bilde"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Velg et bilde"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Velg et bilde"</string> diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml index 1fc6899891aa..3699bf3ec59c 100644 --- a/packages/SettingsLib/res/values-ne/arrays.xml +++ b/packages/SettingsLib/res/values-ne/arrays.xml @@ -260,7 +260,7 @@ <item msgid="6506681373060736204">"बढीमा ४ प्रक्रियाहरू"</item> </string-array> <string-array name="usb_configuration_titles"> - <item msgid="3358668781763928157">"चार्ज हुँदै"</item> + <item msgid="3358668781763928157">"चार्ज हुँदै छ"</item> <item msgid="7804797564616858506">"MTP (मिडिया स्थानान्तरण प्रोटोकल)"</item> <item msgid="910925519184248772">"PTP (चित्र स्थानान्तरण प्रोटोकल)"</item> <item msgid="3825132913289380004">"RNDIS (USB इथरनेट)"</item> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index a54fc0c85071..e6fc70736a2f 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -456,8 +456,8 @@ <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूरा चार्ज हुन <xliff:g id="TIME">%2$s</xliff:g> लाग्ने छ"</string> <string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्जिङ केही समयका लागि सीमित पारिएको छ"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"अज्ञात"</string> - <string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज हुँदै"</string> - <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"द्रुत गतिमा चार्ज गरिँदै"</string> + <string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज हुँदै छ"</string> + <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"द्रुत गतिमा चार्ज गरिँदै छ"</string> <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"बिस्तारै चार्ज गरिँदै"</string> <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"वायरलेस तरिकाले चार्ज गरिँदै छ"</string> <string name="battery_info_status_discharging" msgid="6962689305413556485">"चार्ज भइरहेको छैन"</string> @@ -507,7 +507,7 @@ <string name="alarms_and_reminders_label" msgid="6918395649731424294">"अलार्म र रिमाइन्डरहरू"</string> <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"अलार्म तथा रिमाइन्डर सेट गर्न दिइयोस्"</string> <string name="alarms_and_reminders_title" msgid="8819933264635406032">"घडी तथा रिमाइन्डरहरू"</string> - <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"यो एपलाई अलार्म सेट गर्ने र समयमै पूरा गर्नु पर्ने कारबाहीहरूको रुटिन तय गर्ने अनुमति दिनुहोस्। यो अनुमति दिइएको छ भने यो एप ब्याकग्राउन्डमा यसले चलेर धेरै ब्याट्री खपत गर्न सक्छ।\n\nयो अनुमति दिइएको छैन भने समय तोकिएका अलार्म र यो एपले तय गरेका समयअनुसार चल्ने कार्यक्रमले काम गर्दैन।"</string> + <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"यो एपलाई अलार्म सेट गर्ने र समयमै पूरा गर्नु पर्ने कारबाहीहरूको रुटिन बनाउने अनुमति दिनुहोस्। यो अनुमति दिइएको छ भने यो एप ब्याकग्राउन्डमा चल्छ र धेरै ब्याट्री खपत हुन्छ।\n\nयो अनुमति दिइएको छैन भने सेट गरिएका अलार्म बज्दैनन् र यो एपले तय गरेका गतिविधि चल्दैनन्।"</string> <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"समयतालिका, अलार्म, रिमाइन्डर, घडी"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"सक्रिय गर्नुहोस्"</string> <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"बाधा नपुऱ्याउनुहोस् नामक मोडलाई सक्रिय गर्नुहोस्"</string> @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"उपनाम"</string> <string name="guest_new_guest" msgid="3482026122932643557">"अतिथि थप्नुहोस्"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"अतिथि हटाउनुहोस्"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"अतिथि सत्र रिसेट गर्नुहोस्"</string> <string name="guest_nickname" msgid="6332276931583337261">"अतिथि"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"फोटो खिच्नुहोस्"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"कुनै फोटो छनौट गर्नुहोस्"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"फोटो चयन गर्नुहोस्"</string> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index 1837eabf2370..017de6a6d462 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -568,6 +568,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Gast verwijderen"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Gastsessie resetten"</string> <string name="guest_nickname" msgid="6332276931583337261">"Gast"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Gast resetten?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetten"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Gast resetten…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Foto maken"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Afbeelding kiezen"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Foto selecteren"</string> diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index 6cc3cc560e53..a211fd49ca50 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"ଡାକନାମ"</string> <string name="guest_new_guest" msgid="3482026122932643557">"ଅତିଥି ଯୋଗ କରନ୍ତୁ"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"ଅତିଥିଙ୍କୁ କାଢ଼ି ଦିଅନ୍ତୁ"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"ଅତିଥି ସେସନକୁ ରିସେଟ୍ କରନ୍ତୁ"</string> <string name="guest_nickname" msgid="6332276931583337261">"ଅତିଥି"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"ଗୋଟିଏ ଫଟୋ ଉଠାନ୍ତୁ"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"ଏକ ଛବି ବାଛନ୍ତୁ"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ଫଟୋ ବାଛନ୍ତୁ"</string> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index 0af499023717..969e34d4c891 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -461,7 +461,7 @@ <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"ਹੌਲੀ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ"</string> <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"ਬਿਨਾਂ ਤਾਰ ਤੋਂ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ"</string> <string name="battery_info_status_discharging" msgid="6962689305413556485">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string> - <string name="battery_info_status_not_charging" msgid="3371084153747234837">"ਕਨੈਕਟ ਹੈ, ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string> + <string name="battery_info_status_not_charging" msgid="3371084153747234837">"ਕਨੈਕਟ ਹੈ, ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਹੀ"</string> <string name="battery_info_status_full" msgid="1339002294876531312">"ਚਾਰਜ ਹੋ ਗਈ"</string> <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਕੰਟਰੋਲ ਕੀਤੀ ਗਈ"</string> <string name="disabled" msgid="8017887509554714950">"ਅਯੋਗ ਬਣਾਇਆ"</string> @@ -507,7 +507,7 @@ <string name="alarms_and_reminders_label" msgid="6918395649731424294">"ਅਲਾਰਮ ਅਤੇ ਰਿਮਾਈਂਡਰ"</string> <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"ਅਲਾਰਮ ਅਤੇ ਰਿਮਾਈਂਡਰ ਸੈੱਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string> <string name="alarms_and_reminders_title" msgid="8819933264635406032">"ਅਲਾਰਮ ਅਤੇ ਰਿਮਾਈਂਡਰ"</string> - <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ਇਸ ਐਪ ਨੂੰ ਅਲਾਰਮ ਸੈੱਟ ਕਰਨ ਜਾਂ ਹੋਰ ਸਮਾਂ-ਸੰਵੇਦਨਸ਼ੀਲ ਕਾਰਵਾਈਆਂ ਨੂੰ ਨਿਯਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ। ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚਲਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਮਿਲਦੀ ਹੈ, ਜੋ ਵੱਧ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੀ ਹੈ।\n\nਜੇ ਇਹ ਇਜਾਜ਼ਤ ਬੰਦ ਹੈ, ਤਾਂ ਮੌਜੂਦਾ ਅਲਾਰਮ ਅਤੇ ਇਸ ਐਪ ਰਾਹੀਂ ਸਮਾਂ ਨਿਯਤ ਕੀਤੇ ਸਮਾਂ-ਆਧਾਰਿਤ ਇਵੈਂਟਾਂ ਕੰਮ ਨਹੀਂ ਕਰਨਗੇ।"</string> + <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ਇਸ ਐਪ ਨੂੰ ਅਲਾਰਮ ਸੈੱਟ ਕਰਨ ਜਾਂ ਹੋਰ ਸਮਾਂ-ਸੰਵੇਦਨਸ਼ੀਲ ਕਾਰਵਾਈਆਂ ਨੂੰ ਨਿਯਤ ਕਰਨ ਦਿਓ। ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚਲਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਮਿਲਦੀ ਹੈ, ਜਿਸ ਨਾਲ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਵੱਧ ਸਕਦੀ ਹੈ।\n\nਜੇ ਇਹ ਇਜਾਜ਼ਤ ਬੰਦ ਹੈ, ਤਾਂ ਮੌਜੂਦਾ ਅਲਾਰਮ ਅਤੇ ਇਸ ਐਪ ਰਾਹੀਂ ਨਿਯਤ ਕੀਤੇ ਸਮਾਂ-ਆਧਾਰਿਤ ਇਵੈਂਟ ਕੰਮ ਨਹੀਂ ਕਰਨਗੇ।"</string> <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ਸਮਾਂ-ਸੂਚੀ, ਅਲਾਰਮ, ਰਿਮਾਈਂਡਰ, ਘੜੀ"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ਚਾਲੂ ਕਰੋ"</string> <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਨੂੰ ਚਾਲੂ ਕਰੋ"</string> @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"ਉਪਨਾਮ"</string> <string name="guest_new_guest" msgid="3482026122932643557">"ਮਹਿਮਾਨ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"ਮਹਿਮਾਨ ਹਟਾਓ"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"ਗੈਸਟ ਰੀਸੈੱਟ ਕਰੋ"</string> <string name="guest_nickname" msgid="6332276931583337261">"ਮਹਿਮਾਨ"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"ਇੱਕ ਫ਼ੋਟੋ ਖਿੱਚੋ"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"ਕੋਈ ਚਿੱਤਰ ਚੁਣੋ"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ਫ਼ੋਟੋ ਚੁਣੋ"</string> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index bd77d881560f..9b25f63c1280 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -570,6 +570,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Usuń gościa"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Resetuj sesję gościa"</string> <string name="guest_nickname" msgid="6332276931583337261">"Gość"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Zrób zdjęcie"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Wybierz obraz"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Wybierz zdjęcie"</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index e39b58bb8344..f8eab0ca94cb 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Redefinir sessão de visitante"</string> <string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index a5c0d1d58d40..4f8c6d2173a7 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Repor convidado"</string> <string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index e39b58bb8344..f8eab0ca94cb 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Redefinir sessão de visitante"</string> <string name="guest_nickname" msgid="6332276931583337261">"Convidado"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index e1b0390fbace..75bf3aa34147 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -569,6 +569,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Ștergeți invitatul"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Resetați sesiunea pentru invitați"</string> <string name="guest_nickname" msgid="6332276931583337261">"Invitat"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Faceți o fotografie"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Alegeți o imagine"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Selectați fotografia"</string> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index 1e5fce5f3bc9..b416b069b4d1 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -559,7 +559,7 @@ <string name="user_new_user_name" msgid="60979820612818840">"Новый пользователь"</string> <string name="user_new_profile_name" msgid="2405500423304678841">"Новый профиль"</string> <string name="user_info_settings_title" msgid="6351390762733279907">"Сведения о пользователе"</string> - <string name="profile_info_settings_title" msgid="105699672534365099">"Информация о профиле"</string> + <string name="profile_info_settings_title" msgid="105699672534365099">"Данные профиля"</string> <string name="user_need_lock_message" msgid="4311424336209509301">"Чтобы создать профиль с ограниченным доступом, необходимо предварительно настроить блокировку экрана для защиты приложений и личных данных"</string> <string name="user_set_lock_button" msgid="1427128184982594856">"Включить блокировку"</string> <string name="user_switch_to_user" msgid="6975428297154968543">"Сменить пользователя на <xliff:g id="USER_NAME">%s</xliff:g>"</string> @@ -570,6 +570,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Удалить аккаунт гостя"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Сбросить гостевой сеанс"</string> <string name="guest_nickname" msgid="6332276931583337261">"Гость"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Сделать снимок"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Выбрать фото"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Выбрать фотографию"</string> diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index a385055f8fbb..ecd288862ade 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -566,9 +566,11 @@ <string name="user_nickname" msgid="262624187455825083">"අපනාමය"</string> <string name="guest_new_guest" msgid="3482026122932643557">"අමුත්තා එක් කරන්න"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"අමුත්තා ඉවත් කරන්න"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"ආගන්තුකයා යළි සකසන්න"</string> <string name="guest_nickname" msgid="6332276931583337261">"අමුත්තා"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"අමුත්තා යළි සකසන්නද?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"යළි සකසන්න"</string> + <string name="guest_resetting" msgid="7822120170191509566">"අමුත්තා යළි සකසමින්…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"ඡායාරූපයක් ගන්න"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"රූපයක් තෝරන්න"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ඡායාරූපය තෝරන්න"</string> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index 09c0bf993f34..9c68851e81ae 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -570,6 +570,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Odobrať hosťa"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Obnoviť reláciu hosťa"</string> <string name="guest_nickname" msgid="6332276931583337261">"Hosť"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Odfotiť"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrať obrázok"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Vybrať fotku"</string> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index b698c19ff8b8..490d3aaef0e2 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -570,6 +570,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Odstranitev gosta"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Ponastavi gosta"</string> <string name="guest_nickname" msgid="6332276931583337261">"Gost"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Želite ponastaviti gosta?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ponastavi"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Ponastavljanje gosta …"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Fotografiranje"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Izberi sliko"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Izbira fotografije"</string> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index ba7443600e3d..d38c3613f8a2 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -457,7 +457,7 @@ <string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - Karikimi përkohësisht i kufizuar"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"I panjohur"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Po karikohet"</string> - <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Po ngarkon me shpejtësi"</string> + <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Karikim i shpejtë"</string> <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Po karikohet ngadalë"</string> <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Po karikohet pa tel"</string> <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nuk po karikohet"</string> @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"Pseudonimi"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Shto të ftuar"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Hiq të ftuarin"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"Rivendos vizitorin"</string> <string name="guest_nickname" msgid="6332276931583337261">"I ftuar"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Bëj një fotografi"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Zgjidh një imazh"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Zgjidh një fotografi"</string> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index b3c23b667a42..171ec7517317 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -569,6 +569,9 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Уклони госта"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Ресетуј сесију госта"</string> <string name="guest_nickname" msgid="6332276931583337261">"Гост"</string> + <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Желите ли да ресетујете сесију госта?"</string> + <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ресетуј"</string> + <string name="guest_resetting" msgid="7822120170191509566">"Сесија госта се ресетује…"</string> <string name="user_image_take_photo" msgid="467512954561638530">"Сликај"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Одабери слику"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Изаберите слику"</string> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index 124c063bea95..124c0e75cdcb 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Ta bort gäst"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Återställ gästsession"</string> <string name="guest_nickname" msgid="6332276931583337261">"Gäst"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Ta ett foto"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Välj en bild"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Välj foto"</string> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index 332cd9dc386a..96e089071a15 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -452,9 +452,9 @@ <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"Huenda kompyuta kibao ikazima hivi karibuni (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Huenda kifaa kikazima hivi karibuni (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Zimesalia <xliff:g id="TIME">%1$s</xliff:g> hadi ijae chaji"</string> - <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> zimesalia hadi ijae chaji"</string> - <string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - Hali ya kuchaji kwa muda imedhibitiwa"</string> + <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Zimesalia <xliff:g id="TIME">%1$s</xliff:g> ijae chaji"</string> + <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> zimesalia ijae chaji"</string> + <string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - Kuchaji kumedhibitiwa kwa muda"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Haijulikani"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Inachaji"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Inachaji kwa kasi"</string> @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"Jina wakilishi"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Ongeza mgeni"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Ondoa mgeni"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"Badilisha kipindi cha mgeni"</string> <string name="guest_nickname" msgid="6332276931583337261">"Mgeni"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Piga picha"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Chagua picha"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Chagua picha"</string> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 7952a76859f5..69a094514db9 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -505,8 +505,7 @@ <string name="cancel" msgid="5665114069455378395">"ரத்துசெய்"</string> <string name="okay" msgid="949938843324579502">"சரி"</string> <string name="alarms_and_reminders_label" msgid="6918395649731424294">"அலாரங்களும் நினைவூட்டல்களும்"</string> - <!-- unknown quoting pattern: original -1, translation 1 --> - <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"அலாரங்கள் &amp; நினைவூட்டல்களை அமைக்க அனுமதித்தல்"</string> + <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"அலாரங்கள் & நினைவூட்டல்களை அமைக்க அனுமதித்தல்"</string> <string name="alarms_and_reminders_title" msgid="8819933264635406032">"அலாரங்கள் & நினைவூட்டல்கள்"</string> <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"அலாரங்களை அமைக்கவும் குறிப்பிட்ட கால இடைவெளியில் செயல்களைத் திட்டமிடவும் இந்த ஆப்ஸை அனுமதிக்கும். இது ஆப்ஸ் பின்னணியில் இயங்குவதை அனுமதிக்கும், இதற்காக அதிக பேட்டரியைப் பயன்படுத்தக்கூடும்.\n\nஇந்த அனுமதி முடக்கப்பட்டிருந்தால் இந்த ஆப்ஸ் மூலம் திட்டமிடப்பட்ட ஏற்கெனவே அமைத்த அலாரங்களும் நேர அடிப்படையிலான நிகழ்வுகளும் வேலை செய்யாது."</string> <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"திட்டமிடல், அலாரம், நினைவூட்டல், கடிகாரம்"</string> @@ -567,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"புனைப்பெயர்"</string> <string name="guest_new_guest" msgid="3482026122932643557">"கெஸ்ட்டைச் சேர்"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"கெஸ்ட்டை அகற்று"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"கெஸ்ட் அமர்வை மீட்டமை"</string> <string name="guest_nickname" msgid="6332276931583337261">"கெஸ்ட்"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"படமெடுங்கள்"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"படத்தைத் தேர்வுசெய்யுங்கள்"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"படத்தைத் தேர்ந்தெடுங்கள்"</string> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index da0380d13107..d8da8da5d72c 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"మారుపేరు"</string> <string name="guest_new_guest" msgid="3482026122932643557">"గెస్ట్ను జోడించండి"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"గెస్ట్ను తీసివేయండి"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"గెస్ట్ సెషన్ను రీసెట్ చేయండి"</string> <string name="guest_nickname" msgid="6332276931583337261">"గెస్ట్"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"ఒక ఫోటో తీయండి"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"ఇమేజ్ను ఎంచుకోండి"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"ఫోటోను ఎంచుకోండి"</string> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 7f67b88aa837..ca0e37671941 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"นำผู้ใช้ชั่วคราวออก"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"รีเซ็ตผู้เข้าร่วม"</string> <string name="guest_nickname" msgid="6332276931583337261">"ผู้ใช้ชั่วคราว"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"ถ่ายรูป"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"เลือกรูปภาพ"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"เลือกรูปภาพ"</string> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index cc7db29f3d32..1c5092f7ffab 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Alisin ang bisita"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"I-reset ang bisita"</string> <string name="guest_nickname" msgid="6332276931583337261">"Bisita"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Kumuha ng larawan"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Pumili ng larawan"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Pumili ng larawan"</string> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 36144ebf1c63..42e7c5e3a178 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -507,7 +507,7 @@ <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmlar ve hatırlatıcılar"</string> <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Alarm ve hatırlatıcı ayarlanmasına izin ver"</string> <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmlar ve hatırlatıcılar"</string> - <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Bu uygulamanın alarmlar kurmasına ve zamana bağlı işlemler programlamasına izin verin. Bu izin, uygulamanın arka planda çalışmasına olanak sağlayarak daha fazla pil harcanmasına neden olabilir.\n\nBu izin verilmezse bu uygulama tarafından programlanmış mevcut alarmlar ve zamana bağlı etkinlikler çalışmaz."</string> + <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Bu uygulamanın alarm kurmasına ve zamana bağlı işlemler programlamasına izin verin. Bu izin, uygulamanın arka planda çalışmasına olanak sağlayarak daha fazla pil harcanmasına neden olabilir.\n\nBu izin verilmezse bu uygulama tarafından programlanmış mevcut alarmlar ve zamana bağlı etkinlikler çalışmaz."</string> <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"program, alarm, hatırlatıcı, saat"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aç"</string> <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Rahatsız Etmeyin\'i açın"</string> @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"Takma ad"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Misafir ekle"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Misafir oturumunu kaldır"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"Misafir oturumunu sıfırla"</string> <string name="guest_nickname" msgid="6332276931583337261">"Misafir"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Fotoğraf çek"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Resim seç"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Fotoğraf seç"</string> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index 2cb10763fcc9..ba7a6789fe73 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -570,6 +570,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Видалити гостя"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Скинути сеанс у режимі \"Гість\""</string> <string name="guest_nickname" msgid="6332276931583337261">"Гість"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Зробити фотографію"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Вибрати зображення"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Вибрати фотографію"</string> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index d0ed2ab8ba34..d0cc6de87daf 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"عرفی نام"</string> <string name="guest_new_guest" msgid="3482026122932643557">"مہمان کو شامل کریں"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"مہمان کو ہٹائیں"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"مہمان کو ری سیٹ کریں"</string> <string name="guest_nickname" msgid="6332276931583337261">"مہمان"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"ایک تصویر لیں"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"ایک تصویر منتخب کریں"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"تصویر منتخب کریں"</string> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index 3e11124597d9..c433c958e1f8 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Mehmonni olib tashlash"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Mehmon seansini tiklash"</string> <string name="guest_nickname" msgid="6332276931583337261">"Mehmon"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Suratga olish"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Rasm tanlash"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Surat tanlash"</string> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index 0fba1ecffe02..f200467a10fe 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"Biệt hiệu"</string> <string name="guest_new_guest" msgid="3482026122932643557">"Thêm khách"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"Xóa phiên khách"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"Đặt lại phiên khách"</string> <string name="guest_nickname" msgid="6332276931583337261">"Khách"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Chụp ảnh"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Chọn một hình ảnh"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Chọn ảnh"</string> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index d226f0170ac6..9e7c410facb3 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -429,10 +429,10 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"调整设备上的颜色显示方式。此设置对以下情况有帮助:<br/><br/> <ol> <li>&nbsp;您想更准确地看颜色</li> <li>&nbsp;您想去除一些颜色,以便集中注意力</li> </ol>"</string> <string name="daltonizer_type_overridden" msgid="4509604753672535721">"已被“<xliff:g id="TITLE">%1$s</xliff:g>”覆盖"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> - <string name="power_remaining_duration_only" msgid="8264199158671531431">"大约还可使用 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> - <string name="power_discharging_duration" msgid="1076561255466053220">"大约还可使用 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"根据您的使用情况,大约还可使用 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> - <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"根据您的使用情况,大约还可使用 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_duration_only" msgid="8264199158671531431">"大约还可使用<xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <string name="power_discharging_duration" msgid="1076561255466053220">"大约还可使用<xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"根据您的使用情况,大约还可使用<xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> + <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"根据您的使用情况,大约还可使用<xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <!-- no translation found for power_remaining_duration_only_short (7438846066602840588) --> <skip /> <string name="power_discharge_by_enhanced" msgid="563438403581662942">"根据您的使用情况,估计能用到<xliff:g id="TIME">%1$s</xliff:g>(目前电量为 <xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -452,8 +452,8 @@ <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"平板电脑可能即将关机 (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"设备可能即将关机 (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"还需 <xliff:g id="TIME">%1$s</xliff:g>充满"</string> - <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需 <xliff:g id="TIME">%2$s</xliff:g>充满"</string> + <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"还需<xliff:g id="TIME">%1$s</xliff:g>充满"</string> + <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满"</string> <string name="power_charging_limited" msgid="7956120998372505295">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充电暂时受限"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"未知"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"正在充电"</string> @@ -461,7 +461,7 @@ <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"正在慢速充电"</string> <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"正在无线充电"</string> <string name="battery_info_status_discharging" msgid="6962689305413556485">"未在充电"</string> - <string name="battery_info_status_not_charging" msgid="3371084153747234837">"已连接,尚未充电"</string> + <string name="battery_info_status_not_charging" msgid="3371084153747234837">"已连接,未充电"</string> <string name="battery_info_status_full" msgid="1339002294876531312">"已充满电"</string> <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"由管理员控制"</string> <string name="disabled" msgid="8017887509554714950">"已停用"</string> @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"昵称"</string> <string name="guest_new_guest" msgid="3482026122932643557">"添加访客"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"移除访客"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"重置访客会话"</string> <string name="guest_nickname" msgid="6332276931583337261">"访客"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"拍摄照片"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"选择图片"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"选择照片"</string> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index 642dd1dcb4ed..7c10c2cff852 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"暱稱"</string> <string name="guest_new_guest" msgid="3482026122932643557">"新增訪客"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"移除訪客"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"重設訪客"</string> <string name="guest_nickname" msgid="6332276931583337261">"訪客"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"拍照"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"選擇圖片"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"揀相"</string> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 1cab0afbead2..583bf18b01b2 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -566,9 +566,14 @@ <string name="user_nickname" msgid="262624187455825083">"暱稱"</string> <string name="guest_new_guest" msgid="3482026122932643557">"新增訪客"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"移除訪客"</string> - <!-- no translation found for guest_reset_guest (6110013010356013758) --> - <skip /> + <string name="guest_reset_guest" msgid="6110013010356013758">"重設訪客"</string> <string name="guest_nickname" msgid="6332276931583337261">"訪客"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"拍照"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"選擇圖片"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"選取相片"</string> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index 0fa97e2011ce..8d1feda61784 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -568,6 +568,12 @@ <string name="guest_exit_guest" msgid="5908239569510734136">"Susa isihambeli"</string> <string name="guest_reset_guest" msgid="6110013010356013758">"Setha kabusha isivakashi"</string> <string name="guest_nickname" msgid="6332276931583337261">"Isihambeli"</string> + <!-- no translation found for guest_reset_guest_dialog_title (8047270010895437534) --> + <skip /> + <!-- no translation found for guest_reset_guest_confirm_button (2989915693215617237) --> + <skip /> + <!-- no translation found for guest_resetting (7822120170191509566) --> + <skip /> <string name="user_image_take_photo" msgid="467512954561638530">"Thatha isithombe"</string> <string name="user_image_choose_photo" msgid="1363820919146782908">"Khetha isithombe"</string> <string name="user_image_photo_selector" msgid="433658323306627093">"Khetha isithombe"</string> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index 8651595753a7..6b840bd7901d 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -1426,7 +1426,12 @@ <string name="guest_reset_guest">Reset guest</string> <!-- Name for the guest user [CHAR LIMIT=35] --> <string name="guest_nickname">Guest</string> - + <!-- Title of the confirmation dialog to confirm resetting guest. [CHAR LIMIT=NONE] --> + <string name="guest_reset_guest_dialog_title">Reset guest?</string> + <!-- Label for button in confirmation dialog when resetting guest user [CHAR LIMIT=35] --> + <string name="guest_reset_guest_confirm_button">Reset</string> + <!-- Status message indicating the device is in the process of resetting the guest user. [CHAR_LIMIT=NONE] --> + <string name="guest_resetting">Resetting guest\u2026</string> <!-- An option in a photo selection dialog to take a new photo [CHAR LIMIT=50] --> <string name="user_image_take_photo">Take a photo</string> <!-- An option in a photo selection dialog to choose a pre-existing image [CHAR LIMIT=50] --> diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java index 44cafb17e1d8..bd9e0d341b2e 100644 --- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java +++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java @@ -33,15 +33,17 @@ public final class ActionDisabledByAdminControllerFactory { /** * Returns the relevant instance of {@link ActionDisabledByAdminController}. + * @param userHandle user on which to launch the help page, if necessary */ public static ActionDisabledByAdminController createInstance(Context context, - String restriction, DeviceAdminStringProvider stringProvider) { + String restriction, DeviceAdminStringProvider stringProvider, + UserHandle userHandle) { if (doesBiometricRequireParentalConsent(context, restriction)) { return new BiometricActionDisabledByAdminController(stringProvider); } else if (isFinancedDevice(context)) { return new FinancedDeviceActionDisabledByAdminController(stringProvider); } else { - return new ManagedDeviceActionDisabledByAdminController(stringProvider); + return new ManagedDeviceActionDisabledByAdminController(stringProvider, userHandle); } } diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java index 849c3d97d731..411487976fe5 100644 --- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java +++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java @@ -54,11 +54,12 @@ public abstract class ActionDisabledLearnMoreButtonLauncher { /** * Sets up a "learn more" button which launches a help page */ - public final void setupLearnMoreButtonToLaunchHelpPage(Context context, String url) { + public final void setupLearnMoreButtonToLaunchHelpPage( + Context context, String url, UserHandle userHandle) { requireNonNull(context, "context cannot be null"); requireNonNull(url, "url cannot be null"); - setLearnMoreButton(() -> showHelpPage(context, url)); + setLearnMoreButton(() -> showHelpPage(context, url, userHandle)); } /** @@ -105,8 +106,8 @@ public abstract class ActionDisabledLearnMoreButtonLauncher { * Shows the help page using the given {@code url}. */ @VisibleForTesting - public void showHelpPage(Context context, String url) { - context.startActivityAsUser(createLearnMoreIntent(url), UserHandle.of(context.getUserId())); + public void showHelpPage(Context context, String url, UserHandle userHandle) { + context.startActivityAsUser(createLearnMoreIntent(url), userHandle); finishSelf(); } diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java index 814d5d23f458..1472980efd4e 100644 --- a/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java +++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java @@ -32,8 +32,10 @@ public class BiometricActionDisabledByAdminController extends BaseActionDisabled // These MUST not change, as they are the stable API between here and device admin specified // by the component below. - private static final String ACTION_LEARN_MORE = "android.settings.LEARN_MORE"; - private static final String EXTRA_FROM_BIOMETRIC_SETUP = "from_biometric_setup"; + private static final String ACTION_LEARN_MORE = + "android.intent.action.MANAGE_RESTRICTED_SETTING"; + private static final String EXTRA_SETTING_KEY = "extra_setting"; + private static final String EXTRA_SETTING_VALUE = "biometric_disabled_by_admin_controller"; BiometricActionDisabledByAdminController( DeviceAdminStringProvider stringProvider) { @@ -63,7 +65,7 @@ public class BiometricActionDisabledByAdminController extends BaseActionDisabled Log.d(TAG, "Positive button clicked, component: " + enforcedAdmin.component); final Intent intent = new Intent(ACTION_LEARN_MORE) .setComponent(enforcedAdmin.component) - .putExtra(EXTRA_FROM_BIOMETRIC_SETUP, true) + .putExtra(EXTRA_SETTING_KEY, EXTRA_SETTING_VALUE) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); }; diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java index df6bab74e014..93e811d6baaa 100644 --- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java +++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java @@ -16,13 +16,18 @@ package com.android.settingslib.enterprise; +import static java.util.Objects.requireNonNull; + import android.app.admin.DevicePolicyManager; import android.content.Context; +import android.os.UserHandle; import android.os.UserManager; import android.text.TextUtils; import androidx.annotation.Nullable; +import java.util.Objects; + /** * An {@link ActionDisabledByAdminController} to be used with managed devices. @@ -30,8 +35,17 @@ import androidx.annotation.Nullable; final class ManagedDeviceActionDisabledByAdminController extends BaseActionDisabledByAdminController { - ManagedDeviceActionDisabledByAdminController(DeviceAdminStringProvider stringProvider) { + private final UserHandle mUserHandle; + + /** + * Constructs a {@link ManagedDeviceActionDisabledByAdminController} + * @param userHandle - user on which to launch the help web page, if necessary + */ + ManagedDeviceActionDisabledByAdminController( + DeviceAdminStringProvider stringProvider, + UserHandle userHandle) { super(stringProvider); + mUserHandle = requireNonNull(userHandle); } @Override @@ -43,7 +57,7 @@ final class ManagedDeviceActionDisabledByAdminController mLauncher.setupLearnMoreButtonToShowAdminPolicies(context, mEnforcementAdminUserId, mEnforcedAdmin); } else { - mLauncher.setupLearnMoreButtonToLaunchHelpPage(context, url); + mLauncher.setupLearnMoreButtonToLaunchHelpPage(context, url, mUserHandle); } } diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/ConversationIconFactory.java b/packages/SettingsLib/src/com/android/settingslib/notification/ConversationIconFactory.java index 549bc8a455cf..ebdfbeade99d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/notification/ConversationIconFactory.java +++ b/packages/SettingsLib/src/com/android/settingslib/notification/ConversationIconFactory.java @@ -33,6 +33,7 @@ import android.util.Log; import com.android.launcher3.icons.BaseIconFactory; import com.android.settingslib.R; +import com.android.settingslib.Utils; /** * Factory for creating normalized conversation icons. @@ -99,7 +100,7 @@ public class ConversationIconFactory extends BaseIconFactory { try { final ApplicationInfo appInfo = mPackageManager.getApplicationInfoAsUser( packageName, PackageManager.GET_META_DATA, userId); - badge = mIconDrawableFactory.getBadgedIcon(appInfo, userId); + badge = Utils.getBadgedIcon(mContext, appInfo); } catch (PackageManager.NameNotFoundException e) { badge = mPackageManager.getDefaultActivityIcon(); } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerTestUtils.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerTestUtils.java index e57335fbd3c5..636d08182a24 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerTestUtils.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerTestUtils.java @@ -73,7 +73,7 @@ public final class ActionDisabledByAdminControllerTestUtils { } @Override - public void showHelpPage(Context context, String url) { + public void showHelpPage(Context context, String url, UserHandle userHandle) { mLearnMoreButtonAction = LEARN_MORE_ACTION_LAUNCH_HELP_PAGE; } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncherTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncherTest.java index 62582d71f8fb..c2063c65d9c8 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncherTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncherTest.java @@ -181,18 +181,20 @@ public final class ActionDisabledLearnMoreButtonLauncherTest { @Test public void testSetupLearnMoreButtonToLaunchHelpPage_nullContext() { assertThrows(NullPointerException.class, - () -> mLauncher.setupLearnMoreButtonToLaunchHelpPage(/* context= */ null, URL)); + () -> mLauncher.setupLearnMoreButtonToLaunchHelpPage( + /* context= */ null, URL, CONTEXT_USER)); } @Test public void testSetupLearnMoreButtonToLaunchHelpPage_nullUrl() { assertThrows(NullPointerException.class, - () -> mLauncher.setupLearnMoreButtonToLaunchHelpPage(mContext, /* url= */ null)); + () -> mLauncher.setupLearnMoreButtonToLaunchHelpPage( + mContext, /* url= */ null, CONTEXT_USER)); } @Test public void testSetupLearnMoreButtonToLaunchHelpPage() { - mLauncher.setupLearnMoreButtonToLaunchHelpPage(mContext, URL); + mLauncher.setupLearnMoreButtonToLaunchHelpPage(mContext, URL, CONTEXT_USER); tapLearnMore(); verify(mContext).startActivityAsUser(mIntentCaptor.capture(), eq(CONTEXT_USER)); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java index 19f6aa1d55a6..d9be4f336797 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java @@ -116,7 +116,7 @@ public class ManagedDeviceActionDisabledByAdminControllerTest { private ManagedDeviceActionDisabledByAdminController createController(String url) { ManagedDeviceActionDisabledByAdminController controller = new ManagedDeviceActionDisabledByAdminController( - new FakeDeviceAdminStringProvider(url)); + new FakeDeviceAdminStringProvider(url), mContext.getUser()); controller.initialize(mTestUtils.createLearnMoreButtonLauncher()); controller.updateEnforcedAdmin(ENFORCED_ADMIN, ENFORCEMENT_ADMIN_USER_ID); return controller; diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 959b5ca56687..c7b50c22b8c1 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -419,6 +419,9 @@ <!-- Permission required for running networking unit tests --> <uses-permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS" /> + <!-- Permission required for CTS test - CtsHostsideNetworkTests --> + <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY" /> + <!-- Permissions required for CTS test - TunerTest --> <uses-permission android:name="android.permission.ACCESS_TV_DESCRAMBLER" /> <uses-permission android:name="android.permission.ACCESS_TV_TUNER" /> @@ -433,6 +436,8 @@ <!-- Permissions required for CTS test - TVInputManagerTest --> <uses-permission android:name="android.permission.ACCESS_TUNED_INFO" /> <uses-permission android:name="android.permission.TV_INPUT_HARDWARE" /> + <uses-permission android:name="com.android.providers.tv.permission.ACCESS_WATCHED_PROGRAMS" /> + <uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA"/> <!-- Permission needed for CTS test - PrivilegedLocationPermissionTest --> <uses-permission android:name="android.permission.LOCATION_HARDWARE" /> @@ -563,6 +568,9 @@ <!-- Permission required for CTS test - GlobalSearchSessionPlatformCtsTests --> <uses-permission android:name="android.permission.READ_GLOBAL_APP_SEARCH_DATA" /> + <!-- Permission required for GTS test - PendingSystemUpdateTest --> + <uses-permission android:name="android.permission.NOTIFY_PENDING_SYSTEM_UPDATE" /> + <application android:label="@string/app_label" android:theme="@android:style/Theme.DeviceDefault.DayNight" android:defaultToDeviceProtectedStorage="true" diff --git a/packages/Shell/res/values-mr/strings.xml b/packages/Shell/res/values-mr/strings.xml index a957184cdf6a..89b49a2a6295 100644 --- a/packages/Shell/res/values-mr/strings.xml +++ b/packages/Shell/res/values-mr/strings.xml @@ -18,30 +18,30 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="3701846017049540910">"शेल"</string> <string name="bugreport_notification_channel" msgid="2574150205913861141">"बग रीपोर्ट"</string> - <string name="bugreport_in_progress_title" msgid="4311705936714972757">"बग रीपोर्ट <xliff:g id="ID">#%d</xliff:g> तयार केला जात आहे"</string> - <string name="bugreport_finished_title" msgid="4429132808670114081">"बग रीपोर्ट <xliff:g id="ID">#%d</xliff:g> कॅप्चर केला"</string> - <string name="bugreport_updating_title" msgid="4423539949559634214">"दोष अहवालामध्ये तपशील जोडत आहे"</string> + <string name="bugreport_in_progress_title" msgid="4311705936714972757">"बग रिपोर्ट <xliff:g id="ID">#%d</xliff:g> तयार केला जात आहे"</string> + <string name="bugreport_finished_title" msgid="4429132808670114081">"बग रिपोर्ट <xliff:g id="ID">#%d</xliff:g> कॅप्चर केला"</string> + <string name="bugreport_updating_title" msgid="4423539949559634214">"बग रिपोर्टमध्ये तपशील जोडत आहे"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"कृपया प्रतीक्षा करा..."</string> - <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"फोनवर बग रीपोर्ट लवकरच दिसेल"</string> + <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"फोनवर बग रिपोर्ट लवकरच दिसेल"</string> <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"तुमचा बग रीपोर्ट शेअर करण्यासाठी निवडा"</string> - <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"तुमचा बग रीपोर्ट शेअर करण्यासाठी टॅप करा"</string> + <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"तुमचा बग रिपोर्ट शेअर करण्यासाठी टॅप करा"</string> <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"तुमचा बग रीपोर्ट स्क्रीनशॉटशिवाय शेअर करण्यासाठी टॅप करा किंवा स्क्रीनशॉट पूर्ण होण्याची प्रतीक्षा करा"</string> <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"स्क्रीनशॉट शिवाय तुमचा बग रीपोर्ट शेअर करण्यासाठी टॅप करा किंवा समाप्त करण्यासाठी स्क्रीनशॉटची प्रतीक्षा करा"</string> <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"स्क्रीनशॉट शिवाय तुमचा बग रीपोर्ट शेअर करण्यासाठी टॅप करा किंवा समाप्त करण्यासाठी स्क्रीनशॉटची प्रतीक्षा करा"</string> <string name="bugreport_confirm" msgid="5917407234515812495">"बग रीपोर्टांमध्ये तुम्ही संवेदनशील (अॅप-वापर आणि स्थान डेटा यासारखा) डेटा म्हणून विचार करता त्या डेटाच्या समावेशासह सिस्टीमच्या विविध लॉग फायलींमधील डेटा असतो. ज्या लोकांवर आणि अॅपवर तुमचा विश्वास आहे केवळ त्यांच्यासह हा बग रीपोर्ट शेअर करा."</string> <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"पुन्हा दर्शवू नका"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"बग रीपोर्ट"</string> - <string name="bugreport_unreadable_text" msgid="586517851044535486">"बग रीपोर्ट फाइल वाचणे शक्य झाले नाही"</string> - <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"झिप फाइल मध्ये बग रीपोर्ट तपशील जोडणे शक्य झाले नाही"</string> + <string name="bugreport_unreadable_text" msgid="586517851044535486">"बग रिपोर्ट फाइल वाचणे शक्य झाले नाही"</string> + <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"झिप फाइल मध्ये बग रिपोर्ट तपशील जोडणे शक्य झाले नाही"</string> <string name="bugreport_unnamed" msgid="2800582406842092709">"अनामित"</string> <string name="bugreport_info_action" msgid="2158204228510576227">"तपशील"</string> <string name="bugreport_screenshot_action" msgid="8677781721940614995">"स्क्रीनशॉट"</string> <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"स्क्रीनशॉट यशस्वीरित्या घेतला."</string> <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"स्क्रीनशॉट घेणे शक्य झाले नाही."</string> - <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"बग रीपोर्ट <xliff:g id="ID">#%d</xliff:g> तपशील"</string> + <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"बग रिपोर्ट <xliff:g id="ID">#%d</xliff:g> तपशील"</string> <string name="bugreport_info_name" msgid="4414036021935139527">"फाईलनाव"</string> <string name="bugreport_info_title" msgid="2306030793918239804">"दोष शीर्षक"</string> <string name="bugreport_info_description" msgid="5072835127481627722">"दोष सारांश"</string> <string name="save" msgid="4781509040564835759">"सेव्ह करा"</string> - <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"बग रीपोर्ट शेअर करा"</string> + <string name="bugreport_intent_chooser_title" msgid="7605709494790894076">"बग रिपोर्ट शेअर करा"</string> </resources> diff --git a/packages/StatementService/Android.bp b/packages/StatementService/Android.bp index a0d8ac9b8adc..ff1a756479b6 100644 --- a/packages/StatementService/Android.bp +++ b/packages/StatementService/Android.bp @@ -22,8 +22,7 @@ package { android_app { name: "StatementService", - // Removed because Errorprone doesn't work with Kotlin, can fix up in the future - // defaults: ["platform_app_defaults"], + defaults: ["platform_app_defaults"], srcs: [ "src/**/*.java", "src/**/*.kt", diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 8c092ae37222..604310a9e905 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -454,6 +454,14 @@ android:finishOnCloseSystemDialogs="true"> </activity> + <!-- started from SensoryPrivacyService --> + <activity android:name=".sensorprivacy.television.TvUnblockSensorActivity" + android:exported="true" + android:permission="android.permission.MANAGE_SENSOR_PRIVACY" + android:theme="@style/BottomSheet" + android:finishOnCloseSystemDialogs="true"> + </activity> + <!-- started from UsbDeviceSettingsManager --> <activity android:name=".usb.UsbAccessoryUriActivity" diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt index 2579e7084e08..ac9298dc9e89 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt @@ -159,7 +159,6 @@ class ActivityLaunchAnimator( // If we expect an animation, post a timeout to cancel it in case the remote animation is // never started. if (willAnimate) { - keyguardHandler.disableKeyguardBlurs() runner.postTimeout() // Hide the keyguard using the launch animation instead of the default unlock animation. @@ -220,8 +219,8 @@ class ActivityLaunchAnimator( /** Hide the keyguard and animate using [runner]. */ fun hideKeyguardWithAnimation(runner: IRemoteAnimationRunner) - /** Disable window blur so they don't overlap with the window launch animation **/ - fun disableKeyguardBlurs() + /** Enable/disable window blur so they don't overlap with the window launch animation **/ + fun setBlursDisabledForAppLaunch(disabled: Boolean) } /** @@ -491,6 +490,7 @@ class ActivityLaunchAnimator( animator.addListener(object : AnimatorListenerAdapter() { override fun onAnimationStart(animation: Animator?, isReverse: Boolean) { Log.d(TAG, "Animation started") + keyguardHandler.setBlursDisabledForAppLaunch(true) controller.onLaunchAnimationStart(isExpandingFullyAbove) // Add the drawable to the launch container overlay. Overlays always draw @@ -501,6 +501,7 @@ class ActivityLaunchAnimator( override fun onAnimationEnd(animation: Animator?) { Log.d(TAG, "Animation ended") + keyguardHandler.setBlursDisabledForAppLaunch(false) iCallback?.invoke() controller.onLaunchAnimationEnd(isExpandingFullyAbove) launchContainerOverlay.remove(windowBackgroundLayer) diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java index 98ef9e20ac3b..de2eca2b655c 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java @@ -23,6 +23,8 @@ import com.android.systemui.plugins.annotations.DependsOn; import com.android.systemui.plugins.annotations.ProvidesInterface; import com.android.systemui.plugins.qs.QS.HeightListener; +import java.util.function.Consumer; + /** * Fragment that contains QS in the notification shade. Most of the interface is for * handling the expand/collapsing of the view interaction. @@ -33,7 +35,7 @@ public interface QS extends FragmentBase { String ACTION = "com.android.systemui.action.PLUGIN_QS"; - int VERSION = 9; + int VERSION = 10; String TAG = "QS"; @@ -101,6 +103,11 @@ public interface QS extends FragmentBase { return true; } + /** + * Add a listener for when the collapsed media visibility changes. + */ + void setCollapsedMediaVisibilityChangedListener(Consumer<Boolean> listener); + @ProvidesInterface(version = HeightListener.VERSION) interface HeightListener { int VERSION = 1; diff --git a/packages/SystemUI/res-keyguard/values-az/strings.xml b/packages/SystemUI/res-keyguard/values-az/strings.xml index 91c201402dc3..8f8d1c5d1b14 100644 --- a/packages/SystemUI/res-keyguard/values-az/strings.xml +++ b/packages/SystemUI/res-keyguard/values-az/strings.xml @@ -38,7 +38,7 @@ <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Enerji yığır"</string> <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Sürətlə enerji yığır"</string> <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Yavaş enerji yığır"</string> - <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Şarj müvəqqəti olaraq məhdudlaşdırılıb"</string> + <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Şarj müvəqqəti məhdudlaşdırılıb"</string> <string name="keyguard_low_battery" msgid="1868012396800230904">"Adapteri qoşun."</string> <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Kilidi açmaq üçün Menyu düyməsinə basın."</string> <string name="keyguard_network_locked_message" msgid="407096292844868608">"Şəbəkə kilidlidir"</string> diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml index 149b31323ab3..0a036c811867 100644 --- a/packages/SystemUI/res-keyguard/values-fa/strings.xml +++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml @@ -85,7 +85,7 @@ <string name="kg_login_too_many_attempts" msgid="4519957179182578690">"تلاشهای زیادی برای کشیدن الگو صورت گرفته است"</string> <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"پین خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه تایپ کردید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string> <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"گذرواژه خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه تایپ کردید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string> - <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"الگوی باز کردن قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدید. \n\nلطفاً پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string> + <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. \n\nلطفاً پساز <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string> <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"کد پین سیمکارت اشتباه است، اکنون برای باز کردن قفل دستگاهتان باید با شرکت مخابراتی تماس بگیرید."</string> <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026"> <item quantity="one">کد پین سیمکارت اشتباه است، <xliff:g id="NUMBER_1">%d</xliff:g> بار دیگر میتوانید تلاش کنید.</item> diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml index af43cf7a293f..a41cce7b74bf 100644 --- a/packages/SystemUI/res-keyguard/values-gu/strings.xml +++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml @@ -38,7 +38,7 @@ <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ચાર્જિંગ"</string> <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ઝડપથી ચાર્જિંગ"</string> <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ધીમેથી ચાર્જિંગ"</string> - <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ચાર્જિંગ હંગામી રૂપે પ્રતિબંધિત કરવામાં આવ્યું છે"</string> + <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ચાર્જિંગ હંગામીરૂપે પ્રતિબંધિત કરવામાં આવ્યું છે"</string> <string name="keyguard_low_battery" msgid="1868012396800230904">"તમારું ચાર્જર કનેક્ટ કરો."</string> <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"અનલૉક કરવા માટે મેનૂ દબાવો."</string> <string name="keyguard_network_locked_message" msgid="407096292844868608">"નેટવર્ક લૉક થયું"</string> diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml index d0218f6bfb3e..e53964dcab14 100644 --- a/packages/SystemUI/res-keyguard/values-hi/strings.xml +++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml @@ -38,7 +38,7 @@ <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्ज हो रहा है"</string> <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • तेज़ चार्ज हो रहा है"</string> <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • धीरे चार्ज हो रहा है"</string> - <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्जिंग कुछ समय के लिए रोकी गई"</string> + <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • कुछ समय के लिए चार्जिंग रोक दी गई"</string> <string name="keyguard_low_battery" msgid="1868012396800230904">"अपना चार्जर कनेक्ट करें."</string> <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"लॉक खोलने के लिए मेन्यू दबाएं."</string> <string name="keyguard_network_locked_message" msgid="407096292844868608">"नेटवर्क लॉक किया हुआ है"</string> diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml index b307544f5e3c..0692aeff0e0e 100644 --- a/packages/SystemUI/res-keyguard/values-ne/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml @@ -36,7 +36,7 @@ <string name="keyguard_charged" msgid="5478247181205188995">"चार्ज भयो"</string> <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • तारविनै चार्ज गर्दै"</string> <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्ज गरिँदै"</string> - <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • द्रुत गतिमा चार्ज गरिँदै"</string> + <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • द्रुत गतिमा चार्ज गरिँदै छ"</string> <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • मन्द गतिमा चार्ज गरिँदै"</string> <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्जिङ केही समयका लागि सीमित पारिएको छ"</string> <string name="keyguard_low_battery" msgid="1868012396800230904">"तपाईंको चार्जर जोड्नुहोस्।"</string> diff --git a/packages/SystemUI/res-keyguard/values-sw/strings.xml b/packages/SystemUI/res-keyguard/values-sw/strings.xml index fcf8edc34e49..5381d762cbe2 100644 --- a/packages/SystemUI/res-keyguard/values-sw/strings.xml +++ b/packages/SystemUI/res-keyguard/values-sw/strings.xml @@ -38,7 +38,7 @@ <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Inachaji"</string> <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Inachaji kwa kasi"</string> <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Inachaji pole pole"</string> - <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hali ya kuchaji kwa muda imedhibitiwa"</string> + <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Kuchaji kumedhibitiwa kwa muda"</string> <string name="keyguard_low_battery" msgid="1868012396800230904">"Unganisha chaja yako."</string> <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Bonyeza Menyu ili kufungua."</string> <string name="keyguard_network_locked_message" msgid="407096292844868608">"Mtandao umefungwa"</string> diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml index e5031c8213a3..937ad064e689 100644 --- a/packages/SystemUI/res-keyguard/values-ta/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml @@ -26,7 +26,7 @@ <string name="keyguard_password_enter_puk_prompt" msgid="3529260761374385243">"சிம் PUK குறியீடு"</string> <string name="keyguard_password_enter_pin_prompt" msgid="2304037870481240781">"புதிய சிம் பின் குறியீடு"</string> <string name="keyguard_password_entry_touch_hint" msgid="6180028658339706333"><font size="17">"கடவுச்சொல்லை உள்ளிட, தொடவும்"</font></string> - <string name="keyguard_password_enter_password_code" msgid="7393393239623946777">"திறக்க, கடவுச்சொல்லை உள்ளிடவும்"</string> + <string name="keyguard_password_enter_password_code" msgid="7393393239623946777">"அன்லாக் செய்ய கடவுச்சொல்லை உள்ளிடவும்"</string> <string name="keyguard_password_enter_pin_password_code" msgid="3692259677395250509">"திறக்க, பின்னை உள்ளிடவும்"</string> <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"பின்னை உள்ளிடுக"</string> <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"பேட்டர்னை உள்ளிடுக"</string> @@ -40,7 +40,7 @@ <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • மெதுவாகச் சார்ஜாகிறது"</string> <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • சார்ஜாவது தற்காலிகமாக வரம்பிடப்பட்டுள்ளது"</string> <string name="keyguard_low_battery" msgid="1868012396800230904">"சார்ஜரை இணைக்கவும்."</string> - <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"திறக்க, மெனுவை அழுத்தவும்."</string> + <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"அன்லாக் செய்ய மெனுவை அழுத்தவும்."</string> <string name="keyguard_network_locked_message" msgid="407096292844868608">"நெட்வொர்க் பூட்டப்பட்டது"</string> <string name="keyguard_missing_sim_message_short" msgid="704159478161444907">"சிம் கார்டு இல்லை"</string> <string name="keyguard_missing_sim_instructions" msgid="1162120926141335918">"சிம் கார்டைச் செருகவும்."</string> @@ -85,11 +85,11 @@ <string name="kg_login_too_many_attempts" msgid="4519957179182578690">"பேட்டர்னை அதிக முறை தவறாக வரைந்துவிட்டீர்கள்"</string> <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"உங்கள் பின்னை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக உள்ளிட்டுவிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string> <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"உங்கள் கடவுச்சொல்லை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக உள்ளிட்டுவிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string> - <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"திறப்பதற்கான பேட்டர்னை, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துவிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string> - <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"சிம்மின் பின் குறியீடு தவறானது. இனி சாதனத்தைத் திறக்க, உங்கள் தொலைத்தொடர்பு நிறுவனத்தைத் தொடர்புகொள்ள வேண்டும்."</string> + <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"அன்லாக் பேட்டர்னை, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துவிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string> + <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"சிம்மின் பின் குறியீடு தவறானது. இனி சாதனத்தை அன்லாக் செய்ய, உங்கள் தொலைத்தொடர்பு நிறுவனத்தைத் தொடர்புகொள்ள வேண்டும்."</string> <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026"> <item quantity="other">சிம்மின் பின் குறியீடு தவறானது, இன்னும் நீங்கள் <xliff:g id="NUMBER_1">%d</xliff:g> முறை முயலலாம்.</item> - <item quantity="one">சிம்மின் பின் குறியீடு தவறானது, மேலும் <xliff:g id="NUMBER_0">%d</xliff:g> முயற்சிகளுக்குப் பின்னர், உங்கள் தொலைத்தொடர்பு நிறுவனத்தைத் தொடர்பு கொண்டு மட்டுமே சாதனத்தைத் திறக்க முடியும்.</item> + <item quantity="one">சிம்மின் பின் குறியீடு தவறானது, மேலும் <xliff:g id="NUMBER_0">%d</xliff:g> முயற்சிகளுக்குப் பின்னர், உங்கள் தொலைத்தொடர்பு நிறுவனத்தைத் தொடர்பு கொண்டு மட்டுமே சாதனத்தை அன்லாக் செய்ய முடியும்.</item> </plurals> <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"பயன்படுத்த முடியாத சிம். உங்கள் தொலைத்தொடர்பு நிறுவனத்தைத் தொடர்புகொள்ளவும்."</string> <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886"> @@ -129,7 +129,7 @@ <string name="kg_face_not_recognized" msgid="7903950626744419160">"அடையாளங்காணபடவில்லை"</string> <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818"> <item quantity="other">சிம் பின்னை உள்ளிடவும். மேலும், <xliff:g id="NUMBER_1">%d</xliff:g> வாய்ப்புகள் மீதமுள்ளன.</item> - <item quantity="one">சிம் பின்னை உள்ளிடவும். மீதமுள்ள <xliff:g id="NUMBER_0">%d</xliff:g> வாய்ப்பில் தவறுதலான பின் உள்ளிடப்பட்டால், உங்கள் தொலைத்தொடர்பு நிறுவனத்தைத் தொடர்பு கொண்டு மட்டுமே சாதனத்தைத் திறக்க முடியும்.</item> + <item quantity="one">சிம் பின்னை உள்ளிடவும். மீதமுள்ள <xliff:g id="NUMBER_0">%d</xliff:g> வாய்ப்பில் தவறுதலான பின் உள்ளிடப்பட்டால், உங்கள் தொலைத்தொடர்பு நிறுவனத்தைத் தொடர்பு கொண்டு மட்டுமே சாதனத்தை அன்லாக் செய்ய முடியும்.</item> </plurals> <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935"> <item quantity="other">சிம் தற்போது முடக்கப்பட்டுள்ளது. தொடர்வதற்கு, PUK குறியீட்டை உள்ளிடவும். நீங்கள் <xliff:g id="_NUMBER_1">%d</xliff:g> முறை மட்டுமே முயற்சிக்க முடியும். அதன்பிறகு சிம் நிரந்தரமாக முடக்கப்படும். விவரங்களுக்கு, மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளவும்.</item> diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml index 6052f40822dc..3c3972c2a1bc 100644 --- a/packages/SystemUI/res-keyguard/values-vi/strings.xml +++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml @@ -38,7 +38,7 @@ <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đang sạc"</string> <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đang sạc nhanh"</string> <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đang sạc chậm"</string> - <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mức sạc tạm thời bị giới hạn"</string> + <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Khả năng sạc tạm thời bị hạn chế"</string> <string name="keyguard_low_battery" msgid="1868012396800230904">"Kết nối bộ sạc của bạn."</string> <string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Nhấn vào Menu để mở khóa."</string> <string name="keyguard_network_locked_message" msgid="407096292844868608">"Mạng đã bị khóa"</string> diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml index ec0500ffea5d..34c892675a14 100644 --- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml @@ -36,7 +36,7 @@ <string name="keyguard_charged" msgid="5478247181205188995">"已完成充電"</string> <string name="keyguard_plugged_in_wireless" msgid="2537874724955057383">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 無線充電中"</string> <string name="keyguard_plugged_in" msgid="8169926454348380863">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在充電"</string> - <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在快速充電"</string> + <string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 快速充電中"</string> <string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> •正在慢速充電"</string> <string name="keyguard_plugged_in_charging_limited" msgid="6091488837901216962">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 充電暫時受限"</string> <string name="keyguard_low_battery" msgid="1868012396800230904">"請連接充電器。"</string> diff --git a/packages/SystemUI/res-product/values-fa/strings.xml b/packages/SystemUI/res-product/values-fa/strings.xml index 52fa2d85d074..cd98ef60994d 100644 --- a/packages/SystemUI/res-product/values-fa/strings.xml +++ b/packages/SystemUI/res-product/values-fa/strings.xml @@ -38,8 +38,8 @@ <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"<xliff:g id="NUMBER_0">%1$d</xliff:g> تلاش ناموفق برای باز کردن قفل تلفن داشتهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، نمایه کاری پاک میشود که با آن همه دادههای نمایه حذف میشود."</string> <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4417100487251371559">"<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل رایانه لوحی داشتهاید. نمایه کاری پاک میشود که با آن همه دادههای نمایه حذف میشود."</string> <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل تلفن داشتهاید. نمایه کاری پاک میشود که با آن همه دادههای نمایه حذف میشود."</string> - <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"شما الگوی باز کردن قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. بعد از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که با استفاده از یک حساب ایمیل قفل رایانه لوحی خود را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string> - <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"شما الگوی باز کردن قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. پس از <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که با استفاده از یک حساب ایمیل قفل تلفن را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string> + <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. بعداز <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که بااستفاده از یک حساب ایمیل قفل رایانه لوحیتان را باز کنید.\n\n لطفاً پساز <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string> + <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. پساز <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که بااستفاده از یک حساب ایمیل قفل تلفن را باز کنید.\n\n لطفاً پساز <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string> <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"برای گزینههای بیشتر، قفل تلفن را باز کنید"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"برای گزینههای بیشتر، قفل رایانه لوحی را باز کنید"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"برای گزینههای بیشتر، قفل دستگاه را باز کنید"</string> diff --git a/packages/SystemUI/res/anim/tv_bottom_sheet_button_state_list_animator.xml b/packages/SystemUI/res/anim/tv_bottom_sheet_button_state_list_animator.xml new file mode 100644 index 000000000000..fc3b4ed6eecb --- /dev/null +++ b/packages/SystemUI/res/anim/tv_bottom_sheet_button_state_list_animator.xml @@ -0,0 +1,52 @@ +<?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. + --> + +<selector + xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_focused="true"> + <set> + <objectAnimator + android:duration="200" + android:propertyName="scaleX" + android:valueFrom="1.0" + android:valueTo="@dimen/bottom_sheet_button_selection_scaled" + android:valueType="floatType"/> + <objectAnimator + android:duration="200" + android:propertyName="scaleY" + android:valueFrom="1.0" + android:valueTo="@dimen/bottom_sheet_button_selection_scaled" + android:valueType="floatType"/> + </set> + </item> + <item android:state_focused="false"> + <set> + <objectAnimator + android:duration="200" + android:propertyName="scaleX" + android:valueFrom="@dimen/bottom_sheet_button_selection_scaled" + android:valueTo="1.0" + android:valueType="floatType"/> + <objectAnimator + android:duration="200" + android:propertyName="scaleY" + android:valueFrom="@dimen/bottom_sheet_button_selection_scaled" + android:valueTo="1.0" + android:valueType="floatType"/> + </set> + </item> +</selector>
\ No newline at end of file diff --git a/packages/SystemUI/res/anim/tv_bottom_sheet_enter.xml b/packages/SystemUI/res/anim/tv_bottom_sheet_enter.xml new file mode 100644 index 000000000000..cace36d68b43 --- /dev/null +++ b/packages/SystemUI/res/anim/tv_bottom_sheet_enter.xml @@ -0,0 +1,23 @@ +<?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. + --> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@android:interpolator/decelerate_quint"> + <translate android:fromYDelta="100%" + android:toYDelta="0" + android:duration="900"/> +</set>
\ No newline at end of file diff --git a/packages/SystemUI/res/anim/tv_bottom_sheet_exit.xml b/packages/SystemUI/res/anim/tv_bottom_sheet_exit.xml new file mode 100644 index 000000000000..f7efe7cd2584 --- /dev/null +++ b/packages/SystemUI/res/anim/tv_bottom_sheet_exit.xml @@ -0,0 +1,23 @@ +<?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. + --> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@android:interpolator/decelerate_quint"> + <translate android:fromYDelta="0" + android:toYDelta="100%" + android:duration="500"/> +</set>
\ No newline at end of file diff --git a/packages/SystemUI/res/anim/tv_privacy_chip_collapse.xml b/packages/SystemUI/res/anim/tv_privacy_chip_collapse.xml new file mode 100644 index 000000000000..e6ceeb919232 --- /dev/null +++ b/packages/SystemUI/res/anim/tv_privacy_chip_collapse.xml @@ -0,0 +1,41 @@ +<?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. + --> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:ordering="together" + android:interpolator="@interpolator/tv_privacy_chip_collapse_interpolator" + android:duration="@integer/privacy_chip_animation_millis"> + <objectAnimator + android:propertyName="height" + android:valueTo="@dimen/privacy_chip_dot_size" + android:valueType="floatType"/> + <objectAnimator + android:propertyName="marginEnd" + android:valueTo="@dimen/privacy_chip_dot_margin_horizontal" + android:valueType="floatType"/> + <objectAnimator + android:propertyName="radius" + android:valueTo="@dimen/privacy_chip_dot_radius" + android:valueType="floatType"/> + <objectAnimator + android:propertyName="dotAlpha" + android:valueTo="255" + android:valueType="intType"/> + <objectAnimator + android:propertyName="bgAlpha" + android:valueTo="255" + android:valueType="intType"/> +</set>
\ No newline at end of file diff --git a/packages/SystemUI/res/anim/tv_privacy_chip_expand.xml b/packages/SystemUI/res/anim/tv_privacy_chip_expand.xml new file mode 100644 index 000000000000..4a510ae6cab8 --- /dev/null +++ b/packages/SystemUI/res/anim/tv_privacy_chip_expand.xml @@ -0,0 +1,41 @@ +<?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. + --> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:ordering="together" + android:interpolator="@interpolator/tv_privacy_chip_expand_interpolator" + android:duration="@integer/privacy_chip_animation_millis"> + <objectAnimator + android:propertyName="height" + android:valueTo="@dimen/privacy_chip_height" + android:valueType="floatType"/> + <objectAnimator + android:propertyName="marginEnd" + android:valueTo="0" + android:valueType="floatType"/> + <objectAnimator + android:propertyName="radius" + android:valueTo="@dimen/privacy_chip_radius" + android:valueType="floatType"/> + <objectAnimator + android:propertyName="dotAlpha" + android:valueTo="255" + android:valueType="intType"/> + <objectAnimator + android:propertyName="bgAlpha" + android:valueTo="0" + android:valueType="intType"/> +</set>
\ No newline at end of file diff --git a/packages/SystemUI/res/anim/tv_privacy_chip_fade_in.xml b/packages/SystemUI/res/anim/tv_privacy_chip_fade_in.xml new file mode 100644 index 000000000000..701489a28450 --- /dev/null +++ b/packages/SystemUI/res/anim/tv_privacy_chip_fade_in.xml @@ -0,0 +1,25 @@ +<?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. + --> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:ordering="together" + android:interpolator="@interpolator/tv_privacy_chip_collapse_interpolator" + android:duration="@integer/privacy_chip_animation_millis"> + <objectAnimator + android:propertyName="dotAlpha" + android:valueTo="255" + android:valueType="intType"/> +</set>
\ No newline at end of file diff --git a/packages/SystemUI/res/anim/tv_privacy_chip_fade_out.xml b/packages/SystemUI/res/anim/tv_privacy_chip_fade_out.xml new file mode 100644 index 000000000000..fa134717ba6e --- /dev/null +++ b/packages/SystemUI/res/anim/tv_privacy_chip_fade_out.xml @@ -0,0 +1,29 @@ +<?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. + --> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:ordering="together" + android:interpolator="@interpolator/tv_privacy_chip_collapse_interpolator" + android:duration="@integer/privacy_chip_animation_millis"> + <objectAnimator + android:propertyName="dotAlpha" + android:valueTo="0" + android:valueType="intType"/> + <objectAnimator + android:propertyName="bgAlpha" + android:valueTo="0" + android:valueType="intType"/> +</set>
\ No newline at end of file diff --git a/packages/SystemUI/res/color/bottom_sheet_button_background_color.xml b/packages/SystemUI/res/color/bottom_sheet_button_background_color.xml new file mode 100644 index 000000000000..9b0bae09b326 --- /dev/null +++ b/packages/SystemUI/res/color/bottom_sheet_button_background_color.xml @@ -0,0 +1,21 @@ +<?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. + --> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_focused="true" + android:color="@color/bottom_sheet_button_background_color_focused"/> + <item android:color="@color/bottom_sheet_button_background_color_unfocused"/> +</selector>
\ No newline at end of file diff --git a/packages/SystemUI/res/color/bottom_sheet_button_text_color.xml b/packages/SystemUI/res/color/bottom_sheet_button_text_color.xml new file mode 100644 index 000000000000..05248f17097b --- /dev/null +++ b/packages/SystemUI/res/color/bottom_sheet_button_text_color.xml @@ -0,0 +1,21 @@ +<?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. + --> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_focused="true" + android:color="@color/bottom_sheet_button_text_color_focused"/> + <item android:color="@color/bottom_sheet_button_text_color_unfocused"/> +</selector>
\ No newline at end of file diff --git a/packages/SystemUI/res/color/media_player_solid_button_bg.xml b/packages/SystemUI/res/color/media_player_solid_button_bg.xml index 96685ab58303..69c971188d34 100644 --- a/packages/SystemUI/res/color/media_player_solid_button_bg.xml +++ b/packages/SystemUI/res/color/media_player_solid_button_bg.xml @@ -17,5 +17,5 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"> - <item android:color="?androidprv:attr/colorAccentTertiary"/> + <item android:color="?androidprv:attr/colorAccentPrimary"/> </selector>
\ No newline at end of file diff --git a/packages/SystemUI/res/color/screenrecord_switch_thumb_color.xml b/packages/SystemUI/res/color/screenrecord_switch_thumb_color.xml new file mode 100644 index 000000000000..22b7a1e50dd6 --- /dev/null +++ b/packages/SystemUI/res/color/screenrecord_switch_thumb_color.xml @@ -0,0 +1,26 @@ +<?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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- Disabled status of thumb --> + <item android:state_enabled="false" + android:color="@android:color/system_neutral2_100" /> + <!-- Toggle off status of thumb --> + <item android:state_checked="false" + android:color="@android:color/system_neutral2_100" /> + <!-- Enabled or toggle on status of thumb --> + <item android:color="@android:color/system_accent1_100" /> +</selector>
\ No newline at end of file diff --git a/packages/SystemUI/res/color/screenrecord_switch_track_color.xml b/packages/SystemUI/res/color/screenrecord_switch_track_color.xml new file mode 100644 index 000000000000..bb55b07a6731 --- /dev/null +++ b/packages/SystemUI/res/color/screenrecord_switch_track_color.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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- Disabled status of thumb --> + <item android:state_enabled="false" + android:color="@android:color/system_neutral2_600" + android:alpha="?android:attr/disabledAlpha" /> + <!-- Toggle off status of thumb --> + <item android:state_checked="false" + android:color="@android:color/system_neutral2_600" /> + <!-- Enabled or toggle on status of thumb --> + <item android:color="@android:color/system_accent1_600" /> +</selector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/bottom_sheet_background.xml b/packages/SystemUI/res/drawable/bottom_sheet_background.xml new file mode 100644 index 000000000000..87850a0d00ec --- /dev/null +++ b/packages/SystemUI/res/drawable/bottom_sheet_background.xml @@ -0,0 +1,20 @@ +<?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. + --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> + <solid android:color="@color/bottom_sheet_background_color"/> + <corners android:radius="@dimen/bottom_sheet_corner_radius"/> +</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/bottom_sheet_background_with_blur.xml b/packages/SystemUI/res/drawable/bottom_sheet_background_with_blur.xml new file mode 100644 index 000000000000..cd2aa9c751d9 --- /dev/null +++ b/packages/SystemUI/res/drawable/bottom_sheet_background_with_blur.xml @@ -0,0 +1,20 @@ +<?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. + --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> + <solid android:color="@color/bottom_sheet_background_color_with_blur"/> + <corners android:radius="@dimen/bottom_sheet_corner_radius"/> +</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/bottom_sheet_button_background.xml b/packages/SystemUI/res/drawable/bottom_sheet_button_background.xml new file mode 100644 index 000000000000..585a6bc771f7 --- /dev/null +++ b/packages/SystemUI/res/drawable/bottom_sheet_button_background.xml @@ -0,0 +1,20 @@ +<?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. + --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> + <solid android:color="@color/bottom_sheet_button_background_color"/> + <corners android:radius="@dimen/bottom_sheet_button_corner_radius"/> +</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_avatar_with_badge.xml b/packages/SystemUI/res/drawable/ic_avatar_with_badge.xml new file mode 100644 index 000000000000..b96ca0fb5377 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_avatar_with_badge.xml @@ -0,0 +1,36 @@ +<?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 + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:width="50dp" + android:height="50dp" + android:viewportWidth="50" + android:viewportHeight="50"> + <path + android:pathData="M0,24C0,10.7452 10.7452,0 24,0V0C37.2548,0 48,10.7452 48,24V24C48,37.2548 37.2548,48 24,48V48C10.7452,48 0,37.2548 0,24V24Z" + android:fillColor="?androidprv:attr/colorAccentSecondary"/> + <path + android:pathData="M31.2003,19.2C31.2003,23.1764 27.9767,26.4 24.0003,26.4C20.0238,26.4 16.8003,23.1764 16.8003,19.2C16.8003,15.2235 20.0238,12 24.0003,12C27.9767,12 31.2003,15.2235 31.2003,19.2ZM28.8003,19.2C28.8003,21.851 26.6513,24 24.0003,24C21.3493,24 19.2003,21.851 19.2003,19.2C19.2003,16.549 21.3493,14.4 24.0003,14.4C26.6513,14.4 28.8003,16.549 28.8003,19.2Z" + android:fillColor="@color/people_tile_background" + android:fillType="evenOdd"/> + <path + android:pathData="M24.0003,30C16.231,30 9.6114,34.5941 7.0898,41.0305C7.7041,41.6404 8.3512,42.2174 9.0282,42.7585C10.9059,36.8492 16.7964,32.4 24.0003,32.4C31.2042,32.4 37.0947,36.8492 38.9724,42.7585C39.6494,42.2174 40.2965,41.6404 40.9108,41.0305C38.3892,34.5941 31.7696,30 24.0003,30Z" + android:fillColor="@color/people_tile_background"/> + <path + android:pathData="M40,40m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0" + android:fillColor="?androidprv:attr/colorAccentTertiary"/> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_touch.xml b/packages/SystemUI/res/drawable/ic_touch.xml index 4f6698de5251..18ad3679bd1a 100644 --- a/packages/SystemUI/res/drawable/ic_touch.xml +++ b/packages/SystemUI/res/drawable/ic_touch.xml @@ -13,14 +13,13 @@ Copyright (C) 2020 The Android Open Source Project See the License for the specific language governing permissions and limitations under the License. --> -<!-- maybe need android:fillType="evenOdd" --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?attr/colorControlNormal"> <path - android:fillColor="#FF000000" - android:pathData="M9,7.5V11.24C7.79,10.43 7,9.06 7,7.5C7,5.01 9.01,3 11.5,3C13.99,3 16,5.01 16,7.5C16,9.06 15.21,10.43 14,11.24V7.5C14,6.12 12.88,5 11.5,5C10.12,5 9,6.12 9,7.5ZM14.3,13.61L18.84,15.87C19.37,16.09 19.75,16.63 19.75,17.25C19.75,17.31 19.74,17.38 19.73,17.45L18.98,22.72C18.87,23.45 18.29,24 17.54,24H10.75C10.34,24 9.96,23.83 9.69,23.56L4.75,18.62L5.54,17.82C5.74,17.62 6.02,17.49 6.33,17.49C6.39,17.49 6.4411,17.4989 6.4922,17.5078C6.5178,17.5122 6.5433,17.5167 6.57,17.52L10,18.24V7.5C10,6.67 10.67,6 11.5,6C12.33,6 13,6.67 13,7.5V13.5H13.76C13.95,13.5 14.13,13.54 14.3,13.61Z" - /> + android:fillColor="@android:color/white" + android:pathData="M18.19,12.44l-3.24,-1.62c1.29,-1 2.12,-2.56 2.12,-4.32c0,-3.03 -2.47,-5.5 -5.5,-5.5s-5.5,2.47 -5.5,5.5c0,2.13 1.22,3.98 3,4.89v3.26c-2.11,-0.45 -2.01,-0.44 -2.26,-0.44c-0.53,0 -1.03,0.21 -1.41,0.59L4,16.22l5.09,5.09C9.52,21.75 10.12,22 10.74,22h6.3c0.98,0 1.81,-0.7 1.97,-1.67l0.8,-4.71C20.03,14.32 19.38,13.04 18.19,12.44zM17.84,15.29L17.04,20h-6.3c-0.09,0 -0.17,-0.04 -0.24,-0.1l-3.68,-3.68l4.25,0.89V6.5c0,-0.28 0.22,-0.5 0.5,-0.5c0.28,0 0.5,0.22 0.5,0.5v6h1.76l3.46,1.73C17.69,14.43 17.91,14.86 17.84,15.29zM8.07,6.5c0,-1.93 1.57,-3.5 3.5,-3.5s3.5,1.57 3.5,3.5c0,0.95 -0.38,1.81 -1,2.44V6.5c0,-1.38 -1.12,-2.5 -2.5,-2.5c-1.38,0 -2.5,1.12 -2.5,2.5v2.44C8.45,8.31 8.07,7.45 8.07,6.5z"/> </vector> diff --git a/packages/SystemUI/res/drawable/screenrecord_button_background_outline.xml b/packages/SystemUI/res/drawable/screenrecord_button_background_outline.xml new file mode 100644 index 000000000000..59a31e8f6136 --- /dev/null +++ b/packages/SystemUI/res/drawable/screenrecord_button_background_outline.xml @@ -0,0 +1,30 @@ +<?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 + --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:shape="rectangle"> + <stroke + android:color="?androidprv:attr/colorAccentPrimary" + android:width="1dp"/> + <corners android:radius="24dp"/> + <padding + android:left="16dp" + android:right="16dp" + android:top="8dp" + android:bottom="8dp" /> + <solid android:color="@android:color/transparent" /> +</shape> diff --git a/packages/SystemUI/res/drawable/screenrecord_button_background_solid.xml b/packages/SystemUI/res/drawable/screenrecord_button_background_solid.xml new file mode 100644 index 000000000000..d6446fc87ea0 --- /dev/null +++ b/packages/SystemUI/res/drawable/screenrecord_button_background_solid.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. + --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:shape="rectangle"> + <corners android:radius="24dp"/> + <padding + android:left="16dp" + android:right="16dp" + android:top="8dp" + android:bottom="8dp" /> + <solid android:color="?androidprv:attr/colorAccentPrimary" /> +</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/screenrecord_spinner_background.xml b/packages/SystemUI/res/drawable/screenrecord_spinner_background.xml new file mode 100644 index 000000000000..e82fb8f23ce0 --- /dev/null +++ b/packages/SystemUI/res/drawable/screenrecord_spinner_background.xml @@ -0,0 +1,23 @@ +<?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. + --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:shape="rectangle" + android:padding="12dp"> + <corners android:radius="24dp"/> + <solid android:color="?androidprv:attr/colorAccentSecondary" /> +</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/screenrecord_switch_thumb.xml b/packages/SystemUI/res/drawable/screenrecord_switch_thumb.xml new file mode 100644 index 000000000000..f78c582dffd9 --- /dev/null +++ b/packages/SystemUI/res/drawable/screenrecord_switch_thumb.xml @@ -0,0 +1,29 @@ +<?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. + --> + +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> + <item + android:top="4dp" + android:left="4dp" + android:right="4dp" + android:bottom="4dp"> + <shape android:shape="oval" > + <size android:height="20dp" android:width="20dp" /> + <solid android:color="@color/screenrecord_switch_thumb_color" /> + </shape> + </item> +</layer-list>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/screenrecord_switch_track.xml b/packages/SystemUI/res/drawable/screenrecord_switch_track.xml new file mode 100644 index 000000000000..82595e4d6d65 --- /dev/null +++ b/packages/SystemUI/res/drawable/screenrecord_switch_track.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. + --> +<shape + xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle" + android:width="52dp" + android:height="28dp"> + <solid android:color="@color/screenrecord_switch_track_color" /> + <corners android:radius="35dp" /> +</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/interpolator/tv_privacy_chip_collapse_interpolator.xml b/packages/SystemUI/res/interpolator/tv_privacy_chip_collapse_interpolator.xml new file mode 100644 index 000000000000..429812484674 --- /dev/null +++ b/packages/SystemUI/res/interpolator/tv_privacy_chip_collapse_interpolator.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. + --> + +<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" + android:controlX1="0.4" + android:controlY1="1.00" + android:controlX2="0.12" + android:controlY2="1.00"/>
\ No newline at end of file diff --git a/packages/SystemUI/res/interpolator/tv_privacy_chip_expand_interpolator.xml b/packages/SystemUI/res/interpolator/tv_privacy_chip_expand_interpolator.xml new file mode 100644 index 000000000000..ed44715130e9 --- /dev/null +++ b/packages/SystemUI/res/interpolator/tv_privacy_chip_expand_interpolator.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. + --> + +<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" + android:controlX1="0.12" + android:controlY1="1.00" + android:controlX2="0.4" + android:controlY2="1.00"/>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml index 93bd58113bc2..c92b10c447b1 100644 --- a/packages/SystemUI/res/layout/global_screenshot.xml +++ b/packages/SystemUI/res/layout/global_screenshot.xml @@ -19,12 +19,15 @@ android:id="@+id/global_screenshot_frame" android:theme="@style/Screenshot" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:importantForAccessibility="no"> <ImageView android:id="@+id/screenshot_scrolling_scrim" android:layout_width="match_parent" android:layout_height="match_parent" - android:visibility="gone"/> + android:visibility="gone" + android:clickable="true" + android:importantForAccessibility="no"/> <ImageView android:id="@+id/global_screenshot_actions_background" android:layout_height="@dimen/screenshot_bg_protection_height" diff --git a/packages/SystemUI/res/layout/long_screenshot.xml b/packages/SystemUI/res/layout/long_screenshot.xml index 3f4baaf27b84..50f38b6fa67f 100644 --- a/packages/SystemUI/res/layout/long_screenshot.xml +++ b/packages/SystemUI/res/layout/long_screenshot.xml @@ -78,6 +78,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="matrix" + android:visibility="invisible" app:layout_constraintTop_toTopOf="@id/preview" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/packages/SystemUI/res/layout/media_output_list_item.xml b/packages/SystemUI/res/layout/media_output_list_item.xml index b563633f24fe..16c03e124794 100644 --- a/packages/SystemUI/res/layout/media_output_list_item.xml +++ b/packages/SystemUI/res/layout/media_output_list_item.xml @@ -81,6 +81,7 @@ android:visibility="gone"/> <SeekBar android:id="@+id/volume_seekbar" + style="@*android:style/Widget.DeviceDefault.SeekBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true"/> diff --git a/packages/SystemUI/res/layout/media_smartspace_recommendations.xml b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml index 645dba4459a4..c7e54d45626c 100644 --- a/packages/SystemUI/res/layout/media_smartspace_recommendations.xml +++ b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml @@ -184,7 +184,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="@dimen/qs_media_padding" - android:layout_marginEnd="@dimen/qs_media_info_spacing" + android:layout_marginEnd="@dimen/qs_media_action_spacing" android:layout_marginBottom="@dimen/qs_media_padding" app:layout_constrainedWidth="true" app:layout_constraintWidth_min="48dp" @@ -209,8 +209,8 @@ android:background="@drawable/qs_media_light_source" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/qs_media_info_spacing" - android:layout_marginEnd="@dimen/qs_media_info_spacing" + android:layout_marginStart="@dimen/qs_media_action_spacing" + android:layout_marginEnd="@dimen/qs_media_action_spacing" android:layout_marginBottom="@dimen/qs_media_padding" app:layout_constrainedWidth="true" app:layout_constraintWidth_min="48dp" @@ -233,7 +233,7 @@ android:background="@drawable/qs_media_light_source" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/qs_media_info_spacing" + android:layout_marginStart="@dimen/qs_media_action_spacing" android:layout_marginEnd="@dimen/qs_media_padding" android:layout_marginBottom="@dimen/qs_media_padding" app:layout_constrainedWidth="true" diff --git a/packages/SystemUI/res/layout/media_view.xml b/packages/SystemUI/res/layout/media_view.xml index c341f7393318..c0d353bf8f56 100644 --- a/packages/SystemUI/res/layout/media_view.xml +++ b/packages/SystemUI/res/layout/media_view.xml @@ -238,7 +238,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="@dimen/qs_media_padding" - android:layout_marginEnd="@dimen/qs_media_info_spacing" + android:layout_marginEnd="@dimen/qs_media_action_spacing" android:layout_marginBottom="@dimen/qs_media_padding" app:layout_constrainedWidth="true" app:layout_constraintWidth_min="48dp" @@ -263,8 +263,8 @@ android:background="@drawable/qs_media_light_source" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/qs_media_info_spacing" - android:layout_marginEnd="@dimen/qs_media_info_spacing" + android:layout_marginStart="@dimen/qs_media_action_spacing" + android:layout_marginEnd="@dimen/qs_media_action_spacing" android:layout_marginBottom="@dimen/qs_media_padding" app:layout_constrainedWidth="true" app:layout_constraintWidth_min="48dp" @@ -287,7 +287,7 @@ android:background="@drawable/qs_media_light_source" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/qs_media_info_spacing" + android:layout_marginStart="@dimen/qs_media_action_spacing" android:layout_marginEnd="@dimen/qs_media_padding" android:layout_marginBottom="@dimen/qs_media_padding" app:layout_constrainedWidth="true" diff --git a/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml b/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml index 2a4a21f5f1ab..e87bf61417db 100644 --- a/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml +++ b/packages/SystemUI/res/layout/people_space_activity_no_conversations.xml @@ -48,13 +48,13 @@ <Button style="?android:attr/buttonBarButtonStyle" - android:id="@+id/okay_button" + android:id="@+id/got_it_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/rounded_bg_full_large_radius" android:onClick="dismissActivity" - android:text="@string/okay" + android:text="@string/got_it" android:textColor="?android:attr/textColorPrimary" android:layout_marginBottom="60dp" android:layout_alignParentBottom="true" /> @@ -62,7 +62,7 @@ <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_above="@id/okay_button" + android:layout_above="@id/got_it_button" android:layout_below="@id/select_conversation" android:layout_centerInParent="true" android:clipToOutline="true"> @@ -72,7 +72,7 @@ android:layout_height="100dp" android:layout_gravity="center" android:background="@drawable/rounded_bg_full_large_radius" - android:layout_above="@id/okay_button"> + android:layout_above="@id/got_it_button"> <include layout="@layout/people_space_placeholder_layout" /> </LinearLayout> </LinearLayout> diff --git a/packages/SystemUI/res/layout/people_space_initial_layout.xml b/packages/SystemUI/res/layout/people_space_initial_layout.xml index c57ec345ba57..98920417b0ef 100644 --- a/packages/SystemUI/res/layout/people_space_initial_layout.xml +++ b/packages/SystemUI/res/layout/people_space_initial_layout.xml @@ -22,7 +22,8 @@ <LinearLayout android:background="@drawable/people_space_tile_view_card" - android:id="@+id/item" + android:clipToOutline="true" + android:id="@android:id/background" android:orientation="horizontal" android:gravity="center" android:layout_gravity="top" diff --git a/packages/SystemUI/res/layout/people_space_placeholder_layout.xml b/packages/SystemUI/res/layout/people_space_placeholder_layout.xml index 061b0d967652..c728bee641eb 100644 --- a/packages/SystemUI/res/layout/people_space_placeholder_layout.xml +++ b/packages/SystemUI/res/layout/people_space_placeholder_layout.xml @@ -22,26 +22,40 @@ <LinearLayout android:background="@drawable/people_space_tile_view_card" - android:id="@+id/item" + android:clipToOutline="true" + android:id="@android:id/background" android:orientation="horizontal" android:gravity="center" - android:layout_gravity="top" + android:layout_gravity="center" android:paddingVertical="8dp" - android:paddingHorizontal="16dp" + android:paddingHorizontal="2dp" android:layout_width="match_parent" android:layout_height="match_parent"> + <TextView + android:layout_weight="6" + android:layout_width="0dp" + android:layout_height="match_parent"/> <LinearLayout + android:layout_weight="34" android:orientation="vertical" - android:paddingEnd="20dp" - android:gravity="start|bottom" - android:layout_width="wrap_content" - android:layout_height="wrap_content"> - + android:gravity="start|center_vertical" + android:layout_gravity="start|center_vertical" + android:layout_width="0dp" + android:layout_height="match_parent"> + <TextView + android:layout_weight="1" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> <ImageView - android:background="@drawable/ic_person" - android:layout_width="48dp" - android:layout_height="48dp" /> + android:layout_weight="1" + android:gravity="start" + android:layout_gravity="start" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/ic_avatar_with_badge" + android:adjustViewBounds="true" + android:scaleType="centerInside" /> <TextView android:id="@+id/name" @@ -54,16 +68,25 @@ android:ellipsize="end" android:layout_width="wrap_content" android:layout_height="wrap_content" /> + <TextView + android:layout_weight="1" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> </LinearLayout> <TextView + android:layout_weight="52" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:ellipsize="end" + android:maxLines="2" android:text="@string/empty_status" - android:textColor="?android:attr/textColorPrimary" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title" - android:textSize="12sp" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:maxLines="3" - android:ellipsize="end" /> + android:textColor="?android:attr/textColorPrimary" + android:textSize="12sp" /> + <TextView + android:layout_weight="6" + android:layout_width="0dp" + android:layout_height="wrap_content"/> </LinearLayout> </LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/people_space_widget_item.xml b/packages/SystemUI/res/layout/people_space_widget_item.xml index 17d0c561c646..492d3abcb6d0 100644 --- a/packages/SystemUI/res/layout/people_space_widget_item.xml +++ b/packages/SystemUI/res/layout/people_space_widget_item.xml @@ -21,7 +21,8 @@ android:orientation="vertical"> <LinearLayout android:background="@drawable/people_space_tile_view_card" - android:id="@+id/item" + android:clipToOutline="true" + android:id="@android:id/background" android:orientation="vertical" android:padding="4dp" android:layout_marginBottom="2dp" diff --git a/packages/SystemUI/res/layout/people_tile_empty_layout.xml b/packages/SystemUI/res/layout/people_tile_empty_layout.xml index 8e9ebc69c54c..f115002577fd 100644 --- a/packages/SystemUI/res/layout/people_tile_empty_layout.xml +++ b/packages/SystemUI/res/layout/people_tile_empty_layout.xml @@ -14,9 +14,10 @@ ~ limitations under the License. --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/item" + android:id="@android:id/background" android:theme="@android:style/Theme.DeviceDefault.DayNight" android:background="@drawable/people_tile_empty_background" + android:clipToOutline="true" android:layout_width="match_parent" android:layout_height="match_parent"> diff --git a/packages/SystemUI/res/layout/people_tile_large_empty.xml b/packages/SystemUI/res/layout/people_tile_large_empty.xml index d4a8e15101bd..f2a3922aa278 100644 --- a/packages/SystemUI/res/layout/people_tile_large_empty.xml +++ b/packages/SystemUI/res/layout/people_tile_large_empty.xml @@ -14,8 +14,9 @@ ~ limitations under the License. --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/item" + android:id="@android:id/background" android:background="@drawable/people_space_tile_view_card" + android:clipToOutline="true" android:theme="@android:style/Theme.DeviceDefault.DayNight" android:layout_width="match_parent" android:layout_height="match_parent" diff --git a/packages/SystemUI/res/layout/people_tile_large_with_content.xml b/packages/SystemUI/res/layout/people_tile_large_with_content.xml index 3f78fe752609..6da17bc4188f 100644 --- a/packages/SystemUI/res/layout/people_tile_large_with_content.xml +++ b/packages/SystemUI/res/layout/people_tile_large_with_content.xml @@ -126,6 +126,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/people_space_content_background" + android:clipToOutline="true" android:gravity="center" android:scaleType="centerCrop" /> diff --git a/packages/SystemUI/res/layout/people_tile_large_with_notification_content.xml b/packages/SystemUI/res/layout/people_tile_large_with_notification_content.xml index 60ff68edc3f4..c18a59a25812 100644 --- a/packages/SystemUI/res/layout/people_tile_large_with_notification_content.xml +++ b/packages/SystemUI/res/layout/people_tile_large_with_notification_content.xml @@ -15,7 +15,7 @@ --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="@drawable/people_space_tile_view_card" - android:id="@+id/item" + android:id="@android:id/background" android:clipToOutline="true" android:theme="@android:style/Theme.DeviceDefault.DayNight" android:layout_gravity="center" diff --git a/packages/SystemUI/res/layout/people_tile_large_with_status_content.xml b/packages/SystemUI/res/layout/people_tile_large_with_status_content.xml index cbc6ea860044..508a2555341e 100644 --- a/packages/SystemUI/res/layout/people_tile_large_with_status_content.xml +++ b/packages/SystemUI/res/layout/people_tile_large_with_status_content.xml @@ -15,7 +15,7 @@ --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="@drawable/people_space_tile_view_card" - android:id="@+id/item" + android:id="@android:id/background" android:clipToOutline="true" android:theme="@android:style/Theme.DeviceDefault.DayNight" android:layout_gravity="center" diff --git a/packages/SystemUI/res/layout/people_tile_medium_empty.xml b/packages/SystemUI/res/layout/people_tile_medium_empty.xml index ebb61c94eca5..4a186831a2b0 100644 --- a/packages/SystemUI/res/layout/people_tile_medium_empty.xml +++ b/packages/SystemUI/res/layout/people_tile_medium_empty.xml @@ -21,7 +21,8 @@ android:orientation="vertical"> <LinearLayout android:background="@drawable/people_space_tile_view_card" - android:id="@+id/item" + android:clipToOutline="true" + android:id="@android:id/background" android:gravity="center" android:paddingHorizontal="16dp" android:orientation="horizontal" diff --git a/packages/SystemUI/res/layout/people_tile_medium_with_content.xml b/packages/SystemUI/res/layout/people_tile_medium_with_content.xml index 0a5bf1d7c49f..892f64b3123b 100644 --- a/packages/SystemUI/res/layout/people_tile_medium_with_content.xml +++ b/packages/SystemUI/res/layout/people_tile_medium_with_content.xml @@ -18,8 +18,9 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" android:theme="@android:style/Theme.DeviceDefault.DayNight" - android:id="@+id/item" + android:id="@android:id/background" android:background="@drawable/people_space_tile_view_card" + android:clipToOutline="true" android:layout_gravity="center" android:layout_width="match_parent" android:layout_height="match_parent" @@ -28,7 +29,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> <include layout="@layout/people_tile_punctuation_background_medium" /> - <include layout="@layout/people_tile_punctuation_background_medium" /> + <include layout="@layout/people_tile_emoji_background_medium" /> <include layout="@layout/people_status_scrim_layout" /> <LinearLayout android:id="@+id/content" @@ -83,6 +84,7 @@ android:id="@+id/image" android:gravity="center" android:background="@drawable/people_space_content_background" + android:clipToOutline="true" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" /> diff --git a/packages/SystemUI/res/layout/people_tile_small.xml b/packages/SystemUI/res/layout/people_tile_small.xml index 553b8a43e033..44e68e544271 100644 --- a/packages/SystemUI/res/layout/people_tile_small.xml +++ b/packages/SystemUI/res/layout/people_tile_small.xml @@ -20,11 +20,12 @@ android:layout_height="match_parent"> <LinearLayout - android:id="@+id/item" + android:id="@android:id/background" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:background="@drawable/people_space_tile_view_card" + android:clipToOutline="true" android:orientation="vertical" android:paddingHorizontal="4dp" android:paddingTop="6dp" diff --git a/packages/SystemUI/res/layout/people_tile_suppressed_layout.xml b/packages/SystemUI/res/layout/people_tile_suppressed_layout.xml index b151c6065b9a..4820a35ac5b3 100644 --- a/packages/SystemUI/res/layout/people_tile_suppressed_layout.xml +++ b/packages/SystemUI/res/layout/people_tile_suppressed_layout.xml @@ -14,9 +14,10 @@ ~ limitations under the License. --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/item" + android:id="@android:id/background" android:theme="@android:style/Theme.DeviceDefault.DayNight" android:background="@drawable/people_tile_suppressed_background" + android:clipToOutline="true" android:layout_width="match_parent" android:layout_height="match_parent"> diff --git a/packages/SystemUI/res/layout/people_tile_with_suppression_detail_content_horizontal.xml b/packages/SystemUI/res/layout/people_tile_with_suppression_detail_content_horizontal.xml new file mode 100644 index 000000000000..f7e12eba689d --- /dev/null +++ b/packages/SystemUI/res/layout/people_tile_with_suppression_detail_content_horizontal.xml @@ -0,0 +1,46 @@ +<?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. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:theme="@android:style/Theme.DeviceDefault.DayNight" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center" + android:id="@android:id/background" + android:background="@drawable/people_tile_suppressed_background" + android:clipToOutline="true" + android:padding="8dp" + android:orientation="horizontal"> + + <ImageView + android:id="@+id/person_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + + <TextView + android:gravity="start" + android:id="@+id/text_content" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:ellipsize="end" + android:maxLines="2" + android:singleLine="false" + android:text="@string/empty_status" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title" + android:textColor="?android:attr/textColorPrimary" + android:textSize="@dimen/content_text_size_for_medium" /> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout/people_tile_with_suppression_detail_content_vertical.xml b/packages/SystemUI/res/layout/people_tile_with_suppression_detail_content_vertical.xml new file mode 100644 index 000000000000..c488d890986d --- /dev/null +++ b/packages/SystemUI/res/layout/people_tile_with_suppression_detail_content_vertical.xml @@ -0,0 +1,65 @@ +<?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. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:theme="@android:style/Theme.DeviceDefault.DayNight" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center" + android:id="@android:id/background" + android:background="@drawable/people_tile_suppressed_background" + android:clipToOutline="true" + android:padding="8dp" + android:orientation="vertical"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="0dp" + android:layout_weight="1"/> + + <ImageView + android:id="@+id/person_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + + <TextView + android:gravity="center" + android:id="@+id/text_content" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:ellipsize="end" + android:maxLines="2" + android:singleLine="false" + android:text="@string/empty_status" + android:layout_marginTop="@dimen/padding_between_suppressed_layout_items" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title" + android:textColor="?android:attr/textColorSecondary" + android:textSize="@dimen/content_text_size_for_large" /> + + <ImageView + android:id="@+id/predefined_icon" + android:tint="?android:attr/textColorSecondary" + android:layout_marginTop="@dimen/padding_between_suppressed_layout_items" + android:layout_width="@dimen/regular_predefined_icon" + android:layout_height="@dimen/regular_predefined_icon" + tools:ignore="UseAppTint" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="0dp" + android:layout_weight="1"/> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout/people_tile_work_profile_quiet_layout.xml b/packages/SystemUI/res/layout/people_tile_work_profile_quiet_layout.xml index 25ab5a61ffee..1ccfb075553c 100644 --- a/packages/SystemUI/res/layout/people_tile_work_profile_quiet_layout.xml +++ b/packages/SystemUI/res/layout/people_tile_work_profile_quiet_layout.xml @@ -15,9 +15,10 @@ --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" - android:id="@+id/item" + android:id="@android:id/background" android:theme="@android:style/Theme.DeviceDefault.DayNight" android:background="@drawable/people_tile_suppressed_background" + android:clipToOutline="true" android:layout_width="match_parent" android:layout_height="match_parent"> diff --git a/packages/SystemUI/res/layout/screen_record_dialog.xml b/packages/SystemUI/res/layout/screen_record_dialog.xml index c1767ee89743..d1cc01f0694e 100644 --- a/packages/SystemUI/res/layout/screen_record_dialog.xml +++ b/packages/SystemUI/res/layout/screen_record_dialog.xml @@ -28,6 +28,10 @@ <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" + android:paddingStart="24dp" + android:paddingEnd="24dp" + android:paddingTop="26dp" + android:paddingBottom="30dp" android:orientation="vertical"> <!-- Header --> @@ -35,27 +39,28 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:gravity="center" - android:padding="@dimen/screenrecord_dialog_padding"> + android:gravity="center"> <ImageView android:layout_width="@dimen/screenrecord_logo_size" android:layout_height="@dimen/screenrecord_logo_size" android:src="@drawable/ic_screenrecord" - android:tint="@color/GM2_red_500" - android:layout_marginBottom="@dimen/screenrecord_dialog_padding"/> + android:tint="@color/screenrecord_icon_color"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:fontFamily="@*android:string/config_headlineFontFamily" - android:text="@string/screenrecord_start_label"/> + android:text="@string/screenrecord_start_label" + android:layout_marginTop="22dp" + android:layout_marginBottom="15dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/screenrecord_description" android:textAppearance="?android:attr/textAppearanceSmall" - android:paddingTop="@dimen/screenrecord_dialog_padding" - android:paddingBottom="@dimen/screenrecord_dialog_padding"/> + android:textColor="?android:textColorSecondary" + android:gravity="center" + android:layout_marginBottom="20dp"/> <!-- Options --> <LinearLayout @@ -63,18 +68,21 @@ android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView - android:layout_width="@dimen/screenrecord_logo_size" - android:layout_height="@dimen/screenrecord_logo_size" + android:layout_width="@dimen/screenrecord_option_icon_size" + android:layout_height="@dimen/screenrecord_option_icon_size" android:src="@drawable/ic_mic_26dp" - android:tint="@color/GM2_grey_700" + android:tint="?android:attr/textColorSecondary" android:layout_gravity="center" android:layout_weight="0" - android:layout_marginRight="@dimen/screenrecord_dialog_padding"/> + android:layout_marginRight="@dimen/screenrecord_option_padding"/> <Spinner android:id="@+id/screen_recording_options" android:layout_width="0dp" - android:layout_height="48dp" + android:layout_height="wrap_content" + android:minHeight="48dp" android:layout_weight="1" + android:popupBackground="@drawable/screenrecord_spinner_background" + android:dropDownWidth="274dp" android:prompt="@string/screenrecord_audio_label"/> <Switch android:layout_width="wrap_content" @@ -83,63 +91,76 @@ android:layout_weight="0" android:layout_gravity="end" android:contentDescription="@string/screenrecord_audio_label" - android:id="@+id/screenrecord_audio_switch"/> + android:id="@+id/screenrecord_audio_switch" + style="@style/ScreenRecord.Switch"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="horizontal"> + android:orientation="horizontal" + android:layout_marginTop="@dimen/screenrecord_option_padding"> <ImageView - android:layout_width="@dimen/screenrecord_logo_size" - android:layout_height="@dimen/screenrecord_logo_size" + android:layout_width="@dimen/screenrecord_option_icon_size" + android:layout_height="@dimen/screenrecord_option_icon_size" + android:layout_weight="0" android:src="@drawable/ic_touch" - android:tint="@color/GM2_grey_700" + android:tint="?android:attr/textColorSecondary" android:layout_gravity="center" - android:layout_marginRight="@dimen/screenrecord_dialog_padding"/> + android:layout_marginRight="@dimen/screenrecord_option_padding"/> + <TextView + android:layout_width="0dp" + android:layout_height="wrap_content" + android:minHeight="48dp" + android:layout_weight="1" + android:text="@string/screenrecord_taps_label" + android:textAppearance="?android:attr/textAppearanceMedium" + android:fontFamily="@*android:string/config_headlineFontFamily" + android:textColor="?android:attr/textColorPrimary" + android:importantForAccessibility="no"/> <Switch - android:layout_width="match_parent" + android:layout_width="wrap_content" + android:minWidth="48dp" android:layout_height="48dp" + android:layout_weight="0" android:id="@+id/screenrecord_taps_switch" - android:text="@string/screenrecord_taps_label" - android:textColor="?android:attr/textColorPrimary" - android:textAppearance="?android:attr/textAppearanceSmall"/> - + android:contentDescription="@string/screenrecord_taps_label" + style="@style/ScreenRecord.Switch"/> </LinearLayout> </LinearLayout> - <!-- hr --> - <View - android:layout_width="match_parent" - android:layout_height="1dp" - android:background="@color/GM2_grey_300"/> - <!-- Buttons --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:padding="@dimen/screenrecord_dialog_padding"> - <Button + android:layout_marginTop="36dp"> + <TextView android:id="@+id/button_cancel" android:layout_width="wrap_content" - android:layout_height="match_parent" + android:layout_height="wrap_content" android:layout_weight="0" android:layout_gravity="start" android:text="@string/cancel" - style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"/> + android:textColor="?android:textColorPrimary" + android:background="@drawable/screenrecord_button_background_outline" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textSize="14sp"/> <Space android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1"/> - <Button + <TextView android:id="@+id/button_start" android:layout_width="wrap_content" - android:layout_height="match_parent" + android:layout_height="wrap_content" android:layout_weight="0" android:layout_gravity="end" android:text="@string/screenrecord_start" - style="@android:style/Widget.DeviceDefault.Button.Colored"/> + android:textColor="@android:color/system_neutral1_900" + android:background="@drawable/screenrecord_button_background_solid" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textSize="14sp"/> </LinearLayout> </LinearLayout> </ScrollView> diff --git a/packages/SystemUI/res/layout/screen_record_dialog_audio_source.xml b/packages/SystemUI/res/layout/screen_record_dialog_audio_source.xml index 0c4d5a26f95b..ab600b3758bc 100644 --- a/packages/SystemUI/res/layout/screen_record_dialog_audio_source.xml +++ b/packages/SystemUI/res/layout/screen_record_dialog_audio_source.xml @@ -19,18 +19,19 @@ android:layout_width="250dp" android:layout_height="48dp" android:orientation="vertical" - android:padding="13dp"> + android:padding="12dp"> <TextView android:id="@+id/screen_recording_dialog_source_text" - android:layout_width="250dp" + android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center_vertical" - android:textAppearance="?android:attr/textAppearanceSmall" - android:textColor="?android:attr/textColorPrimary"/> + android:textAppearance="?android:attr/textAppearanceMedium" + android:textSize="14sp" + android:textColor="@android:color/system_neutral1_900"/> <TextView android:id="@+id/screen_recording_dialog_source_description" - android:layout_width="250dp" + android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" - android:textColor="?android:attr/textColorSecondary"/> + android:textColor="@android:color/system_neutral2_700"/> </LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/screen_record_dialog_audio_source_selected.xml b/packages/SystemUI/res/layout/screen_record_dialog_audio_source_selected.xml index fabe9e2d4453..e2b8d33e3d8e 100644 --- a/packages/SystemUI/res/layout/screen_record_dialog_audio_source_selected.xml +++ b/packages/SystemUI/res/layout/screen_record_dialog_audio_source_selected.xml @@ -24,7 +24,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/screenrecord_audio_label" - android:textAppearance="?android:attr/textAppearanceSmall" + android:textAppearance="?android:attr/textAppearanceMedium" + android:fontFamily="@*android:string/config_headlineFontFamily" android:textColor="?android:attr/textColorPrimary"/> <TextView android:id="@+id/screen_recording_dialog_source_text" diff --git a/packages/SystemUI/res/layout/tv_bottom_sheet.xml b/packages/SystemUI/res/layout/tv_bottom_sheet.xml new file mode 100644 index 000000000000..b69cdc76ae40 --- /dev/null +++ b/packages/SystemUI/res/layout/tv_bottom_sheet.xml @@ -0,0 +1,87 @@ +<?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. + --> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/bottom_sheet" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:orientation="horizontal" + android:minHeight="@dimen/bottom_sheet_min_height" + android:paddingHorizontal="@dimen/bottom_sheet_padding_horizontal" + android:paddingVertical="@dimen/bottom_sheet_padding_vertical"> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:minWidth="80dp" + android:gravity="center" + android:orientation="horizontal"> + <ImageView + android:id="@+id/bottom_sheet_icon" + android:layout_width="@dimen/bottom_sheet_icon_size" + android:layout_height="@dimen/bottom_sheet_icon_size" + android:layout_gravity="center_vertical" + android:tint="@color/bottom_sheet_icon_color"/> + <ImageView + android:id="@+id/bottom_sheet_second_icon" + android:layout_width="@dimen/bottom_sheet_icon_size" + android:layout_height="@dimen/bottom_sheet_icon_size" + android:layout_marginStart="@dimen/bottom_sheet_icon_margin" + android:layout_gravity="center_vertical" + android:tint="@color/bottom_sheet_icon_color"/> + </LinearLayout> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/bottom_sheet_padding_horizontal" + android:layout_weight="1" + android:orientation="vertical"> + <TextView + android:id="@+id/bottom_sheet_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/bottom_sheet_title_margin_bottom" + android:textAppearance="@style/BottomSheet.TitleText"/> + + <TextView + android:id="@+id/bottom_sheet_body" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/bottom_sheet_details_margin_bottom" + android:textAppearance="@style/BottomSheet.BodyText" /> + </LinearLayout> + + <LinearLayout + android:orientation="vertical" + android:layout_width="@dimen/bottom_sheet_actions_width" + android:layout_height="match_parent" + android:gravity="center"> + <Button + android:id="@+id/bottom_sheet_positive_button" + style="@style/BottomSheet.ActionItem" /> + <Space + android:layout_width="0dp" + android:layout_height="@dimen/bottom_sheet_actions_spacing" /> + <Button + android:id="@+id/bottom_sheet_negative_button" + style="@style/BottomSheet.ActionItem" /> + </LinearLayout> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout/tv_ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/tv_ongoing_privacy_chip.xml index dff148b2c570..6218a5e6ea82 100644 --- a/packages/SystemUI/res/layout/tv_ongoing_privacy_chip.xml +++ b/packages/SystemUI/res/layout/tv_ongoing_privacy_chip.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - ~ Copyright (C) 2019 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. @@ -20,16 +20,25 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:padding="12dp" - android:layout_gravity="center"> + android:gravity="center" + android:animateLayoutChanges="false" + android:padding="@dimen/privacy_chip_margin"> + + <ImageView + android:id="@+id/chip_drawable" + android:layout_width="51dp" + android:layout_height="@dimen/privacy_chip_height" + android:minWidth="@dimen/privacy_chip_dot_bg_width" + android:minHeight="@dimen/privacy_chip_dot_bg_height" + android:layout_gravity="top|end" /> <LinearLayout android:id="@+id/icons_container" - android:background="@drawable/tv_rect_shadow_rounded" - android:padding="@dimen/privacy_chip_icon_padding" android:layout_width="wrap_content" - android:layout_height="match_parent" - android:orientation="horizontal"/> - + android:layout_height="wrap_content" + android:orientation="horizontal" + android:layout_gravity="center_vertical|end" + android:animateLayoutChanges="true" + android:paddingHorizontal="@dimen/privacy_chip_padding_horizontal" /> </FrameLayout> diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml index ee89b97a4a9c..c9256ae5123b 100644 --- a/packages/SystemUI/res/layout/volume_dialog_row.xml +++ b/packages/SystemUI/res/layout/volume_dialog_row.xml @@ -46,7 +46,6 @@ android:id="@+id/volume_row_slider_frame" android:layout_width="match_parent" android:layout_height="@dimen/volume_row_slider_height"> - <include layout="@layout/volume_dnd_icon"/> <SeekBar android:id="@+id/volume_row_slider" android:paddingLeft="0dp" @@ -63,6 +62,7 @@ android:background="@null" android:layoutDirection="ltr" android:rotation="270" /> + <include layout="@layout/volume_dnd_icon"/> </FrameLayout> <com.android.keyguard.AlphaOptimizedImageButton diff --git a/packages/SystemUI/res/layout/volume_dnd_icon.xml b/packages/SystemUI/res/layout/volume_dnd_icon.xml index 10c1472ae993..56587b99b80b 100644 --- a/packages/SystemUI/res/layout/volume_dnd_icon.xml +++ b/packages/SystemUI/res/layout/volume_dnd_icon.xml @@ -18,12 +18,14 @@ android:id="@+id/dnd_icon" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="6dp"> + android:layout_gravity="bottom" + android:layout_marginTop="6dp" + android:layout_marginBottom="6dp"> <ImageView android:layout_width="14dp" android:layout_height="14dp" - android:layout_gravity="right|top" + android:layout_gravity="center" android:src="@*android:drawable/ic_qs_dnd" android:tint="?android:attr/textColorTertiary"/> </FrameLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/transition/tv_privacy_chip_collapse.xml b/packages/SystemUI/res/transition/tv_privacy_chip_collapse.xml new file mode 100644 index 000000000000..f22e8ef9d005 --- /dev/null +++ b/packages/SystemUI/res/transition/tv_privacy_chip_collapse.xml @@ -0,0 +1,20 @@ +<?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. + --> +<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"> + <fade android:fadingMode="fade_in" /> + <changeBounds/> +</transitionSet> diff --git a/packages/SystemUI/res/transition/tv_privacy_chip_expand.xml b/packages/SystemUI/res/transition/tv_privacy_chip_expand.xml new file mode 100644 index 000000000000..059ebc84ea7e --- /dev/null +++ b/packages/SystemUI/res/transition/tv_privacy_chip_expand.xml @@ -0,0 +1,20 @@ +<?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. + --> +<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"> + <changeBounds/> + <fade android:fadingMode="fade_out" /> +</transitionSet> diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index f8d06ce76c24..ab91e7844720 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Voeg gebruiker by"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nuwe gebruiker"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Verwyder gas?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Stel gassessie terug?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle programme en data in hierdie sessie sal uitgevee word."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Verwyder"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Stel terug"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welkom terug, gas!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Wiil jy jou sessie voortsit?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Begin van voor af"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Maak gesprek oop"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Gespreklegstukke"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Tik op \'n gesprek om dit by jou tuisskerm te voeg"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Kom kyk weer nadat jy \'n paar boodskappe gekry het"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Prioriteitgesprekke"</string> <string name="recent_conversations" msgid="8531874684782574622">"Onlangse gesprekke"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Sien onlangse boodskappe, gemiste oproepe en statusopdaterings"</string> <string name="people_tile_title" msgid="6589377493334871272">"Gesprek"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Onderbreek deur Moenie Steur nie"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> het \'n boodskap gestuur"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> het \'n prent gestuur"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Kon nie jou batterymeter lees nie"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 4736adbfb62f..823f9a12dbf2 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"ተጠቃሚ አክል"</string> <string name="user_new_user_name" msgid="2019166282704195789">"አዲስ ተጠቃሚ"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"እንግዳ ይወገድ?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"በዚህ ክፍለ-ጊዜ ውስጥ ያሉ ሁሉም መተግበሪያዎች እና ውሂብ ይሰረዛሉ።"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"አስወግድ"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"እንኳን በደህና ተመለሱ እንግዳ!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"ክፍለ-ጊዜዎን መቀጠል ይፈልጋሉ?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"እንደገና ጀምር"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"ውይይት ይክፈቱ"</string> <string name="select_conversation_title" msgid="6716364118095089519">"የውይይት ምግብሮች"</string> <string name="select_conversation_text" msgid="3376048251434956013">"በመነሻ ማያ ገጽዎ ላይ ለማከል አንድ ውይይት መታ ያድርጉ"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"አንዳንድ መልዕክቶች ከደረሰዎት በኋላ እዚህ ተመልሰው ይፈትሹ"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"የቅድሚያ ውይይቶች"</string> <string name="recent_conversations" msgid="8531874684782574622">"የቅርብ ጊዜ ውይይቶች"</string> <string name="okay" msgid="6490552955618608554">"እሺ"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"የቅርብ ጊዜ መልዕክቶችን፣ ያመለጡ ጥሪዎች እና፣ የሁኔታ ዝመናዎችን ይመልከቱ"</string> <string name="people_tile_title" msgid="6589377493334871272">"ውይይት"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"በአትረብሽ ባለበት ቆሟል"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> መልዕክት ልኳል"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ምስል ልኳል"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"የባትሪ መለኪያዎን የማንበብ ችግር"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index b493d897fd22..999f4abfded8 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -488,12 +488,8 @@ <string name="user_add_user" msgid="4336657383006913022">"إضافة مستخدم"</string> <string name="user_new_user_name" msgid="2019166282704195789">"مستخدم جديد"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"هل تريد إزالة جلسة الضيف؟"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"سيتم حذف كل التطبيقات والبيانات في هذه الجلسة."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"إزالة"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"مرحبًا بك مجددًا في جلسة الضيف"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"هل تريد متابعة جلستك؟"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"البدء من جديد"</string> @@ -1143,7 +1139,8 @@ <string name="basic_status" msgid="2315371112182658176">"محادثة مفتوحة"</string> <string name="select_conversation_title" msgid="6716364118095089519">"أدوات المحادثة"</string> <string name="select_conversation_text" msgid="3376048251434956013">"انقر على محادثة لإضافتها إلى \"الشاشة الرئيسية\"."</string> - <string name="no_conversations_text" msgid="7362374212649891057">"يمكنك الرجوع إلى هذه الأداة عندما تتلقّى بعض الرسائل."</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"المحادثات ذات الأولوية"</string> <string name="recent_conversations" msgid="8531874684782574622">"المحادثات الحديثة"</string> <string name="okay" msgid="6490552955618608554">"حسنًا"</string> @@ -1172,6 +1169,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+<xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="people_tile_description" msgid="8154966188085545556">"عرض أحدث الرسائل والمكالمات الفائتة والتغييرات في الحالة"</string> <string name="people_tile_title" msgid="6589377493334871272">"محادثة"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"تم إيقاف الإشعار مؤقتًا من خلال ميزة \"عدم الإزعاج\""</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"تم إرسال رسالة من <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"تم إرسال صورة من <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"حدثت مشكلة أثناء قراءة مقياس مستوى شحن البطارية."</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index fa528fd9037a..110bf2e50ca4 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -32,14 +32,14 @@ <string name="invalid_charger" msgid="4370074072117767416">"ইউএছবি জৰিয়তে চ্চাৰ্জ কৰিব নোৱাৰি। আপোনাৰ ডিভাইচৰ লগত পোৱা চ্চাৰ্জাৰটো ব্যৱহাৰ কৰক।"</string> <string name="invalid_charger_title" msgid="938685362320735167">"ইউএছবি জৰিয়তে চ্চাৰ্জ কৰিব নোৱাৰি"</string> <string name="invalid_charger_text" msgid="2339310107232691577">"আপোনাৰ ডিভাইচৰ লগত পোৱা চ্চাৰ্জাৰটো ব্যৱহাৰ কৰক।"</string> - <string name="battery_low_why" msgid="2056750982959359863">"ছেটিংসমূহ"</string> + <string name="battery_low_why" msgid="2056750982959359863">"ছেটিং"</string> <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"বেটাৰি সঞ্চয়কাৰী অন কৰেনে?"</string> <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"বেটাৰী সঞ্চয়কাৰীৰ বিষয়ে"</string> <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"অন কৰক"</string> <string name="battery_saver_start_action" msgid="4553256017945469937">"বেটাৰি সঞ্চয়কাৰী অন কৰক"</string> <string name="status_bar_settings_settings_button" msgid="534331565185171556">"ছেটিংসমূহ"</string> <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"ৱাই-ফাই"</string> - <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"স্বয়ং-ঘূৰ্ণন স্ক্ৰীণ"</string> + <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"স্বয়ং-ঘূৰ্ণন স্ক্ৰীন"</string> <string name="status_bar_settings_mute_label" msgid="914392730086057522">"মিউট"</string> <string name="status_bar_settings_auto_brightness_label" msgid="2151934479226017725">"স্বয়ং"</string> <string name="status_bar_settings_notifications" msgid="5285316949980621438">"জাননীসমূহ"</string> @@ -343,7 +343,7 @@ <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"অন কৰি থকা হৈছে…"</string> <string name="quick_settings_brightness_label" msgid="680259653088849563">"উজ্জ্বলতা"</string> <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"স্বয়ং-ঘূৰ্ণন"</string> - <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"স্বয়ং-ঘূৰ্ণন স্ক্ৰীণ"</string> + <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"স্বয়ং-ঘূৰ্ণন স্ক্ৰীন"</string> <string name="accessibility_quick_settings_rotation_value" msgid="2916484894750819251">"<xliff:g id="ID_1">%s</xliff:g> ম\'ড"</string> <string name="quick_settings_rotation_locked_label" msgid="4420863550666310319">"ঘূৰ্ণন লক কৰা হ’ল"</string> <string name="quick_settings_rotation_locked_portrait_label" msgid="1194988975270484482">"প\'ৰ্ট্ৰেইট"</string> @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"ব্যৱহাৰকাৰী যোগ কৰক"</string> <string name="user_new_user_name" msgid="2019166282704195789">"নতুন ব্যৱহাৰকাৰী"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"অতিথি আঁতৰাবনে?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"অতিথিৰ ছেশ্বন ৰিছেট কৰিবনে?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই ছেশ্বনৰ সকলো এপ্ আৰু ডেটা মচা হ\'ব।"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"আঁতৰাওক"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"ৰিছেট কৰক"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"অতিথি, আপোনাক পুনৰ স্বাগতম!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"আপুনি আপোনাৰ ছেশ্বন অব্যাহত ৰাখিব বিচাৰেনে?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"আকৌ আৰম্ভ কৰক"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"বাৰ্তালাপ খোলক"</string> <string name="select_conversation_title" msgid="6716364118095089519">"বাৰ্তালাপ ৱিজেট"</string> <string name="select_conversation_text" msgid="3376048251434956013">"আপোনাৰ গৃহ স্ক্ৰীনত কোনো বাৰ্তালাপ যোগ দিবলৈ সেইটোত টিপক"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"আপুনি কিবা বাৰ্তা পোৱাৰ পাছত ইয়াত পুনৰ চাওক"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"অগ্ৰাধিকাৰপ্ৰাপ্ত বাৰ্তালাপ"</string> <string name="recent_conversations" msgid="8531874684782574622">"শেহতীয়া বাৰ্তালাপ"</string> <string name="okay" msgid="6490552955618608554">"ঠিক আছে"</string> @@ -1146,6 +1145,8 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"শেহতীয়া বাৰ্তা, মিছড্ কল আৰু স্থিতিৰ আপডে’ট চাওক"</string> <string name="people_tile_title" msgid="6589377493334871272">"বাৰ্তালাপ"</string> + <!-- no translation found for paused_by_dnd (7856941866433556428) --> + <skip /> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g>এ এটা বাৰ্তা পঠিয়াইছে"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>এ এখন প্ৰতিচ্ছবি পঠিয়াইছে"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"আপোনাৰ বেটাৰী মিটাৰ পঢ়োঁতে সমস্যা হৈছে"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 9502454d1c8c..b47f2510f8c1 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"İstifadəçi əlavə edin"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Yeni istifadəçi"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Qonaq silinsin?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Qonaq sessiyası sıfırlansın?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu sessiyada bütün tətbiqlər və data silinəcək."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Yığışdır"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Sıfırlayın"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Xoş gəlmisiniz!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Sessiya davam etsin?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Yenidən başlayın"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Açıq söhbət"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Söhbət vidcetləri"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Əsas ekranınıza əlavə etmək üçün söhbətə toxunun"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Mesaj gəldikdə yenidən buraya baxın"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Önəmli söhbətlər"</string> <string name="recent_conversations" msgid="8531874684782574622">"Son söhbətlər"</string> <string name="okay" msgid="6490552955618608554">"Oldu"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Son mesajlar, buraxılmış zənglər və status güncəlləmələrinə baxın"</string> <string name="people_tile_title" msgid="6589377493334871272">"Söhbət"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"\"Narahat Etməyin\" rejimini tərəfindən durdurulub"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> mesaj göndərdi"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> şəkil göndərdi"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batareya ölçüsünü oxuyarkən problem yarandı"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index fe89267456a9..2bf692090eaa 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -482,12 +482,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Dodaj korisnika"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Želite li da uklonite gosta?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Dobro došli nazad, goste!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li da nastavite sesiju?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni iz početka"</string> @@ -1125,7 +1121,8 @@ <string name="basic_status" msgid="2315371112182658176">"Otvorite konverzaciju"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Vidžeti za konverzaciju"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite konverzaciju da biste je dodali na početni ekran"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Vratite se ovde kada dobijete neku poruku"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Prioritetne konverzacije"</string> <string name="recent_conversations" msgid="8531874684782574622">"Nedavne konverzacije"</string> <string name="okay" msgid="6490552955618608554">"Važi"</string> @@ -1154,6 +1151,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Pogledajte nedavne poruke, propuštene pozive i ažuriranja statusa"</string> <string name="people_tile_title" msgid="6589377493334871272">"Konverzacija"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Pauzirano režimom Ne uznemiravaj"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> šalje poruku"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> šalje sliku"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem sa očitavanjem merača baterije"</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 5afd979d34f5..922ebb0bfea3 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -484,10 +484,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Дадаць карыстальніка"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Новы карыстальнік"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Выдаліць госця?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Скінуць гасцявы сеанс?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усе праграмы і даныя гэтага сеанса будуць выдалены."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Выдаліць"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Скінуць"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"З вяртаннем, госць!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Хочаце працягнуць сеанс?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Пачаць зноў"</string> @@ -1129,7 +1127,8 @@ <string name="basic_status" msgid="2315371112182658176">"Адкрытая размова"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Віджэты размовы"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Націсніце на размову, каб дадаць яе на галоўны экран"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Вярніцеся сюды, калі з\'явяцца паведамленні"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Прыярытэтныя размовы"</string> <string name="recent_conversations" msgid="8531874684782574622">"Нядаўнія размовы"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1158,6 +1157,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Глядзець нядаўнія паведамленні, прапушчаныя выклікі і абнаўленні стану"</string> <string name="people_tile_title" msgid="6589377493334871272">"Размова"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Прыпынена функцыяй \"Не турбаваць\""</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"Карыстальнік <xliff:g id="NAME">%1$s</xliff:g> адправіў паведамленне"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"Карыстальнік <xliff:g id="NAME">%1$s</xliff:g> адправіў відарыс"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Праблема з чытаннем індыкатара зараду акумулятара"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 3f9269af1f50..21971d0a5d52 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Добавяне на потребител"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Нов потребител"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Да се премахне ли гостът?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Да се нулира ли сесията като гост?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Всички приложения и данни в тази сесия ще бъдат изтрити."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Премахване"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Нулиране"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Добре дошли отново в сесията като гост!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Искате ли да продължите сесията си?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Започване отначало"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Отворен разговор"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Приспособления за разговор"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Докоснете разговор, за да го добавите към началния си екран"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Проверете отново тук, когато получите съобщения"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Разговори с приоритет"</string> <string name="recent_conversations" msgid="8531874684782574622">"Скорошни разговори"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Над <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="people_tile_description" msgid="8154966188085545556">"Преглеждайте скорошни съобщения, пропуснати обаждания и информация за състоянието"</string> <string name="people_tile_title" msgid="6589377493334871272">"Разговор"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Поставено на пауза от режима „Не безпокойте“"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> изпрати съобщение"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> изпрати изображение"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Възникна проблем при четенето на данните за нивото на батерията"</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 0eedd1ca13f1..8c02a0f4c652 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"ব্যবহারকারী জুড়ুন"</string> <string name="user_new_user_name" msgid="2019166282704195789">"নতুন ব্যবহারকারী"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"অতিথি সরাবেন?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই সেশনের সব অ্যাপ ও ডেটা মুছে ফেলা হবে।"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"সরান"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"অতিথি, আপনি ফিরে আসায় আপনাকে স্বাগত!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"আপনি কি আপনার সেশনটি চালিয়ে যেতে চান?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"আবার শুরু করুন"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"খোলা কথোপকথন"</string> <string name="select_conversation_title" msgid="6716364118095089519">"কথোপকথন উইজেট"</string> <string name="select_conversation_text" msgid="3376048251434956013">"কোনও কথোপথন আপনার হোম স্ক্রিনে যোগ করার জন্য এতে ট্যাপ করুন"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"কোনও মেসেজ পেলে আবার এখানে দেখুন"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"গুরুত্বপূর্ণ কথোপকথন"</string> <string name="recent_conversations" msgid="8531874684782574622">"সাম্প্রতিক কথোপকথন"</string> <string name="okay" msgid="6490552955618608554">"ঠিক আছে"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"সাম্প্রতিক মেসেজ, মিসড কল এবং স্ট্যাটাস সংক্রান্ত আপডেট দেখুন"</string> <string name="people_tile_title" msgid="6589377493334871272">"কথোপকথন"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"\'বিরক্ত করবে না\' মোডের মাধ্যমে পজ করা আছে"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> একটি মেসেজ পাঠিয়েছেন"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> একটি ছবি পাঠিয়েছেন"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ব্যাটারির মিটারের রিডিং নেওয়ার সময় সমস্যা হয়েছে"</string> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 615d34634789..769da0a91933 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -482,10 +482,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Dodaj korisnika"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ukloniti gosta?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Poništiti gostujuću sesiju?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci iz ove sesije će se izbrisati."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Poništi"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Zdravo! Lijepo je opet vidjeti goste."</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string> @@ -1123,7 +1121,8 @@ <string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Vidžeti za razgovor"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite razgovor da ga dodate na početni ekran"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Vratite se ovdje kada dobijete neku poruku"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Prioritetni razgovori"</string> <string name="recent_conversations" msgid="8531874684782574622">"Nedavni razgovori"</string> <string name="okay" msgid="6490552955618608554">"Uredu"</string> @@ -1152,6 +1151,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Pregledajte nedavne poruke, propuštene pozive i ažuriranja statusa"</string> <string name="people_tile_title" msgid="6589377493334871272">"Razgovor"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Pauzirala je funkcija Ne ometaj"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> je poslao/la poruku"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> je poslao/la sliku"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Došlo je do problema prilikom očitavanja mjerača stanja baterije"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 2428d55fa1e6..055e68a17b4e 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Afegeix un usuari"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Usuari nou"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vols suprimir el convidat?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Totes les aplicacions i les dades d\'aquesta sessió se suprimiran."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Suprimeix"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Benvingut de nou, convidat."</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vols continuar amb la sessió?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Torna a començar"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Conversa oberta"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Toca una conversa per afegir-la a la teva pantalla d\'inici"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Torna a consultar aquesta pàgina quan rebis algun missatge"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Converses prioritàries"</string> <string name="recent_conversations" msgid="8531874684782574622">"Converses recents"</string> <string name="okay" msgid="6490552955618608554">"D\'acord"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Consulta els missatges recents, les trucades perdudes i les actualitzacions d\'estat"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversa"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Posat en pausa pel mode No molestis"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> ha enviat un missatge"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ha enviat una imatge"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Hi ha hagut un problema en llegir el mesurador de la bateria"</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index d8e0a6a1d446..6545eec36eb0 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -484,12 +484,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Přidat uživatele"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nový uživatel"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Odstranit hosta?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Veškeré aplikace a data v této relaci budou vymazána."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstranit"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Vítejte zpět v relaci hosta!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relaci pokračovat?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začít znovu"</string> @@ -1131,7 +1127,8 @@ <string name="basic_status" msgid="2315371112182658176">"Otevřít konverzaci"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widgety konverzací"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Klepnutím na konverzaci ji přidáte na plochu"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Vraťte se sem, až dostanete nějaké zprávy"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Prioritní konverzace"</string> <string name="recent_conversations" msgid="8531874684782574622">"Poslední konverzace"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1160,6 +1157,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Zobrazit poslední zprávy, zmeškané hovory a aktualizace stavu"</string> <string name="people_tile_title" msgid="6589377493334871272">"Konverzace"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Pozastaveno funkcí Nerušit"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> posílá zprávu"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> posílá obrázek"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problém s načtením měřiče baterie"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index ca44f0a350d7..caa47a958288 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Tilføj bruger"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Ny bruger"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vil du fjerne gæsten?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps og data i denne session slettes."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjern"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkommen tilbage, gæst!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsætte din session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start forfra"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Åben samtale"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Samtalewidgets"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Tryk på en samtale for at føje den til din startskærm"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Vend tilbage hertil, når du har fået beskeder"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Prioriterede samtaler"</string> <string name="recent_conversations" msgid="8531874684782574622">"Seneste samtaler"</string> <string name="okay" msgid="6490552955618608554">"Okay"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Se dine seneste beskeder, mistede opkald og statusopdateringer"</string> <string name="people_tile_title" msgid="6589377493334871272">"Samtale"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Sat på pause af Forstyr ikke"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> har sendt en sms"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> har sendt et billede"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Der er problemer med at aflæse dit batteriniveau"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 17cb3b9f3c32..7da6f8825b18 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Nutzer hinzufügen"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Neuer Nutzer"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Gast entfernen?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle Apps und Daten in dieser Sitzung werden gelöscht."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Entfernen"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Willkommen zurück im Gastmodus"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Möchtest du deine Sitzung fortsetzen?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Neu starten"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Offene Unterhaltung"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Unterhaltungs-Widgets"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Tippe auf eine Unterhaltung, um sie deinem Startbildschirm hinzuzufügen"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Wenn du Nachrichten empfängst, findest du sie hier"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Vorrangige Unterhaltungen"</string> <string name="recent_conversations" msgid="8531874684782574622">"Neueste Unterhaltungen"</string> <string name="okay" msgid="6490552955618608554">"Ok"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Letzte Nachrichten, verpasste Anrufe und Statusaktualisierungen ansehen"</string> <string name="people_tile_title" msgid="6589377493334871272">"Unterhaltung"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Durch „Bitte nicht stören“ pausiert"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> hat eine Nachricht gesendet"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> hat ein Bild gesendet"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem beim Lesen des Akkustands"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 7b135a3e32da..11bc5ad2c901 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Προσθήκη χρήστη"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Νέος χρήστης"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Κατάργηση επισκέπτη;"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Όλες οι εφαρμογές και τα δεδομένα αυτής της περιόδου σύνδεσης θα διαγραφούν."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Κατάργηση"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Kαλώς ορίσατε ξανά!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Θέλετε να συνεχίσετε την περίοδο σύνδεσής σας;"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Έναρξη από την αρχή"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Άνοιγμα συνομιλίας"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Γραφικά στοιχεία συνομιλίας"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Πατήστε μια συνομιλία για να την προσθέσετε στην αρχική οθόνη"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Ελέγξτε ξανά εδώ όταν λάβετε ορισμένα μηνύματα"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Συζητήσεις προτεραιότητας"</string> <string name="recent_conversations" msgid="8531874684782574622">"Πρόσφατες συζητήσεις"</string> <string name="okay" msgid="6490552955618608554">"Εντάξει"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Δείτε πρόσφατα μηνύματα, αναπάντητες κλήσεις και ενημερώσεις κατάστασης"</string> <string name="people_tile_title" msgid="6589377493334871272">"Συνομιλία"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Σε παύση από τη λειτουργία Μην ενοχλείτε"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"Ο χρήστης <xliff:g id="NAME">%1$s</xliff:g> έστειλε ένα μήνυμα"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"Ο χρήστης <xliff:g id="NAME">%1$s</xliff:g> έστειλε μια εικόνα"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Υπάρχει κάποιο πρόβλημα με την ανάγνωση του μετρητή μπαταρίας"</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index d7b39e260092..f401fd459772 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Add user"</string> <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Reset guest?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Reset"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string> @@ -1117,7 +1115,7 @@ <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Check back here once you get some messages"</string> + <string name="no_conversations_text" msgid="5354115541282395015">"Your recent conversations will show up here"</string> <string name="priority_conversations" msgid="3967482288896653039">"Priority conversations"</string> <string name="recent_conversations" msgid="8531874684782574622">"Recent conversations"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1146,6 +1144,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"See recent messages, missed calls and status updates"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Paused by Do Not Disturb"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> sent a message"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 0a49742058bf..cef55f75b207 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Add user"</string> <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Reset guest?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Reset"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string> @@ -1117,7 +1115,7 @@ <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Check back here once you get some messages"</string> + <string name="no_conversations_text" msgid="5354115541282395015">"Your recent conversations will show up here"</string> <string name="priority_conversations" msgid="3967482288896653039">"Priority conversations"</string> <string name="recent_conversations" msgid="8531874684782574622">"Recent conversations"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1146,6 +1144,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"See recent messages, missed calls and status updates"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Paused by Do Not Disturb"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> sent a message"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index d7b39e260092..f401fd459772 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Add user"</string> <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Reset guest?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Reset"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string> @@ -1117,7 +1115,7 @@ <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Check back here once you get some messages"</string> + <string name="no_conversations_text" msgid="5354115541282395015">"Your recent conversations will show up here"</string> <string name="priority_conversations" msgid="3967482288896653039">"Priority conversations"</string> <string name="recent_conversations" msgid="8531874684782574622">"Recent conversations"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1146,6 +1144,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"See recent messages, missed calls and status updates"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Paused by Do Not Disturb"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> sent a message"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index d7b39e260092..f401fd459772 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Add user"</string> <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Reset guest?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Reset"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string> @@ -1117,7 +1115,7 @@ <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your home screen"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Check back here once you get some messages"</string> + <string name="no_conversations_text" msgid="5354115541282395015">"Your recent conversations will show up here"</string> <string name="priority_conversations" msgid="3967482288896653039">"Priority conversations"</string> <string name="recent_conversations" msgid="8531874684782574622">"Recent conversations"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1146,6 +1144,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"See recent messages, missed calls and status updates"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Paused by Do Not Disturb"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> sent a message"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index ca3d72f6e589..7fe3a635a2f3 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Add user"</string> <string name="user_new_user_name" msgid="2019166282704195789">"New user"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remove guest?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Reset guest?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remove"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Reset"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome back, guest!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start over"</string> @@ -1117,7 +1115,7 @@ <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Conversation widgets"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Tap a conversation to add it to your Home screen"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Check back here once you get some messages"</string> + <string name="no_conversations_text" msgid="5354115541282395015">"Your recent conversations will show up here"</string> <string name="priority_conversations" msgid="3967482288896653039">"Priority conversations"</string> <string name="recent_conversations" msgid="8531874684782574622">"Recent conversations"</string> <string name="okay" msgid="6490552955618608554">"Okay"</string> @@ -1146,6 +1144,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"See recent messages, missed calls, and status updates"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Paused by Do Not Disturb"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> sent a message"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sent an image"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 0479ad0fcb85..f41a02c9c6ff 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -471,7 +471,7 @@ <string name="interruption_level_alarms_twoline" msgid="2045067991335708767">"Solo\nalarmas"</string> <string name="keyguard_indication_charging_time_wireless" msgid="577856646141738675">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando de manera inalámbrica • Se completará en <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time" msgid="6492711711891071502">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando • Se completará en <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando rápido • Se completará en <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> + <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carga rápida • Se completará en <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando lento • Se completará en <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar usuario"</string> <string name="accessibility_multi_user_switch_switcher_with_current" msgid="5759855008166759399">"Cambiar de usuario (usuario actual: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>)"</string> @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Agregar usuario"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Usuario nuevo"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"¿Quitar invitado?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán las aplicaciones y los datos de esta sesión."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Quitar"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"¡Hola de nuevo, invitado!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres retomar la sesión?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversación"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Presiona una conversación para agregarla a tu pantalla principal"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Vuelve a consultar cuando recibas algunos mensajes"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Conversaciones prioritarias"</string> <string name="recent_conversations" msgid="8531874684782574622">"Conversaciones recientes"</string> <string name="okay" msgid="6490552955618608554">"Aceptar"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g> o más"</string> <string name="people_tile_description" msgid="8154966188085545556">"Consulta mensajes recientes, llamadas perdidas y actualizaciones de estado"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversación"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Se detuvo por el modo No interrumpir"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> envió un mensaje"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> envió una imagen"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema al leer el medidor de batería"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 65648153e8f9..b5d1b22f6ffb 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Añadir usuario"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nuevo usuario"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"¿Quitar invitado?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán todas las aplicaciones y datos de esta sesión."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Quitar"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Hola de nuevo, invitado"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres continuar con la sesión?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversación"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Toca una conversación para añadirla a la pantalla de inicio"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Vuelve cuando recibas algún mensaje"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Conversaciones prioritarias"</string> <string name="recent_conversations" msgid="8531874684782574622">"Conversaciones recientes"</string> <string name="okay" msgid="6490552955618608554">"Vale"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Consulta los mensajes recientes, las llamadas perdidas y los cambios de estado"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversación"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Pausado por No molestar"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> ha enviado un mensaje"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ha enviado una imagen"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"No se ha podido leer el indicador de batería"</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 497845707e46..7d04f8157201 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Lisa kasutaja"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Uus kasutaja"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Kas eemaldada külaline?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Kas lähtestada külastajaseanss?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Seansi kõik rakendused ja andmed kustutatakse."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eemalda"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Lähtesta"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Tere tulemast tagasi, külaline!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Kas soovite seansiga jätkata?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Alusta uuesti"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Avage vestlus"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Vestlusvidinad"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Puudutage vestlust, et lisada see oma avakuvale"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Tulge tagasi, kui olete mõne sõnumi saanud"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Prioriteetsed vestlused"</string> <string name="recent_conversations" msgid="8531874684782574622">"Hiljutised vestlused"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Vaadake hiljutisi sõnumeid, vastamata kõnesid ja olekuvärskendusi"</string> <string name="people_tile_title" msgid="6589377493334871272">"Vestlus"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Peatas režiim Mitte segada"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> saatis sõnumi"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> saatis pildi"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Probleem akumõõdiku lugemisel"</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 6d8a8fdfad0c..633c91fa4c57 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Gehitu erabiltzaile bat"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Erabiltzaile berria"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Gonbidatua kendu nahi duzu?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Saioko aplikazio eta datu guztiak ezabatuko dira."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Kendu"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Ongi etorri berriro, gonbidatu hori!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Saioarekin jarraitu nahi duzu?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Hasi berriro"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Elkarrizketa irekia"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Elkarrizketa-widgetak"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Sakatu elkarrizketa bat hasierako pantailan gehitzeko"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Itzuli geroago, zenbait mezu jasotakoan"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Lehentasunezko elkarrizketak"</string> <string name="recent_conversations" msgid="8531874684782574622">"Azken elkarrizketak"</string> <string name="okay" msgid="6490552955618608554">"Ados"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Ikusi azken mezuak, dei galduak eta egoerari buruzko informazio eguneratua"</string> <string name="people_tile_title" msgid="6589377493334871272">"Elkarrizketa"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Ez molestatzeko moduak pausatu du"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzaileak mezu bat bidali du"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzaileak irudi bat bidali du"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Arazo bat gertatu da bateria-neurgailua irakurtzean"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index ce3e676db760..7420ad60ffed 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"افزودن کاربر"</string> <string name="user_new_user_name" msgid="2019166282704195789">"کاربر جدید"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"مهمان حذف شود؟"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"همه برنامهها و دادههای این جلسه حذف خواهد شد."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"حذف"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"مهمان گرامی، بازگشتتان را خوش آمد میگوییم!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"آیا میخواهید جلسهتان را ادامه دهید؟"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"شروع مجدد"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"باز کردن مکالمه"</string> <string name="select_conversation_title" msgid="6716364118095089519">"ابزارکهای مکالمه"</string> <string name="select_conversation_text" msgid="3376048251434956013">"روی مکالمهای ضربه بزنید تا به «صفحه اصلی» اضافه شود"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"بهمحض اینکه چند پیام دریافت کردید، به اینجا سربزنید"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"مکالمههای اولویتدار"</string> <string name="recent_conversations" msgid="8531874684782574622">"گفتگوهای اخیر"</string> <string name="okay" msgid="6490552955618608554">"تأیید"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"بیشاز <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="people_tile_description" msgid="8154966188085545556">"دیدن بهروزرسانیهای وضعیت، تماسهای بیپاسخ، و پیامهای اخیر"</string> <string name="people_tile_title" msgid="6589377493334871272">"مکالمه"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"با «مزاحم نشوید» موقتاً متوقف شده است"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> پیامی ارسال کرد"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> تصویری ارسال کرد"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"مشکلی در خواندن میزان باتری وجود دارد"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 90f47ef42a5a..8c546f7b456a 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Lisää käyttäjä"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Uusi käyttäjä"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Poistetaaanko vieras?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Kaikki sovellukset ja tämän istunnon tiedot poistetaan."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Poista"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Tervetuloa takaisin!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Haluatko jatkaa istuntoa?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Aloita alusta"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Avaa keskustelu"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Keskusteluwidgetit"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Lisää keskustelu aloitusnäytölle napauttamalla sitä"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Palaa taas tänne, kun olet saanut viestejä"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Tärkeät keskustelut"</string> <string name="recent_conversations" msgid="8531874684782574622">"Uusimmat keskustelut"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Yli <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="people_tile_description" msgid="8154966188085545556">"Katso viimeaikaiset viestit, vastaamattomat puhelut ja tilapäivitykset"</string> <string name="people_tile_title" msgid="6589377493334871272">"Keskustelu"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Älä häiritse ‑tilan keskeyttämä"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> lähetti viestin"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> lähetti kuvan"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Ongelma akkumittarin lukemisessa"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 030428034545..a6987f4bb5cc 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -349,7 +349,7 @@ <string name="quick_settings_rotation_locked_portrait_label" msgid="1194988975270484482">"Portrait"</string> <string name="quick_settings_rotation_locked_landscape_label" msgid="2000295772687238645">"Paysage"</string> <string name="quick_settings_ime_label" msgid="3351174938144332051">"Mode de saisie"</string> - <string name="quick_settings_location_label" msgid="2621868789013389163">"Position"</string> + <string name="quick_settings_location_label" msgid="2621868789013389163">"Localisation"</string> <string name="quick_settings_location_off_label" msgid="7923929131443915919">"Localisation désactivée"</string> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Accès à l\'appareil photo"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Accès au micro"</string> @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Ajouter un utilisateur"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nouvel utilisateur"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Supprimer l\'invité?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Supprimer"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bienvenue à nouveau dans la session Invité"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recommencer"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Ouvrir la conversation"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversation"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Touchez une conversation pour l\'ajouter à votre écran d\'accueil"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Revenez ici quand vous aurez reçu des messages"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Conversations prioritaires"</string> <string name="recent_conversations" msgid="8531874684782574622">"Conversations récentes"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Affichez les messages récents, les appels manqués et les mises à jour d\'état"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Interrompues par la fonctionnalité Ne pas déranger"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé un message"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé une image"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Un problème est survenu lors de la lecture du niveau de charge de la pile"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index c4022611f897..d67cac4a1e34 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Ajouter un utilisateur"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nouvel utilisateur"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Supprimer l\'invité ?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Supprimer"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bienvenue à nouveau dans la session Invité"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la dernière session ?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Non, nouvelle session"</string> @@ -737,8 +733,8 @@ <string name="notification_automatic_title" msgid="3745465364578762652">"Automatique"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Aucun son ni vibration"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Aucun son ni vibration, s\'affiche plus bas dans la section des conversations"</string> - <string name="notification_channel_summary_default" msgid="3282930979307248890">"Peut sonner ou vibrer en fonction des paramètres du téléphone"</string> - <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Peut sonner ou vibrer en fonction des paramètres du téléphone. Les conversations provenant de <xliff:g id="APP_NAME">%1$s</xliff:g> s\'affichent sous forme de bulles par défaut."</string> + <string name="notification_channel_summary_default" msgid="3282930979307248890">"Son ou vibreur, selon les paramètres du téléphone"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Son ou vibreur, selon les paramètres du téléphone. Les conversations provenant de <xliff:g id="APP_NAME">%1$s</xliff:g> s\'affichent sous forme de bulles par défaut."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Attire votre attention à l\'aide d\'un raccourci flottant vers ce contenu."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Laisser le système déterminer si cette notification doit être accompagnée d\'un son ou d\'une vibration"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>État :</b> Élevée à la catégorie \"Par défaut\""</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Conversation ouverte"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversation"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Appuyez sur une conversation pour l\'ajouter à votre écran d\'accueil"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Revenez quand vous aurez reçu des messages"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Conversations prioritaires"</string> <string name="recent_conversations" msgid="8531874684782574622">"Conversations récentes"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+ de <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="people_tile_description" msgid="8154966188085545556">"Voir les messages récents, les appels manqués et les notifications d\'état"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversation"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Mise en pause par Ne pas déranger"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé un message"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> a envoyé une image"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Un problème est survenu au niveau de la lecture de votre outil de mesure de batterie"</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index e7b3e925d5e2..5f47203e0a3f 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Engadir usuario"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Novo usuario"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Queres quitar o convidado?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Eliminaranse todas as aplicacións e datos desta sesión."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Quitar"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Benvido de novo, convidado"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Queres continuar coa túa sesión?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Comezar de novo"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Toca unha conversa para engadila á pantalla de inicio"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Volve aquí despois de recibir mensaxes"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Conversas prioritarias"</string> <string name="recent_conversations" msgid="8531874684782574622">"Conversas recentes"</string> <string name="okay" msgid="6490552955618608554">"De acordo"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+ de <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="people_tile_description" msgid="8154966188085545556">"Consulta as mensaxes recentes, as chamadas perdidas e as actualizacións dos estados"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversa"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Púxose en pausa debido ao modo Non molestar"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> enviou unha mensaxe"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou unha imaxe"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Produciuse un problema ao ler o medidor da batería"</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index a99558e4d84e..3f4d524428f7 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"વપરાશકર્તા ઉમેરો"</string> <string name="user_new_user_name" msgid="2019166282704195789">"નવો વપરાશકર્તા"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"અતિથિ દૂર કરીએ?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"અતિથિ સત્રને રીસેટ કરીએ?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"આ સત્રમાંની તમામ ઍપ અને ડેટા કાઢી નાખવામાં આવશે."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"દૂર કરો"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"રીસેટ કરો"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"ફરી સ્વાગત છે, અતિથિ!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"શું તમે તમારું સત્ર ચાલુ રાખવા માંગો છો?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"શરૂ કરો"</string> @@ -1036,8 +1034,7 @@ <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"સ્ક્રીનનો કોઈ ભાગ મોટો કરો"</string> <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"સ્વિચ"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"ઍક્સેસિબિલિટી સંકેતને ઍક્સેસિબિલિટી બટન વડે બદલવામાં આવ્યા છે\n\n"<annotation id="link">"સેટિંગ જુઓ"</annotation></string> - <!-- no translation found for accessibility_floating_button_switch_migration_tooltip (6248529129221218770) --> - <skip /> + <string name="accessibility_floating_button_switch_migration_tooltip" msgid="6248529129221218770">"તમે ઍક્સેસિબિલિટી સંકેત પરથી કોઈ બટન પર સ્વિચ કરી શકો છો\n\n"<annotation id="link">"સેટિંગ"</annotation></string> <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"તેને હંગામી રૂપે ખસેડવા માટે બટનને કિનારી પર ખસેડો"</string> <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"ઉપર ડાબે ખસેડો"</string> <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"ઉપર જમણે ખસેડો"</string> @@ -1118,7 +1115,7 @@ <string name="basic_status" msgid="2315371112182658176">"વાતચીત ખોલો"</string> <string name="select_conversation_title" msgid="6716364118095089519">"વાતચીતના વિજેટ"</string> <string name="select_conversation_text" msgid="3376048251434956013">"તમારી હોમ સ્ક્રીનમાં વાતચીત ઉમેરવા માટે તેના પર ટૅપ કરો"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"એકવાર તમને અમુક સંદેશા મળે પછી ફરીથી અહીં ચેક કરો"</string> + <string name="no_conversations_text" msgid="5354115541282395015">"તમારી તાજેતરની વાતચીતો અહીં બતાવવામાં આવશે"</string> <string name="priority_conversations" msgid="3967482288896653039">"પ્રાધાન્યતા ધરાવતી વાતચીતો"</string> <string name="recent_conversations" msgid="8531874684782574622">"તાજેતરની વાતચીતો"</string> <string name="okay" msgid="6490552955618608554">"ઓકે"</string> @@ -1147,6 +1144,8 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"તાજેતરના સંદેશા, ચૂકી ગયેલા કૉલ અને સ્ટેટસ અપડેટ જુઓ"</string> <string name="people_tile_title" msgid="6589377493334871272">"વાતચીત"</string> + <!-- no translation found for paused_by_dnd (7856941866433556428) --> + <skip /> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા કોઈ સંદેશ મોકલવામાં આવ્યો"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> દ્વારા કોઈ છબી મોકલવામાં આવી"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"તમારું બૅટરી મીટર વાંચવામાં સમસ્યા આવી"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 4196b1f41d86..47a98204e116 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"उपयोगकर्ता जोड़ें"</string> <string name="user_new_user_name" msgid="2019166282704195789">"नया उपयोगकर्ता"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"क्या आप मेहमान को हटाना चाहते हैं?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"इस सत्र के सभी ऐप्लिकेशन और डेटा को हटा दिया जाएगा."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"निकालें"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"मेहमान, आपका फिर से स्वागत है!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"क्या आप अपना सत्र जारी रखना चाहते हैं?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"फिर से शुरू करें"</string> @@ -732,7 +728,7 @@ <string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"सूचना देना जारी रखें"</string> <string name="inline_turn_off_notifications" msgid="8543989584403106071">"सूचनाएं बंद करें"</string> <string name="inline_keep_showing_app" msgid="4393429060390649757">"इस ऐप्लिकेशन से जुड़ी सूचनाएं दिखाना जारी रखें?"</string> - <string name="notification_silence_title" msgid="8608090968400832335">"आवाज़ के बिना सूचनाएं दिखाएं"</string> + <string name="notification_silence_title" msgid="8608090968400832335">"बिना आवाज़ के सूचनाएं दिखाएं"</string> <string name="notification_alert_title" msgid="3656229781017543655">"डिफ़ॉल्ट"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"अपने-आप"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"किसी तरह की आवाज़ या वाइब्रेशन न हो"</string> @@ -1119,7 +1115,7 @@ <string name="basic_status" msgid="2315371112182658176">"ऐसी बातचीत जिसमें इंटरैक्शन डेटा मौजूद नहीं है"</string> <string name="select_conversation_title" msgid="6716364118095089519">"बातचीत विजेट"</string> <string name="select_conversation_text" msgid="3376048251434956013">"किसी बातचीत को होम स्क्रीन पर जोड़ने के लिए, उस बातचीत पर टैप करें"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"नए मैसेज आने पर यहां देखें"</string> + <string name="no_conversations_text" msgid="5354115541282395015">"हाल ही में हुई बातचीत यहां दिखेंगी"</string> <string name="priority_conversations" msgid="3967482288896653039">"प्राथमिकता वाली बातचीत"</string> <string name="recent_conversations" msgid="8531874684782574622">"हाल ही में की गई बातचीत"</string> <string name="okay" msgid="6490552955618608554">"ठीक है"</string> @@ -1148,6 +1144,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"हाल के मैसेज, मिस्ड कॉल, और स्टेटस अपडेट देखें"</string> <string name="people_tile_title" msgid="6589377493334871272">"बातचीत"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"\'परेशान न करें\' की वजह से सूचनाएं नहीं दिख रहीं"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> ने एक मैसेज भेजा है"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ने एक इमेज भेजी है"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"आपके डिवाइस के बैटरी मीटर की रीडिंग लेने में समस्या आ रही है"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index abbbae7985d4..ee13344fdcf5 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -482,10 +482,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Dodavanje korisnika"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Novi korisnik"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ukloniti gosta?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Poništiti gostujuću sesiju?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji bit će izbrisani."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ukloni"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Poništi"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Dobro došli natrag, gostu!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string> @@ -1123,7 +1121,8 @@ <string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widgeti razgovora"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Dodirnite razgovor da biste ga dodali na početni zaslon"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Ponovno provjerite ovdje kad dobijete poruke"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Prioritetni razgovori"</string> <string name="recent_conversations" msgid="8531874684782574622">"Nedavni razgovori"</string> <string name="okay" msgid="6490552955618608554">"U redu"</string> @@ -1152,6 +1151,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Pogledajte nedavne poruke, propuštene pozive i ažuriranja statusa"</string> <string name="people_tile_title" msgid="6589377493334871272">"Razgovor"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Pauzirala značajka Ne uznemiravaj"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"Korisnik <xliff:g id="NAME">%1$s</xliff:g> šalje poruku"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"Korisnik <xliff:g id="NAME">%1$s</xliff:g> poslao je sliku"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem s očitavanjem mjerača baterije"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 15106bb4c157..fae365d2cbf7 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Felhasználó hozzáadása"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Új felhasználó"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Eltávolítja a vendég munkamenetet?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Visszaállítja a vendég munkamenetet?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"A munkamenetben található összes alkalmazás és adat törlődni fog."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Eltávolítás"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Visszaállítás"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Örülünk, hogy visszatért, vendég!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Folytatja a munkamenetet?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Újrakezdés"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Beszélgetés megnyitása"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Beszélgetési modulok"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Koppintson a kívánt beszélgetésre a kezdőképernyőre való felvételhez"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Térjen vissza ide, miután kapott néhány üzenetet"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Fontos beszélgetések"</string> <string name="recent_conversations" msgid="8531874684782574622">"Legutóbbi beszélgetések"</string> <string name="okay" msgid="6490552955618608554">"Rendben"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Megtekintheti a legutóbbi üzeneteket, a nem fogadott hívásokat és az állapotfrissítéseket."</string> <string name="people_tile_title" msgid="6589377493334871272">"Beszélgetés"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"A Ne zavarjanak mód által szüneteltetve"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> üzenetet küldött"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> képet küldött"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Probléma merült fel az akkumulátor-töltésmérő olvasásakor"</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 2e2141ee075c..2063d43d48ec 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Ավելացնել օգտատեր"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Նոր օգտատեր"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Հեռացնե՞լ հյուրին"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Վերակայե՞լ հյուրի աշխատաշրջանը"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Այս աշխատաշրջանի բոլոր ծրագրերն ու տվյալները կջնջվեն:"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Հեռացնել"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Վերակայել"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Բարի վերադարձ, հյուր"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Շարունակե՞լ աշխատաշրջանը։"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Վերսկսել"</string> @@ -1117,7 +1115,7 @@ <string name="basic_status" msgid="2315371112182658176">"Բաց զրույց"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Զրույցի վիջեթներ"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Հպեք զրույցին՝ այն հիմնական էկրանին ավելացնելու համար"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Վերադարձեք այստեղ, երբ հաղորդագրություններ ստանաք"</string> + <string name="no_conversations_text" msgid="5354115541282395015">"Ձեր վերջին զրույցները կցուցադրվեն այստեղ"</string> <string name="priority_conversations" msgid="3967482288896653039">"Կարևոր զրույցներ"</string> <string name="recent_conversations" msgid="8531874684782574622">"Վերջին հաղորդագրությունները"</string> <string name="okay" msgid="6490552955618608554">"Եղավ"</string> @@ -1146,6 +1144,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Տեսեք վերջին հաղորդագրությունները, բաց թողնված զանգերը և կարգավիճակի մասին թարմացումները"</string> <string name="people_tile_title" msgid="6589377493334871272">"Զրույց"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Դադարեցվել է «Չանհանգստացնել» գործառույթի կողմից"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> օգտատերը հաղորդագրություն է ուղարկել"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> օգտատերը պատկեր է ուղարկել"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Մարտկոցի ցուցիչի ցուցմունքը կարդալու հետ կապված խնդիր կա"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 53a3165776fd..7da7482cc2bc 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Tambahkan pengguna"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Pengguna baru"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Hapus tamu?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Reset sesi tamu?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua aplikasi dan data di sesi ini akan dihapus."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Hapus"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Reset"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Selamat datang kembali, tamu!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Lanjutkan sesi Anda?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulai ulang"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Membuka percakapan"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widget Percakapan"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Ketuk percakapan untuk menambahkannya ke Layar utama"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Periksa kembali setelah Anda mendapatkan pesan"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Percakapan prioritas"</string> <string name="recent_conversations" msgid="8531874684782574622">"Percakapan terbaru"</string> <string name="okay" msgid="6490552955618608554">"Oke"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Lihat pesan terbaru, panggilan tak terjawab, dan pembaruan status"</string> <string name="people_tile_title" msgid="6589377493334871272">"Percakapan"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Dijeda oleh fitur Jangan Ganggu"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> mengirim pesan"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> mengirim gambar"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Terjadi masalah saat membaca indikator baterai"</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 01bad1c1ce90..a996cb11c7bb 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Bæta notanda við"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nýr notandi"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Fjarlægja gest?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Öllum forritum og gögnum í þessari lotu verður eytt."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjarlægja"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkominn aftur, gestur!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Viltu halda áfram með lotuna?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Byrja upp á nýtt"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Opna samtal"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Samtalsgræjur"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Ýttu á samtal til að bæta því á heimaskjáinn"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Komdu aftur hingað þegar þú hefur fengið skilaboð"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Forgangssamtöl"</string> <string name="recent_conversations" msgid="8531874684782574622">"Nýleg samtöl"</string> <string name="okay" msgid="6490552955618608554">"Í lagi"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Sjá nýleg skilboð, ósvöruð símtöl og stöðuuppfærslur"</string> <string name="people_tile_title" msgid="6589377493334871272">"Samtal"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Sett í bið af „Ónáðið ekki“"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> sendi skilaboð"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> sendi mynd"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Vandamál við að lesa stöðu rafhlöðu"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 454b5bba4a49..8cdc484e47dd 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Aggiungi utente"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nuovo utente"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Rimuovere l\'ospite?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Reimpostare sessione Ospite?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tutte le app e i dati di questa sessione verranno eliminati."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Rimuovi"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Reimposta"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Ti ridiamo il benvenuto alla sessione Ospite."</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vuoi continuare la sessione?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Ricomincia"</string> @@ -736,7 +734,7 @@ <string name="notification_channel_summary_low" msgid="4860617986908931158">"Nessun suono o vibrazione"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Nessun suono o vibrazione e appare più in basso nella sezione delle conversazioni"</string> <string name="notification_channel_summary_default" msgid="3282930979307248890">"Può suonare o vibrare in base alle impostazioni del telefono"</string> - <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Può suonare o vibrare in base alle impostazioni del telefono. Conversazioni dalla bolla <xliff:g id="APP_NAME">%1$s</xliff:g> per impostazione predefinita."</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"Può suonare o vibrare in base alle impostazioni del telefono. Le conversazioni di <xliff:g id="APP_NAME">%1$s</xliff:g> appaiono come bolla per impostazione predefinita."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Mantiene la tua attenzione con una scorciatoia mobile a questi contenuti."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Fai stabilire al sistema se questa notifica deve emettere suoni o vibrazioni"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>Stato:</b> promossa a Predefinita"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Apri conversazione"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widget di conversazione"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Tocca una conversazione per aggiungerla alla schermata Home"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Torna qui quando avrai ricevuto qualche messaggio"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Conversazioni prioritarie"</string> <string name="recent_conversations" msgid="8531874684782574622">"Conversazioni recenti"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+<xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="people_tile_description" msgid="8154966188085545556">"Visualizza messaggi recenti, chiamate senza risposta e aggiornamenti dello stato"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversazione"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"In pausa in base alla modalità Non disturbare"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> ha inviato un messaggio"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ha inviato un\'immagine"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema durante la lettura dell\'indicatore di livello della batteria"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 32c386d9993e..75a9d753323f 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -484,12 +484,8 @@ <string name="user_add_user" msgid="4336657383006913022">"הוספת משתמש"</string> <string name="user_new_user_name" msgid="2019166282704195789">"משתמש חדש"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"להסיר אורח?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"כל האפליקציות והנתונים בסשן הזה יימחקו."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"הסרה"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"שמחים לראותך שוב!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"האם ברצונך להמשיך בפעילות באתר?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"סשן חדש"</string> @@ -754,7 +750,7 @@ <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"מוצגת בחלק העליון של קטע ההתראות וכתמונת פרופיל במסך הנעילה"</string> <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"מוצגת בחלק העליון של קטע התראות השיחה וכתמונת פרופיל במסך הנעילה, מופיעה בבועה"</string> <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"מוצגת בחלק העליון של קטע התראות השיחה וכתמונת פרופיל במסך הנעילה, מפריעה במצב \'נא לא להפריע\'"</string> - <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"מוצגת בחלק העליון של קטע התראות השיחה וכתמונת פרופיל במסך הנעילה, מופיעה בבועה הצפה ומפריעה במצב \'נא לא להפריע\'"</string> + <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"מוצגת בחלק העליון של קטע התראות השיחה וכתמונת פרופיל במסך הנעילה, מופיעה בבועה צפה ומפריעה במצב \'נא לא להפריע\'"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"הגדרות"</string> <string name="notification_priority_title" msgid="2079708866333537093">"בעדיפות גבוהה"</string> <string name="no_shortcut" msgid="8257177117568230126">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> לא תומכת בתכונות השיחה"</string> @@ -1131,7 +1127,8 @@ <string name="basic_status" msgid="2315371112182658176">"פתיחת שיחה"</string> <string name="select_conversation_title" msgid="6716364118095089519">"ווידג\'טים של שיחות"</string> <string name="select_conversation_text" msgid="3376048251434956013">"יש להקיש על שיחה כדי להוסיף אותה למסך הבית"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"אפשר לחזור לכאן ולהתעדכן לאחר קבלת מספר הודעות"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"שיחות בעדיפות גבוהה"</string> <string name="recent_conversations" msgid="8531874684782574622">"שיחות אחרונות"</string> <string name="okay" msgid="6490552955618608554">"בסדר"</string> @@ -1160,6 +1157,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"ההודעות האחרונות, שיחות שלא נענו ועדכוני סטטוס"</string> <string name="people_tile_title" msgid="6589377493334871272">"שיחה"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"ההתראה הושהתה על ידי \'נא לא להפריע\'"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> שלח/ה הודעה"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> שלח/ה תמונה"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"בעיה בקריאת מדדי הסוללה"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index dacdf2146540..065167a2e7c0 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -190,12 +190,12 @@ <string name="accessibility_compatibility_zoom_example" msgid="2617218726091234073">"小さい画面から大きい画面に拡大。"</string> <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetoothに接続済み。"</string> <string name="accessibility_bluetooth_disconnected" msgid="7195823280221275929">"Bluetoothが切断されました。"</string> - <string name="accessibility_no_battery" msgid="3789287732041910804">"電池残量:なし"</string> - <string name="accessibility_battery_one_bar" msgid="8868347318237585329">"電池残量:レベル1"</string> - <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"電池残量:レベル2"</string> - <string name="accessibility_battery_three_bars" msgid="118341923832368291">"電池残量:レベル3"</string> - <string name="accessibility_battery_full" msgid="1480463938961288494">"電池残量:満"</string> - <string name="accessibility_battery_unknown" msgid="1807789554617976440">"電池残量は不明です。"</string> + <string name="accessibility_no_battery" msgid="3789287732041910804">"バッテリー残量: なし"</string> + <string name="accessibility_battery_one_bar" msgid="8868347318237585329">"バッテリー残量: レベル1"</string> + <string name="accessibility_battery_two_bars" msgid="7895789999668425551">"バッテリー残量: レベル2"</string> + <string name="accessibility_battery_three_bars" msgid="118341923832368291">"バッテリー残量: レベル3"</string> + <string name="accessibility_battery_full" msgid="1480463938961288494">"バッテリー残量: フル"</string> + <string name="accessibility_battery_unknown" msgid="1807789554617976440">"バッテリー残量は不明です。"</string> <string name="accessibility_wifi_name" msgid="4863440268606851734">"<xliff:g id="WIFI">%s</xliff:g>に接続しました。"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>に接続しました。"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>に接続されています。"</string> @@ -227,8 +227,8 @@ <string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN は ON です。"</string> <string name="accessibility_no_sims" msgid="5711270400476534667">"SIMカードが挿入されていません。"</string> <string name="accessibility_battery_details" msgid="6184390274150865789">"電池の詳細情報を開きます"</string> - <string name="accessibility_battery_level" msgid="5143715405241138822">"電池残量: <xliff:g id="NUMBER">%d</xliff:g>パーセント"</string> - <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"電池残量: <xliff:g id="PERCENTAGE">%1$s</xliff:g>、およそ <xliff:g id="TIME">%2$s</xliff:g> に電池切れ(使用状況に基づく)"</string> + <string name="accessibility_battery_level" msgid="5143715405241138822">"バッテリー残量: <xliff:g id="NUMBER">%d</xliff:g>パーセント"</string> + <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"バッテリー残量: <xliff:g id="PERCENTAGE">%1$s</xliff:g>、およそ <xliff:g id="TIME">%2$s</xliff:g> にバッテリー切れ(使用状況に基づく)"</string> <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"電池充電中: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>パーセント"</string> <string name="accessibility_settings_button" msgid="2197034218538913880">"システム設定。"</string> <string name="accessibility_notifications_button" msgid="3960913924189228831">"通知。"</string> @@ -255,7 +255,7 @@ <string name="accessibility_quick_settings_wifi_changed_off" msgid="2230487165558877262">"Wi-FiをOFFにしました。"</string> <string name="accessibility_quick_settings_wifi_changed_on" msgid="1490362586009027611">"Wi-FiをONにしました。"</string> <string name="accessibility_quick_settings_mobile" msgid="1817825313718492906">"モバイル: <xliff:g id="SIGNAL">%1$s</xliff:g>、<xliff:g id="TYPE">%2$s</xliff:g>、<xliff:g id="NETWORK">%3$s</xliff:g>"</string> - <string name="accessibility_quick_settings_battery" msgid="533594896310663853">"電池<xliff:g id="STATE">%s</xliff:g>"</string> + <string name="accessibility_quick_settings_battery" msgid="533594896310663853">"バッテリー<xliff:g id="STATE">%s</xliff:g>"</string> <string name="accessibility_quick_settings_airplane_off" msgid="1275658769368793228">"機内モードがOFFです。"</string> <string name="accessibility_quick_settings_airplane_on" msgid="8106176561295294255">"機内モードがONです。"</string> <string name="accessibility_quick_settings_airplane_changed_off" msgid="8880183481476943754">"機内モードをOFFにしました。"</string> @@ -335,7 +335,7 @@ <string name="quick_settings_bluetooth_multiple_devices_label" msgid="6595808498429809855">"Bluetooth(デバイス数<xliff:g id="NUMBER">%d</xliff:g>)"</string> <string name="quick_settings_bluetooth_off_label" msgid="6375098046500790870">"Bluetooth OFF"</string> <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"ペア設定されたデバイスがありません"</string> - <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> + <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"バッテリー <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"オーディオ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ヘッドセット"</string> <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"入力"</string> @@ -414,7 +414,7 @@ <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"日の出まで"</string> <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"<xliff:g id="TIME">%s</xliff:g> に ON"</string> <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"<xliff:g id="TIME">%s</xliff:g> まで"</string> - <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"ダークテーマ"</string> + <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"ダークモード"</string> <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"バッテリー セーバー"</string> <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"日の入りに ON"</string> <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"日の出まで"</string> @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"ユーザーを追加"</string> <string name="user_new_user_name" msgid="2019166282704195789">"新しいユーザー"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ゲストを削除しますか?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"ゲストをリセットしますか?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"このセッションでのアプリとデータはすべて削除されます。"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"削除"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"リセット"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"おかえりなさい、ゲストさん"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"セッションを続行しますか?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"最初から開始"</string> @@ -657,8 +655,8 @@ <string name="output_service_wifi" msgid="9003667810868222134">"Wi-Fi"</string> <string name="output_service_bt_wifi" msgid="7186882540475524124">"Bluetooth と Wi-Fi"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"システムUI調整ツール"</string> - <string name="show_battery_percentage" msgid="6235377891802910455">"内蔵電池の残量の割合を表示する"</string> - <string name="show_battery_percentage_summary" msgid="9053024758304102915">"充電していないときには電池残量の割合をステータスバーアイコンに表示する"</string> + <string name="show_battery_percentage" msgid="6235377891802910455">"内蔵バッテリーの残量の割合を表示する"</string> + <string name="show_battery_percentage_summary" msgid="9053024758304102915">"充電していないときにはバッテリー残量の割合をステータスバーアイコンに表示する"</string> <string name="quick_settings" msgid="6211774484997470203">"クイック設定"</string> <string name="status_bar" msgid="4357390266055077437">"ステータスバー"</string> <string name="overview" msgid="3522318590458536816">"最近"</string> @@ -695,7 +693,7 @@ <string name="remove_from_settings_prompt" msgid="551565437265615426">"設定からシステムUI調整ツールを削除して、全機能の使用を停止しますか?"</string> <string name="activity_not_found" msgid="8711661533828200293">"アプリがデバイスにインストールされていません"</string> <string name="clock_seconds" msgid="8709189470828542071">"時計の秒を表示"</string> - <string name="clock_seconds_desc" msgid="2415312788902144817">"ステータスバーに時計の秒を表示します。電池使用量に影響する可能性があります。"</string> + <string name="clock_seconds_desc" msgid="2415312788902144817">"ステータスバーに時計の秒を表示します。バッテリー使用量に影響する可能性があります。"</string> <string name="qs_rearrange" msgid="484816665478662911">"クイック設定を並べ替え"</string> <string name="show_brightness" msgid="6700267491672470007">"クイック設定に明るさ調整バーを表示する"</string> <string name="experimental" msgid="3549865454812314826">"試験運用版"</string> @@ -852,7 +850,7 @@ <string name="volume_and_do_not_disturb" msgid="502044092739382832">"サイレント モード"</string> <string name="volume_dnd_silent" msgid="4154597281458298093">"音量ボタンのショートカット"</string> <string name="volume_up_silent" msgid="1035180298885717790">"音量大ボタンでサイレント モードを OFF にします"</string> - <string name="battery" msgid="769686279459897127">"電池"</string> + <string name="battery" msgid="769686279459897127">"バッテリー"</string> <string name="clock" msgid="8978017607326790204">"時計"</string> <string name="headset" msgid="4485892374984466437">"ヘッドセット"</string> <string name="accessibility_long_click_tile" msgid="210472753156768705">"設定を開く"</string> @@ -961,7 +959,7 @@ <string name="tuner_menu" msgid="363690665924769420">"メニュー"</string> <string name="tuner_app" msgid="6949280415826686972">"<xliff:g id="APP">%1$s</xliff:g> アプリ"</string> <string name="notification_channel_alerts" msgid="3385787053375150046">"アラート"</string> - <string name="notification_channel_battery" msgid="9219995638046695106">"電池"</string> + <string name="notification_channel_battery" msgid="9219995638046695106">"バッテリー"</string> <string name="notification_channel_screenshot" msgid="7665814998932211997">"スクリーンショット"</string> <string name="notification_channel_general" msgid="4384774889645929705">"一般メッセージ"</string> <string name="notification_channel_storage" msgid="2720725707628094977">"ストレージ"</string> @@ -985,7 +983,7 @@ <string name="qs_dnd_keep" msgid="3829697305432866434">"設定を維持"</string> <string name="qs_dnd_replace" msgid="7712119051407052689">"設定を変更"</string> <string name="running_foreground_services_title" msgid="5137313173431186685">"バックグラウンドで実行中のアプリ"</string> - <string name="running_foreground_services_msg" msgid="3009459259222695385">"タップして電池やデータの使用量を確認"</string> + <string name="running_foreground_services_msg" msgid="3009459259222695385">"タップしてバッテリーやデータの使用量を確認"</string> <string name="mobile_data_disable_title" msgid="5366476131671617790">"モバイルデータを OFF にしますか?"</string> <string name="mobile_data_disable_message" msgid="8604966027899770415">"<xliff:g id="CARRIER">%s</xliff:g>でデータやインターネットにアクセスできなくなります。インターネットには Wi-Fi からのみ接続できます。"</string> <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"携帯通信会社"</string> @@ -1117,7 +1115,7 @@ <string name="basic_status" msgid="2315371112182658176">"空の会話"</string> <string name="select_conversation_title" msgid="6716364118095089519">"会話ウィジェット"</string> <string name="select_conversation_text" msgid="3376048251434956013">"会話をタップするとホーム画面に追加されます"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"メッセージを受信すると、ここに表示されます"</string> + <string name="no_conversations_text" msgid="5354115541282395015">"最近の会話がここに表示されます"</string> <string name="priority_conversations" msgid="3967482288896653039">"優先度の高い会話"</string> <string name="recent_conversations" msgid="8531874684782574622">"最近の会話"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1146,9 +1144,10 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g> 件以上"</string> <string name="people_tile_description" msgid="8154966188085545556">"最近のメッセージ、不在着信、最新のステータスが表示されます"</string> <string name="people_tile_title" msgid="6589377493334871272">"会話"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"サイレント モードにより一時停止"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> さんからメッセージが届きました"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> さんが画像を送信しました"</string> - <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"電池残量の読み込み中に問題が発生しました"</string> + <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"バッテリー残量の読み込み中に問題が発生しました"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"タップすると詳細が表示されます"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"アラーム未設定"</string> <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"指紋認証センサー"</string> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 06af42adff22..dd66db3988c7 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"მომხმარებლის დამატება"</string> <string name="user_new_user_name" msgid="2019166282704195789">"ახალი მომხმარებელი"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"სტუმრის ამოშლა?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"გადაყენდეს სტუმარი?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ამ სესიის ყველა აპი და მონაცემი წაიშლება."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ამოშლა"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"გადაყენება"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"სტუმარო, გვიხარია, რომ დაბრუნდით!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"გსურთ, თქვენი სესიის გაგრძელება?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ხელახლა დაწყება"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"მიმოწერის გახსნა"</string> <string name="select_conversation_title" msgid="6716364118095089519">"საუბრის ვიჯეტები"</string> <string name="select_conversation_text" msgid="3376048251434956013">"შეეხეთ საუბარს მის თქვენს მთავარ ეკრანზე დასამატებლად"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"შეამოწმეთ ეს სივრცე, როცა რაღაც რაოდენობის შეტყობინებებს მიიღებთ"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"პრიორიტეტული საუბრები"</string> <string name="recent_conversations" msgid="8531874684782574622">"ბოლო მიმოწერები"</string> <string name="okay" msgid="6490552955618608554">"კარგი"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"ბოლოდროინდელი შეტყობინებების, გამოტოვებული ზარების და სტატუსის განახლებების ნახვა"</string> <string name="people_tile_title" msgid="6589377493334871272">"მიმოწერა"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"დაპაუზებულია ფუნქციის „არ შემაწუხოთ“ მიერ"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g>-მ(ა) შეტყობინება გამოგზავნა"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>-მ(ა) სურათი გამოგზავნა"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"თქვენი ბატარეის მზომის წაკითხვასთან დაკავშირებით პრობლემა დაფიქსირდა"</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 8366b2f48927..c6a9e9a1e290 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Пайдаланушы қосу"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Жаңа пайдаланушы"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Қонақты жою керек пе?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Қонақ сеансы бастапқы күйге қайтарылсын ба?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Осы сеанстағы барлық қолданбалар мен деректер жойылады."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Алып тастау"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Бастапқы күйге қайтару"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Қош келдіңіз, қонақ!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансты жалғастыру керек пе?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Қайта бастау"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Ашық әңгіме"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Әңгіме виджеттері"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Негізгі экранға қосқыңыз келетін әңгімені түртіңіз."</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Хабарлар алғаннан кейін осында оралыңыз."</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Маңызды әңгімелер"</string> <string name="recent_conversations" msgid="8531874684782574622">"Соңғы әңгімелер"</string> <string name="okay" msgid="6490552955618608554">"Жарайды"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Соңғы хабарларды, өткізіп алған қоңыраулар мен жаңартылған күйлерді көруге болады."</string> <string name="people_tile_title" msgid="6589377493334871272">"Әңгіме"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"\"Мазаламау\" режимі арқылы кідіртілді."</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> хабар жіберді."</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> сурет жіберді."</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Батарея зарядының дерегі алынбай жатыр"</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 3baa4e1411f1..7a586cd7bc45 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"បញ្ចូលអ្នកប្រើ"</string> <string name="user_new_user_name" msgid="2019166282704195789">"អ្នកប្រើថ្មី"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ដកភ្ញៀវចេញឬ?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"កំណត់ភ្ញៀវឡើងវិញឬ?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"កម្មវិធី និងទិន្នន័យទាំងអស់ក្នុងវគ្គនេះនឹងត្រូវលុប។"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ដកចេញ"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"កំណត់ឡើងវិញ"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"សូមស្វាគមន៍ការត្រឡប់មកវិញ, ភ្ញៀវ!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"តើអ្នកចង់បន្តវគ្គរបស់អ្នកទេ?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ចាប់ផ្ដើមសាជាថ្មី"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"បើកការសន្ទនា"</string> <string name="select_conversation_title" msgid="6716364118095089519">"ធាតុក្រាហ្វិកនៃការសន្ទនា"</string> <string name="select_conversation_text" msgid="3376048251434956013">"ចុចការសន្ទនា ដើម្បីបញ្ចូលវាទៅក្នុងអេក្រង់ដើមរបស់អ្នក"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"ត្រឡប់មកមើលនៅទីនេះវិញ នៅពេលអ្នកទទួលបានសារមួយចំនួន"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"ការសន្ទនាអាទិភាព"</string> <string name="recent_conversations" msgid="8531874684782574622">"ការសន្ទនាថ្មីៗ"</string> <string name="okay" msgid="6490552955618608554">"យល់ព្រម"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"មើលព័ត៌មានថ្មីៗអំពីស្ថានភាព ការខកខានទទួល និងសារថ្មីៗ"</string> <string name="people_tile_title" msgid="6589377493334871272">"ការសន្ទនា"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"បានផ្អាកដោយមុខងារកុំរំខាន"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> បានផ្ញើសារ"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> បានផ្ញើរូបភាព"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"មានបញ្ហាក្នុងការអានឧបករណ៍រង្វាស់កម្រិតថ្មរបស់អ្នក"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 0b21c0f37010..41b6c44c6e1b 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿ"</string> <string name="user_new_user_name" msgid="2019166282704195789">"ಹೊಸ ಬಳಕೆದಾರರು"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕುವುದೇ?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ಈ ಸೆಷನ್ನಲ್ಲಿನ ಎಲ್ಲ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ತೆಗೆದುಹಾಕಿ"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"ಮತ್ತೆ ಸುಸ್ವಾಗತ, ಅತಿಥಿ!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"ನಿಮ್ಮ ಸೆಷನ್ ಮುಂದುವರಿಸಲು ಇಚ್ಚಿಸುವಿರಾ?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ಪ್ರಾರಂಭಿಸಿ"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"ಸಂಭಾಷಣೆಯನ್ನು ತೆರೆಯಿರಿ"</string> <string name="select_conversation_title" msgid="6716364118095089519">"ಸಂಭಾಷಣೆ ವಿಜೆಟ್ಗಳು"</string> <string name="select_conversation_text" msgid="3376048251434956013">"ಸಂಭಾಷಣೆಯನ್ನು ಹೋಮ್ ಸ್ಕ್ರೀನ್ಗೆ ಸೇರಿಸಲು ಅದನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"ನೀವು ಕೆಲವು ಸಂದೇಶಗಳನ್ನು ಪಡೆದ ನಂತರ ಇಲ್ಲಿ ಮತ್ತೆ ಪರಿಶೀಲಿಸಿ"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"ಆದ್ಯತೆಯ ಸಂಭಾಷಣೆಗಳು"</string> <string name="recent_conversations" msgid="8531874684782574622">"ಇತ್ತೀಚಿನ ಸಂಭಾಷಣೆಗಳು"</string> <string name="okay" msgid="6490552955618608554">"ಸರಿ"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"ಇತ್ತೀಚಿನ ಸಂದೇಶಗಳು, ಮಿಸ್ಡ್ ಕಾಲ್ಗಳು ಮತ್ತು ಸ್ಥಿತಿ ಅಪ್ಡೇಟ್ಗಳು"</string> <string name="people_tile_title" msgid="6589377493334871272">"ಸಂಭಾಷಣೆ"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"\'ಅಡಚಣೆ ಮಾಡಬೇಡಿ\' ನಿಂದ ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> ಸಂದೇಶವನ್ನು ಕಳುಹಿಸಿದ್ದಾರೆ"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ಅವರು ಚಿತ್ರವನ್ನು ಕಳುಹಿಸಿದ್ದಾರೆ"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ನಿಮ್ಮ ಬ್ಯಾಟರಿ ಮೀಟರ್ ಓದುವಾಗ ಸಮಸ್ಯೆ ಎದುರಾಗಿದೆ"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index ab80f7f3acdc..1e48ebd15473 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"사용자 추가"</string> <string name="user_new_user_name" msgid="2019166282704195789">"신규 사용자"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"게스트를 삭제하시겠습니까?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"게스트를 초기화하시겠습니까?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"이 세션에 있는 모든 앱과 데이터가 삭제됩니다."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"삭제"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"초기화"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"게스트 세션 진행"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"세션을 계속 진행하시겠습니까?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"다시 시작"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"대화 열기"</string> <string name="select_conversation_title" msgid="6716364118095089519">"대화 위젯"</string> <string name="select_conversation_text" msgid="3376048251434956013">"대화를 탭하여 홈 화면에 추가하세요."</string> - <string name="no_conversations_text" msgid="7362374212649891057">"메시지를 받으면 여기서 다시 확인해 주세요."</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"우선순위 대화"</string> <string name="recent_conversations" msgid="8531874684782574622">"최근 대화"</string> <string name="okay" msgid="6490552955618608554">"확인"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"최근 메시지, 부재중 전화, 상태 업데이트 보기"</string> <string name="people_tile_title" msgid="6589377493334871272">"대화"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"방해 금지 모드로 인해 일시중지됨"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g>님이 메시지를 보냈습니다."</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>님이 이미지를 보냈습니다."</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"배터리 수준을 읽는 중에 문제가 발생함"</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 037a765870d4..bfc899cb5eb8 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Колдонуучу кошуу"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Жаңы колдонуучу"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Конокту алып саласызбы?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Конок сеансын баштапкы абалга келтиресизби?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Бул сеанстагы бардык колдонмолор жана маалыматтар өчүрүлөт."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Өчүрүү"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Баштапкы абалга келтирүү"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Кайтып келишиңиз менен!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансыңызды улантасызбы?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Кайра баштоо"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Ачык сүйлөшүү"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Сүйлөшүүлөр виджеттери"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Сүйлөшүүнү башкы экранга кошуу үчүн таптап коюңуз"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Билдирүүлөрдү алгандан кийин бул жерди кайрадан текшериңиз"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Маанилүү сүйлөшүүлөр"</string> <string name="recent_conversations" msgid="8531874684782574622">"Акыркы сүйлөшүүлөр"</string> <string name="okay" msgid="6490552955618608554">"Макул"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Акыркы билдирүүлөрдү, жооп берилбеген чалууларды жана статустардын жаңырганын көрөсүз"</string> <string name="people_tile_title" msgid="6589377493334871272">"Сүйлөшүү"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"\"Тынчымды алба\" режими тындырды"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> билдирүү жөнөттү"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> сүрөт жөнөттү"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Батареяңыздын кубаты аныкталбай жатат"</string> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 4cdc8a5fcb4e..27d684877a81 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"ເພີ່ມຜູ້ໃຊ້"</string> <string name="user_new_user_name" msgid="2019166282704195789">"ຜູ່ໃຊ້ໃໝ່"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ລຶບແຂກບໍ?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"ຣີເຊັດແຂກບໍ?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ແອັບຯແລະຂໍ້ມູນທັງໝົດໃນເຊດຊັນນີ້ຈະຖືກລຶບອອກ."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ລຶບ"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"ຣີເຊັດ"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"ຍິນດີຕ້ອນຮັບກັບມາ, ຜູ້ຢ້ຽມຢາມ!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"ທ່ານຕ້ອງການສືບຕໍ່ເຊດຊັນຂອງທ່ານບໍ່?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ເລີ່ມຕົ້ນໃຫມ່"</string> @@ -1117,7 +1115,7 @@ <string name="basic_status" msgid="2315371112182658176">"ເປີດການສົນທະນາ"</string> <string name="select_conversation_title" msgid="6716364118095089519">"ວິດເຈັດການສົນທະນາ"</string> <string name="select_conversation_text" msgid="3376048251434956013">"ແຕະໃສ່ການສົນທະນາໃດໜຶ່ງເພື່ອເພີ່ມມັນໃສ່ໂຮມສະກຣີນຂອງທ່ານ"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"ກັບມາກວດເບິ່ງຢູ່ບ່ອນນີ້ຄືນໃໝ່ຫຼັງຈາກທີ່ທ່ານໄດ້ຮັບຂໍ້ຄວາມ"</string> + <string name="no_conversations_text" msgid="5354115541282395015">"ການສົນທະນາຫຼ້າສຸດຂອງທ່ານຈະສະແດງຢູ່ບ່ອນນີ້"</string> <string name="priority_conversations" msgid="3967482288896653039">"ການສົນທະນາສຳຄັນ"</string> <string name="recent_conversations" msgid="8531874684782574622">"ການສົນທະນາຫຼ້າສຸດ"</string> <string name="okay" msgid="6490552955618608554">"ຕົກລົງ"</string> @@ -1146,6 +1144,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"ເບິ່ງຂໍ້ຄວາມຫຼ້າສຸດ, ສາຍບໍ່ໄດ້ຮັບ ແລະ ອັບເດດສະຖານະ"</string> <string name="people_tile_title" msgid="6589377493334871272">"ການສົນທະນາ"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"ຢຸດຊົ່ວຄາວແລ້ວໂດຍໂໝດຫ້າມລົບກວນ"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> ສົ່ງຂໍ້ຄວາມແລ້ວ"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ສົ່ງຮູບພາບແລ້ວ"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ເກີດບັນຫາໃນການອ່ານຕົວວັດແທກແບັດເຕີຣີຂອງທ່ານ"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 44dc8bb6aa30..04dc3fca5a59 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -484,12 +484,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Pridėti naudotoją"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Naujas naudotojas"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Pašalinti svečią?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bus ištrintos visos šios sesijos programos ir duomenys."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Pašalinti"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Sveiki sugrįžę, svety!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Ar norite tęsti sesiją?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Pradėti iš naujo"</string> @@ -1131,7 +1127,8 @@ <string name="basic_status" msgid="2315371112182658176">"Atidaryti pokalbį"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Pokalbio valdikliai"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Palieskite pokalbį, kad pridėtumėte jį prie pagrindinio ekrano"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Sugrįžkite, kai gausite pranešimų"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Svarbiausi pokalbiai"</string> <string name="recent_conversations" msgid="8531874684782574622">"Paskutiniai pokalbiai"</string> <string name="okay" msgid="6490552955618608554">"Gerai"</string> @@ -1160,6 +1157,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g> +"</string> <string name="people_tile_description" msgid="8154966188085545556">"Peržiūrėkite naujausius pranešimus, praleistus skambučius ir būsenos atnaujinimus"</string> <string name="people_tile_title" msgid="6589377493334871272">"Pokalbis"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Pristabdyta dėl netrukdymo režimo"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> išsiuntė pranešimą"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> išsiuntė vaizdą"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nuskaitant akumuliatoriaus skaitiklį iškilo problema"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index b846be4491f3..ade61cd497aa 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -482,12 +482,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Lietotāja pievienošana"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Jauns lietotājs"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vai noņemt viesi?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tiks dzēstas visas šīs sesijas lietotnes un dati."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Noņemt"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Laipni lūdzam atpakaļ, viesi!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vai vēlaties turpināt savu sesiju?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Sākt no sākuma"</string> @@ -1125,7 +1121,8 @@ <string name="basic_status" msgid="2315371112182658176">"Atvērt sarunu"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Sarunu logrīki"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Pieskarieties kādai sarunai, lai pievienotu to savam sākuma ekrānam."</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Atgriezieties šeit, kad būsiet saņēmis ziņojumus."</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Prioritārās sarunas"</string> <string name="recent_conversations" msgid="8531874684782574622">"Jaunākās sarunas"</string> <string name="okay" msgid="6490552955618608554">"Labi"</string> @@ -1154,6 +1151,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Skatiet jaunākos ziņojumus, neatbildētos zvanus un statusa atjauninājumus."</string> <string name="people_tile_title" msgid="6589377493334871272">"Saruna"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Rādīšana pārtraukta režīma Netraucēt dēļ"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> nosūtīja ziņojumu"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> nosūtīja attēlu"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nevar iegūt informāciju par akumulatora uzlādes līmeni."</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 90f775bcd310..4e4793a466de 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Додај корисник"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Нов корисник"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Да се отстрани гостинот?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Да се ресетира гостинот?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Сите апликации и податоци во сесијата ќе се избришат."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Отстрани"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Ресетирај"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Добре дојде пак, гостине!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Дали сакате да продолжите со сесијата?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни одново"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Започни разговор"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Виџети за разговор"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Допрете на разговор за да го додадете на вашиот почетен екран"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Вратете се тука кога ќе добиете пораки"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Приоритетни разговори"</string> <string name="recent_conversations" msgid="8531874684782574622">"Неодамнешни разговори"</string> <string name="okay" msgid="6490552955618608554">"Во ред"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Видете ги неодамнешните пораки, пропуштени повици и промени на статусот"</string> <string name="people_tile_title" msgid="6589377493334871272">"Разговор"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Паузирано од „Не вознемирувај“"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> испрати порака"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> испрати слика"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Проблем при читањето на мерачот на батеријата"</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 74d087c73d39..d96aa060bdd2 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"ഉപയോക്താവിനെ ചേര്ക്കുക"</string> <string name="user_new_user_name" msgid="2019166282704195789">"പുതിയ ഉപയോക്താവ്"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"അതിഥിയെ നീക്കംചെയ്യണോ?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ഈ സെഷനിലെ എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കും."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"നീക്കംചെയ്യുക"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"അതിഥി, വീണ്ടും സ്വാഗതം!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"നിങ്ങളുടെ സെഷൻ തുടരണോ?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"പുനരാംരംഭിക്കുക"</string> @@ -738,7 +734,7 @@ <string name="notification_channel_summary_low" msgid="4860617986908931158">"ശബ്ദമോ വൈബ്രേഷനോ ഇല്ല"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ശബ്ദമോ വൈബ്രേഷനോ ഇല്ല, സംഭാഷണ വിഭാഗത്തിന് താഴെയായി ദൃശ്യമാകും"</string> <string name="notification_channel_summary_default" msgid="3282930979307248890">"ഫോൺ ക്രമീകരണം അടിസ്ഥാനമാക്കി റിംഗ്/വൈബ്രേറ്റ് ചെയ്യും"</string> - <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"ഫോൺ ക്രമീകരണം അടിസ്ഥാനമാക്കി റിംഗ് ചെയ്തേക്കാം അല്ലെങ്കിൽ വൈബ്രേറ്റ് ചെയ്തേക്കാം. <xliff:g id="APP_NAME">%1$s</xliff:g>-ൽ നിന്നുള്ള സംഭാഷണങ്ങൾ ഡിഫോൾട്ടായി ബബിൾ ആവുന്നു."</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"ഫോൺ ക്രമീകരണം അടിസ്ഥാനമാക്കി റിംഗ്/വൈബ്രേറ്റ് ചെയ്തേക്കാം. <xliff:g id="APP_NAME">%1$s</xliff:g>-ൽ നിന്നുള്ള സംഭാഷണങ്ങൾ ഡിഫോൾട്ടായി ബബിൾ ചെയ്യുന്നു."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"ഈ ഉള്ളടക്കത്തിലേക്ക് ഒരു ഫ്ലോട്ടിംഗ് കുറുക്കുവഴി ഉപയോഗിച്ച് നിങ്ങളുടെ ശ്രദ്ധ നിലനിർത്തുന്നു."</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ഈ അറിയിപ്പ് വരുമ്പോൾ ശബ്ദിക്കുകയാണോ വൈബ്രേറ്റ് ചെയ്യുകയാണോ വേണ്ടതെന്ന് നിർണ്ണയിക്കാൻ സിസ്റ്റത്തെ അനുവദിക്കുക"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>നില:</b> ഡിഫോൾട്ടാക്കി പ്രമോട്ട് ചെയ്തു"</string> @@ -748,7 +744,7 @@ <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"സംഭാഷണ അറിയിപ്പുകളുടെ മുകളിലും സ്ക്രീൻ ലോക്കായിരിക്കുമ്പോൾ ഒരു പ്രൊഫൈൽ ചിത്രമായും കാണിക്കുന്നു"</string> <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"സംഭാഷണ അറിയിപ്പുകളുടെ മുകളിലും സ്ക്രീൻ ലോക്കായിരിക്കുമ്പോൾ ഒരു പ്രൊഫൈൽ ചിത്രമായും കാണിക്കുന്നു, ഒരു ബബിൾ രൂപത്തിൽ ദൃശ്യമാകുന്നു"</string> <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"സംഭാഷണ അറിയിപ്പുകളുടെ മുകളിലും സ്ക്രീൻ ലോക്കായിരിക്കുമ്പോൾ ഒരു പ്രൊഫൈൽ ചിത്രമായും കാണിക്കുന്നു, ശല്യപ്പെടുത്തരുത് മോഡ് തടസ്സപ്പെടുത്തുന്നു"</string> - <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"സംഭാഷണ അറിയിപ്പുകളുടെ മുകളിലും സ്ക്രീൻ ലോക്കായിരിക്കുമ്പോൾ ഒരു പ്രൊഫൈൽ ചിത്രമായും കാണിക്കുന്നു, ഒരു ബബിൾ രൂപത്തിൽ ദൃശ്യമാകുന്നു, ശല്യപ്പെടുത്തരുത് മോഡ് തടസ്സപ്പെടുത്തുന്നു"</string> + <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"സംഭാഷണ അറിയിപ്പുകളുടെ മുകളിലും സ്ക്രീൻ ലോക്കായിരിക്കുമ്പോൾ ഒരു പ്രൊഫൈൽ ചിത്രമായും ബബിൾ രൂപത്തിൽ ദൃശ്യമാകുന്നു, ശല്യപ്പെടുത്തരുത് മോഡ് തടസ്സപ്പെടുത്തുന്നു"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ക്രമീകരണം"</string> <string name="notification_priority_title" msgid="2079708866333537093">"മുൻഗണന"</string> <string name="no_shortcut" msgid="8257177117568230126">"സംഭാഷണ ഫീച്ചറുകളെ <xliff:g id="APP_NAME">%1$s</xliff:g> പിന്തുണയ്ക്കുന്നില്ല"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"സംഭാഷണം തുറക്കുക"</string> <string name="select_conversation_title" msgid="6716364118095089519">"സംഭാഷണ വിജറ്റുകൾ"</string> <string name="select_conversation_text" msgid="3376048251434956013">"നിങ്ങളുടെ ഹോം സ്ക്രീനിൽ ചേർക്കാൻ സംഭാഷണത്തിൽ ടാപ്പ് ചെയ്യുക"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"കുറച്ച് സന്ദേശങ്ങൾ ലഭിച്ച ശേഷം ഇവിടെ വീണ്ടും പരിശോധിക്കൂ"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"മുൻഗണനാ സംഭാഷണങ്ങൾ"</string> <string name="recent_conversations" msgid="8531874684782574622">"അടുത്തിടെയുള്ള സംഭാഷണങ്ങൾ"</string> <string name="okay" msgid="6490552955618608554">"ശരി"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"അടുത്തിടെയുള്ള സന്ദേശങ്ങൾ, മിസ്ഡ് കോൾ, സ്റ്റാറ്റസ് അപ്ഡേറ്റുകൾ എന്നിവ കാണൂ"</string> <string name="people_tile_title" msgid="6589377493334871272">"സംഭാഷണം"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"\'ശല്യപ്പെടുത്തരുത്\' ഓണായതിനാൽ തൽക്കാലം നിർത്തി"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g>, ഒരു സന്ദേശം അയച്ചു"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>, ഒരു ചിത്രം അയച്ചു"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"നിങ്ങളുടെ ബാറ്ററി മീറ്റർ വായിക്കുന്നതിൽ പ്രശ്നമുണ്ട്"</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 976c2dd420c8..900fbd8bf1ec 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Хэрэглэгч нэмэх"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Шинэ хэрэглэгч"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Зочныг хасах уу?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Зочныг шинэчлэх үү?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Энэ харилцан үйлдлийн бүх апп болон дата устах болно."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Хасах"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Шинэчлэх"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Эргэн тавтай морилно уу!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Та үргэлжлүүлэхийг хүсэж байна уу?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Дахин эхлүүлэх"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Харилцан яриаг нээх"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Харилцан ярианы жижиг хэрэгслүүд"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Үндсэн нүүрэндээ нэмэх харилцан яриаг товшино уу"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Та зарим мессеж авсныхаа дараа эндээс буцаж шалгана уу"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Чухал харилцан яриа"</string> <string name="recent_conversations" msgid="8531874684782574622">"Саяхны харилцан яриа"</string> <string name="okay" msgid="6490552955618608554">"За"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Саяхны мессеж, аваагүй дуудлага болон төлөвийн шинэчлэлтийг харах"</string> <string name="people_tile_title" msgid="6589377493334871272">"Харилцан яриа"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Бүү саад бол горимоор түр зогсоосон"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> мессеж илгээсэн"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> зураг илгээсэн"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Таны батарей хэмжигчийг уншихад асуудал гарлаа"</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 84b559475019..5dd7abd86ab7 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"वापरकर्ता जोडा"</string> <string name="user_new_user_name" msgid="2019166282704195789">"नवीन वापरकर्ता"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"अतिथी काढायचे?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"या सत्रातील सर्व अॅप्स आणि डेटा हटवला जाईल."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"काढा"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"अतिथी, तुमचे पुन्हा स्वागत आहे!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"तुम्ही तुमचे सत्र सुरू ठेवू इच्छिता?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"येथून सुरू करा"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"संभाषण उघडा"</string> <string name="select_conversation_title" msgid="6716364118095089519">"संभाषण विजेट"</string> <string name="select_conversation_text" msgid="3376048251434956013">"तुमच्या होम स्क्रीन वर संभाषण जोडण्यासाठी त्यावर टॅप करा"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"तुम्हाला काही मेसेज मिळाल्यावर येथे पुन्हा पाहा"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"प्राधान्य दिलेली संभाषणे"</string> <string name="recent_conversations" msgid="8531874684782574622">"अलीकडील संभाषणे"</string> <string name="okay" msgid="6490552955618608554">"ओके"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"अलीकडील मेसेज, मिस्ड कॉल आणि स्टेटस अपडेट पाहा"</string> <string name="people_tile_title" msgid="6589377493334871272">"संभाषण"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"व्यत्यय आणू नका द्वारे थांबवले गेले"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> यांनी मेसेज पाठवला"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> यांनी इमेज पाठवली"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"तुमचे बॅटरी मीटर वाचताना समस्या आली"</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index f3838c4ce802..28ad7a7473b8 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Tambah pengguna"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Pengguna baharu"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Alih keluar tetamu?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua apl dan data dalam sesi ini akan dipadam."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Alih keluar"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Selamat kembali, tetamu!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Adakah anda ingin meneruskan sesi anda?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulakan semula"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Buka perbualan"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widget perbualan"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Ketik perbualan untuk menambahkan perbualan itu pada skrin Utama anda"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Semak di sini semula selepas anda mendapat beberapa mesej"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Perbualan keutamaan"</string> <string name="recent_conversations" msgid="8531874684782574622">"Perbualan terbaharu"</string> <string name="okay" msgid="6490552955618608554">"Okey"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Lihat mesej terbaharu, panggilan terlepas dan kemaskinian status"</string> <string name="people_tile_title" msgid="6589377493334871272">"Perbualan"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Dijeda oleh Jangan Ganggu"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> menghantar mesej"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> menghantar imej"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Masalah membaca meter bateri anda"</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index efe716e9d04a..54d1a5fa9b58 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -39,7 +39,7 @@ <string name="battery_saver_start_action" msgid="4553256017945469937">"ဘက်ထရီ အားထိန်းကို ဖွင့်ရန်"</string> <string name="status_bar_settings_settings_button" msgid="534331565185171556">"အပြင်အဆင်များ"</string> <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi-Fi"</string> - <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"မျက်နှာပြင်အလိုအလျောက်လှည့်ရန်"</string> + <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"ဖန်သားပြင် အလိုအလျောက်လှည့်ရန်"</string> <string name="status_bar_settings_mute_label" msgid="914392730086057522">"MUTE"</string> <string name="status_bar_settings_auto_brightness_label" msgid="2151934479226017725">"AUTO"</string> <string name="status_bar_settings_notifications" msgid="5285316949980621438">"အကြောင်းကြားချက်များ"</string> @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"အသုံးပြုသူ ထည့်ရန်"</string> <string name="user_new_user_name" msgid="2019166282704195789">"အသုံးပြုသူ အသစ်"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ဧည့်သည်ကို ဖယ်မလား။"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"ဧည့်သည်ကို ပြင်ဆင်သတ်မှတ်မလား။"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ဒီချိတ်ဆက်မှု ထဲက အက်ပ်များ အားလုံး နှင့် ဒေတာကို ဖျက်ပစ်မည်။"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ဖယ်ထုတ်ပါ"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"ပြင်ဆင်သတ်မှတ်ရန်"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"ဧည့်သည်ကို ပြန်လည် ကြိုဆိုပါသည်။"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"သင်၏ စက်ရှင်ကို ဆက်လုပ်လိုပါသလား။"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ပြန်စပါ"</string> @@ -736,7 +734,7 @@ <string name="notification_channel_summary_low" msgid="4860617986908931158">"အသံ သို့မဟုတ် တုန်ခါမှုမရှိပါ"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"အသံ သို့မဟုတ် တုန်ခါမှုမရှိပါ၊ စကားဝိုင်းကဏ္ဍ၏ အောက်ပိုင်းတွင် မြင်ရသည်"</string> <string name="notification_channel_summary_default" msgid="3282930979307248890">"ဖုန်းဆက်တင်များပေါ် အခြေခံပြီး အသံမြည်နိုင်သည် သို့မဟုတ် တုန်ခါနိုင်သည်"</string> - <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"ဖုန်းဆက်တင်များပေါ် အခြေခံပြီး အသံမြည်နိုင်သည် သို့မဟုတ် တုန်ခါနိုင်သည်။ မူရင်းသတ်မှတ်ချက်အဖြစ် <xliff:g id="APP_NAME">%1$s</xliff:g> မှ စကားဝိုင်းများကို ပူဖောင်းကွက်ဖြင့် ပြသည်။"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"ဖုန်းဆက်တင်ပေါ် အခြေခံပြီး အသံမြည် (သို့) တုန်ခါနိုင်သည်။ <xliff:g id="APP_NAME">%1$s</xliff:g> မှ စကားဝိုင်းများကို ပူဖောင်းကွက်ဖြင့် အလိုအလျောက်ပြသည်။"</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"အကြောင်းအရာကို floating shortcut ကိုသုံး၍ အာရုံစိုက်လာအောင်လုပ်ပါ။"</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ဤအကြောင်းကြားချက်က အသံ သို့မဟုတ် တုန်ခါမှု ပေးရန် သင့်/မသင့်ကို စနစ်က ဆုံးဖြတ်ပါစေ"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>အခြေအနေ-</b> မူရင်းသို့ ချိန်ညှိထားသည်"</string> @@ -1117,7 +1115,7 @@ <string name="basic_status" msgid="2315371112182658176">"စကားဝိုင်းကို ဖွင့်ရန်"</string> <string name="select_conversation_title" msgid="6716364118095089519">"စကားဝိုင်း ဝိဂျက်များ"</string> <string name="select_conversation_text" msgid="3376048251434956013">"စကားဝိုင်းကို သင်၏ ‘ပင်မစာမျက်နှာ’ သို့ထည့်ရန် တို့ပါ"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"မက်ဆေ့ဂျ်အချို့ရလျှင် ဤနေရာသို့ ပြန်လာကြည့်ပါ"</string> + <string name="no_conversations_text" msgid="5354115541282395015">"သင်၏မကြာသေးမီက စကားဝိုင်းများကို ဤနေရာတွင် ပြပါမည်"</string> <string name="priority_conversations" msgid="3967482288896653039">"ဦးစားပေး စကားဝိုင်းများ"</string> <string name="recent_conversations" msgid="8531874684782574622">"မကြာသေးမီက စကားဝိုင်းများ"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1146,6 +1144,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"မကြာသေးမီက မက်ဆေ့ဂျ်၊ လွတ်သွားသောခေါ်ဆိုမှုနှင့် အခြေအနေအပ်ဒိတ်များကို ကြည့်နိုင်သည်"</string> <string name="people_tile_title" msgid="6589377493334871272">"စကားဝိုင်း"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"‘မနှောင့်ယှက်ရ’ ဖြင့် ခဏရပ်ထားသည်"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> က မက်ဆေ့ဂျ်ပို့လိုက်သည်"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> က ပုံပို့လိုက်သည်"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"သင်၏ ဘက်ထရီမီတာကို ဖတ်ရာတွင် ပြဿနာရှိနေသည်"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 71ae67261280..c549debf9e3f 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Legg til brukere"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Ny bruker"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vil du fjerne gjesten?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle appene og all informasjon i denne økten slettes."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Fjern"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Velkommen tilbake, gjest!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsette økten?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start på nytt"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Åpen samtale"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Samtalemoduler"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Trykk på en samtale for å legge den til på startskjermen"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Sjekk her igjen når du mottar noen meldinger"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Prioriterte samtaler"</string> <string name="recent_conversations" msgid="8531874684782574622">"Nylige samtaler"</string> <string name="okay" msgid="6490552955618608554">"Ok"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Se nylige meldinger, tapte anrop og statusoppdateringer"</string> <string name="people_tile_title" msgid="6589377493334871272">"Samtale"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Satt på pause av «Ikke forstyrr»"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> har sendt en melding"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> har sendt et bilde"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Kunne ikke lese batterimåleren"</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 52e615519148..b9ef04f2cbbc 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -437,7 +437,7 @@ <string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"एपहरू बदल्न द्रुत गतिमा दायाँतिर ड्र्याग गर्नुहोस्"</string> <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"परिदृश्य टगल गर्नुहोस्"</string> <string name="expanded_header_battery_charged" msgid="5307907517976548448">"चार्ज भयो"</string> - <string name="expanded_header_battery_charging" msgid="1717522253171025549">"चार्ज हुँदै"</string> + <string name="expanded_header_battery_charging" msgid="1717522253171025549">"चार्ज हुँदै छ"</string> <string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"<xliff:g id="CHARGING_TIME">%s</xliff:g> पूर्ण नभएसम्म"</string> <string name="expanded_header_battery_not_charging" msgid="809409140358955848">"चार्ज भइरहेको छैन"</string> <string name="ssl_ca_cert_warning" msgid="8373011375250324005">"नेटवर्क \n अनुगमनमा हुन सक्छ"</string> @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"प्रयोगकर्ता थप्नुहोस्"</string> <string name="user_new_user_name" msgid="2019166282704195789">"नयाँ प्रयोगकर्ता"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"अतिथि हटाउने हो?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यो सत्रमा भएका सबै एपहरू र डेटा मेटाइने छ।"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"हटाउनुहोस्"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"तपाईंलाई फेरि स्वागत छ, अतिथि"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"तपाईं आफ्नो सत्र जारी गर्न चाहनुहुन्छ?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"सुरु गर्नुहोस्"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"वार्तालाप खोल्नुहोस्"</string> <string name="select_conversation_title" msgid="6716364118095089519">"वार्तालापसम्बन्धी विजेटहरू"</string> <string name="select_conversation_text" msgid="3376048251434956013">"कुनै वार्तालाप होम स्क्रिनमा हाल्न उक्त वार्तालापमा ट्याप गर्नुहोस्"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"तपाईंले कुनै म्यासेज प्राप्त गरेपछि यहाँ आएर सो म्यासेज हेर्नुहोस्"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"महत्त्वपूर्ण वार्तालापहरू"</string> <string name="recent_conversations" msgid="8531874684782574622">"हालसालैका वार्तालापहरू"</string> <string name="okay" msgid="6490552955618608554">"ठिक छ"</string> @@ -1148,6 +1145,8 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"हालसालैका म्यासेज, मिस कल र स्ट्याटस अपडेट हेर्नुहोस्"</string> <string name="people_tile_title" msgid="6589377493334871272">"वार्तालाप"</string> + <!-- no translation found for paused_by_dnd (7856941866433556428) --> + <skip /> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> ले एउटा म्यासेज पठाउनुभयो"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ले एउटा फोटो पठाउनुभयो"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"डिभाइसको ब्याट्रीको मिटर रिडिङ क्रममा समस्या भयो"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 8bd41deb9499..07decdf1c71e 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Gebruiker toevoegen"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nieuwe gebruiker"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Gast verwijderen?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Gastsessie resetten?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps en gegevens in deze sessie worden verwijderd."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Verwijderen"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Resetten"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welkom terug, gast!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Wil je doorgaan met je sessie?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Opnieuw starten"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Gesprek openen"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Gesprekswidgets"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Tik op een gesprek om het toe te voegen aan je startscherm"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Kom hier terug zodra je wat berichten hebt"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Prioriteitsgesprekken"</string> <string name="recent_conversations" msgid="8531874684782574622">"Recente gesprekken"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Bekijk recente berichten, gemiste gesprekken en statusupdates"</string> <string name="people_tile_title" msgid="6589377493334871272">"Gesprek"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Onderbroken door Niet storen"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> heeft een bericht gestuurd"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> heeft een afbeelding gestuurd"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Probleem bij het lezen van je batterijmeter"</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 003ce4c4b5ce..f4b3b3ea5d59 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରନ୍ତୁ"</string> <string name="user_new_user_name" msgid="2019166282704195789">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ଅତିଥିଙ୍କୁ କାଢ଼ିଦେବେ?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"ଅତିଥିଙ୍କୁ ରିସେଟ୍ କରିବେ?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ଏହି ସେସନର ସମସ୍ତ ଆପ୍ ଓ ଡାଟା ଡିଲିଟ୍ ହୋଇଯିବ।"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"କାଢ଼ିଦିଅନ୍ତୁ"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"ରିସେଟ୍ କରନ୍ତୁ"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"ପୁଣି ସ୍ୱାଗତ, ଅତିଥି!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"ଆପଣ ନିଜର ସେସନ୍ ଜାରି ରଖିବାକୁ ଚାହାଁନ୍ତି କି?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ଆରମ୍ଭ କରନ୍ତୁ"</string> @@ -1036,8 +1034,7 @@ <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ସ୍କ୍ରିନର ଅଂଶ ମାଗ୍ନିଫାଏ କରନ୍ତୁ"</string> <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ସ୍ୱିଚ୍ କରନ୍ତୁ"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"ଆକ୍ସେସିବିଲିଟୀ ଜେଶ୍ଚରକୁ ଆକ୍ସେସିବିଲିଟୀ ବଟନରେ ପରିବର୍ତ୍ତନ କରାଯାଇଛି\n\n"<annotation id="link">"ସେଟିଂସ୍ ଦେଖନ୍ତୁ"</annotation></string> - <!-- no translation found for accessibility_floating_button_switch_migration_tooltip (6248529129221218770) --> - <skip /> + <string name="accessibility_floating_button_switch_migration_tooltip" msgid="6248529129221218770">"ଆପଣ ଆକ୍ସେସିବିଲିଟୀ ଜେଶ୍ଚରରୁ ଏକ ବଟନକୁ ସ୍ୱିଚ୍ କରିପାରିବେ\n\n"<annotation id="link">"ସେଟିଂସ୍"</annotation></string> <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"ବଟନକୁ ଅସ୍ଥାୟୀ ଭାବେ ଲୁଚାଇବା ପାଇଁ ଏହାକୁ ଗୋଟିଏ ଧାରକୁ ମୁଭ୍ କରନ୍ତୁ"</string> <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"ଶୀର୍ଷ ବାମକୁ ମୁଭ୍ କରନ୍ତୁ"</string> <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"ଶୀର୍ଷ ଡାହାଣକୁ ମୁଭ୍ କରନ୍ତୁ"</string> @@ -1118,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"ବାର୍ତ୍ତାଳାପ ଖୋଲନ୍ତୁ"</string> <string name="select_conversation_title" msgid="6716364118095089519">"ବାର୍ତ୍ତାଳାପ ୱିଜେଟଗୁଡ଼ିକ"</string> <string name="select_conversation_text" msgid="3376048251434956013">"ଏକ ବାର୍ତ୍ତାଳାପକୁ ଆପଣଙ୍କ ମୂଳସ୍କ୍ରିନରେ ଯୋଗ କରିବା ପାଇଁ ସେଥିରେ ଟାପ୍ କରନ୍ତୁ"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"ଆପଣ କିଛି ମେସେଜ୍ ପାଇଲେ ଏଠାରେ ପୁଣି ଯାଞ୍ଚ କରନ୍ତୁ"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"ପ୍ରାଥମିକତା ଦିଆଯାଇଥିବା ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ"</string> <string name="recent_conversations" msgid="8531874684782574622">"ବର୍ତ୍ତମାନର ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ"</string> <string name="okay" msgid="6490552955618608554">"ଠିକ୍ ଅଛି"</string> @@ -1147,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"ବର୍ତ୍ତମାନର ମେସେଜ୍, ମିସ୍ଡ କଲ୍ ଏବଂ ସ୍ଥିତି ଅପଡେଟଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ"</string> <string name="people_tile_title" msgid="6589377493334871272">"ବାର୍ତ୍ତାଳାପ"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଦ୍ୱାରା ବିରତ କରାଯାଇଛି"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> ଏକ ମେସେଜ୍ ପଠାଇଛନ୍ତି"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ଏକ ଛବି ପଠାଇଛନ୍ତି"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ଆପଣଙ୍କ ବ୍ୟାଟେରୀ ମିଟର୍ ପଢ଼ିବାରେ ସମସ୍ୟା ହେଉଛି"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 0f687a142544..7f96ea816321 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="user_new_user_name" msgid="2019166282704195789">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ਕੀ ਮਹਿਮਾਨ ਹਟਾਉਣਾ ਹੈ?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ਇਸ ਸੈਸ਼ਨ ਵਿੱਚ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਏਗਾ।"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ਹਟਾਓ"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"ਮਹਿਮਾਨ, ਫਿਰ ਤੁਹਾਡਾ ਸੁਆਗਤ ਹੈ!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਸੈਸ਼ਨ ਜਾਰੀ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string> @@ -738,7 +734,7 @@ <string name="notification_channel_summary_low" msgid="4860617986908931158">"ਕੋਈ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਹੀਂ"</string> <string name="notification_conversation_summary_low" msgid="1734433426085468009">"ਕੋਈ ਧੁਨੀ ਜਾਂ ਥਰਥਰਾਹਟ ਨਹੀਂ ਅਤੇ ਸੂਚਨਾਵਾਂ ਗੱਲਬਾਤ ਸੈਕਸ਼ਨ ਵਿੱਚ ਹੇਠਲੇ ਪਾਸੇ ਦਿਸਦੀਆਂ ਹਨ"</string> <string name="notification_channel_summary_default" msgid="3282930979307248890">"ਫ਼ੋਨ ਸੈਟਿੰਗਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਘੰਟੀ ਵੱਜ ਸਕਦੀ ਹੈ ਜਾਂ ਥਰਥਰਾਹਟ ਹੋ ਸਕਦੀ ਹੈ"</string> - <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"ਫ਼ੋਨ ਸੈਟਿੰਗਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਘੰਟੀ ਵੱਜ ਸਕਦੀ ਹੈ ਜਾਂ ਥਰਥਰਾਹਟ ਹੋ ਸਕਦੀ ਹੈ। ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੌਰ \'ਤੇ <xliff:g id="APP_NAME">%1$s</xliff:g> ਬਬਲ ਤੋਂ ਗੱਲਾਂਬਾਤਾਂ।"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="1782419896613644568">"ਫ਼ੋਨ ਸੈਟਿੰਗਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਘੰਟੀ ਵੱਜ ਸਕਦੀ ਹੈ ਜਾਂ ਥਰਥਰਾਹਟ ਹੋ ਸਕਦੀ ਹੈ। ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਤੌਰ \'ਤੇ <xliff:g id="APP_NAME">%1$s</xliff:g> ਤੋਂ ਗੱਲਾਂਬਾਤਾਂ ਬਬਲ ਵਜੋਂ ਦਿਸਦੀਆਂ ਹਨ।"</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"ਇਸ ਸਮੱਗਰੀ ਦੇ ਅਸਥਿਰ ਸ਼ਾਰਟਕੱਟ ਨਾਲ ਆਪਣਾ ਧਿਆਨ ਕੇਂਦਰਿਤ ਰੱਖੋ।"</string> <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"ਸਿਸਟਮ ਨੂੰ ਨਿਰਧਾਰਤ ਕਰਨ ਦਿਓ ਕਿ ਇਸ ਸੂਚਨਾ ਲਈ ਕੋਈ ਧੁਨੀ ਵਜਾਉਣੀ ਚਾਹੀਦੀ ਹੈ ਜਾਂ ਥਰਥਰਾਹਟ ਕਰਨੀ ਚਾਹੀਦੀ ਹੈ"</string> <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"<b>ਸਥਿਤੀ:</b> ਦਰਜਾ ਵਧਾ ਕੇ ਪੂਰਵ-ਨਿਰਧਾਰਤ \'ਤੇ ਸੈੱਟ ਕੀਤਾ ਗਿਆ"</string> @@ -748,7 +744,7 @@ <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"ਗੱਲਬਾਤ ਸੂਚਨਾਵਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਵਜੋਂ ਦਿਖਾਉਂਦਾ ਹੈ"</string> <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"ਗੱਲਬਾਤ ਸੂਚਨਾਵਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਵਜੋਂ ਦਿਖਾਈਆਂ ਜਾਂਦੀਆਂ ਹਨ, ਜੋ ਕਿ ਬਬਲ ਵਜੋਂ ਦਿਸਦੀਆਂ ਹਨ"</string> <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"ਗੱਲਬਾਤ ਸੂਚਨਾਵਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਵਜੋਂ ਦਿਖਾਉਂਦਾ ਹੈ, \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਸੁਵਿਧਾ ਵਿੱਚ ਵੀ ਵਿਘਨ ਪੈ ਸਕਦਾ ਹੈ"</string> - <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ਗੱਲਬਾਤ ਸੂਚਨਾਵਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ, ਬਬਲ ਵਜੋਂ ਦਿਖਾਉਂਦਾ ਹੈ, \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਸੁਵਿਧਾ ਵਿੱਚ ਵੀ ਵਿਘਨ ਪੈ ਸਕਦਾ ਹੈ"</string> + <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ਗੱਲਬਾਤ ਸੂਚਨਾਵਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਵਜੋਂ ਦਿਖਾਈਆਂ ਜਾਂਦੀਆਂ ਹਨ, ਜੋ ਕਿ ਬਬਲ ਵਜੋਂ ਦਿਸਦੀਆਂ ਹਨ ਅਤੇ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਸੁਵਿਧਾ ਵਿੱਚ ਵਿਘਨ ਵੀ ਪਾ ਸਕਦੀਆਂ ਹਨ"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ਸੈਟਿੰਗਾਂ"</string> <string name="notification_priority_title" msgid="2079708866333537093">"ਤਰਜੀਹ"</string> <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ ਗੱਲਬਾਤ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"ਗੱਲਬਾਤ ਖੋਲ੍ਹੋ"</string> <string name="select_conversation_title" msgid="6716364118095089519">"ਗੱਲਬਾਤ ਵਿਜੇਟ"</string> <string name="select_conversation_text" msgid="3376048251434956013">"ਆਪਣੀ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਕੋਈ ਗੱਲਬਾਤ ਚੁਣੋ"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"ਤੁਹਾਨੂੰ ਕੁਝ ਸੁਨੇਹੇ ਮਿਲਣ \'ਤੇ, ਉਹਨਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਵਾਪਸ ਇੱਥੇ ਆਓ"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"ਤਰਜੀਹੀ ਗੱਲਾਂਬਾਤਾਂ"</string> <string name="recent_conversations" msgid="8531874684782574622">"ਹਾਲੀਆ ਗੱਲਾਂਬਾਤਾਂ"</string> <string name="okay" msgid="6490552955618608554">"ਠੀਕ ਹੈ"</string> @@ -1148,6 +1145,8 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"ਹਾਲੀਆ ਸੁਨੇਹੇ, ਮਿਸ ਕਾਲਾਂ ਅਤੇ ਸਥਿਤੀ ਸੰਬੰਧੀ ਅੱਪਡੇਟ ਦੇਖੋ"</string> <string name="people_tile_title" msgid="6589377493334871272">"ਗੱਲਬਾਤ"</string> + <!-- no translation found for paused_by_dnd (7856941866433556428) --> + <skip /> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> ਨੇ ਇੱਕ ਸੁਨੇਹਾ ਭੇਜਿਆ"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ਨੇ ਇੱਕ ਚਿੱਤਰ ਭੇਜਿਆ ਹੈ"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ਤੁਹਾਡੇ ਬੈਟਰੀ ਮੀਟਰ ਨੂੰ ਪੜ੍ਹਨ ਵਿੱਚ ਸਮੱਸਿਆ ਹੋ ਰਹੀ ਹੈ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index e822d936eca4..51a9f3786384 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -484,12 +484,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Dodaj użytkownika"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nowy użytkownik"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Usunąć gościa?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wszystkie aplikacje i dane w tej sesji zostaną usunięte."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Usuń"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Witaj ponownie, Gościu!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcesz kontynuować sesję?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Rozpocznij nową"</string> @@ -1131,7 +1127,8 @@ <string name="basic_status" msgid="2315371112182658176">"Otwarta rozmowa"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widżety Rozmowa"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Kliknij rozmowę, aby dodać ją do ekranu głównego"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Tu pojawią się otrzymane wiadomości"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Rozmowy priorytetowe"</string> <string name="recent_conversations" msgid="8531874684782574622">"Ostatnie rozmowy"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1160,6 +1157,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+ <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="people_tile_description" msgid="8154966188085545556">"Zobacz ostatnie wiadomości, nieodebrane połączenia i stany"</string> <string name="people_tile_title" msgid="6589377493334871272">"Rozmowa"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Wstrzymane przez tryb Nie przeszkadzać"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> wysyła wiadomość"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> wysyła zdjęcie"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem z odczytaniem pomiaru wykorzystania baterii"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index e4dbca5eb8e3..1d7ba07d3d15 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Adicionar usuário"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Novo usuário"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover visitante?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Redefinir sessão de visitante?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Redefinir"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Você voltou, visitante!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Toque em uma conversa para adicioná-la à tela inicial"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Volte aqui quando receber mensagens"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Conversas prioritárias"</string> <string name="recent_conversations" msgid="8531874684782574622">"Conversas recentes"</string> <string name="okay" msgid="6490552955618608554">"Ok"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Veja mensagens recentes, chamadas perdidas e atualizações de status"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversa"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Pausado pelo Não perturbe"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma mensagem"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma imagem"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema para ler seu medidor de bateria"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index a9cb3dc88fa1..e89aab361bc1 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Adicionar utilizador"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Novo utilizador"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover o convidado?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Pretende repor a sessão de convidado?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todas as apps e dados desta sessão serão eliminados."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Repor"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bem-vindo de volta, convidado!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Pretende continuar a sessão?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Abrir conversa"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Toque numa conversa para a adicionar ao ecrã principal"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Volte aqui quando tiver mensagens"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Conversas com prioridade"</string> <string name="recent_conversations" msgid="8531874684782574622">"Conversas recentes"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Veja mensagens recentes, chamadas não atendidas e atualizações de estado"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversa"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Colocado em pausa pelo modo Não incomodar"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma mensagem"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma imagem"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Ocorreu um problema ao ler o medidor da bateria"</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index e4dbca5eb8e3..1d7ba07d3d15 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Adicionar usuário"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Novo usuário"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Remover visitante?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Redefinir sessão de visitante?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Remover"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Redefinir"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Você voltou, visitante!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widgets de conversa"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Toque em uma conversa para adicioná-la à tela inicial"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Volte aqui quando receber mensagens"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Conversas prioritárias"</string> <string name="recent_conversations" msgid="8531874684782574622">"Conversas recentes"</string> <string name="okay" msgid="6490552955618608554">"Ok"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Veja mensagens recentes, chamadas perdidas e atualizações de status"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversa"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Pausado pelo Não perturbe"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma mensagem"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> enviou uma imagem"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema para ler seu medidor de bateria"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 3f9a576156d5..377af789fcda 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -482,12 +482,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Adăugați un utilizator"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Utilizator nou"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ștergeți invitatul?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toate aplicațiile și datele din această sesiune vor fi șterse."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ștergeți"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bine ați revenit în sesiunea pentru invitați!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vreți să continuați sesiunea?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Începeți din nou"</string> @@ -1125,7 +1121,8 @@ <string name="basic_status" msgid="2315371112182658176">"Deschideți conversația"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Widgeturi pentru conversație"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Atingeți o conversație ca să o adăugați pe ecranul de pornire"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Reveniți aici după ce primiți câteva mesaje"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Conversații cu prioritate"</string> <string name="recent_conversations" msgid="8531874684782574622">"Conversații recente"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1154,6 +1151,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Vedeți mesaje recente, apeluri pierdute și actualizări de stare"</string> <string name="people_tile_title" msgid="6589377493334871272">"Conversație"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Întrerupt de Nu deranja"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> a trimis un mesaj"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> a trimis o imagine"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problemă la citirea măsurării bateriei"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 67091b957467..f9bc9b210ea4 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -484,12 +484,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Добавить пользователя"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Новый пользователь"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Удалить аккаунт гостя?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Все приложения и данные этого профиля будут удалены."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Удалить"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Рады видеть вас снова!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Продолжить сеанс?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Начать заново"</string> @@ -1131,7 +1127,8 @@ <string name="basic_status" msgid="2315371112182658176">"Открытый чат"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Виджеты чатов"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Нажмите на чат, чтобы добавить его на главный экран"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Здесь вы увидите свои сообщения."</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Важные разговоры"</string> <string name="recent_conversations" msgid="8531874684782574622">"Недавние разговоры"</string> <string name="okay" msgid="6490552955618608554">"ОК"</string> @@ -1160,6 +1157,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Будьте в курсе последних сообщений, пропущенных вызовов и обновлений статуса."</string> <string name="people_tile_title" msgid="6589377493334871272">"Чат"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Приостановлено в режиме \"Не беспокоить\""</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> отправил сообщение"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> отправил изображение"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Не удается получить данные об уровне заряда батареи"</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 6c82ad58a25f..0339baa323d3 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"පරිශීලකයෙක් එක් කරන්න"</string> <string name="user_new_user_name" msgid="2019166282704195789">"නව පරිශීලකයා"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"අමුත්තාන් ඉවත් කරන්නද?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"ආගන්තුකයා යළි සකසන්නද?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"මෙම සැසියේ සියළුම යෙදුම් සහ දත්ත මකාවී."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ඉවත් කරන්න"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"යළි සකසන්න"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"නැවත සාදරයෙන් පිළිගනිමු, අමුත්තා!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"ඔබගේ සැසිය දිගටම කරගෙන යෑමට ඔබට අවශ්යද?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"යළි මුල සිට අරඹන්න"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"සංවාදය විවෘත කරන්න"</string> <string name="select_conversation_title" msgid="6716364118095089519">"සංවාද විජට්"</string> <string name="select_conversation_text" msgid="3376048251434956013">"ඔබගේ මුල් තිරයට එය එක් කිරීමට සංවාදයක් තට්ටු කරන්න"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"ඔබට පණිවිඩ කිහිපයක් ලැබුණු පසු නැවත මෙහි පරීක්ෂා කරන්න"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"ප්රමුඛතා සංවාද"</string> <string name="recent_conversations" msgid="8531874684782574622">"මෑත සංවාද"</string> <string name="okay" msgid="6490552955618608554">"හරි"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"මෑත පණිවිඩ, මඟ හැරුණු ඇමතුම් සහ තත්ත්ව යාවත්කාලීන කිරීම් බලන්න"</string> <string name="people_tile_title" msgid="6589377493334871272">"සංවාදය"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"බාධා නොකිරීම මගින් විරාම කර ඇත"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> පණිවිඩයක් එවා ඇත"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> රූපයක් යවන ලදී"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ඔබගේ බැටරි මනුව කියවීමේ දෝෂයකි"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 19a871e461d3..b0d8d3bf717f 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -484,12 +484,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Pridať používateľa"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nový používateľ"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Odstrániť hosťa?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Všetky aplikácie a údaje v tejto relácii budú odstránené."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstrániť"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Hosť, vitajte späť!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relácii pokračovať?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začať odznova"</string> @@ -1131,7 +1127,8 @@ <string name="basic_status" msgid="2315371112182658176">"Otvorená konverzácia"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Miniaplikácie konverzácií"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Klepnite na konverzáciu a pridajte ju tak na plochu"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Vráťte sa sem, až dostanete nejaké správy"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Prioritné konverzácie"</string> <string name="recent_conversations" msgid="8531874684782574622">"Nedávne konverzácie"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1160,6 +1157,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Pozrite si nedávne správy, zmeškané hovory a aktualizácie stavu"</string> <string name="people_tile_title" msgid="6589377493334871272">"Konverzácia"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Pozastavené režimom bez vyrušení"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> poslal(a) správu"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> poslal(a) obrázok"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Pri čítaní meradla batérie sa vyskytol problém"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index c58343a9fd9e..9d84910d8f7e 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -484,12 +484,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Dodajanje uporabnika"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Nov uporabnik"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Želite odstraniti gosta?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Vse aplikacije in podatki v tej seji bodo izbrisani."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Odstrani"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Znova pozdravljeni, gost!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite nadaljevati sejo?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začni znova"</string> @@ -753,8 +749,8 @@ <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"<b>Stanje:</b> Uvrščeno nižje"</string> <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Prikaz na vrhu razdelka z obvestili za pogovor in kot profilna slika na zaklenjenem zaslonu"</string> <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Prikaz v obliki oblačka na vrhu razdelka z obvestili za pogovor in kot profilna slika na zaklenjenem zaslonu."</string> - <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Prikaz na vrhu razdelka z obvestili za pogovor in kot profilna slika na zaklenjenem zaslonu, preglasitev načina Ne moti"</string> - <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikaz v obliki oblačka na vrhu razdelka z obvestili za pogovor in kot profilna slika na zaklenjenem zaslonu, preglasitev načina Ne moti"</string> + <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Prikaz na vrhu razdelka z obvestili za pogovor in kot profilna slika na zaklenjenem zaslonu, preglasitev načina Ne moti."</string> + <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikaz v obliki oblačka na vrhu razdelka z obvestili za pogovor in kot profilna slika na zaklenjenem zaslonu, preglasitev načina Ne moti."</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Nastavitve"</string> <string name="notification_priority_title" msgid="2079708866333537093">"Prednostno"</string> <string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podpira pogovornih funkcij."</string> @@ -1131,7 +1127,8 @@ <string name="basic_status" msgid="2315371112182658176">"Odprt pogovor"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Pripomočki za pogovore"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Dotaknite se pogovora, da ga dodate na začetni zaslon."</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Znova preverite tukaj, ko boste prejeli kakšno sporočilo."</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Prednostni pogovori"</string> <string name="recent_conversations" msgid="8531874684782574622">"Nedavni pogovori"</string> <string name="okay" msgid="6490552955618608554">"V redu"</string> @@ -1160,6 +1157,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Več kot <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="people_tile_description" msgid="8154966188085545556">"Ogled nedavnih sporočil, neodgovorjenih klicev in posodobitev stanj"</string> <string name="people_tile_title" msgid="6589377493334871272">"Pogovor"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"To je začasno zaustavil način »ne moti«."</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"Oseba <xliff:g id="NAME">%1$s</xliff:g> je poslala sporočilo."</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"Oseba <xliff:g id="NAME">%1$s</xliff:g> je poslala sliko."</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Težava z branjem indikatorja stanja napolnjenosti baterije"</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 334b2ed0a603..78ab1fa16823 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Shto përdorues"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Përdorues i ri"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Të hiqet i ftuari?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Të gjitha aplikacionet dhe të dhënat në këtë sesion do të fshihen."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Hiq"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Mirë se erdhe, i ftuar!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Dëshiron ta vazhdosh sesionin tënd?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Fillo nga e para"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Hap bisedën"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Miniaplikacionet e bisedave"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Trokit te një bisedë dhe shtoje në ekranin bazë"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Kontrollo përsëri këtu pasi të marrësh disa mesazhe"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Bisedat me përparësi"</string> <string name="recent_conversations" msgid="8531874684782574622">"Bisedat e fundit"</string> <string name="okay" msgid="6490552955618608554">"Në rregull"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Mbi <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="people_tile_description" msgid="8154966188085545556">"Shiko mesazhet e fundit, telefonatat e humbura dhe përditësimet e statusit"</string> <string name="people_tile_title" msgid="6589377493334871272">"Biseda"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Vendosur në pauzë nga \"Mos shqetëso\""</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> dërgoi një mesazh"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> dërgoi një imazh"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem me leximin e matësit të baterisë"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index e4a1bea6f998..d14854b55f6e 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -482,12 +482,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Додај корисника"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Нови корисник"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Желите ли да уклоните госта?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Све апликације и подаци у овој сесији ће бити избрисани."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Уклони"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Добро дошли назад, госте!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Желите ли да наставите сесију?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни из почетка"</string> @@ -1125,7 +1121,8 @@ <string name="basic_status" msgid="2315371112182658176">"Отворите конверзацију"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Виџети за конверзацију"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Додирните конверзацију да бисте је додали на почетни екран"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Вратите се овде када добијете неку поруку"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Приоритетне конверзације"</string> <string name="recent_conversations" msgid="8531874684782574622">"Недавне конверзације"</string> <string name="okay" msgid="6490552955618608554">"Важи"</string> @@ -1154,6 +1151,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Погледајте недавне поруке, пропуштене позиве и ажурирања статуса"</string> <string name="people_tile_title" msgid="6589377493334871272">"Конверзација"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Паузирано режимом Не узнемиравај"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> шаље поруку"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> шаље слику"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Проблем са очитавањем мерача батерије"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 390a7bc268e3..708b93828d8b 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Lägg till användare"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Ny användare"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Vill du ta bort gästen?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Vill du återställa gästsessionen?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alla appar och data i denna session kommer att raderas."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ta bort"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Återställ"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Välkommen tillbaka som gäst!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vill du fortsätta sessionen?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Börja om"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Öppen konversation"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Konversationswidgetar"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Tryck på en konversation för att lägga till den på startskärmen"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Besök den här sidan igen när du har fått meddelanden"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Prioriterade konversationer"</string> <string name="recent_conversations" msgid="8531874684782574622">"Senaste konversationerna"</string> <string name="okay" msgid="6490552955618608554">"Okej"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"över <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="people_tile_description" msgid="8154966188085545556">"Se de senaste meddelandena, missade samtal och statusuppdateringar"</string> <string name="people_tile_title" msgid="6589377493334871272">"Konversation"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Pausad av Stör ej"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> skickade ett meddelande"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> skickade en bild"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batteriindikatorn visas inte"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 99bf399b3c1b..f9f2ca37d3bf 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -349,7 +349,7 @@ <string name="quick_settings_rotation_locked_portrait_label" msgid="1194988975270484482">"Wima"</string> <string name="quick_settings_rotation_locked_landscape_label" msgid="2000295772687238645">"Mlalo"</string> <string name="quick_settings_ime_label" msgid="3351174938144332051">"Mbinu ya uingizaji"</string> - <string name="quick_settings_location_label" msgid="2621868789013389163">"Kutambua Mahali"</string> + <string name="quick_settings_location_label" msgid="2621868789013389163">"Mahali"</string> <string name="quick_settings_location_off_label" msgid="7923929131443915919">"Kitambua eneo kimezimwa"</string> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Ufikiaji wa kamera"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Ufikiaji wa maikrofoni"</string> @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Ongeza mtumiaji"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Mtumiaji mpya"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Ungependa kumwondoa mgeni?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Ungependa kubadilisha kipindi cha mgeni?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Data na programu zote katika kipindi hiki zitafutwa."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Ondoa"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Badilisha"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Karibu tena mgeni!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Je, unataka kuendelea na kipindi chako?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Anza upya"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Fungua mazungumzo"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Wijeti za mazungumzo"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Gusa mazungumzo ili uyaweke kwenye Skrini yako ya kwanza"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Angalia hapa tena utakapopokea ujumbe"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Mazungumzo yenye kipaumbele"</string> <string name="recent_conversations" msgid="8531874684782574622">"Mazungumzo ya hivi majuzi"</string> <string name="okay" msgid="6490552955618608554">"Sawa"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Angalia ujumbe wa hivi majuzi, simu ambazo hukujibu na taarifa za hali"</string> <string name="people_tile_title" msgid="6589377493334871272">"Mazungumzo"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Imesimamishwa na kipengele cha Usinisumbue"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> ametuma ujumbe"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ametuma picha"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Tatizo la kusoma mita ya betri yako"</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 5dc158195ddc..0ec1d1f09e23 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -137,10 +137,10 @@ <string name="accessibility_phone_button" msgid="4256353121703100427">"ஃபோன்"</string> <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"குரல் உதவி"</string> <string name="accessibility_wallet_button" msgid="1458258783460555507">"வாலட்"</string> - <string name="accessibility_unlock_button" msgid="122785427241471085">"திற"</string> + <string name="accessibility_unlock_button" msgid="122785427241471085">"அன்லாக் செய்"</string> <string name="accessibility_lock_icon" msgid="661492842417875775">"சாதனம் பூட்டப்பட்டுள்ளது"</string> <string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"கைரேகைக்காகக் காத்திருக்கிறது"</string> - <string name="accessibility_unlock_without_fingerprint" msgid="1811563723195375298">"உங்கள் கைரேகையைப் பயன்படுத்தாமல் திறக்கவும்"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="1811563723195375298">"உங்கள் கைரேகையைப் பயன்படுத்தாமல் அன்லாக் செய்யுங்கள்"</string> <string name="accessibility_scanning_face" msgid="3093828357921541387">"முகத்தை ஸ்கேன் செய்கிறது"</string> <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"அனுப்பு"</string> <string name="accessibility_manage_notification" msgid="582215815790143983">"அறிவிப்புகளை நிர்வகிக்கும் பட்டன்"</string> @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"பயனரைச் சேர்"</string> <string name="user_new_user_name" msgid="2019166282704195789">"புதியவர்"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"கெஸ்ட்டை அகற்றவா?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"இந்த அமர்வின் எல்லா ஆப்ஸும் தரவும் நீக்கப்படும்."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"அகற்று"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"நல்வரவு!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"உங்கள் அமர்வைத் தொடர விருப்பமா?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"மீண்டும் தொடங்கு"</string> @@ -590,10 +586,10 @@ <string name="monitoring_description_app_work" msgid="3713084153786663662">"உங்கள் பணிக் கணக்கை <xliff:g id="ORGANIZATION">%1$s</xliff:g> நிர்வகிக்கிறது. மின்னஞ்சல்கள், ஆப்ஸ், இணையதளங்கள் உட்பட உங்கள் பணி நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION">%2$s</xliff:g> உடன் அது இணைக்கப்பட்டுள்ளது.\n\nமேலும் தகவலுக்கு, நிர்வாகியைத் தொடர்புகொள்ளவும்."</string> <string name="monitoring_description_app_personal_work" msgid="6175816356939166101">"உங்கள் பணிக் கணக்கை <xliff:g id="ORGANIZATION">%1$s</xliff:g> நிர்வகிக்கிறது. மின்னஞ்சல்கள், ஆப்ஸ், இணையதளங்கள் உட்பட உங்கள் பணி நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> உடன் அது இணைக்கப்பட்டுள்ளது.\n\nஉங்கள் தனிப்பட்ட நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> உடனும் இணைக்கப்பட்டுள்ளீர்கள்."</string> <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent இதைத் திறந்தே வைத்துள்ளது"</string> - <string name="keyguard_indication_trust_disabled" msgid="6820793704816727918">"நீங்கள் கைமுறையாகத் திறக்கும் வரை, சாதனம் பூட்டப்பட்டிருக்கும்"</string> + <string name="keyguard_indication_trust_disabled" msgid="6820793704816727918">"நீங்கள் கைமுறையாக அன்லாக் செய்யும் வரை, சாதனம் பூட்டப்பட்டிருக்கும்"</string> <string name="keyguard_indication_trust_unlocked_plugged_in" msgid="2323452175329362855">"<xliff:g id="KEYGUARD_INDICATION">%1$s</xliff:g>\n<xliff:g id="POWER_INDICATION">%2$s</xliff:g>"</string> <string name="hidden_notifications_title" msgid="1782412844777612795">"விரைவாக அறிவிப்புகளைப் பெறுதல்"</string> - <string name="hidden_notifications_text" msgid="5899627470450792578">"திறக்கும் முன் அவற்றைப் பார்க்கவும்"</string> + <string name="hidden_notifications_text" msgid="5899627470450792578">"அன்லாக் செய்யும் முன் அவற்றைப் பார்க்கவும்"</string> <string name="hidden_notifications_cancel" msgid="4805370226181001278">"வேண்டாம்"</string> <string name="hidden_notifications_setup" msgid="2064795578526982467">"அமை"</string> <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"திறந்தநிலை உரையாடல்"</string> <string name="select_conversation_title" msgid="6716364118095089519">"உரையாடல் விட்ஜெட்டுகள்"</string> <string name="select_conversation_text" msgid="3376048251434956013">"ஓர் உரையாடலை உங்கள் முகப்புத் திரையில் சேர்க்க அந்த உரையாடலைத் தட்டுங்கள்"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"செய்திகளைப் பெற்றதும் இங்கே மீண்டும் வரவும்"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"முன்னுரிமை அளிக்கப்பட்ட உரையாடல்கள்"</string> <string name="recent_conversations" msgid="8531874684782574622">"சமீபத்திய உரையாடல்கள்"</string> <string name="okay" msgid="6490552955618608554">"சரி"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"சமீபத்திய மெசேஜ்களையும் தவறிய அழைப்புகளையும் ஸ்டேட்டஸ் அப்டேட்களையும் பார்க்கலாம்"</string> <string name="people_tile_title" msgid="6589377493334871272">"உரையாடல்"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"தொந்தரவு செய்ய வேண்டாம் அம்சத்தால் இடைநிறுத்தப்பட்டது"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> ஒரு மெசேஜ் அனுப்பியுள்ளார்"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ஒரு படம் அனுப்பியுள்ளார்"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"பேட்டரி அளவை அறிவதில் சிக்கல்"</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 348c37ae2e60..48dbe3731aaa 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"యూజర్ను జోడించండి"</string> <string name="user_new_user_name" msgid="2019166282704195789">"కొత్త వినియోగదారు"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"గెస్ట్ను తీసివేయాలా?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ఈ సెషన్లోని అన్ని యాప్లు మరియు డేటా తొలగించబడతాయి."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"తీసివేయి"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"గెస్ట్కు తిరిగి స్వాగతం!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"మీరు మీ సెషన్ని కొనసాగించాలనుకుంటున్నారా?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"మొదటి నుండి ప్రారంభించు"</string> @@ -1038,8 +1034,7 @@ <string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"స్క్రీన్లో భాగాన్ని మాగ్నిఫై చేయండి"</string> <string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"స్విచ్ చేయి"</string> <string name="accessibility_floating_button_migration_tooltip" msgid="4431046858918714564">"యాక్సెసిబిలిటీ బటన్, యాక్సెసిబిలిటీ సంజ్ఞను భర్తీ చేసింది\n\n"<annotation id="link">"సెట్టింగ్లను చూడండి"</annotation></string> - <!-- no translation found for accessibility_floating_button_switch_migration_tooltip (6248529129221218770) --> - <skip /> + <string name="accessibility_floating_button_switch_migration_tooltip" msgid="6248529129221218770">"మీరు యాక్సెసిబిలిటీ సంజ్ఞ నుండి బటన్ మధ్య మారవచ్చు\n\n"<annotation id="link">"సెట్టింగ్లు"</annotation></string> <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"తాత్కాలికంగా దానిని దాచడానికి బటన్ను చివరకు తరలించండి"</string> <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"ఎగువ ఎడమ వైపునకు తరలించు"</string> <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"ఎగువ కుడి వైపునకు తరలించు"</string> @@ -1120,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"సంభాషణను తెరవండి"</string> <string name="select_conversation_title" msgid="6716364118095089519">"సంభాషణ విడ్జెట్లు"</string> <string name="select_conversation_text" msgid="3376048251434956013">"దీనిని మీ మొదటి స్క్రీన్కు జోడించడానికి సంభాషణను ట్యాప్ చేయండి"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"మీరు కొన్ని మెసేజ్లను పొందిన తర్వాత తిరిగి ఇక్కడ చెక్ చేయండి"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"ప్రాధాన్య సంభాషణలు"</string> <string name="recent_conversations" msgid="8531874684782574622">"ఇటీవలి సంభాషణలు"</string> <string name="okay" msgid="6490552955618608554">"సరే"</string> @@ -1149,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"ఇటీవలి మెసేజ్లు, మిస్డ్ కాల్లు, అలాగే స్టేటస్ అప్డేట్లను చూడండి"</string> <string name="people_tile_title" msgid="6589377493334871272">"సంభాషణ"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"అంతరాయం కలిగించవద్దు ద్వారా పాజ్ చేయబడింది"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> మెసేజ్ను పంపారు"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ఇమేజ్ను పంపారు"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"మీ బ్యాటరీ మీటర్ను చదవడంలో సమస్య"</string> diff --git a/packages/SystemUI/res/values-television/colors.xml b/packages/SystemUI/res/values-television/colors.xml index e5f3b4768fe2..566f6b229bc9 100644 --- a/packages/SystemUI/res/values-television/colors.xml +++ b/packages/SystemUI/res/values-television/colors.xml @@ -19,4 +19,22 @@ <resources> <color name="volume_dialog_background_color">#E61F232B</color> <color name="volume_dialog_background_color_above_blur">#C71F232B</color> + + <color name="bottom_sheet_icon_color">#D2E3FC</color> + + <color name="bottom_sheet_title_color">#E8F0FE</color> + <color name="bottom_sheet_body_color">#D2E3FC</color> + + <color name="bottom_sheet_background_color">#1F232C</color> + <color name="bottom_sheet_background_color_with_blur">#AA1A2734</color> + + <color name="bottom_sheet_button_background_color_focused">#E8F0FE</color> + <color name="bottom_sheet_button_background_color_unfocused">#0FE8EAED</color> + + <color name="bottom_sheet_button_text_color_focused">#DB202124</color> + <color name="bottom_sheet_button_text_color_unfocused">#B5E8EAED</color> + + <color name="privacy_circle">#5BB974</color> <!-- g400 --> + <color name="privacy_icon_tint">#30302A</color> + <color name="privacy_chip_dot_bg_tint">#66000000</color> </resources> diff --git a/packages/SystemUI/res/values-television/dimens.xml b/packages/SystemUI/res/values-television/dimens.xml index 7626db93dd76..c258fcc4273a 100644 --- a/packages/SystemUI/res/values-television/dimens.xml +++ b/packages/SystemUI/res/values-television/dimens.xml @@ -18,7 +18,42 @@ <!-- Opacity at which the background for the shutdown UI will be drawn. --> <item name="shutdown_scrim_behind_alpha" format="float" type="dimen">1.0</item> - <dimen name="privacy_chip_icon_margin">3dp</dimen> - <dimen name="privacy_chip_icon_padding">8dp</dimen> - <dimen name="privacy_chip_icon_size">13dp</dimen> + <dimen name="bottom_sheet_padding_horizontal">32dp</dimen> + <dimen name="bottom_sheet_padding_vertical">24dp</dimen> + + <dimen name="bottom_sheet_icon_size">42dp</dimen> + <dimen name="bottom_sheet_icon_margin">8dp</dimen> + <dimen name="bottom_sheet_title_margin_bottom">18dp</dimen> + <dimen name="bottom_sheet_details_margin_bottom">8dp</dimen> + + <dimen name="bottom_sheet_actions_width">296dp</dimen> + <dimen name="bottom_sheet_actions_spacing">12dp</dimen> + <item name="bottom_sheet_button_selection_scaled" format="float" type="dimen">1.1</item> + <dimen name="bottom_sheet_button_width">232dp</dimen> + <dimen name="bottom_sheet_button_padding_horizontal">20dp</dimen> + <dimen name="bottom_sheet_button_padding_vertical">16dp</dimen> + + <dimen name="bottom_sheet_corner_radius">24dp</dimen> + <dimen name="bottom_sheet_button_corner_radius">10dp</dimen> + + <dimen name="bottom_sheet_min_height">208dp</dimen> + <dimen name="bottom_sheet_margin">24dp</dimen> + <dimen name="bottom_sheet_background_blur_radius">120dp</dimen> + + <dimen name="privacy_chip_margin">12dp</dimen> + <dimen name="privacy_chip_icon_margin_in_between">9dp</dimen> + <dimen name="privacy_chip_padding_horizontal">9dp</dimen> + <dimen name="privacy_chip_icon_size">12dp</dimen> + <dimen name="privacy_chip_height">24dp</dimen> + <dimen name="privacy_chip_min_width">30dp</dimen> + <dimen name="privacy_chip_radius">12dp</dimen> + + <dimen name="privacy_chip_dot_size">8dp</dimen> + <dimen name="privacy_chip_dot_radius">4dp</dimen> + <dimen name="privacy_chip_dot_margin_horizontal">8dp</dimen> + + <dimen name="privacy_chip_dot_bg_width">24dp</dimen> + <dimen name="privacy_chip_dot_bg_height">18dp</dimen> + <dimen name="privacy_chip_dot_bg_radius">9dp</dimen> + </resources>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-television/integers.xml b/packages/SystemUI/res/values-television/integers.xml index 587497edfdfb..b265d7812229 100644 --- a/packages/SystemUI/res/values-television/integers.xml +++ b/packages/SystemUI/res/values-television/integers.xml @@ -20,4 +20,6 @@ Value 81 corresponds to BOTTOM|CENTER_HORIZONTAL. Value 21 corresponds to RIGHT|CENTER_VERTICAL. --> <integer name="volume_dialog_gravity">21</integer> + + <integer name="privacy_chip_animation_millis">300</integer> </resources> diff --git a/packages/SystemUI/res/values-television/styles.xml b/packages/SystemUI/res/values-television/styles.xml index 00217fb39b93..0fb789863bd9 100644 --- a/packages/SystemUI/res/values-television/styles.xml +++ b/packages/SystemUI/res/values-television/styles.xml @@ -28,4 +28,34 @@ <item name="android:textColorPrimaryInverse">@color/tv_volume_dialog_accent</item> <item name="android:dialogCornerRadius">@dimen/volume_dialog_panel_width_half</item> </style> + + <style name="BottomSheet" parent="Theme.Leanback"> + <item name="android:windowIsFloating">true</item> + <item name="android:windowActivityTransitions">true</item> + <item name="android:windowNoTitle">true</item> + <item name="android:windowIsTranslucent">true</item> + <item name="android:backgroundDimAmount">0.2</item> + </style> + + <style name="BottomSheet.TitleText"> + <item name="android:textSize">28sp</item> + <item name="android:textColor">@color/bottom_sheet_title_color</item> + </style> + + <style name="BottomSheet.BodyText"> + <item name="android:textSize">16sp</item> + <item name="android:textColor">@color/bottom_sheet_body_color</item> + </style> + + <style name="BottomSheet.ActionItem"> + <item name="android:layout_width">@dimen/bottom_sheet_button_width</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:gravity">left|center_vertical</item> + <item name="android:textSize">16sp</item> + <item name="android:textColor">@color/bottom_sheet_button_text_color</item> + <item name="android:background">@drawable/bottom_sheet_button_background</item> + <item name="android:paddingHorizontal">@dimen/bottom_sheet_button_padding_horizontal</item> + <item name="android:paddingVertical">@dimen/bottom_sheet_button_padding_vertical</item> + <item name="android:stateListAnimator">@anim/tv_bottom_sheet_button_state_list_animator</item> + </style> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index b21d22faf958..64b211389d39 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -438,7 +438,7 @@ <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"สลับภาพรวม"</string> <string name="expanded_header_battery_charged" msgid="5307907517976548448">"ชาร์จแล้ว"</string> <string name="expanded_header_battery_charging" msgid="1717522253171025549">"กำลังชาร์จ"</string> - <string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"อีก <xliff:g id="CHARGING_TIME">%s</xliff:g> จึงจะเต็ม"</string> + <string name="expanded_header_battery_charging_with_time" msgid="757991461445765011">"อีก <xliff:g id="CHARGING_TIME">%s</xliff:g> จะเต็ม"</string> <string name="expanded_header_battery_not_charging" msgid="809409140358955848">"ไม่ได้ชาร์จ"</string> <string name="ssl_ca_cert_warning" msgid="8373011375250324005">"เครือข่ายอาจ\nถูกตรวจสอบ"</string> <string name="description_target_search" msgid="3875069993128855865">"ค้นหา"</string> @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"เพิ่มผู้ใช้"</string> <string name="user_new_user_name" msgid="2019166282704195789">"ผู้ใช้ใหม่"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"ต้องการนำผู้ใช้ชั่วคราวออกไหม"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"รีเซ็ตผู้เข้าร่วมไหม"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ระบบจะลบแอปและข้อมูลทั้งหมดในเซสชันนี้"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"นำออก"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"รีเซ็ต"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"ยินดีต้อนรับผู้เข้าร่วมกลับมาอีกครั้ง"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"คุณต้องการอยู่ในเซสชันต่อไปไหม"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"เริ่มต้นใหม่"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"เปิดการสนทนา"</string> <string name="select_conversation_title" msgid="6716364118095089519">"วิดเจ็ตการสนทนา"</string> <string name="select_conversation_text" msgid="3376048251434956013">"แตะการสนทนาเพื่อเพิ่มไปยังหน้าจอหลัก"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"กลับมาดูที่นี่อีกครั้งเมื่อได้รับข้อความ"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"การสนทนาสำคัญ"</string> <string name="recent_conversations" msgid="8531874684782574622">"การสนทนาล่าสุด"</string> <string name="okay" msgid="6490552955618608554">"ตกลง"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"ดูข้อความล่าสุด สายที่ไม่ได้รับ และการอัปเดตสถานะ"</string> <string name="people_tile_title" msgid="6589377493334871272">"การสนทนา"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"หยุดชั่วคราวโดยฟีเจอร์ห้ามรบกวน"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> ส่งข้อความ"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> ส่งรูปภาพ"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"พบปัญหาในการอ่านเครื่องวัดแบตเตอรี่"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 5b48488f18fe..7b4a4d18bc55 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Magdagdag ng user"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Bagong user"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Alisin ang bisita?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"I-reset ang session ng bisita?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ide-delete ang lahat ng app at data sa session na ito."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Alisin"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"I-reset"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Welcome ulit, bisita!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Gusto mo bang ipagpatuloy ang iyong session?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Magsimulang muli"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Buksan ang pag-uusap"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Mga widget ng pag-uusap"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Mag-tap sa isang pag-uusap para idagdag ito sa iyong Home screen"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Bumalik dito kapag nakakuha ka na ng ilang mensahe"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Mga priyoridad na pag-uusap"</string> <string name="recent_conversations" msgid="8531874684782574622">"Mga kamakailang pag-uusap"</string> <string name="okay" msgid="6490552955618608554">"Okay"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Tingnan ang mga kamakailang mensahe, hindi nasagot na tawag, at update sa status"</string> <string name="people_tile_title" msgid="6589377493334871272">"Pag-uusap"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Na-pause ng Huwag Istorbohin"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"Nagpadala si <xliff:g id="NAME">%1$s</xliff:g> ng mensahe"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"Nagpadala si <xliff:g id="NAME">%1$s</xliff:g> ng larawan"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nagkaproblema sa pagbabasa ng iyong battery meter"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 8a3d467fbe58..fba8b30afb43 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Kullanıcı ekle"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Yeni kullanıcı"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Misafir oturumu kaldırılsın mı?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Misafir oturumu sıfırlansın mı?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu oturumdaki tüm uygulamalar ve veriler silinecek."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Kaldır"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Sıfırla"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Misafir kullanıcı, tekrar hoşgeldiniz"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Oturumunuza devam etmek istiyor musunuz?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Baştan başla"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Görüşmeyi aç"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Görüşme widget\'ları"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Ana ekranınıza eklemek için bir ileti dizisine dokunun"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Birkaç mesaj aldıktan sonra burayı tekrar kontrol edin"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Öncelikli görüşmeler"</string> <string name="recent_conversations" msgid="8531874684782574622">"Son görüşmeler"</string> <string name="okay" msgid="6490552955618608554">"Tamam"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Yeni mesajları, cevapsız aramaları ve durum güncellemelerini görün"</string> <string name="people_tile_title" msgid="6589377493334871272">"Görüşme"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Rahatsız Etmeyin özelliği tarafından duraklatıldı"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> bir mesaj gönderdi"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> bir resim gönderdi"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Pil ölçeriniz okunurken sorun oluştu"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 89be1299e836..b80ed19aebdc 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -351,7 +351,7 @@ <string name="quick_settings_rotation_locked_portrait_label" msgid="1194988975270484482">"Книжкова орієнтація"</string> <string name="quick_settings_rotation_locked_landscape_label" msgid="2000295772687238645">"Альбомна орієнтація"</string> <string name="quick_settings_ime_label" msgid="3351174938144332051">"Метод введення"</string> - <string name="quick_settings_location_label" msgid="2621868789013389163">"Місцезнаходження"</string> + <string name="quick_settings_location_label" msgid="2621868789013389163">"Геодані"</string> <string name="quick_settings_location_off_label" msgid="7923929131443915919">"Місцезнаходження вимкнено"</string> <string name="quick_settings_camera_label" msgid="5612076679385269339">"Доступ до камери"</string> <string name="quick_settings_mic_label" msgid="8392773746295266375">"Доступ до мікрофона"</string> @@ -484,10 +484,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Додати користувача"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Новий користувач"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Видалити гостя?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Скинути сеанс у режимі \"Гість\"?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усі додатки й дані з цього сеансу буде видалено."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Вийти"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Скинути"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"З поверненням!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Продовжити сеанс?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почати знову"</string> @@ -752,7 +750,7 @@ <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані"</string> <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, показується у вигляді спливаючої підказки"</string> <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, показується навіть у режимі \"Не турбувати\""</string> - <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, відображається у вигляді спливаючої підказки, показується навіть у режимі \"Не турбувати\""</string> + <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, відображається як спливаючий чат, перериває режим \"Не турбувати\""</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Налаштування"</string> <string name="notification_priority_title" msgid="2079708866333537093">"Пріоритет"</string> <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не підтримує функції розмов"</string> @@ -1129,7 +1127,8 @@ <string name="basic_status" msgid="2315371112182658176">"Відкрита розмова"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Віджети розмов"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Натисніть розмову, щоб додати її на головний екран"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Поверніться сюди, коли отримаєте повідомлення"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Важливі розмови"</string> <string name="recent_conversations" msgid="8531874684782574622">"Нещодавні розмови"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1158,6 +1157,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Переглядайте останні повідомлення, пропущені виклики й оновлення статусу"</string> <string name="people_tile_title" msgid="6589377493334871272">"Розмова"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Призупинено функцією \"Не турбувати\""</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> надсилає повідомлення"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> надсилає зображення"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Не вдалось отримати дані лічильника акумулятора"</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 930bb0586753..22883832cabe 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"صارف کو شامل کریں"</string> <string name="user_new_user_name" msgid="2019166282704195789">"نیا صارف"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"مہمان کو ہٹائیں؟"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"اس سیشن میں موجود سبھی ایپس اور ڈیٹا کو حذف کر دیا جائے گا۔"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"ہٹائیں"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"مہمان، پھر سے خوش آمدید!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"کیا آپ اپنا سیشن جاری رکھنا چاہتے ہیں؟"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"دوبارہ شروع کریں"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"گفتگو کھولیں"</string> <string name="select_conversation_title" msgid="6716364118095089519">"گفتگو ویجیٹس"</string> <string name="select_conversation_text" msgid="3376048251434956013">"اسے اپنے ہوم اسکرین پر شامل کرنے کے لیے گفتگو پر تھپتھپائیں"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"کچھ پیغامات حاصل کرنے کے بعد یہاں دوبارہ چیک کریں"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"ترجیحی گفتگوئیں"</string> <string name="recent_conversations" msgid="8531874684782574622">"حالیہ گفتگوئیں"</string> <string name="okay" msgid="6490552955618608554">"ٹھیک ہے"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"+<xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="people_tile_description" msgid="8154966188085545556">"حالیہ پیغامات، چھوٹی ہوئی کالز اور اسٹیٹس اپ ڈیٹس دیکھیں"</string> <string name="people_tile_title" msgid="6589377493334871272">"گفتگو"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"\'ڈسٹرب نہ کریں\' کے ذریعے موقوف کیا گیا"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> نے ایک پیغام بھیجا"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> نے ایک تصویر بھیجی"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"آپ کے بیٹری میٹر کو پڑھنے میں دشواری"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index df7f7cd72ee9..0c1d6c64dc88 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Foydalanuvchi"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Yangi foydalanuvchi"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Mehmon olib tashlansinmi?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"Mehmon seansi tiklansinmi?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ushbu seansdagi barcha ilovalar va ma’lumotlar o‘chirib tashlanadi."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Olib tashlash"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"Tiklash"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Xush kelibsiz, mehmon!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Seansni davom ettirmoqchimisiz?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Boshidan boshlansin"</string> @@ -1117,7 +1115,7 @@ <string name="basic_status" msgid="2315371112182658176">"Suhbatni ochish"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Suhbat vidjetlari"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Bosh ekranga chiqariladigan suhbat ustiga bosing"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Keyinroq bu yerda ayrim xabarlar chiqadi"</string> + <string name="no_conversations_text" msgid="5354115541282395015">"Oxirgi suhbatlaringiz shu yerda chiqadi"</string> <string name="priority_conversations" msgid="3967482288896653039">"Muhim suhbatlar"</string> <string name="recent_conversations" msgid="8531874684782574622">"Oxirgi suhbatlar"</string> <string name="okay" msgid="6490552955618608554">"OK"</string> @@ -1146,6 +1144,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Oxirgi xabarlar, javobsiz chaqiruvlar va holat yangilanishlari"</string> <string name="people_tile_title" msgid="6589377493334871272">"Suhbat"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Bezovta qilinmasin rejimi pauza qildi"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> xabar yubordi"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> rasm yubordi"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batareya quvvati aniqlanmadi"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 241cfb222a18..96ea6df3b5ea 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Thêm người dùng"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Người dùng mới"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Xóa phiên khách?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tất cả ứng dụng và dữ liệu trong phiên này sẽ bị xóa."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Xóa"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Chào mừng bạn trở lại!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Bạn có muốn tiếp tục phiên của mình không?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Bắt đầu lại"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Mở cuộc trò chuyện"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Tiện ích trò chuyện"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Nhấn vào một cuộc trò chuyện để thêm cuộc trò chuyện đó vào Màn hình chính"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Hãy quay lại đây khi bạn nhận được tin nhắn"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Cuộc trò chuyện ưu tiên"</string> <string name="recent_conversations" msgid="8531874684782574622">"Cuộc trò chuyện gần đây"</string> <string name="okay" msgid="6490552955618608554">"Ok"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"Hơn <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="people_tile_description" msgid="8154966188085545556">"Xem các tin nhắn, cuộc gọi nhỡ và thông tin cập nhật trạng thái gần đây"</string> <string name="people_tile_title" msgid="6589377493334871272">"Cuộc trò chuyện"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Đã tạm dừng do chế độ Không làm phiền"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g> đã gửi một tin nhắn"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g> đã gửi một hình ảnh"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Đã xảy ra vấn đề khi đọc dung lượng pin của bạn"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 9592b2d6aa5c..ebffe95c1bef 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_latest_events_title" msgid="202755896454005436">"通知"</string> <string name="battery_low_title" msgid="6891106956328275225">"电池电量可能很快就要耗尽"</string> <string name="battery_low_percent_format" msgid="4276661262843170964">"剩余<xliff:g id="PERCENTAGE">%s</xliff:g>"</string> - <string name="battery_low_percent_format_hybrid" msgid="3985614339605686167">"剩余电量:<xliff:g id="PERCENTAGE">%1$s</xliff:g>;根据您的使用情况,大约还可使用 <xliff:g id="TIME">%2$s</xliff:g>"</string> - <string name="battery_low_percent_format_hybrid_short" msgid="5917433188456218857">"剩余电量:<xliff:g id="PERCENTAGE">%1$s</xliff:g>;大约还可使用 <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="battery_low_percent_format_hybrid" msgid="3985614339605686167">"剩余电量:<xliff:g id="PERCENTAGE">%1$s</xliff:g>;根据您的使用情况,大约还可使用<xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="battery_low_percent_format_hybrid_short" msgid="5917433188456218857">"剩余电量:<xliff:g id="PERCENTAGE">%1$s</xliff:g>;大约还可使用<xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"剩余 <xliff:g id="PERCENTAGE">%s</xliff:g>。省电模式已开启。"</string> <string name="invalid_charger" msgid="4370074072117767416">"无法通过 USB 充电。请使用设备随附的充电器。"</string> <string name="invalid_charger_title" msgid="938685362320735167">"无法通过 USB 充电"</string> @@ -228,7 +228,7 @@ <string name="accessibility_no_sims" msgid="5711270400476534667">"没有 SIM 卡。"</string> <string name="accessibility_battery_details" msgid="6184390274150865789">"打开电量详情"</string> <string name="accessibility_battery_level" msgid="5143715405241138822">"电池电量为百分之 <xliff:g id="NUMBER">%d</xliff:g>。"</string> - <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"电池电量为 <xliff:g id="PERCENTAGE">%1$s</xliff:g>,根据您的使用情况,大约还可使用 <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"电池电量为 <xliff:g id="PERCENTAGE">%1$s</xliff:g>,根据您的使用情况,大约还可使用<xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"正在充电,已完成 <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%。"</string> <string name="accessibility_settings_button" msgid="2197034218538913880">"系统设置。"</string> <string name="accessibility_notifications_button" msgid="3960913924189228831">"通知。"</string> @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"添加用户"</string> <string name="user_new_user_name" msgid="2019166282704195789">"新用户"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"要移除访客吗?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"要重置访客会话吗?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"此会话中的所有应用和数据都将被删除。"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"重置"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"访客,欢迎回来!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"要继续您的会话吗?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新开始"</string> @@ -1117,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"开放式对话"</string> <string name="select_conversation_title" msgid="6716364118095089519">"对话微件"</string> <string name="select_conversation_text" msgid="3376048251434956013">"点按对话即可将其添加到主屏幕"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"请在收到一些消息后再回来查看"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"优先对话"</string> <string name="recent_conversations" msgid="8531874684782574622">"近期对话"</string> <string name="okay" msgid="6490552955618608554">"确定"</string> @@ -1146,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"查看近期的消息、未接电话和状态更新"</string> <string name="people_tile_title" msgid="6589377493334871272">"对话"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"勿扰模式已暂停通知"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g>发送了一条消息"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>发送了一张图片"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"读取电池计量器时出现问题"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 7be08d3fda5a..7f2edd9fdc9f 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -480,10 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"加入使用者"</string> <string name="user_new_user_name" msgid="2019166282704195789">"新使用者"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"移除訪客?"</string> - <string name="guest_reset_guest_dialog_title" msgid="8904781614074479690">"要重設訪客嗎?"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會被刪除。"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string> - <string name="guest_reset_guest_dialog_remove" msgid="4359825585658228699">"重設"</string> <string name="guest_wipe_session_title" msgid="7147965814683990944">"訪客您好,歡迎回來!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"您要繼續您的工作階段嗎?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string> @@ -1117,7 +1115,7 @@ <string name="basic_status" msgid="2315371112182658176">"開啟對話"</string> <string name="select_conversation_title" msgid="6716364118095089519">"對話小工具"</string> <string name="select_conversation_text" msgid="3376048251434956013">"輕按對話即可新增至主畫面"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"等你收到一些訊息後再回來查看吧"</string> + <string name="no_conversations_text" msgid="5354115541282395015">"您最近的對話會在這裡顯示"</string> <string name="priority_conversations" msgid="3967482288896653039">"優先對話"</string> <string name="recent_conversations" msgid="8531874684782574622">"最近的對話"</string> <string name="okay" msgid="6490552955618608554">"確定"</string> @@ -1146,6 +1144,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"查看最近的訊息、未接來電和狀態更新"</string> <string name="people_tile_title" msgid="6589377493334871272">"對話"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"「請勿騷擾」已暫停通知"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g>傳送了訊息"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>傳送了圖片"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"讀取電池計量器時發生問題"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 5c4c3b15e997..53a281e492c4 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"新增使用者"</string> <string name="user_new_user_name" msgid="2019166282704195789">"新使用者"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"移除訪客?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會遭到刪除。"</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"移除"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"訪客你好,歡迎回來!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"你要繼續這個工作階段嗎?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"開放式對話"</string> <string name="select_conversation_title" msgid="6716364118095089519">"對話小工具"</string> <string name="select_conversation_text" msgid="3376048251434956013">"輕觸對話即可新增至主畫面"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"等你收到一些訊息後再回來這裡看看"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"優先對話"</string> <string name="recent_conversations" msgid="8531874684782574622">"最近的對話"</string> <string name="okay" msgid="6490552955618608554">"確定"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"查看最近的訊息、未接來電和狀態更新"</string> <string name="people_tile_title" msgid="6589377493334871272">"對話"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"零打擾模式已將通知暫停"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"<xliff:g id="NAME">%1$s</xliff:g>傳送了一則訊息"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"<xliff:g id="NAME">%1$s</xliff:g>傳送了一張圖片"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"讀取電池計量器時發生問題"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 647102ac4895..76df48a93059 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -480,12 +480,8 @@ <string name="user_add_user" msgid="4336657383006913022">"Engeza umsebenzisi"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Umsebenzisi omusha"</string> <string name="guest_exit_guest_dialog_title" msgid="5015697561580641422">"Susa isivakashi?"</string> - <!-- no translation found for guest_reset_guest_dialog_title (8904781614074479690) --> - <skip /> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Zonke izinhlelo zokusebenza nedatha kulesi sikhathi zizosuswa."</string> <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"Susa"</string> - <!-- no translation found for guest_reset_guest_dialog_remove (4359825585658228699) --> - <skip /> <string name="guest_wipe_session_title" msgid="7147965814683990944">"Siyakwamukela futhi, sivakashi!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Ingabe ufuna ukuqhubeka ngesikhathi sakho?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Qala phansi"</string> @@ -1119,7 +1115,8 @@ <string name="basic_status" msgid="2315371112182658176">"Vula ingxoxo"</string> <string name="select_conversation_title" msgid="6716364118095089519">"Amawijethi wengxoxo"</string> <string name="select_conversation_text" msgid="3376048251434956013">"Thepha ingxoxo ukuyengeza Kusikrini sakho sasekhaya"</string> - <string name="no_conversations_text" msgid="7362374212649891057">"Phinda uhlole futhi lapho uthola imilayezo ethile"</string> + <!-- no translation found for no_conversations_text (5354115541282395015) --> + <skip /> <string name="priority_conversations" msgid="3967482288896653039">"Izingxoxo ezibalulekile"</string> <string name="recent_conversations" msgid="8531874684782574622">"Izingxoxo zakamuva"</string> <string name="okay" msgid="6490552955618608554">"Kulungile"</string> @@ -1148,6 +1145,7 @@ <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string> <string name="people_tile_description" msgid="8154966188085545556">"Bona imiyalezo yakamuva, amakholi akuphuthile, nezibuyekezo zesimo"</string> <string name="people_tile_title" msgid="6589377493334871272">"Ingxoxo"</string> + <string name="paused_by_dnd" msgid="7856941866433556428">"Kumiswe okuthi Ungaphazamisi"</string> <string name="new_notification_text_content_description" msgid="5574393603145263727">"U-<xliff:g id="NAME">%1$s</xliff:g> uthumele umlayezo"</string> <string name="new_notification_image_content_description" msgid="6017506886810813123">"U-<xliff:g id="NAME">%1$s</xliff:g> uthumele isithombe"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Kube khona inkinga ngokufunda imitha yakho yebhethri"</string> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index e7edb0e6a57d..020a100fa1b5 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -272,6 +272,7 @@ <color name="misalignment_text_color">#F28B82</color> <color name="screenrecord_status_color">#E94235</color> + <color name="screenrecord_icon_color">#D93025</color><!-- red 600 --> <color name="privacy_chip_background">#3ddc84</color> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 7525a9b1c19c..a52680365ae7 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1149,7 +1149,7 @@ <dimen name="edge_margin">8dp</dimen> <!-- The absolute side margins of quick settings --> - <dimen name="quick_settings_bottom_margin_media">16dp</dimen> + <dimen name="quick_settings_bottom_margin_media">8dp</dimen> <dimen name="rounded_corner_content_padding">0dp</dimen> <dimen name="nav_content_padding">0dp</dimen> <dimen name="nav_quick_scrub_track_edge_padding">24dp</dimen> @@ -1278,12 +1278,12 @@ <dimen name="qs_media_album_radius">14dp</dimen> <dimen name="qs_media_album_device_padding">26dp</dimen> <dimen name="qs_media_info_margin">12dp</dimen> - <dimen name="qs_media_info_spacing">4dp</dimen> + <dimen name="qs_media_info_spacing">8dp</dimen> <dimen name="qs_media_icon_size">20dp</dimen> <dimen name="qs_media_icon_offset">4dp</dimen> <dimen name="qs_center_guideline_padding">10dp</dimen> <dimen name="qs_media_action_spacing">4dp</dimen> - <dimen name="qs_media_action_top">8dp</dimen> + <dimen name="qs_media_action_margin">12dp</dimen> <dimen name="qs_seamless_height">24dp</dimen> <dimen name="qs_seamless_icon_size">12dp</dimen> <dimen name="qs_seamless_fallback_icon_size">@dimen/qs_seamless_icon_size</dimen> @@ -1291,8 +1291,8 @@ <dimen name="qs_footer_horizontal_margin">22dp</dimen> <dimen name="qs_media_disabled_seekbar_height">1dp</dimen> <dimen name="qs_media_enabled_seekbar_height">2dp</dimen> - <dimen name="qs_media_enabled_seekbar_vertical_padding">35dp</dimen> - <dimen name="qs_media_disabled_seekbar_vertical_padding">36dp</dimen> + <dimen name="qs_media_enabled_seekbar_vertical_padding">31dp</dimen> + <dimen name="qs_media_disabled_seekbar_vertical_padding">32dp</dimen> <!-- Size of Smartspace media recommendations cards in the QSPanel carousel --> <dimen name="qs_aa_media_rec_album_size_collapsed">72dp</dimen> @@ -1398,9 +1398,11 @@ <dimen name="controls_dialog_padding">32dp</dimen> <dimen name="controls_dialog_control_width">200dp</dimen> - <!-- Screen Record --> - <dimen name="screenrecord_dialog_padding">18dp</dimen> - <dimen name="screenrecord_logo_size">24dp</dimen> + <!-- Screen record dialog --> + <dimen name="screenrecord_option_padding">18dp</dimen> + <dimen name="screenrecord_logo_size">26dp</dimen> + <dimen name="screenrecord_option_icon_size">24dp</dimen> + <!-- Screen record status bar icon --> <dimen name="screenrecord_status_text_size">14sp</dimen> <dimen name="screenrecord_status_icon_radius">7dp</dimen> <dimen name="screenrecord_status_icon_width">21dp</dimen> @@ -1451,7 +1453,7 @@ <dimen name="people_space_messages_count_radius">12dp</dimen> <dimen name="people_space_widget_background_padding">6dp</dimen> <dimen name="required_width_for_medium">136dp</dimen> - <dimen name="required_width_for_large">138dp</dimen> + <dimen name="required_width_for_large">120dp</dimen> <dimen name="required_height_for_large">168dp</dimen> <dimen name="default_width">146dp</dimen> <dimen name="default_height">92dp</dimen> @@ -1470,10 +1472,12 @@ <dimen name="below_name_text_padding">16dp</dimen> <dimen name="above_notification_text_padding">22dp</dimen> <dimen name="regular_predefined_icon">18dp</dimen> - <dimen name="large_predefined_icon">24dp</dimen> + <dimen name="larger_predefined_icon">24dp</dimen> + <dimen name="largest_predefined_icon">32dp</dimen> <dimen name="availability_dot_status_padding">8dp</dimen> <dimen name="availability_dot_notification_padding">12dp</dimen> <dimen name="medium_content_padding_above_name">4dp</dimen> + <dimen name="padding_between_suppressed_layout_items">8dp</dimen> <!-- Accessibility floating menu --> <dimen name="accessibility_floating_menu_elevation">3dp</dimen> diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml index 027f162445c0..b999e51bdaa5 100644 --- a/packages/SystemUI/res/values/flags.xml +++ b/packages/SystemUI/res/values/flags.xml @@ -36,6 +36,13 @@ <!-- The new animations to/from lockscreen and AOD! --> <bool name="flag_lockscreen_animations">false</bool> + <!-- The new swipe to unlock animation, which shows the app/launcher behind the keyguard during + the swipe. --> + <bool name="flag_new_unlock_swipe_animation">true</bool> + + <!-- The shared-element transition between lockscreen smartspace and launcher smartspace. --> + <bool name="flag_smartspace_shared_element_transition">false</bool> + <bool name="flag_pm_lite">true</bool> <bool name="flag_charging_ripple">false</bool> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 83dbad1677aa..bc1c67c78fef 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1148,18 +1148,12 @@ <!-- Title of the confirmation dialog when exiting guest session [CHAR LIMIT=NONE] --> <string name="guest_exit_guest_dialog_title">Remove guest?</string> - <!-- Title of the confirmation dialog when resetting guest session [CHAR LIMIT=NONE] --> - <string name="guest_reset_guest_dialog_title">Reset guest?</string> - <!-- Message of the confirmation dialog when exiting guest session [CHAR LIMIT=NONE] --> <string name="guest_exit_guest_dialog_message">All apps and data in this session will be deleted.</string> <!-- Label for button in confirmation dialog when exiting guest session [CHAR LIMIT=35] --> <string name="guest_exit_guest_dialog_remove">Remove</string> - <!-- Label for button in confirmation dialog when resetting guest session [CHAR LIMIT=35] --> - <string name="guest_reset_guest_dialog_remove">Reset</string> - <!-- Title of the notification when resuming an existing guest session [CHAR LIMIT=NONE] --> <string name="guest_wipe_session_title">Welcome back, guest!</string> @@ -2895,7 +2889,7 @@ <!--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> <!--Text explaining there are no existing conversations to show in their Conversation widget [CHAR LIMIT=100] --> - <string name="no_conversations_text">Check back here once you get some messages</string> + <string name="no_conversations_text">Your recent conversations will show up here</string> <!--Text header for priority conversation tiles available to be added to the home screen [CHAR LIMIT=100] --> <string name="priority_conversations">Priority conversations</string> <!--Text header for recent conversation tiles available to be added to the home screen [CHAR LIMIT=100] --> @@ -2938,7 +2932,7 @@ <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] --> + <!-- Empty user name before user has selected a friend for their Conversation widget [CHAR LIMIT=10] --> <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> @@ -2952,6 +2946,8 @@ <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> + <!-- Text when the Conversation widget when Do Not Disturb is suppressing the notification. [CHAR LIMIT=50] --> + <string name="paused_by_dnd">Paused by Do Not Disturb</string> <!-- Content description text on the Conversation widget when a person has sent a new text message [CHAR LIMIT=150] --> <string name="new_notification_text_content_description"><xliff:g id="name" example="Anna">%1$s</xliff:g> sent a message</string> <!-- Content description text on the Conversation widget when a person has sent a new image message [CHAR LIMIT=150] --> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 7a5a3480d0c5..17a984e48ff1 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -404,6 +404,7 @@ <item name="offStateColor">@android:color/system_neutral1_800</item> <item name="underSurfaceColor">@android:color/system_neutral1_1000</item> <item name="android:colorBackground">@android:color/system_neutral1_900</item> + <item name="android:itemTextAppearance">@style/Control.MenuItem</item> </style> <style name="Theme.SystemUI.QuickSettings.BrightnessDialog" parent="@android:style/Theme.DeviceDefault.Dialog"> @@ -641,7 +642,10 @@ <item name="android:background">@drawable/qs_media_light_source</item> <item name="android:tint">?android:attr/textColorPrimary</item> <item name="android:stateListAnimator">@anim/media_button_state_list_animator</item> - <item name="android:padding">12dp</item> + <item name="android:paddingTop">8dp</item> + <item name="android:paddingStart">12dp</item> + <item name="android:paddingEnd">12dp</item> + <item name="android:paddingBottom">16dp</item> <item name="android:scaleType">centerInside</item> </style> @@ -693,6 +697,15 @@ <item name="android:windowCloseOnTouchOutside">true</item> </style> + <style name="ScreenRecord.Switch"> + <item name="android:textAppearance">?android:attr/textAppearanceMedium</item> + <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item> + <item name="android:switchMinWidth">52dp</item> + <item name="android:minHeight">48dp</item> + <item name="android:track">@drawable/settingslib_switch_track</item> + <item name="android:thumb">@drawable/settingslib_switch_thumb</item> + </style> + <!-- Screenshots --> <style name="LongScreenshotActivity" parent="@android:style/Theme.DeviceDefault.DayNight"> <item name="android:windowNoTitle">true</item> diff --git a/packages/SystemUI/res/values/tiles_states_strings.xml b/packages/SystemUI/res/values/tiles_states_strings.xml index 5ac7c1d3c65b..a0920bb8d540 100644 --- a/packages/SystemUI/res/values/tiles_states_strings.xml +++ b/packages/SystemUI/res/values/tiles_states_strings.xml @@ -40,9 +40,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_internet"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for wifi tile: unavailable, off, on. @@ -50,9 +50,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_wifi"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for cell (data) tile: unavailable, off, on. @@ -60,9 +60,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear.[CHAR LIMIT=32] --> <string-array name="tile_states_cell"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for battery (saver) tile: unavailable, off, on. @@ -70,9 +70,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_battery"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for dnd (Do not disturb) tile: unavailable, off, on. @@ -80,9 +80,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_dnd"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for flashlight tile: unavailable, off, on. @@ -90,9 +90,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_flashlight"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for rotation (lock) tile: unavailable, off, on. @@ -100,9 +100,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_rotation"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for bt (bluetooth) tile: unavailable, off, on. @@ -110,16 +110,16 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_bt"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for airplane tile: unavailable, off, on [CHAR LIMIT=32] --> <string-array name="tile_states_airplane"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for location tile: unavailable, off, on. @@ -127,9 +127,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_location"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for hotspot tile: unavailable, off, on. @@ -137,9 +137,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_hotspot"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for (color) inversion tile: unavailable, off, on. @@ -147,9 +147,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_inversion"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for (data) saver tile: unavailable, off, on. @@ -157,9 +157,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_saver"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for dark (mode) tile: unavailable, off, on. @@ -167,9 +167,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_dark"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for work (mode) tile: unavailable, off, on. @@ -177,9 +177,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_work"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for cast tile: unavailable, off, on. @@ -187,9 +187,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_cast"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for night (light) tile: unavailable, off, on. @@ -197,9 +197,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_night"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for screenrecord tile: unavailable, off, on. @@ -207,9 +207,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_screenrecord"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for reverse (charging) tile: unavailable, off, on. @@ -217,9 +217,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_reverse"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for reduce_brightness tile: unavailable, off, on. @@ -227,9 +227,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_reduce_brightness"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for cameratoggle tile: unavailable, off, on. @@ -237,9 +237,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear.[CHAR LIMIT=32] --> <string-array name="tile_states_cameratoggle"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for mictoggle tile: unavailable, off, on. @@ -247,9 +247,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_mictoggle"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for (home) controls tile: unavailable, off, on. @@ -257,9 +257,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_controls"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for (quick access) wallet tile: unavailable, off, on. @@ -267,9 +267,9 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_wallet"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> <!-- State names for alarm tile: unavailable, off, on. @@ -277,8 +277,8 @@ subtitle, so some of these may never appear on screen. They should still be translated as if they could appear. [CHAR LIMIT=32] --> <string-array name="tile_states_alarm"> - <item>@string/tile_unavailable</item> - <item>@string/switch_bar_off</item> - <item>@string/switch_bar_on</item> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> </string-array> </resources>
\ No newline at end of file diff --git a/packages/SystemUI/res/xml/media_collapsed.xml b/packages/SystemUI/res/xml/media_collapsed.xml index a03a1d3accfb..d6c6a60d56b8 100644 --- a/packages/SystemUI/res/xml/media_collapsed.xml +++ b/packages/SystemUI/res/xml/media_collapsed.xml @@ -92,7 +92,7 @@ android:layout_height="wrap_content" app:layout_constrainedWidth="true" android:layout_marginTop="@dimen/qs_media_info_spacing" - app:layout_constraintTop_toTopOf="@id/center_horizontal_guideline" + app:layout_constraintTop_toBottomOf="@id/center_horizontal_guideline" app:layout_constraintStart_toStartOf="@id/header_title" app:layout_constraintEnd_toStartOf="@id/media_action_barrier" app:layout_constraintHorizontal_bias="0"/> @@ -123,7 +123,7 @@ <Constraint android:id="@+id/action0" android:layout_width="48dp" - android:layout_height="56dp" + android:layout_height="48dp" android:layout_marginStart="@dimen/qs_media_padding" android:layout_marginEnd="@dimen/qs_media_action_spacing" android:visibility="gone" @@ -139,7 +139,7 @@ <Constraint android:id="@+id/action1" android:layout_width="48dp" - android:layout_height="56dp" + android:layout_height="48dp" android:layout_marginStart="@dimen/qs_media_action_spacing" android:layout_marginEnd="@dimen/qs_media_action_spacing" app:layout_constraintTop_toBottomOf="@id/center_horizontal_guideline" @@ -152,7 +152,7 @@ <Constraint android:id="@+id/action2" android:layout_width="48dp" - android:layout_height="56dp" + android:layout_height="48dp" android:layout_marginStart="@dimen/qs_media_action_spacing" android:layout_marginEnd="@dimen/qs_media_action_spacing" app:layout_constraintTop_toBottomOf="@id/center_horizontal_guideline" @@ -165,7 +165,7 @@ <Constraint android:id="@+id/action3" android:layout_width="48dp" - android:layout_height="56dp" + android:layout_height="48dp" android:layout_marginStart="@dimen/qs_media_action_spacing" android:layout_marginEnd="@dimen/qs_media_action_spacing" app:layout_constraintTop_toBottomOf="@id/center_horizontal_guideline" @@ -178,7 +178,7 @@ <Constraint android:id="@+id/action4" android:layout_width="48dp" - android:layout_height="56dp" + android:layout_height="48dp" android:layout_marginStart="@dimen/qs_media_action_spacing" android:layout_marginEnd="@dimen/qs_media_padding" android:visibility="gone" diff --git a/packages/SystemUI/res/xml/media_expanded.xml b/packages/SystemUI/res/xml/media_expanded.xml index fd04fa0723aa..9d706c5bad20 100644 --- a/packages/SystemUI/res/xml/media_expanded.xml +++ b/packages/SystemUI/res/xml/media_expanded.xml @@ -91,7 +91,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="@dimen/qs_media_padding" - android:layout_marginBottom="@dimen/qs_media_padding" + android:layout_marginBottom="@dimen/qs_media_info_margin" app:layout_constrainedWidth="true" android:layout_marginTop="@dimen/qs_media_info_spacing" app:layout_constraintTop_toBottomOf="@id/header_title" @@ -124,10 +124,10 @@ android:id="@+id/action0" android:layout_width="48dp" android:layout_height="48dp" - android:layout_marginTop="@dimen/qs_media_action_top" + android:layout_marginTop="@dimen/qs_media_action_margin" android:layout_marginStart="@dimen/qs_media_padding" android:layout_marginEnd="@dimen/qs_media_action_spacing" - android:layout_marginBottom="@dimen/qs_media_padding" + android:layout_marginBottom="@dimen/qs_media_action_margin" app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@id/action1" @@ -139,10 +139,10 @@ android:id="@+id/action1" android:layout_width="48dp" android:layout_height="48dp" - android:layout_marginTop="@dimen/qs_media_action_top" + android:layout_marginTop="@dimen/qs_media_action_margin" android:layout_marginStart="@dimen/qs_media_action_spacing" android:layout_marginEnd="@dimen/qs_media_action_spacing" - android:layout_marginBottom="@dimen/qs_media_padding" + android:layout_marginBottom="@dimen/qs_media_action_margin" app:layout_constraintLeft_toRightOf="@id/action0" app:layout_constraintRight_toLeftOf="@id/action2" app:layout_constraintTop_toBottomOf="@id/media_progress_bar" @@ -153,10 +153,10 @@ android:id="@+id/action2" android:layout_width="48dp" android:layout_height="48dp" - android:layout_marginTop="@dimen/qs_media_action_top" + android:layout_marginTop="@dimen/qs_media_action_margin" android:layout_marginStart="@dimen/qs_media_action_spacing" android:layout_marginEnd="@dimen/qs_media_action_spacing" - android:layout_marginBottom="@dimen/qs_media_padding" + android:layout_marginBottom="@dimen/qs_media_action_margin" app:layout_constraintLeft_toRightOf="@id/action1" app:layout_constraintRight_toLeftOf="@id/action3" app:layout_constraintTop_toBottomOf="@id/media_progress_bar" @@ -167,10 +167,10 @@ android:id="@+id/action3" android:layout_width="48dp" android:layout_height="48dp" - android:layout_marginTop="@dimen/qs_media_action_top" + android:layout_marginTop="@dimen/qs_media_action_margin" android:layout_marginStart="@dimen/qs_media_action_spacing" android:layout_marginEnd="@dimen/qs_media_action_spacing" - android:layout_marginBottom="@dimen/qs_media_padding" + android:layout_marginBottom="@dimen/qs_media_action_margin" app:layout_constraintLeft_toRightOf="@id/action2" app:layout_constraintRight_toLeftOf="@id/action4" app:layout_constraintTop_toBottomOf="@id/media_progress_bar" @@ -181,10 +181,10 @@ android:id="@+id/action4" android:layout_width="48dp" android:layout_height="48dp" - android:layout_marginTop="@dimen/qs_media_action_top" + android:layout_marginTop="@dimen/qs_media_action_margin" android:layout_marginStart="@dimen/qs_media_action_spacing" android:layout_marginEnd="@dimen/qs_media_padding" - android:layout_marginBottom="@dimen/qs_media_padding" + android:layout_marginBottom="@dimen/qs_media_action_margin" app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintLeft_toRightOf="@id/action3" app:layout_constraintRight_toRightOf="parent" diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java index c90833c5b8f2..2b35bcd9a3ea 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java @@ -345,7 +345,7 @@ public class PluginInstanceManager<T extends Plugin> { // Create our own ClassLoader so we can use our own code as the parent. ClassLoader classLoader = mManager.getClassLoader(info); Context pluginContext = new PluginContextWrapper( - mContext.createPackageContext(pkg, 0), classLoader); + mContext.createApplicationContext(info, 0), classLoader); Class<?> pluginClass = Class.forName(cls, true, classLoader); // TODO: Only create the plugin before version check if we need it for // legacy version check. diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/BlurUtils.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/BlurUtils.java index 59e1cb5db03e..61b0e4d9024f 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/BlurUtils.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/BlurUtils.java @@ -19,6 +19,7 @@ package com.android.systemui.shared.system; import static android.view.CrossWindowBlurListeners.CROSS_WINDOW_BLUR_SUPPORTED; import android.app.ActivityManager; +import android.os.SystemProperties; public abstract class BlurUtils { @@ -28,6 +29,7 @@ public abstract class BlurUtils { * @return {@code true} when supported. */ public static boolean supportsBlursOnWindows() { - return CROSS_WINDOW_BLUR_SUPPORTED && ActivityManager.isHighEndGfx(); + return CROSS_WINDOW_BLUR_SUPPORTED && ActivityManager.isHighEndGfx() + && !SystemProperties.getBoolean("persist.sysui.disableBlur", false); } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index 4827cab3b5c0..fde8213de0c6 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -173,7 +173,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard @Override public void onSwipeUp() { if (!mUpdateMonitor.isFaceDetectionRunning()) { - mUpdateMonitor.requestFaceAuth(); + mUpdateMonitor.requestFaceAuth(true); mKeyguardSecurityCallback.userActivity(); showMessage(null, null); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 38f8f7ac321f..bd000b2effa3 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -71,6 +71,7 @@ import android.os.ServiceManager; import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; +import android.os.Vibrator; import android.provider.Settings; import android.service.dreams.DreamService; import android.service.dreams.IDreamManager; @@ -85,6 +86,7 @@ import android.util.Log; import android.util.SparseArray; import android.util.SparseBooleanArray; +import androidx.annotation.Nullable; import androidx.lifecycle.Observer; import com.android.internal.annotations.VisibleForTesting; @@ -95,6 +97,7 @@ import com.android.systemui.DejankUtils; import com.android.systemui.Dumpable; import com.android.systemui.R; import com.android.systemui.biometrics.AuthController; +import com.android.systemui.biometrics.UdfpsController; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; @@ -282,6 +285,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab @VisibleForTesting protected boolean mTelephonyCapable; + private final boolean mAcquiredHapticEnabled; + @Nullable private final Vibrator mVibrator; + // Device provisioning state private boolean mDeviceProvisioned; @@ -309,6 +315,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private RingerModeTracker mRingerModeTracker; private int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED; private int mFaceRunningState = BIOMETRIC_STATE_STOPPED; + private boolean mIsFaceAuthUserRequested; private LockPatternUtils mLockPatternUtils; private final IDreamManager mDreamManager; private boolean mIsDreaming; @@ -778,8 +785,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) { - mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, - getCurrentUser()); + mFingerprintLockedOutPermanent = true; + requireStrongAuthIfAllLockedOut(); } if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT @@ -800,6 +807,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private void handleFingerprintLockoutReset() { mFingerprintLockedOut = false; + mFingerprintLockedOutPermanent = false; updateFingerprintListeningState(); } @@ -960,8 +968,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) { - mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, - getCurrentUser()); + mFaceLockedOutPermanent = true; + requireStrongAuthIfAllLockedOut(); } for (int i = 0; i < mCallbacks.size(); i++) { @@ -974,6 +982,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } private void handleFaceLockoutReset() { + mFaceLockedOutPermanent = false; updateFaceListeningState(); } @@ -1049,6 +1058,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab || isSimPinSecure()); } + private void requireStrongAuthIfAllLockedOut() { + final boolean faceLock = + mFaceLockedOutPermanent || !shouldListenForFace(); + final boolean fpLock = + mFingerprintLockedOutPermanent || !shouldListenForFingerprint(isUdfpsEnrolled()); + + if (faceLock && fpLock) { + Log.d(TAG, "All biometrics locked out - requiring strong auth"); + mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, + getCurrentUser()); + } + } public boolean getUserCanSkipBouncer(int userId) { return getUserHasTrust(userId) || getUserUnlockedWithBiometric(userId); @@ -1332,46 +1353,74 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab handleFingerprintAuthenticated(userId, isStrongBiometric); }; - private final FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback + @VisibleForTesting + final FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback = new AuthenticationCallback() { + private boolean mPlayedAcquiredHaptic; - @Override - public void onAuthenticationFailed() { - handleFingerprintAuthFailed(); - } + @Override + public void onAuthenticationFailed() { + handleFingerprintAuthFailed(); + } - @Override - public void onAuthenticationSucceeded(AuthenticationResult result) { - Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded"); - handleFingerprintAuthenticated(result.getUserId(), result.isStrongBiometric()); - Trace.endSection(); - } + @Override + public void onAuthenticationSucceeded(AuthenticationResult result) { + Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded"); + handleFingerprintAuthenticated(result.getUserId(), result.isStrongBiometric()); + Trace.endSection(); + + // on auth success, we sometimes never received an acquired haptic + if (!mPlayedAcquiredHaptic && isUdfpsEnrolled()) { + playAcquiredHaptic(); + } + } - @Override - public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { - handleFingerprintHelp(helpMsgId, helpString.toString()); - } + @Override + public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { + handleFingerprintHelp(helpMsgId, helpString.toString()); + } - @Override - public void onAuthenticationError(int errMsgId, CharSequence errString) { - handleFingerprintError(errMsgId, errString.toString()); - } + @Override + public void onAuthenticationError(int errMsgId, CharSequence errString) { + handleFingerprintError(errMsgId, errString.toString()); + } - @Override - public void onAuthenticationAcquired(int acquireInfo) { - handleFingerprintAcquired(acquireInfo); - } + @Override + public void onAuthenticationAcquired(int acquireInfo) { + handleFingerprintAcquired(acquireInfo); + if (acquireInfo == FingerprintManager.FINGERPRINT_ACQUIRED_GOOD + && isUdfpsEnrolled()) { + mPlayedAcquiredHaptic = true; + playAcquiredHaptic(); + } + } - @Override - public void onUdfpsPointerDown(int sensorId) { - Log.d(TAG, "onUdfpsPointerDown, sensorId: " + sensorId); - } + @Override + public void onUdfpsPointerDown(int sensorId) { + Log.d(TAG, "onUdfpsPointerDown, sensorId: " + sensorId); + mPlayedAcquiredHaptic = false; + } - @Override - public void onUdfpsPointerUp(int sensorId) { - Log.d(TAG, "onUdfpsPointerUp, sensorId: " + sensorId); + @Override + public void onUdfpsPointerUp(int sensorId) { + Log.d(TAG, "onUdfpsPointerUp, sensorId: " + sensorId); + } + }; + + /** + * Play haptic to signal udfps fingeprrint acquired. + */ + @VisibleForTesting + public void playAcquiredHaptic() { + if (mAcquiredHapticEnabled && mVibrator != null) { + String effect = Settings.Global.getString( + mContext.getContentResolver(), + "udfps_acquired_type"); + mVibrator.vibrate(UdfpsController.getVibration(effect, + UdfpsController.EFFECT_TICK), + UdfpsController.VIBRATION_SONIFICATION_ATTRIBUTES); } - }; + } private final FaceManager.FaceDetectionCallback mFaceDetectionCallback = (sensorId, userId, isStrongBiometric) -> { @@ -1380,7 +1429,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab }; @VisibleForTesting - FaceManager.AuthenticationCallback mFaceAuthenticationCallback + final FaceManager.AuthenticationCallback mFaceAuthenticationCallback = new FaceManager.AuthenticationCallback() { @Override @@ -1417,6 +1466,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private FaceManager mFaceManager; private List<FaceSensorPropertiesInternal> mFaceSensorProperties; private boolean mFingerprintLockedOut; + private boolean mFingerprintLockedOutPermanent; + private boolean mFaceLockedOutPermanent; private TelephonyManager mTelephonyManager; /** @@ -1663,7 +1714,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab LockPatternUtils lockPatternUtils, AuthController authController, TelephonyListenerManager telephonyListenerManager, - FeatureFlags featureFlags) { + FeatureFlags featureFlags, + @Nullable Vibrator vibrator) { mContext = context; mSubscriptionManager = SubscriptionManager.from(context); mTelephonyListenerManager = telephonyListenerManager; @@ -1678,6 +1730,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mLockPatternUtils = lockPatternUtils; mAuthController = authController; dumpManager.registerDumpable(getClass().getName(), this); + mAcquiredHapticEnabled = Settings.Global.getInt(mContext.getContentResolver(), + "udfps_acquired", 0) == 1; + mVibrator = vibrator; mHandler = new Handler(mainLooper) { @Override @@ -2057,12 +2112,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab /** * Requests face authentication if we're on a state where it's allowed. * This will re-trigger auth in case it fails. + * @param userInitiatedRequest true if the user explicitly requested face auth */ - public void requestFaceAuth() { - if (DEBUG) Log.d(TAG, "requestFaceAuth()"); + public void requestFaceAuth(boolean userInitiatedRequest) { + if (DEBUG) Log.d(TAG, "requestFaceAuth() userInitiated=" + userInitiatedRequest); + mIsFaceAuthUserRequested |= userInitiatedRequest; updateFaceListeningState(); } + public boolean isFaceAuthUserRequested() { + return mIsFaceAuthUserRequested; + } + /** * In case face auth is running, cancel it. */ @@ -2079,6 +2140,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mHandler.removeCallbacks(mRetryFaceAuthentication); boolean shouldListenForFace = shouldListenForFace(); if (mFaceRunningState == BIOMETRIC_STATE_RUNNING && !shouldListenForFace) { + mIsFaceAuthUserRequested = false; stopListeningForFace(); } else if (mFaceRunningState != BIOMETRIC_STATE_RUNNING && shouldListenForFace) { startListeningForFace(); diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java index 7cd43eff8e2a..cff6cf1f53f1 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java @@ -19,6 +19,7 @@ package com.android.systemui.accessibility.floatingmenu; import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU; import android.content.Context; +import android.os.UserHandle; import android.text.TextUtils; import androidx.annotation.MainThread; @@ -40,11 +41,11 @@ public class AccessibilityFloatingMenuController implements AccessibilityButtonModeObserver.ModeChangedListener, AccessibilityButtonTargetsObserver.TargetsChangedListener { - private final Context mContext; private final AccessibilityButtonModeObserver mAccessibilityButtonModeObserver; private final AccessibilityButtonTargetsObserver mAccessibilityButtonTargetsObserver; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; + private Context mContext; @VisibleForTesting IAccessibilityFloatingMenu mFloatingMenu; private int mBtnMode; @@ -79,6 +80,7 @@ public class AccessibilityFloatingMenuController implements @Override public void onUserSwitchComplete(int userId) { + mContext = mContext.createContextAsUser(UserHandle.of(userId), /* flags= */ 0); mBtnMode = mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode(); mBtnTargets = mAccessibilityButtonTargetsObserver.getCurrentAccessibilityButtonTargets(); diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java index 5bb55222e09b..e891e5b64b3d 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java @@ -16,6 +16,7 @@ package com.android.systemui.accessibility.floatingmenu; +import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.util.MathUtils.constrain; import static android.util.MathUtils.sq; import static android.view.WindowInsets.Type.ime; @@ -200,6 +201,7 @@ public class AccessibilityFloatingMenuView extends FrameLayout mListView = listView; mWindowManager = context.getSystemService(WindowManager.class); + mLastConfiguration = new Configuration(getResources().getConfiguration()); mAdapter = new AccessibilityTargetAdapter(mTargets); mUiHandler = createUiHandler(); mPosition = position; @@ -243,7 +245,6 @@ public class AccessibilityFloatingMenuView extends FrameLayout } }); - mLastConfiguration = new Configuration(getResources().getConfiguration()); initListView(); updateStrokeWith(getResources().getConfiguration().uiMode, mAlignment); @@ -567,8 +568,10 @@ public class AccessibilityFloatingMenuView extends FrameLayout final int currentX = (int) event.getX(); final int currentY = (int) event.getY(); + final int marginStartEnd = getMarginStartEndWith(mLastConfiguration); final Rect touchDelegateBounds = - new Rect(mMargin, mMargin, mMargin + getLayoutWidth(), mMargin + getLayoutHeight()); + new Rect(marginStartEnd, mMargin, marginStartEnd + getLayoutWidth(), + mMargin + getLayoutHeight()); if (action == MotionEvent.ACTION_DOWN && touchDelegateBounds.contains(currentX, currentY)) { mIsDownInEnlargedTouchArea = true; @@ -682,15 +685,13 @@ public class AccessibilityFloatingMenuView extends FrameLayout mListView.setLayoutManager(layoutManager); mListView.addOnItemTouchListener(this); mListView.animate().setInterpolator(new OvershootInterpolator()); - updateListView(); + updateListViewWith(mLastConfiguration); addView(mListView); } - private void updateListView() { - final LayoutParams layoutParams = (FrameLayout.LayoutParams) mListView.getLayoutParams(); - layoutParams.setMargins(mMargin, mMargin, mMargin, mMargin); - mListView.setLayoutParams(layoutParams); + private void updateListViewWith(Configuration configuration) { + updateMarginWith(configuration); final int elevation = getResources().getDimensionPixelSize(R.dimen.accessibility_floating_menu_elevation); @@ -719,13 +720,15 @@ public class AccessibilityFloatingMenuView extends FrameLayout @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); + mLastConfiguration.setTo(newConfig); + final int diff = newConfig.diff(mLastConfiguration); if ((diff & ActivityInfo.CONFIG_LOCALE) != 0) { updateAccessibilityTitle(mCurrentLayoutParams); } updateDimensions(); - updateListView(); + updateListViewWith(newConfig); updateItemViewWith(mSizeType); updateColor(); updateStrokeWith(newConfig.uiMode, mAlignment); @@ -733,8 +736,6 @@ public class AccessibilityFloatingMenuView extends FrameLayout updateRadiusWith(mSizeType, mRadiusType, mTargets.size()); updateScrollModeWith(hasExceededMaxLayoutHeight()); setSystemGestureExclusion(); - - mLastConfiguration.setTo(newConfig); } @VisibleForTesting @@ -756,11 +757,11 @@ public class AccessibilityFloatingMenuView extends FrameLayout } private int getMinWindowX() { - return -mMargin; + return -getMarginStartEndWith(mLastConfiguration); } private int getMaxWindowX() { - return mScreenWidth - mMargin - getLayoutWidth(); + return mScreenWidth - getMarginStartEndWith(mLastConfiguration) - getLayoutWidth(); } private int getMaxWindowY() { @@ -805,6 +806,15 @@ public class AccessibilityFloatingMenuView extends FrameLayout return layoutBottomY > imeY ? (layoutBottomY - imeY) : 0; } + private void updateMarginWith(Configuration configuration) { + // Avoid overlapping with system bars under landscape mode, update the margins of the menu + // to align the edge of system bars. + final int marginStartEnd = getMarginStartEndWith(configuration); + final LayoutParams layoutParams = (FrameLayout.LayoutParams) mListView.getLayoutParams(); + layoutParams.setMargins(marginStartEnd, mMargin, marginStartEnd, mMargin); + mListView.setLayoutParams(layoutParams); + } + private void updateOffsetWith(@ShapeType int shapeType, @Alignment int side) { final float halfWidth = getLayoutWidth() / 2.0f; final float offset = (shapeType == ShapeType.OVAL) ? 0 : halfWidth; @@ -896,6 +906,12 @@ public class AccessibilityFloatingMenuView extends FrameLayout return (mPadding + mIconHeight) * mTargets.size() + mPadding; } + private int getMarginStartEndWith(Configuration configuration) { + return configuration != null + && configuration.orientation == ORIENTATION_PORTRAIT + ? mMargin : 0; + } + private @DimenRes int getRadiusResId(@SizeType int sizeType, int itemCount) { return sizeType == SizeType.SMALL ? getSmallSizeResIdWith(itemCount) @@ -932,7 +948,7 @@ public class AccessibilityFloatingMenuView extends FrameLayout } private int getWindowWidth() { - return mMargin * 2 + getLayoutWidth(); + return getMarginStartEndWith(mLastConfiguration) * 2 + getLayoutWidth(); } private int getWindowHeight() { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index ec930b0c41d1..2d04d8da0cdc 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -16,6 +16,8 @@ package com.android.systemui.biometrics; +import static android.os.VibrationEffect.Composition.PRIMITIVE_LOW_TICK; + import static com.android.internal.util.Preconditions.checkArgument; import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION; @@ -67,9 +69,11 @@ import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.util.concurrency.DelayableExecutor; +import com.android.systemui.util.concurrency.Execution; import java.util.Optional; @@ -96,6 +100,7 @@ public class UdfpsController implements DozeReceiver { private static final long MIN_TOUCH_LOG_INTERVAL = 50; private final Context mContext; + private final Execution mExecution; private final FingerprintManager mFingerprintManager; @NonNull private final LayoutInflater mInflater; private final WindowManager mWindowManager; @@ -111,6 +116,7 @@ public class UdfpsController implements DozeReceiver { @NonNull private final FalsingManager mFalsingManager; @NonNull private final PowerManager mPowerManager; @NonNull private final AccessibilityManager mAccessibilityManager; + @NonNull private final LockscreenShadeTransitionController mLockscreenShadeTransitionController; @Nullable private final UdfpsHbmProvider mHbmProvider; // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple // sensors, this, in addition to a lot of the code here, will be updated. @@ -143,32 +149,22 @@ public class UdfpsController implements DozeReceiver { private Runnable mAodInterruptRunnable; @VisibleForTesting - static final AudioAttributes VIBRATION_SONIFICATION_ATTRIBUTES = + public static final AudioAttributes VIBRATION_SONIFICATION_ATTRIBUTES = new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) .build(); - private final VibrationEffect mEffectTick = VibrationEffect.get(VibrationEffect.EFFECT_TICK); - private final VibrationEffect mEffectTextureTick = + public static final VibrationEffect EFFECT_TICK = + VibrationEffect.get(VibrationEffect.EFFECT_TICK); + private static final VibrationEffect EFFECT_TEXTURE_TICK = VibrationEffect.get(VibrationEffect.EFFECT_TEXTURE_TICK); @VisibleForTesting - final VibrationEffect mEffectClick = VibrationEffect.get(VibrationEffect.EFFECT_CLICK); - private final VibrationEffect mEffectHeavy = + static final VibrationEffect EFFECT_CLICK = VibrationEffect.get(VibrationEffect.EFFECT_CLICK); + private static final VibrationEffect EFFECT_HEAVY = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK); - private final VibrationEffect mDoubleClick = + private static final VibrationEffect EFFECT_DOUBLE_CLICK = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK); - private final Runnable mAcquiredVibration = new Runnable() { - @Override - public void run() { - if (mVibrator == null) { - return; - } - String effect = Settings.Global.getString(mContext.getContentResolver(), - "udfps_acquired_type"); - mVibrator.vibrate(getVibration(effect, mEffectTick), VIBRATION_SONIFICATION_ATTRIBUTES); - } - }; private final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() { @Override @@ -434,30 +430,7 @@ public class UdfpsController implements DozeReceiver { mTouchLogTime = SystemClock.elapsedRealtime(); mPowerManager.userActivity(SystemClock.uptimeMillis(), PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0); - - // TODO: this should eventually be removed after ux testing - if (mVibrator != null) { - final ContentResolver contentResolver = - mContext.getContentResolver(); - int startEnabled = Settings.Global.getInt(contentResolver, - "udfps_start", 1); - if (startEnabled > 0) { - String startEffectSetting = Settings.Global.getString( - contentResolver, "udfps_start_type"); - mVibrator.vibrate(getVibration(startEffectSetting, - mEffectClick), VIBRATION_SONIFICATION_ATTRIBUTES); - } - - int acquiredEnabled = Settings.Global.getInt(contentResolver, - "udfps_acquired", 0); - if (acquiredEnabled > 0) { - int delay = Settings.Global.getInt(contentResolver, - "udfps_acquired_delay", 500); - mMainHandler.removeCallbacks(mAcquiredVibration); - mMainHandler.postDelayed(mAcquiredVibration, delay); - } - } - + playStartHaptic(); handled = true; } else if (sinceLastLog >= MIN_TOUCH_LOG_INTERVAL) { Log.v(TAG, "onTouch | finger move: " + touchInfo); @@ -494,6 +467,7 @@ public class UdfpsController implements DozeReceiver { @Inject public UdfpsController(@NonNull Context context, + @NonNull Execution execution, @NonNull LayoutInflater inflater, @Nullable FingerprintManager fingerprintManager, @NonNull WindowManager windowManager, @@ -507,10 +481,13 @@ public class UdfpsController implements DozeReceiver { @NonNull FalsingManager falsingManager, @NonNull PowerManager powerManager, @NonNull AccessibilityManager accessibilityManager, + @NonNull LockscreenShadeTransitionController lockscreenShadeTransitionController, @NonNull ScreenLifecycle screenLifecycle, @Nullable Vibrator vibrator, + @NonNull UdfpsHapticsSimulator udfpsHapticsSimulator, @NonNull Optional<UdfpsHbmProvider> hbmProvider) { mContext = context; + mExecution = execution; // TODO (b/185124905): inject main handler and vibrator once done prototyping mMainHandler = new Handler(Looper.getMainLooper()); mVibrator = vibrator; @@ -529,6 +506,7 @@ public class UdfpsController implements DozeReceiver { mFalsingManager = falsingManager; mPowerManager = powerManager; mAccessibilityManager = accessibilityManager; + mLockscreenShadeTransitionController = lockscreenShadeTransitionController; mHbmProvider = hbmProvider.orElse(null); screenLifecycle.addObserver(mScreenObserver); mScreenOn = screenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_ON; @@ -553,6 +531,29 @@ public class UdfpsController implements DozeReceiver { final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); context.registerReceiver(mBroadcastReceiver, filter); + + udfpsHapticsSimulator.setUdfpsController(this); + } + + /** + * Play haptic to signal udfps scanning started. + */ + @VisibleForTesting + public void playStartHaptic() { + if (mVibrator != null) { + final ContentResolver contentResolver = + mContext.getContentResolver(); + // TODO: these settings checks should eventually be removed after ux testing + // (b/185124905) + int startEnabled = Settings.Global.getInt(contentResolver, + "udfps_start", 1); + if (startEnabled > 0) { + String startEffectSetting = Settings.Global.getString( + contentResolver, "udfps_start_type"); + mVibrator.vibrate(getVibration(startEffectSetting, + EFFECT_CLICK), VIBRATION_SONIFICATION_ATTRIBUTES); + } + } } private int getCoreLayoutParamFlags() { @@ -716,6 +717,7 @@ public class UdfpsController implements DozeReceiver { mFgExecutor, mDumpManager, mKeyguardViewMediator, + mLockscreenShadeTransitionController, this ); case IUdfpsOverlayController.REASON_AUTH_BP: @@ -815,8 +817,8 @@ public class UdfpsController implements DozeReceiver { mIsAodInterruptActive = false; } - // This method can be called from the UI thread. private void onFingerDown(int x, int y, float minor, float major) { + mExecution.assertIsMainThread(); if (mView == null) { Log.w(TAG, "Null view in onFingerDown"); return; @@ -830,11 +832,10 @@ public class UdfpsController implements DozeReceiver { }); } - // This method can be called from the UI thread. private void onFingerUp() { + mExecution.assertIsMainThread(); mActivePointerId = -1; mGoodCaptureReceived = false; - mMainHandler.removeCallbacks(mAcquiredVibration); if (mView == null) { Log.w(TAG, "Null view in onFingerUp"); return; @@ -845,24 +846,34 @@ public class UdfpsController implements DozeReceiver { } } - - private VibrationEffect getVibration(String effect, VibrationEffect defaultEffect) { + /** + * get vibration to play given string + * used for testing purposes (b/185124905) + */ + public static VibrationEffect getVibration(String effect, VibrationEffect defaultEffect) { if (TextUtils.isEmpty(effect)) { return defaultEffect; } switch (effect.toLowerCase()) { case "click": - return mEffectClick; + return EFFECT_CLICK; case "heavy": - return mEffectHeavy; + return EFFECT_HEAVY; case "texture_tick": - return mEffectTextureTick; + return EFFECT_TEXTURE_TICK; case "tick": - return mEffectTick; + return EFFECT_TICK; case "double_tap": - return mDoubleClick; + return EFFECT_DOUBLE_CLICK; default: + try { + int primitive = Integer.parseInt(effect); + if (primitive <= PRIMITIVE_LOW_TICK && primitive > -1) { + return VibrationEffect.startComposition().addPrimitive(primitive).compose(); + } + } catch (NumberFormatException e) { + } return defaultEffect; } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHapticsSimulator.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHapticsSimulator.kt new file mode 100644 index 000000000000..ea2bbfad1b74 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHapticsSimulator.kt @@ -0,0 +1,94 @@ +/* + * 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.biometrics + +import android.media.AudioAttributes +import android.os.VibrationEffect +import android.os.Vibrator + +import com.android.keyguard.KeyguardUpdateMonitor + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.statusbar.commandline.Command +import com.android.systemui.statusbar.commandline.CommandRegistry + +import java.io.PrintWriter + +import javax.inject.Inject + +/** + * Used to simulate haptics that may be used for udfps authentication. + */ +@SysUISingleton +class UdfpsHapticsSimulator @Inject constructor( + commandRegistry: CommandRegistry, + val vibrator: Vibrator?, + val keyguardUpdateMonitor: KeyguardUpdateMonitor +) : Command { + val sonificationEffects = + AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) + .build() + var udfpsController: UdfpsController? = null + + init { + commandRegistry.registerCommand("udfps-haptic") { this } + } + + override fun execute(pw: PrintWriter, args: List<String>) { + if (args.isEmpty()) { + invalidCommand(pw) + } else { + when (args[0]) { + "start" -> { + udfpsController?.playStartHaptic() + } + "acquired" -> { + keyguardUpdateMonitor.playAcquiredHaptic() + } + "success" -> { + // needs to be kept up to date with AcquisitionClient#SUCCESS_VIBRATION_EFFECT + vibrator?.vibrate( + VibrationEffect.get(VibrationEffect.EFFECT_CLICK), + sonificationEffects) + } + "error" -> { + // needs to be kept up to date with AcquisitionClient#ERROR_VIBRATION_EFFECT + vibrator?.vibrate( + VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK), + sonificationEffects) + } + else -> invalidCommand(pw) + } + } + } + + override fun help(pw: PrintWriter) { + pw.println("Usage: adb shell cmd statusbar udfps-haptic <haptic>") + pw.println("Available commands:") + pw.println(" start") + pw.println(" acquired") + pw.println(" success, always plays CLICK haptic") + pw.println(" error, always plays DOUBLE_CLICK haptic") + } + + fun invalidCommand(pw: PrintWriter) { + pw.println("invalid command") + help(pw) + } +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java index 00888dfe48d3..35ca470df523 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java @@ -31,6 +31,7 @@ import com.android.systemui.R; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.phone.KeyguardBouncer; import com.android.systemui.statusbar.phone.StatusBar; @@ -54,6 +55,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud @NonNull private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; @NonNull private final DelayableExecutor mExecutor; @NonNull private final KeyguardViewMediator mKeyguardViewMediator; + @NonNull private final LockscreenShadeTransitionController mLockScreenShadeTransitionController; @NonNull private final UdfpsController mUdfpsController; @Nullable private Runnable mCancelDelayedHintRunnable; @@ -63,6 +65,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud private boolean mFaceDetectRunning; private boolean mHintShown; private int mStatusBarState; + private float mTransitionToFullShadeProgress; /** * hidden amount of pin/pattern/password bouncer @@ -81,12 +84,14 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud @NonNull DelayableExecutor mainDelayableExecutor, @NonNull DumpManager dumpManager, @NonNull KeyguardViewMediator keyguardViewMediator, + @NonNull LockscreenShadeTransitionController transitionController, @NonNull UdfpsController udfpsController) { super(view, statusBarStateController, statusBar, dumpManager); mKeyguardViewManager = statusBarKeyguardViewManager; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mExecutor = mainDelayableExecutor; mKeyguardViewMediator = keyguardViewMediator; + mLockScreenShadeTransitionController = transitionController; mUdfpsController = udfpsController; } @@ -116,6 +121,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud updatePauseAuth(); mKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor); + mLockScreenShadeTransitionController.setUdfpsKeyguardViewController(this); } @Override @@ -127,6 +133,9 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud mStatusBarStateController.removeCallback(mStateListener); mKeyguardViewManager.removeAlternateAuthInterceptor(mAlternateAuthInterceptor); mKeyguardUpdateMonitor.requestFaceAuthOnOccludingApp(false); + if (mLockScreenShadeTransitionController.getUdfpsKeyguardViewController() == this) { + mLockScreenShadeTransitionController.setUdfpsKeyguardViewController(null); + } if (mCancelDelayedHintRunnable != null) { mCancelDelayedHintRunnable.run(); @@ -256,11 +265,21 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud } } + /** + * Set the progress we're currently transitioning to the full shade. 0.0f means we're not + * transitioning yet, while 1.0f means we've fully dragged down. + */ + public void setTransitionToFullShadeProgress(float progress) { + mTransitionToFullShadeProgress = progress; + updateAlpha(); + } + private void updateAlpha() { // fade icon on transition to showing bouncer int alpha = mShowingUdfpsBouncer ? 255 : Math.abs((int) MathUtils.constrainedMap(0f, 255f, .4f, .7f, mInputBouncerHiddenAmount)); + alpha *= (1.0f - mTransitionToFullShadeProgress); mView.setUnpausedAlpha(alpha); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java index f8be35ab6cd8..77fad35d32d4 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java @@ -23,43 +23,36 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.RectF; -import android.os.Build; -import android.os.UserHandle; -import android.provider.Settings; import android.util.AttributeSet; import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; -import com.android.systemui.biometrics.UdfpsHbmTypes.HbmType; - /** - * Under-display fingerprint sensor Surface View. The surface should be used for HBM-specific things - * only. All other animations should be done on the other view. + * Surface View for providing the Global High-Brightness Mode (GHBM) illumination for UDFPS. */ -public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator { +public class UdfpsSurfaceView extends SurfaceView implements SurfaceHolder.Callback { private static final String TAG = "UdfpsSurfaceView"; - private static final String SETTING_HBM_TYPE = - "com.android.systemui.biometrics.UdfpsSurfaceView.hbmType"; - private static final @HbmType int DEFAULT_HBM_TYPE = UdfpsHbmTypes.GLOBAL_HBM; /** - * This is used instead of {@link android.graphics.drawable.Drawable}, because the latter has - * several abstract methods that are not used here but require implementation. + * Notifies {@link UdfpsView} when to enable GHBM illumination. */ - private interface SimpleDrawable { - void draw(Canvas canvas); + interface GhbmIlluminationListener { + /** + * @param surface the surface for which GHBM should be enabled. + * @param onIlluminatedRunnable a runnable that should be run after GHBM is enabled. + */ + void enableGhbm(@NonNull Surface surface, @Nullable Runnable onIlluminatedRunnable); } @NonNull private final SurfaceHolder mHolder; @NonNull private final Paint mSensorPaint; - @NonNull private final SimpleDrawable mIlluminationDotDrawable; - private final int mOnIlluminatedDelayMs; - private final @HbmType int mHbmType; - @NonNull private RectF mSensorRect; - @Nullable private UdfpsHbmProvider mHbmProvider; + @Nullable private GhbmIlluminationListener mGhbmIlluminationListener; + @Nullable private Runnable mOnIlluminatedRunnable; + boolean mAwaitingSurfaceToStartIllumination; + boolean mHasValidSurface; public UdfpsSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); @@ -71,82 +64,77 @@ public class UdfpsSurfaceView extends SurfaceView implements UdfpsIlluminator { setZOrderOnTop(true); mHolder = getHolder(); + mHolder.addCallback(this); mHolder.setFormat(PixelFormat.RGBA_8888); - mSensorRect = new RectF(); mSensorPaint = new Paint(0 /* flags */); mSensorPaint.setAntiAlias(true); mSensorPaint.setARGB(255, 255, 255, 255); mSensorPaint.setStyle(Paint.Style.FILL); + } - mIlluminationDotDrawable = canvas -> { - canvas.drawOval(mSensorRect, mSensorPaint); - }; - - mOnIlluminatedDelayMs = mContext.getResources().getInteger( - com.android.internal.R.integer.config_udfps_illumination_transition_ms); - - if (Build.IS_ENG || Build.IS_USERDEBUG) { - mHbmType = Settings.Secure.getIntForUser(mContext.getContentResolver(), - SETTING_HBM_TYPE, DEFAULT_HBM_TYPE, UserHandle.USER_CURRENT); - } else { - mHbmType = DEFAULT_HBM_TYPE; + @Override public void surfaceCreated(SurfaceHolder holder) { + mHasValidSurface = true; + if (mAwaitingSurfaceToStartIllumination) { + doIlluminate(mOnIlluminatedRunnable); + mOnIlluminatedRunnable = null; + mAwaitingSurfaceToStartIllumination = false; } } @Override - public void setHbmProvider(@Nullable UdfpsHbmProvider hbmProvider) { - mHbmProvider = hbmProvider; + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + // Unused. } - @Override - public void startIllumination(@Nullable Runnable onIlluminatedRunnable) { - if (mHbmProvider != null) { - final Surface surface = - (mHbmType == UdfpsHbmTypes.GLOBAL_HBM) ? mHolder.getSurface() : null; - - final Runnable onHbmEnabled = () -> { - if (mHbmType == UdfpsHbmTypes.GLOBAL_HBM) { - drawImmediately(mIlluminationDotDrawable); - } - if (onIlluminatedRunnable != null) { - // No framework API can reliably tell when a frame reaches the panel. A timeout - // is the safest solution. - postDelayed(onIlluminatedRunnable, mOnIlluminatedDelayMs); - } else { - Log.w(TAG, "startIllumination | onIlluminatedRunnable is null"); - } - }; - - mHbmProvider.enableHbm(mHbmType, surface, onHbmEnabled); - } else { - Log.e(TAG, "startIllumination | mHbmProvider is null"); - } + @Override public void surfaceDestroyed(SurfaceHolder holder) { + mHasValidSurface = false; } - @Override - public void stopIllumination() { - if (mHbmProvider != null) { - final Runnable onHbmDisabled = - (mHbmType == UdfpsHbmTypes.GLOBAL_HBM) ? this::invalidate : null; - mHbmProvider.disableHbm(onHbmDisabled); + void setGhbmIlluminationListener(@Nullable GhbmIlluminationListener listener) { + mGhbmIlluminationListener = listener; + } + + /** + * Note: there is no corresponding method to stop GHBM illumination. It is expected that + * {@link UdfpsView} will hide this view, which would destroy the surface and remove the + * illumination dot. + */ + void startGhbmIllumination(@Nullable Runnable onIlluminatedRunnable) { + if (mGhbmIlluminationListener == null) { + Log.e(TAG, "startIllumination | mGhbmIlluminationListener is null"); + return; + } + + if (mHasValidSurface) { + doIlluminate(onIlluminatedRunnable); } else { - Log.e(TAG, "stopIllumination | mHbmProvider is null"); + mAwaitingSurfaceToStartIllumination = true; + mOnIlluminatedRunnable = onIlluminatedRunnable; } } - void onSensorRectUpdated(@NonNull RectF sensorRect) { - mSensorRect = sensorRect; + private void doIlluminate(@Nullable Runnable onIlluminatedRunnable) { + if (mGhbmIlluminationListener == null) { + Log.e(TAG, "doIlluminate | mGhbmIlluminationListener is null"); + return; + } + + mGhbmIlluminationListener.enableGhbm(mHolder.getSurface(), onIlluminatedRunnable); } /** - * Immediately draws the provided drawable on this SurfaceView's surface. + * Immediately draws the illumination dot on this SurfaceView's surface. */ - private void drawImmediately(@NonNull SimpleDrawable drawable) { + void drawIlluminationDot(@NonNull RectF sensorRect) { + if (!mHasValidSurface) { + Log.e(TAG, "drawIlluminationDot | the surface is destroyed or was never created."); + return; + } Canvas canvas = null; try { canvas = mHolder.lockCanvas(); - drawable.draw(canvas); + canvas.drawOval(sensorRect, mSensorPaint); } finally { // Make sure the surface is never left in a bad state. if (canvas != null) { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java index 5e5584cf30ea..15f77ffc08fd 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java @@ -26,14 +26,19 @@ import android.graphics.Paint; import android.graphics.PointF; import android.graphics.RectF; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; +import android.os.Build; +import android.os.UserHandle; +import android.provider.Settings; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; +import android.view.Surface; import android.view.View; import android.widget.FrameLayout; import com.android.systemui.R; +import com.android.systemui.biometrics.UdfpsHbmTypes.HbmType; import com.android.systemui.doze.DozeReceiver; /** @@ -43,18 +48,25 @@ import com.android.systemui.doze.DozeReceiver; public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIlluminator { private static final String TAG = "UdfpsView"; + private static final String SETTING_HBM_TYPE = + "com.android.systemui.biometrics.UdfpsSurfaceView.hbmType"; + private static final @HbmType int DEFAULT_HBM_TYPE = UdfpsHbmTypes.LOCAL_HBM; + private static final int DEBUG_TEXT_SIZE_PX = 32; @NonNull private final RectF mSensorRect; @NonNull private final Paint mDebugTextPaint; + private final float mSensorTouchAreaCoefficient; + private final int mOnIlluminatedDelayMs; + private final @HbmType int mHbmType; - @NonNull private UdfpsSurfaceView mHbmSurfaceView; + // Only used for UdfpsHbmTypes.GLOBAL_HBM. + @Nullable private UdfpsSurfaceView mGhbmView; + // Can be different for enrollment, BiometricPrompt, Keyguard, etc. @Nullable private UdfpsAnimationViewController mAnimationViewController; - // Used to obtain the sensor location. @NonNull private FingerprintSensorPropertiesInternal mSensorProps; - - private final float mSensorTouchAreaCoefficient; + @Nullable private UdfpsHbmProvider mHbmProvider; @Nullable private String mDebugMessage; private boolean mIlluminationRequested; @@ -81,7 +93,15 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin mDebugTextPaint.setColor(Color.BLUE); mDebugTextPaint.setTextSize(DEBUG_TEXT_SIZE_PX); - mIlluminationRequested = false; + mOnIlluminatedDelayMs = mContext.getResources().getInteger( + com.android.internal.R.integer.config_udfps_illumination_transition_ms); + + if (Build.IS_ENG || Build.IS_USERDEBUG) { + mHbmType = Settings.Secure.getIntForUser(mContext.getContentResolver(), + SETTING_HBM_TYPE, DEFAULT_HBM_TYPE, UserHandle.USER_CURRENT); + } else { + mHbmType = DEFAULT_HBM_TYPE; + } } // Don't propagate any touch events to the child views. @@ -93,7 +113,9 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin @Override protected void onFinishInflate() { - mHbmSurfaceView = findViewById(R.id.hbm_view); + if (mHbmType == UdfpsHbmTypes.GLOBAL_HBM) { + mGhbmView = findViewById(R.id.hbm_view); + } } void setSensorProperties(@NonNull FingerprintSensorPropertiesInternal properties) { @@ -102,7 +124,7 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin @Override public void setHbmProvider(@Nullable UdfpsHbmProvider hbmProvider) { - mHbmSurfaceView.setHbmProvider(hbmProvider); + mHbmProvider = hbmProvider; } @Override @@ -125,7 +147,6 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin 2 * mSensorProps.sensorRadius + paddingX, 2 * mSensorProps.sensorRadius + paddingY); - mHbmSurfaceView.onSensorRectUpdated(new RectF(mSensorRect)); if (mAnimationViewController != null) { mAnimationViewController.onSensorRectUpdated(new RectF(mSensorRect)); } @@ -204,8 +225,32 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin if (mAnimationViewController != null) { mAnimationViewController.onIlluminationStarting(); } - mHbmSurfaceView.setVisibility(View.VISIBLE); - mHbmSurfaceView.startIllumination(onIlluminatedRunnable); + + if (mGhbmView != null) { + mGhbmView.setGhbmIlluminationListener(this::doIlluminate); + mGhbmView.setVisibility(View.VISIBLE); + mGhbmView.startGhbmIllumination(onIlluminatedRunnable); + } else { + doIlluminate(null /* surface */, onIlluminatedRunnable); + } + } + + private void doIlluminate(@Nullable Surface surface, @Nullable Runnable onIlluminatedRunnable) { + if (mGhbmView != null && surface == null) { + Log.e(TAG, "doIlluminate | surface must be non-null for GHBM"); + } + mHbmProvider.enableHbm(mHbmType, surface, () -> { + if (mGhbmView != null) { + mGhbmView.drawIlluminationDot(mSensorRect); + } + if (onIlluminatedRunnable != null) { + // No framework API can reliably tell when a frame reaches the panel. A timeout + // is the safest solution. + postDelayed(onIlluminatedRunnable, mOnIlluminatedDelayMs); + } else { + Log.w(TAG, "doIlluminate | onIlluminatedRunnable is null"); + } + }); } @Override @@ -214,7 +259,10 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin if (mAnimationViewController != null) { mAnimationViewController.onIlluminationStopped(); } - mHbmSurfaceView.setVisibility(View.INVISIBLE); - mHbmSurfaceView.stopIllumination(); + if (mGhbmView != null) { + mGhbmView.setGhbmIlluminationListener(null); + mGhbmView.setVisibility(View.INVISIBLE); + } + mHbmProvider.disableHbm(null /* onHbmDisabled */); } } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java index 2dbf30fdd289..de8ed7013ab2 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java @@ -25,6 +25,7 @@ import com.android.systemui.people.widget.LaunchConversationActivity; import com.android.systemui.screenrecord.ScreenRecordDialog; import com.android.systemui.screenshot.LongScreenshotActivity; import com.android.systemui.sensorprivacy.SensorUseStartedActivity; +import com.android.systemui.sensorprivacy.television.TvUnblockSensorActivity; import com.android.systemui.settings.brightness.BrightnessDialog; import com.android.systemui.statusbar.tv.notifications.TvNotificationPanelActivity; import com.android.systemui.tuner.TunerActivity; @@ -120,4 +121,10 @@ public abstract class DefaultActivityBinder { @IntoMap @ClassKey(SensorUseStartedActivity.class) public abstract Activity bindSensorUseStartedActivity(SensorUseStartedActivity activity); + + /** Inject into TvUnblockSensorActivity. */ + @Binds + @IntoMap + @ClassKey(TvUnblockSensorActivity.class) + public abstract Activity bindTvUnblockSensorActivity(TvUnblockSensorActivity activity); } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java index 746621dfda27..c97a30e6e13e 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java @@ -77,6 +77,7 @@ import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationRemoteInputManager; +import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.phone.AutoHideController; import com.android.systemui.statusbar.phone.ConfigurationControllerImpl; import com.android.systemui.statusbar.phone.ShadeController; @@ -227,11 +228,13 @@ public class DependencyProvider { Lazy<StatusBar> statusBarLazy, ShadeController shadeController, NotificationRemoteInputManager notificationRemoteInputManager, + NotificationShadeDepthController notificationShadeDepthController, SystemActions systemActions, @Main Handler mainHandler, UiEventLogger uiEventLogger, NavigationBarOverlayController navBarOverlayController, - ConfigurationController configurationController) { + ConfigurationController configurationController, + UserTracker userTracker) { return new NavigationBarController(context, windowManager, assistManagerLazy, @@ -252,11 +255,13 @@ public class DependencyProvider { statusBarLazy, shadeController, notificationRemoteInputManager, + notificationShadeDepthController, systemActions, mainHandler, uiEventLogger, navBarOverlayController, - configurationController); + configurationController, + userTracker); } /** */ diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java index 053d75d96720..954ba797e164 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java @@ -63,6 +63,7 @@ import android.service.dreams.IDreamManager; import android.telecom.TelecomManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; +import android.view.CrossWindowBlurListeners; import android.view.IWindowManager; import android.view.ViewConfiguration; import android.view.WindowManager; @@ -139,6 +140,12 @@ public class FrameworkServicesModule { } @Provides + @Singleton + static CrossWindowBlurListeners provideCrossWindowBlurListeners() { + return CrossWindowBlurListeners.getInstance(); + } + + @Provides @DisplayId static int provideDisplayId(Context context) { return context.getDisplayId(); diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index bb44b09f1bce..bc4ced452630 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -71,7 +71,6 @@ import com.android.systemui.model.SysUiState; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.GlobalActions.GlobalActionsManager; import com.android.systemui.plugins.GlobalActionsPanelPlugin; -import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -103,7 +102,6 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite private final LockPatternUtils mLockPatternUtils; private final KeyguardStateController mKeyguardStateController; - private final NotificationShadeDepthController mDepthController; private final SysUiState mSysUiState; private final ActivityStarter mActivityStarter; private final SysuiColorExtractor mSysuiColorExtractor; @@ -164,7 +162,6 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite IActivityManager iActivityManager, @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger, - NotificationShadeDepthController depthController, SysuiColorExtractor colorExtractor, IStatusBarService statusBarService, NotificationShadeWindowController notificationShadeWindowController, @@ -196,7 +193,6 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite iActivityManager, telecomManager, metricsLogger, - depthController, colorExtractor, statusBarService, notificationShadeWindowController, @@ -212,7 +208,6 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite mLockPatternUtils = lockPatternUtils; mKeyguardStateController = keyguardStateController; - mDepthController = depthController; mSysuiColorExtractor = colorExtractor; mStatusBarService = statusBarService; mNotificationShadeWindowController = notificationShadeWindowController; @@ -267,9 +262,8 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite protected ActionsDialogLite createDialog() { initDialogItems(); - mDepthController.setShowingHomeControls(true); ActionsDialog dialog = new ActionsDialog(getContext(), mAdapter, mOverflowAdapter, - this::getWalletViewController, mDepthController, mSysuiColorExtractor, + this::getWalletViewController, mSysuiColorExtractor, mStatusBarService, mNotificationShadeWindowController, mSysUiState, this::onRotate, isKeyguardShowing(), mPowerAdapter, getEventLogger(), getStatusBar()); @@ -336,16 +330,15 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite ActionsDialog(Context context, MyAdapter adapter, MyOverflowAdapter overflowAdapter, Provider<GlobalActionsPanelPlugin.PanelViewController> walletFactory, - NotificationShadeDepthController depthController, SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService, NotificationShadeWindowController notificationShadeWindowController, SysUiState sysuiState, Runnable onRotateCallback, boolean keyguardShowing, MyPowerOptionsAdapter powerAdapter, UiEventLogger uiEventLogger, StatusBar statusBar) { super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions, - adapter, overflowAdapter, depthController, sysuiColorExtractor, - statusBarService, notificationShadeWindowController, sysuiState, - onRotateCallback, keyguardShowing, powerAdapter, uiEventLogger, null, + adapter, overflowAdapter, sysuiColorExtractor, statusBarService, + notificationShadeWindowController, sysuiState, onRotateCallback, + keyguardShowing, powerAdapter, uiEventLogger, null, statusBar); mWalletFactory = walletFactory; @@ -494,8 +487,6 @@ public class GlobalActionsDialog extends GlobalActionsDialogLite float animatedValue = animation.getAnimatedFraction(); int alpha = (int) (animatedValue * mScrimAlpha * 255); mBackgroundDrawable.setAlpha(alpha); - mDepthController.updateGlobalDialogVisibility(animatedValue, - mGlobalActionsLayout); }); ObjectAnimator xAnimator = diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java index f30d6b13ad02..5acb3038b91b 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java @@ -119,7 +119,6 @@ import com.android.systemui.model.SysUiState; import com.android.systemui.plugins.GlobalActions.GlobalActionsManager; import com.android.systemui.plugins.GlobalActionsPanelPlugin; import com.android.systemui.scrim.ScrimDrawable; -import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -190,7 +189,6 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene private final TelecomManager mTelecomManager; private final MetricsLogger mMetricsLogger; private final UiEventLogger mUiEventLogger; - private final NotificationShadeDepthController mDepthController; private final SysUiState mSysUiState; private final GlobalActionsInfoProvider mInfoProvider; @@ -329,7 +327,6 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene IActivityManager iActivityManager, @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger, - NotificationShadeDepthController depthController, SysuiColorExtractor colorExtractor, IStatusBarService statusBarService, NotificationShadeWindowController notificationShadeWindowController, @@ -362,7 +359,6 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene mMetricsLogger = metricsLogger; mUiEventLogger = uiEventLogger; mInfoProvider = infoProvider; - mDepthController = depthController; mSysuiColorExtractor = colorExtractor; mStatusBarService = statusBarService; mNotificationShadeWindowController = notificationShadeWindowController; @@ -652,11 +648,9 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene protected ActionsDialogLite createDialog() { initDialogItems(); - mDepthController.setShowingHomeControls(false); ActionsDialogLite dialog = new ActionsDialogLite(mContext, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActionsLite, - mAdapter, mOverflowAdapter, - mDepthController, mSysuiColorExtractor, + mAdapter, mOverflowAdapter, mSysuiColorExtractor, mStatusBarService, mNotificationShadeWindowController, mSysUiState, this::onRotate, mKeyguardShowing, mPowerAdapter, mUiEventLogger, mInfoProvider, mStatusBar); @@ -2125,7 +2119,6 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene protected boolean mShowing; protected float mScrimAlpha; protected final NotificationShadeWindowController mNotificationShadeWindowController; - protected final NotificationShadeDepthController mDepthController; protected final SysUiState mSysUiState; private ListPopupWindow mOverflowPopup; private Dialog mPowerOptionsDialog; @@ -2181,7 +2174,6 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene ActionsDialogLite(Context context, int themeRes, MyAdapter adapter, MyOverflowAdapter overflowAdapter, - NotificationShadeDepthController depthController, SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService, NotificationShadeWindowController notificationShadeWindowController, SysUiState sysuiState, Runnable onRotateCallback, boolean keyguardShowing, @@ -2192,7 +2184,6 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene mAdapter = adapter; mOverflowAdapter = overflowAdapter; mPowerOptionsAdapter = powerAdapter; - mDepthController = depthController; mColorExtractor = sysuiColorExtractor; mStatusBarService = statusBarService; mNotificationShadeWindowController = notificationShadeWindowController; @@ -2409,7 +2400,6 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene float animatedValue = animation.getAnimatedFraction(); int alpha = (int) (animatedValue * mScrimAlpha * 255); mBackgroundDrawable.setAlpha(alpha); - mDepthController.updateGlobalDialogVisibility(animatedValue, mGlobalActionsLayout); }); ObjectAnimator xAnimator = @@ -2439,7 +2429,6 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene float animatedValue = 1f - animation.getAnimatedFraction(); int alpha = (int) (animatedValue * mScrimAlpha * 255); mBackgroundDrawable.setAlpha(alpha); - mDepthController.updateGlobalDialogVisibility(animatedValue, mGlobalActionsLayout); }); float xOffset = mGlobalActionsLayout.getAnimationOffsetX(); @@ -2476,7 +2465,6 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene dismissOverflow(true); dismissPowerOptions(true); mNotificationShadeWindowController.setRequestTopUi(false, TAG); - mDepthController.updateGlobalDialogVisibility(0, null /* view */); mSysUiState.setFlag(SYSUI_STATE_GLOBAL_ACTIONS_SHOWING, false) .commitUpdate(mContext.getDisplayId()); super.dismiss(); diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java index e37d3d586ccc..a641ad4b338b 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java @@ -30,7 +30,6 @@ import android.widget.ProgressBar; import android.widget.TextView; import com.android.internal.R; -import com.android.keyguard.KeyguardUpdateMonitor; import com.android.settingslib.Utils; import com.android.systemui.plugins.GlobalActions; import com.android.systemui.scrim.ScrimDrawable; @@ -51,7 +50,6 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks private final KeyguardStateController mKeyguardStateController; private final DeviceProvisionedController mDeviceProvisionedController; private final BlurUtils mBlurUtils; - private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final CommandQueue mCommandQueue; private GlobalActionsDialogLite mGlobalActionsDialog; private boolean mDisabled; @@ -60,15 +58,13 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks public GlobalActionsImpl(Context context, CommandQueue commandQueue, Lazy<GlobalActionsDialogLite> globalActionsDialogLazy, BlurUtils blurUtils, KeyguardStateController keyguardStateController, - DeviceProvisionedController deviceProvisionedController, - KeyguardUpdateMonitor keyguardUpdateMonitor) { + DeviceProvisionedController deviceProvisionedController) { mContext = context; mGlobalActionsDialogLazy = globalActionsDialogLazy; mKeyguardStateController = keyguardStateController; mDeviceProvisionedController = deviceProvisionedController; mCommandQueue = commandQueue; mBlurUtils = blurUtils; - mKeyguardUpdateMonitor = keyguardUpdateMonitor; mCommandQueue.addCallback(this); } @@ -87,7 +83,6 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks mGlobalActionsDialog = mGlobalActionsDialogLazy.get(); mGlobalActionsDialog.showOrHideDialog(mKeyguardStateController.isShowing(), mDeviceProvisionedController.isDeviceProvisioned()); - mKeyguardUpdateMonitor.requestFaceAuth(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java index 2873cd36409d..9b83b75cec22 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndication.java @@ -40,18 +40,22 @@ public class KeyguardIndication { private final View.OnClickListener mOnClickListener; @Nullable private final Drawable mBackground; + @Nullable + private final Long mMinVisibilityMillis; // in milliseconds private KeyguardIndication( CharSequence message, ColorStateList textColor, Drawable icon, View.OnClickListener onClickListener, - Drawable background) { + Drawable background, + Long minVisibilityMillis) { mMessage = message; mTextColor = textColor; mIcon = icon; mOnClickListener = onClickListener; mBackground = background; + mMinVisibilityMillis = minVisibilityMillis; } /** @@ -89,6 +93,14 @@ public class KeyguardIndication { return mBackground; } + /** + * Minimum time to show text in milliseconds. + * @return null if unspecified + */ + public @Nullable Long getMinVisibilityMillis() { + return mMinVisibilityMillis; + } + @Override public String toString() { String str = "KeyguardIndication{"; @@ -96,6 +108,7 @@ public class KeyguardIndication { if (mIcon != null) str += " mIcon=" + mIcon; if (mOnClickListener != null) str += " mOnClickListener=" + mOnClickListener; if (mBackground != null) str += " mBackground=" + mBackground; + if (mMinVisibilityMillis != null) str += " mMinVisibilityMillis=" + mMinVisibilityMillis; str += "}"; return str; } @@ -109,6 +122,7 @@ public class KeyguardIndication { private View.OnClickListener mOnClickListener; private ColorStateList mTextColor; private Drawable mBackground; + private Long mMinVisibilityMillis; public Builder() { } @@ -155,6 +169,15 @@ public class KeyguardIndication { } /** + * Optional. Set a required minimum visibility time in milliseconds for the text + * to show. + */ + public Builder setMinVisibilityMillis(Long minVisibilityMillis) { + this.mMinVisibilityMillis = minVisibilityMillis; + return this; + } + + /** * Build the KeyguardIndication. */ public KeyguardIndication build() { @@ -166,7 +189,8 @@ public class KeyguardIndication { } return new KeyguardIndication( - mMessage, mTextColor, mIcon, mOnClickListener, mBackground); + mMessage, mTextColor, mIcon, mOnClickListener, mBackground, + mMinVisibilityMillis); } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java index fc5f3b8ae994..df9977fddf5b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java @@ -167,12 +167,14 @@ public class KeyguardIndicationRotateTextViewController extends * - can be presented with an "error" color if isError is true */ public void showTransient(CharSequence newIndication, boolean isError) { + final long inAnimationDuration = 600L; // see KeyguardIndicationTextView.getYInDuration updateIndication(INDICATION_TYPE_TRANSIENT, new KeyguardIndication.Builder() .setMessage(newIndication) .setTextColor(isError ? Utils.getColorError(getContext()) : mInitialTextColorState) + .setMinVisibilityMillis(2000L + inAnimationDuration) .build(), /* showImmediately */true); } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt index 38d153e38ca9..941f2c6f4282 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt @@ -31,6 +31,7 @@ import com.android.keyguard.KeyguardViewController import com.android.systemui.animation.Interpolators import com.android.systemui.dagger.SysUISingleton import com.android.systemui.shared.system.smartspace.SmartspaceTransitionController +import com.android.systemui.statusbar.FeatureFlags import com.android.systemui.statusbar.policy.KeyguardStateController import dagger.Lazy import javax.inject.Inject @@ -89,7 +90,8 @@ class KeyguardUnlockAnimationController @Inject constructor( private val keyguardStateController: KeyguardStateController, private val keyguardViewMediator: Lazy<KeyguardViewMediator>, private val keyguardViewController: KeyguardViewController, - private val smartspaceTransitionController: SmartspaceTransitionController + private val smartspaceTransitionController: SmartspaceTransitionController, + private val featureFlags: FeatureFlags ) : KeyguardStateController.Callback { /** @@ -346,6 +348,10 @@ class KeyguardUnlockAnimationController @Inject constructor( * keyguard visible. */ private fun updateKeyguardViewMediatorIfThresholdsReached() { + if (!featureFlags.isNewKeyguardSwipeAnimationEnabled) { + return + } + val dismissAmount = keyguardStateController.dismissAmount // Hide the keyguard if we're fully dismissed, or if we're swiping to dismiss and have @@ -382,6 +388,10 @@ class KeyguardUnlockAnimationController @Inject constructor( * know if it needs to do something as a result. */ private fun updateSmartSpaceTransition() { + if (!featureFlags.isSmartSpaceSharedElementTransitionEnabled) { + return + } + val dismissAmount = keyguardStateController.dismissAmount // If we've begun a swipe, and are capable of doing the SmartSpace transition, start it! diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 88e9f69620ed..c84d6a87246a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -1677,8 +1677,8 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, * Disable notification shade background blurs until the keyguard is dismissed. * (Used during app launch animations) */ - public void disableBlursUntilHidden() { - mNotificationShadeDepthController.get().setIgnoreShadeBlurUntilHidden(true); + public void setBlursDisabledForAppLaunch(boolean disabled) { + mNotificationShadeDepthController.get().setBlursDisabledForAppLaunch(disabled); } public boolean isSecure() { @@ -2178,12 +2178,6 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, mDrawnCallback = null; } - // only play "unlock" noises if not on a call (since the incall UI - // disables the keyguard) - if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) { - playSounds(false); - } - LatencyTracker.getInstance(mContext) .onActionEnd(LatencyTracker.ACTION_LOCKSCREEN_UNLOCK); @@ -2301,6 +2295,13 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, } private void onKeyguardExitFinished() { + // only play "unlock" noises if not on a call (since the incall UI + // disables the keyguard) + if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) { + Log.i("TEST", "playSounds: false"); + playSounds(false); + } + setShowingLocked(false); mWakeAndUnlocking = false; mDismissCallbackRegistry.notifyDismissSucceeded(); diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt index 3957a60c5b45..8c6a3cad8b9f 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt @@ -204,7 +204,7 @@ class MediaCarouselController @Inject constructor( isSsReactivated: Boolean ) { if (addOrUpdatePlayer(key, oldKey, data)) { - MediaPlayerData.getMediaPlayer(key, null)?.let { + MediaPlayerData.getMediaPlayer(key)?.let { logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED it.mInstanceId, /* isRecommendationCard */ false, @@ -241,7 +241,7 @@ class MediaCarouselController @Inject constructor( if (DEBUG) Log.d(TAG, "Loading Smartspace media update") if (data.isActive) { addSmartspaceMediaRecommendations(key, data, shouldPrioritize) - MediaPlayerData.getMediaPlayer(key, null)?.let { + MediaPlayerData.getMediaPlayer(key)?.let { logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED it.mInstanceId, /* isRecommendationCard */ true, @@ -344,7 +344,8 @@ class MediaCarouselController @Inject constructor( // Returns true if new player is added private fun addOrUpdatePlayer(key: String, oldKey: String?, data: MediaData): Boolean { val dataCopy = data.copy(backgroundColor = bgColor) - val existingPlayer = MediaPlayerData.getMediaPlayer(key, oldKey) + MediaPlayerData.moveIfExists(oldKey, key) + val existingPlayer = MediaPlayerData.getMediaPlayer(key) val curVisibleMediaKey = MediaPlayerData.playerKeys() .elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex) if (existingPlayer == null) { @@ -386,7 +387,7 @@ class MediaCarouselController @Inject constructor( shouldPrioritize: Boolean ) { if (DEBUG) Log.d(TAG, "Updating smartspace target in carousel") - if (MediaPlayerData.getMediaPlayer(key, null) != null) { + if (MediaPlayerData.getMediaPlayer(key) != null) { Log.w(TAG, "Skip adding smartspace target in carousel") return } @@ -795,13 +796,18 @@ internal object MediaPlayerData { smartspaceMediaData = data } - fun getMediaPlayer(key: String, oldKey: String?): MediaControlPanel? { - // If the key was changed, update entry - oldKey?.let { - if (it != key) { - mediaData.remove(it)?.let { sortKey -> mediaData.put(key, sortKey) } - } + fun moveIfExists(oldKey: String?, newKey: String) { + if (oldKey == null || oldKey == newKey) { + return + } + + mediaData.remove(oldKey)?.let { + removeMediaPlayer(newKey) + mediaData.put(newKey, it) } + } + + fun getMediaPlayer(key: String): MediaControlPanel? { return mediaData.get(key)?.let { mediaPlayers.get(it) } } diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt index b0d4cb1c9818..cbcec9531ce4 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt @@ -236,7 +236,7 @@ class MediaCarouselScrollHandler( } private fun updateSettingsPresentation() { - if (showsSettingsButton) { + if (showsSettingsButton && settingsButton.width > 0) { val settingsOffset = MathUtils.map( 0.0f, getMaxTranslation().toFloat(), diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java index 19a67e95a496..a3d7a811cab1 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java @@ -347,10 +347,11 @@ public class MediaControlPanel { artistText.setText(data.getArtist()); // Transfer chip - mPlayerViewHolder.getSeamless().setVisibility(View.VISIBLE); + ViewGroup seamlessView = mPlayerViewHolder.getSeamless(); + seamlessView.setVisibility(View.VISIBLE); setVisibleAndAlpha(collapsedSet, R.id.media_seamless, true /*visible */); setVisibleAndAlpha(expandedSet, R.id.media_seamless, true /*visible */); - mPlayerViewHolder.getSeamless().setOnClickListener(v -> { + seamlessView.setOnClickListener(v -> { mMediaOutputDialogFactory.create(data.getPackageName(), true); }); @@ -374,9 +375,9 @@ public class MediaControlPanel { collapsedSet.setAlpha(seamlessId, seamlessAlpha); // Disable clicking on output switcher for resumption controls. mPlayerViewHolder.getSeamless().setEnabled(!data.getResumption()); + String deviceString = null; if (showFallback) { iconView.setImageDrawable(null); - deviceName.setText(null); } else if (device != null) { Drawable icon = device.getIcon(); iconView.setVisibility(View.VISIBLE); @@ -387,13 +388,16 @@ public class MediaControlPanel { } else { iconView.setImageDrawable(icon); } - deviceName.setText(device.getName()); + deviceString = device.getName(); } else { // Reset to default Log.w(TAG, "device is null. Not binding output chip."); iconView.setVisibility(View.GONE); - deviceName.setText(com.android.internal.R.string.ext_media_seamless_action); + deviceString = mContext.getString( + com.android.internal.R.string.ext_media_seamless_action); } + deviceName.setText(deviceString); + seamlessView.setContentDescription(deviceString); List<Integer> actionsWhenCollapsed = data.getActionsToShowInCompact(); // Media controls diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java index 0d5faff65aab..391dff634dab 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java @@ -46,7 +46,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private ViewGroup mConnectedItem; - private boolean mInclueDynamicGroup; + private boolean mIncludeDynamicGroup; public MediaOutputAdapter(MediaOutputController controller) { super(controller); @@ -56,7 +56,6 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { public MediaDeviceBaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) { super.onCreateViewHolder(viewGroup, viewType); - return new MediaDeviceViewHolder(mHolderView); } @@ -66,7 +65,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { if (position == size && mController.isZeroMode()) { viewHolder.onBind(CUSTOMIZED_ITEM_PAIR_NEW, false /* topMargin */, true /* bottomMargin */); - } else if (mInclueDynamicGroup) { + } else if (mIncludeDynamicGroup) { if (position == 0) { viewHolder.onBind(CUSTOMIZED_ITEM_DYNAMIC_GROUP, true /* topMargin */, false /* bottomMargin */); @@ -76,11 +75,12 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { // from "position - 1". viewHolder.onBind(((List<MediaDevice>) (mController.getMediaDevices())) .get(position - 1), - false /* topMargin */, position == size /* bottomMargin */); + false /* topMargin */, position == size /* bottomMargin */, position); } } else if (position < size) { viewHolder.onBind(((List<MediaDevice>) (mController.getMediaDevices())).get(position), - position == 0 /* topMargin */, position == (size - 1) /* bottomMargin */); + position == 0 /* topMargin */, position == (size - 1) /* bottomMargin */, + position); } else if (DEBUG) { Log.d(TAG, "Incorrect position: " + position); } @@ -88,8 +88,8 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { @Override public int getItemCount() { - mInclueDynamicGroup = mController.getSelectedMediaDevice().size() > 1; - if (mController.isZeroMode() || mInclueDynamicGroup) { + mIncludeDynamicGroup = mController.getSelectedMediaDevice().size() > 1; + if (mController.isZeroMode() || mIncludeDynamicGroup) { // Add extra one for "pair new" or dynamic group return mController.getMediaDevices().size() + 1; } @@ -120,15 +120,17 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { } @Override - void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) { - super.onBind(device, topMargin, bottomMargin); - final boolean currentlyConnected = !mInclueDynamicGroup && isCurrentlyConnected(device); + void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin, int position) { + super.onBind(device, topMargin, bottomMargin, position); + final boolean currentlyConnected = !mIncludeDynamicGroup + && isCurrentlyConnected(device); if (currentlyConnected) { mConnectedItem = mContainerLayout; } mBottomDivider.setVisibility(View.GONE); mCheckBox.setVisibility(View.GONE); - if (currentlyConnected && mController.isActiveRemoteDevice(device)) { + if (currentlyConnected && mController.isActiveRemoteDevice(device) + && mController.getSelectableMediaDevice().size() > 0) { // Init active device layout mDivider.setVisibility(View.VISIBLE); mDivider.setTransitionAlpha(1); @@ -140,6 +142,9 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { mDivider.setVisibility(View.GONE); mAddIcon.setVisibility(View.GONE); } + if (mCurrentActivePosition == position) { + mCurrentActivePosition = -1; + } if (mController.isTransferring()) { if (device.getState() == MediaDeviceState.STATE_CONNECTING && !mController.hasAdjustVolumeUserRestriction()) { @@ -160,6 +165,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { setTwoLineLayout(device, true /* bFocused */, true /* showSeekBar */, false /* showProgressBar */, false /* showSubtitle */); initSeekbar(device); + mCurrentActivePosition = position; } else { setSingleLineLayout(getItemTitle(device), false /* bFocused */); mContainerLayout.setOnClickListener(v -> onItemClick(v, device)); @@ -186,11 +192,16 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { mConnectedItem = mContainerLayout; mBottomDivider.setVisibility(View.GONE); mCheckBox.setVisibility(View.GONE); - mDivider.setVisibility(View.VISIBLE); - mDivider.setTransitionAlpha(1); - mAddIcon.setVisibility(View.VISIBLE); - mAddIcon.setTransitionAlpha(1); - mAddIcon.setOnClickListener(v -> onEndItemClick()); + if (mController.getSelectableMediaDevice().size() > 0) { + mDivider.setVisibility(View.VISIBLE); + mDivider.setTransitionAlpha(1); + mAddIcon.setVisibility(View.VISIBLE); + mAddIcon.setTransitionAlpha(1); + mAddIcon.setOnClickListener(v -> onEndItemClick()); + } else { + mDivider.setVisibility(View.GONE); + mAddIcon.setVisibility(View.GONE); + } mTitleIcon.setImageDrawable(getSpeakerDrawable()); final CharSequence sessionName = mController.getSessionName(); final CharSequence title = TextUtils.isEmpty(sessionName) @@ -206,6 +217,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { return; } + mCurrentActivePosition = -1; playSwitchingAnim(mConnectedItem, view); mController.connectDevice(device); device.setState(MediaDeviceState.STATE_CONNECTING); diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java index bcef43c93be4..0890841eb4fb 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java @@ -64,10 +64,12 @@ public abstract class MediaOutputBaseAdapter extends Context mContext; View mHolderView; boolean mIsDragging; + int mCurrentActivePosition; public MediaOutputBaseAdapter(MediaOutputController controller) { mController = controller; mIsDragging = false; + mCurrentActivePosition = -1; } @Override @@ -99,6 +101,10 @@ public abstract class MediaOutputBaseAdapter extends return mIsAnimating; } + int getCurrentActivePosition() { + return mCurrentActivePosition; + } + /** * ViewHolder for binding device view. */ @@ -136,7 +142,7 @@ public abstract class MediaOutputBaseAdapter extends mCheckBox = view.requireViewById(R.id.check_box); } - void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) { + void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin, int position) { mDeviceId = device.getId(); ThreadUtils.postOnBackgroundThread(() -> { Icon icon = mController.getDeviceIconCompat(device).toIcon(mContext); @@ -214,6 +220,9 @@ public abstract class MediaOutputBaseAdapter extends } void initSeekbar(MediaDevice device) { + if (!mController.isVolumeControlEnabled(device)) { + disableSeekBar(); + } mSeekBar.setMax(device.getMaxVolume()); mSeekBar.setMin(0); final int currentVolume = device.getCurrentVolume(); @@ -242,6 +251,7 @@ public abstract class MediaOutputBaseAdapter extends } void initSessionSeekbar() { + disableSeekBar(); mSeekBar.setMax(mController.getSessionVolumeMax()); mSeekBar.setMin(0); final int currentVolume = mController.getSessionVolume(); @@ -330,5 +340,10 @@ public abstract class MediaOutputBaseAdapter extends PorterDuff.Mode.SRC_IN)); return BluetoothUtils.buildAdvancedDrawable(mContext, drawable); } + + private void disableSeekBar() { + mSeekBar.setEnabled(false); + mSeekBar.setOnTouchListener((v, event) -> true); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java index 8a9a6e694658..cdcdf9a1d4de 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java @@ -174,7 +174,12 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements mHeaderTitle.setGravity(Gravity.NO_GRAVITY); } if (!mAdapter.isDragging() && !mAdapter.isAnimating()) { - mAdapter.notifyDataSetChanged(); + int currentActivePosition = mAdapter.getCurrentActivePosition(); + if (currentActivePosition >= 0) { + mAdapter.notifyItemChanged(currentActivePosition); + } else { + mAdapter.notifyDataSetChanged(); + } } // Show when remote media session is available mStopButton.setVisibility(getStopButtonVisibility()); diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java index 8fee9253a421..5293c8850267 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java @@ -465,6 +465,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback { || features.contains(MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK)); } + boolean isVolumeControlEnabled(@NonNull MediaDevice device) { + return !device.getFeatures().contains(MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK); + } + private final MediaController.Callback mCb = new MediaController.Callback() { @Override public void onMetadataChanged(MediaMetadata metadata) { diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java index 24e076bb22f1..968c3506f39f 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java @@ -68,7 +68,7 @@ public class MediaOutputGroupAdapter extends MediaOutputBaseAdapter { final int size = mGroupMediaDevices.size(); if (newPosition < size) { viewHolder.onBind(mGroupMediaDevices.get(newPosition), false /* topMargin */, - newPosition == (size - 1) /* bottomMargin */); + newPosition == (size - 1) /* bottomMargin */, position); return; } if (DEBUG) { @@ -94,8 +94,8 @@ public class MediaOutputGroupAdapter extends MediaOutputBaseAdapter { } @Override - void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) { - super.onBind(device, topMargin, bottomMargin); + void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin, int position) { + super.onBind(device, topMargin, bottomMargin, position); mDivider.setVisibility(View.GONE); mAddIcon.setVisibility(View.GONE); mBottomDivider.setVisibility(View.GONE); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index da09793580bb..26f38ddd5919 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -129,12 +129,14 @@ import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; +import com.android.systemui.settings.UserTracker; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.AutoHideUiElement; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue.Callbacks; import com.android.systemui.statusbar.NotificationRemoteInputManager; +import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.AutoHideController; @@ -199,6 +201,8 @@ public class NavigationBar implements View.OnAttachStateChangeListener, private final Handler mHandler; private final NavigationBarOverlayController mNavbarOverlayController; private final UiEventLogger mUiEventLogger; + private final UserTracker mUserTracker; + private final NotificationShadeDepthController mNotificationShadeDepthController; private Bundle mSavedState; private NavigationBarView mNavigationBarView; @@ -232,7 +236,6 @@ public class NavigationBar implements View.OnAttachStateChangeListener, private boolean mTransientShown; private int mNavBarMode = NAV_BAR_MODE_3BUTTON; - private int mA11yBtnMode; private LightBarController mLightBarController; private AutoHideController mAutoHideController; @@ -437,6 +440,25 @@ public class NavigationBar implements View.OnAttachStateChangeListener, } }; + private final NotificationShadeDepthController.DepthListener mDepthListener = + new NotificationShadeDepthController.DepthListener() { + boolean mHasBlurs; + + @Override + public void onWallpaperZoomOutChanged(float zoomOut) { + } + + @Override + public void onBlurRadiusChanged(int radius) { + boolean hasBlurs = radius != 0; + if (hasBlurs == mHasBlurs) { + return; + } + mHasBlurs = hasBlurs; + mNavigationBarView.setWindowHasBlurs(hasBlurs); + } + }; + public NavigationBar(Context context, WindowManager windowManager, Lazy<AssistManager> assistManagerLazy, @@ -456,10 +478,12 @@ public class NavigationBar implements View.OnAttachStateChangeListener, Optional<Recents> recentsOptional, Lazy<StatusBar> statusBarLazy, ShadeController shadeController, NotificationRemoteInputManager notificationRemoteInputManager, + NotificationShadeDepthController notificationShadeDepthController, SystemActions systemActions, @Main Handler mainHandler, NavigationBarOverlayController navbarOverlayController, - UiEventLogger uiEventLogger) { + UiEventLogger uiEventLogger, + UserTracker userTracker) { mContext = context; mWindowManager = windowManager; mAccessibilityManager = accessibilityManager; @@ -484,10 +508,11 @@ public class NavigationBar implements View.OnAttachStateChangeListener, mHandler = mainHandler; mNavbarOverlayController = navbarOverlayController; mUiEventLogger = uiEventLogger; + mUserTracker = userTracker; + mNotificationShadeDepthController = notificationShadeDepthController; mNavBarMode = mNavigationModeController.addListener(this); mAccessibilityButtonModeObserver.addListener(this); - mA11yBtnMode = mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode(); } public NavigationBarView getView() { @@ -568,6 +593,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener, mIsCurrentUserSetup = mDeviceProvisionedController.isCurrentUserSetup(); mDeviceProvisionedController.addCallback(mUserSetupListener); + mNotificationShadeDepthController.addListener(mDepthListener); setAccessibilityFloatingMenuModeIfNeeded(); @@ -584,6 +610,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener, mAccessibilityManagerWrapper.removeCallback(mAccessibilityListener); mContentResolver.unregisterContentObserver(mAssistContentObserver); mDeviceProvisionedController.removeCallback(mUserSetupListener); + mNotificationShadeDepthController.removeListener(mDepthListener); DeviceConfig.removeOnPropertiesChangedListener(mOnPropertiesChangedListener); } @@ -1375,8 +1402,9 @@ public class NavigationBar implements View.OnAttachStateChangeListener, private void setAccessibilityFloatingMenuModeIfNeeded() { if (QuickStepContract.isGesturalMode(mNavBarMode)) { - Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE, - ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU); + Settings.Secure.putIntForUser(mContentResolver, + Settings.Secure.ACCESSIBILITY_BUTTON_MODE, + ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU, UserHandle.USER_CURRENT); } } @@ -1437,7 +1465,8 @@ public class NavigationBar implements View.OnAttachStateChangeListener, // If accessibility button is floating menu mode, click and long click state should be // disabled. - if (mA11yBtnMode == ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU) { + if (mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode() + == ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU) { return 0; } @@ -1450,12 +1479,14 @@ public class NavigationBar implements View.OnAttachStateChangeListener, .getAssistInfoForUser(UserHandle.USER_CURRENT) != null; boolean longPressDefault = mContext.getResources().getBoolean( com.android.internal.R.bool.config_assistLongPressHomeEnabledDefault); - mLongPressHomeEnabled = Settings.Secure.getInt(mContentResolver, - Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, longPressDefault ? 1 : 0) != 0; + mLongPressHomeEnabled = Settings.Secure.getIntForUser(mContentResolver, + Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, longPressDefault ? 1 : 0, + mUserTracker.getUserId()) != 0; boolean gestureDefault = mContext.getResources().getBoolean( com.android.internal.R.bool.config_assistTouchGestureEnabledDefault); - mAssistantTouchGestureEnabled = Settings.Secure.getInt(mContentResolver, - Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED, gestureDefault ? 1 : 0) != 0; + mAssistantTouchGestureEnabled = Settings.Secure.getIntForUser(mContentResolver, + Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED, gestureDefault ? 1 : 0, + mUserTracker.getUserId()) != 0; if (mOverviewProxyService.getProxy() != null) { try { mOverviewProxyService.getProxy().onAssistantAvailable(mAssistantAvailable @@ -1546,7 +1577,6 @@ public class NavigationBar implements View.OnAttachStateChangeListener, @Override public void onAccessibilityButtonModeChanged(int mode) { - mA11yBtnMode = mode; updateAccessibilityServicesState(mAccessibilityManager); } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java index 8b5a537ba242..b9e9240b354a 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java @@ -57,9 +57,11 @@ import com.android.systemui.model.SysUiState; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; +import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue.Callbacks; import com.android.systemui.statusbar.NotificationRemoteInputManager; +import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; @@ -114,8 +116,10 @@ public class NavigationBarController implements Callbacks, private final DisplayManager mDisplayManager; private final NavigationBarOverlayController mNavBarOverlayController; private final TaskbarDelegate mTaskbarDelegate; + private final NotificationShadeDepthController mNotificationShadeDepthController; private int mNavMode; private boolean mIsTablet; + private final UserTracker mUserTracker; /** A displayId - nav bar maps. */ @VisibleForTesting @@ -147,11 +151,13 @@ public class NavigationBarController implements Callbacks, Lazy<StatusBar> statusBarLazy, ShadeController shadeController, NotificationRemoteInputManager notificationRemoteInputManager, + NotificationShadeDepthController notificationShadeDepthController, SystemActions systemActions, @Main Handler mainHandler, UiEventLogger uiEventLogger, NavigationBarOverlayController navBarOverlayController, - ConfigurationController configurationController) { + ConfigurationController configurationController, + UserTracker userTracker) { mContext = context; mWindowManager = windowManager; mAssistManagerLazy = assistManagerLazy; @@ -172,6 +178,7 @@ public class NavigationBarController implements Callbacks, mStatusBarLazy = statusBarLazy; mShadeController = shadeController; mNotificationRemoteInputManager = notificationRemoteInputManager; + mNotificationShadeDepthController = notificationShadeDepthController; mSystemActions = systemActions; mUiEventLogger = uiEventLogger; mHandler = mainHandler; @@ -184,6 +191,7 @@ public class NavigationBarController implements Callbacks, mNavigationModeController.addListener(this); mTaskbarDelegate = new TaskbarDelegate(mOverviewProxyService); mIsTablet = isTablet(mContext.getResources().getConfiguration()); + mUserTracker = userTracker; } @Override @@ -358,10 +366,12 @@ public class NavigationBarController implements Callbacks, mStatusBarLazy, mShadeController, mNotificationRemoteInputManager, + mNotificationShadeDepthController, mSystemActions, mHandler, mNavBarOverlayController, - mUiEventLogger); + mUiEventLogger, + mUserTracker); mNavigationBars.put(displayId, navBar); View navigationBarView = navBar.createView(savedState); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java index 7af4853dd3f2..4816f1cf8d6a 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java @@ -413,6 +413,13 @@ public class NavigationBarView extends FrameLayout implements return super.onTouchEvent(event); } + /** + * If we're blurring the shade window. + */ + public void setWindowHasBlurs(boolean hasBlurs) { + mRegionSamplingHelper.setWindowHasBlurs(hasBlurs); + } + void onTransientStateChanged(boolean isTransient) { mEdgeBackGestureHandler.onNavBarTransientStateChanged(isTransient); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/RegionSamplingHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/RegionSamplingHelper.java index 70117eb6d2f0..560d89af8e92 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/RegionSamplingHelper.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/RegionSamplingHelper.java @@ -65,6 +65,7 @@ public class RegionSamplingHelper implements View.OnAttachStateChangeListener, private final float mLuminanceChangeThreshold; private boolean mFirstSamplingAfterStart; private boolean mWindowVisible; + private boolean mWindowHasBlurs; private SurfaceControl mRegisteredStopLayer = null; private ViewTreeObserver.OnDrawListener mUpdateOnDraw = new ViewTreeObserver.OnDrawListener() { @Override @@ -153,6 +154,7 @@ public class RegionSamplingHelper implements View.OnAttachStateChangeListener, boolean isSamplingEnabled = mSamplingEnabled && !mSamplingRequestBounds.isEmpty() && mWindowVisible + && !mWindowHasBlurs && (mSampledView.isAttachedToWindow() || mFirstSamplingAfterStart); if (isSamplingEnabled) { ViewRootImpl viewRootImpl = mSampledView.getViewRootImpl(); @@ -225,6 +227,14 @@ public class RegionSamplingHelper implements View.OnAttachStateChangeListener, updateSamplingListener(); } + /** + * If we're blurring the shade window. + */ + public void setWindowHasBlurs(boolean hasBlurs) { + mWindowHasBlurs = hasBlurs; + updateSamplingListener(); + } + public void dump(PrintWriter pw) { pw.println("RegionSamplingHelper:"); pw.println(" sampleView isAttached: " + mSampledView.isAttachedToWindow()); @@ -238,6 +248,7 @@ public class RegionSamplingHelper implements View.OnAttachStateChangeListener, pw.println(" mLastMedianLuma: " + mLastMedianLuma); pw.println(" mCurrentMedianLuma: " + mCurrentMedianLuma); pw.println(" mWindowVisible: " + mWindowVisible); + pw.println(" mWindowHasBlurs: " + mWindowHasBlurs); pw.println(" mWaitingOnDraw: " + mWaitingOnDraw); pw.println(" mRegisteredStopLayer: " + mRegisteredStopLayer); pw.println(" mIsDestroyed: " + mIsDestroyed); diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java index d9e2648750a4..93a3f81fdd6b 100644 --- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java +++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java @@ -89,7 +89,7 @@ public class PeopleSpaceActivity extends Activity { // The Tile preview has colorBackground as its background. Change it so it's different // than the activity's background. - LinearLayout item = findViewById(R.id.item); + LinearLayout item = findViewById(android.R.id.background); GradientDrawable shape = (GradientDrawable) item.getBackground(); final TypedArray ta = mContext.getTheme().obtainStyledAttributes( new int[]{com.android.internal.R.attr.colorSurface}); diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java b/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java index 96aeb60ae93c..4ee951f3cdb1 100644 --- a/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java +++ b/packages/SystemUI/src/com/android/systemui/people/PeopleStoryIconFactory.java @@ -211,7 +211,8 @@ class PeopleStoryIconFactory implements AutoCloseable { @Override public void setColorFilter(ColorFilter colorFilter) { - // unimplemented + if (mAvatar != null) mAvatar.setColorFilter(colorFilter); + if (mBadgeIcon != null) mBadgeIcon.setColorFilter(colorFilter); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java index 0e17c8bfcab5..844a8c6b6583 100644 --- a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java +++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java @@ -29,6 +29,9 @@ import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT; import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH; import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT; import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH; +import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_SIZES; +import static android.util.TypedValue.COMPLEX_UNIT_DIP; +import static android.util.TypedValue.COMPLEX_UNIT_PX; import static com.android.systemui.people.PeopleSpaceUtils.STARRED_CONTACT; import static com.android.systemui.people.PeopleSpaceUtils.VALID_CONTACT; @@ -41,25 +44,33 @@ import android.app.people.ConversationStatus; import android.app.people.PeopleSpaceTile; import android.content.Context; import android.content.Intent; -import android.content.res.Configuration; import android.graphics.Bitmap; +import android.graphics.ColorMatrix; +import android.graphics.ColorMatrixColorFilter; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; +import android.graphics.text.LineBreaker; import android.net.Uri; import android.os.Bundle; import android.os.UserHandle; +import android.text.StaticLayout; +import android.text.TextPaint; import android.text.TextUtils; import android.util.IconDrawableFactory; import android.util.Log; import android.util.Pair; +import android.util.SizeF; import android.util.TypedValue; import android.view.Gravity; import android.view.View; import android.widget.RemoteViews; import android.widget.TextView; +import androidx.annotation.DimenRes; +import androidx.annotation.Px; import androidx.core.graphics.drawable.RoundedBitmapDrawable; import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; +import androidx.core.math.MathUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.launcher3.icons.FastBitmapDrawable; @@ -75,8 +86,10 @@ import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -108,6 +121,8 @@ public class PeopleTileViewHelper { private static final int MESSAGES_COUNT_OVERFLOW = 6; + private static final CharSequence EMOJI_CAKE = "\ud83c\udf82"; + 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("[!?][!?]+"); @@ -163,28 +178,64 @@ public class PeopleTileViewHelper { private Locale mLocale; private NumberFormat mIntegerFormat; - public PeopleTileViewHelper(Context context, @Nullable PeopleSpaceTile tile, - int appWidgetId, Bundle options, PeopleTileKey key) { + PeopleTileViewHelper(Context context, @Nullable PeopleSpaceTile tile, + int appWidgetId, int width, int height, PeopleTileKey key) { mContext = context; mTile = tile; mKey = key; mAppWidgetId = appWidgetId; mDensity = mContext.getResources().getDisplayMetrics().density; - int display = mContext.getResources().getConfiguration().orientation; - mWidth = display == Configuration.ORIENTATION_PORTRAIT - ? options.getInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.default_width)) : options.getInt( - OPTION_APPWIDGET_MAX_WIDTH, - getSizeInDp(R.dimen.default_width)); - mHeight = display == Configuration.ORIENTATION_PORTRAIT ? options.getInt( - OPTION_APPWIDGET_MAX_HEIGHT, - getSizeInDp(R.dimen.default_height)) - : options.getInt(OPTION_APPWIDGET_MIN_HEIGHT, - getSizeInDp(R.dimen.default_height)); + mWidth = width; + mHeight = height; mLayoutSize = getLayoutSize(); } - public RemoteViews getViews() { + /** + * Creates a {@link RemoteViews} for the specified arguments. The RemoteViews will support all + * the sizes present in {@code options.}. + */ + public static RemoteViews createRemoteViews(Context context, @Nullable PeopleSpaceTile tile, + int appWidgetId, Bundle options, PeopleTileKey key) { + List<SizeF> widgetSizes = getWidgetSizes(context, options); + Map<SizeF, RemoteViews> sizeToRemoteView = + widgetSizes + .stream() + .distinct() + .collect(Collectors.toMap( + Function.identity(), + size -> new PeopleTileViewHelper( + context, tile, appWidgetId, + (int) size.getWidth(), + (int) size.getHeight(), + key) + .getViews())); + return new RemoteViews(sizeToRemoteView); + } + + private static List<SizeF> getWidgetSizes(Context context, Bundle options) { + float density = context.getResources().getDisplayMetrics().density; + List<SizeF> widgetSizes = options.getParcelableArrayList(OPTION_APPWIDGET_SIZES); + // If the full list of sizes was provided in the options bundle, use that. + if (widgetSizes != null && !widgetSizes.isEmpty()) return widgetSizes; + + // Otherwise, create a list using the portrait/landscape sizes. + int defaultWidth = getSizeInDp(context, R.dimen.default_width, density); + int defaultHeight = getSizeInDp(context, R.dimen.default_height, density); + widgetSizes = new ArrayList<>(2); + + int portraitWidth = options.getInt(OPTION_APPWIDGET_MIN_WIDTH, defaultWidth); + int portraitHeight = options.getInt(OPTION_APPWIDGET_MAX_HEIGHT, defaultHeight); + widgetSizes.add(new SizeF(portraitWidth, portraitHeight)); + + int landscapeWidth = options.getInt(OPTION_APPWIDGET_MAX_WIDTH, defaultWidth); + int landscapeHeight = options.getInt(OPTION_APPWIDGET_MIN_HEIGHT, defaultHeight); + widgetSizes.add(new SizeF(landscapeWidth, landscapeHeight)); + + return widgetSizes; + } + + @VisibleForTesting + RemoteViews getViews() { RemoteViews viewsForTile = getViewForTile(); int maxAvatarSize = getMaxAvatarSize(viewsForTile); RemoteViews views = setCommonRemoteViewsFields(viewsForTile, maxAvatarSize); @@ -197,12 +248,16 @@ public class PeopleTileViewHelper { */ private RemoteViews getViewForTile() { if (DEBUG) Log.d(TAG, "Creating view for tile key: " + mKey.toString()); - if (mTile == null || mTile.isPackageSuspended() || mTile.isUserQuieted() - || isDndBlockingTileData(mTile)) { + if (mTile == null || mTile.isPackageSuspended() || mTile.isUserQuieted()) { if (DEBUG) Log.d(TAG, "Create suppressed view: " + mTile); return createSuppressedView(); } + if (isDndBlockingTileData(mTile)) { + if (DEBUG) Log.d(TAG, "Create dnd view"); + return createDndRemoteViews().mRemoteViews; + } + if (Objects.equals(mTile.getNotificationCategory(), CATEGORY_MISSED_CALL)) { if (DEBUG) Log.d(TAG, "Create missed call view"); return createMissedCallRemoteViews(); @@ -236,7 +291,9 @@ public class PeopleTileViewHelper { return createLastInteractionRemoteViews(); } - private boolean isDndBlockingTileData(PeopleSpaceTile tile) { + private static boolean isDndBlockingTileData(@Nullable PeopleSpaceTile tile) { + if (tile == null) return false; + int notificationPolicyState = tile.getNotificationPolicyState(); if ((notificationPolicyState & PeopleSpaceTile.SHOW_CONVERSATIONS) != 0) { // Not in DND, or all conversations @@ -413,6 +470,11 @@ public class PeopleTileViewHelper { int avatarWidthSpace = mWidth - (14 + 14); avatarSize = Math.min(avatarHeightSpace, avatarWidthSpace); } + + if (isDndBlockingTileData(mTile)) { + avatarSize = createDndRemoteViews().mAvatarSize; + } + return Math.min(avatarSize, getSizeInDp(R.dimen.max_people_avatar_size)); } @@ -432,7 +494,6 @@ public class PeopleTileViewHelper { views.setViewVisibility(R.id.availability, View.GONE); } - views.setBoolean(R.id.image, "setClipToOutline", true); views.setImageViewBitmap(R.id.person_icon, getPersonIconBitmap(mContext, mTile, maxAvatarSize)); return views; @@ -460,7 +521,7 @@ public class PeopleTileViewHelper { PeopleSpaceWidgetProvider.EXTRA_NOTIFICATION_KEY, mTile.getNotificationKey()); } - views.setOnClickPendingIntent(R.id.item, PendingIntent.getActivity( + views.setOnClickPendingIntent(android.R.id.background, PendingIntent.getActivity( mContext, mAppWidgetId, activityIntent, @@ -473,6 +534,87 @@ public class PeopleTileViewHelper { return views; } + private RemoteViewsAndSizes createDndRemoteViews() { + boolean isHorizontal = mLayoutSize == LAYOUT_MEDIUM; + int layoutId = isHorizontal + ? R.layout.people_tile_with_suppression_detail_content_horizontal + : R.layout.people_tile_with_suppression_detail_content_vertical; + RemoteViews views = new RemoteViews(mContext.getPackageName(), layoutId); + + int outerPadding = mLayoutSize == LAYOUT_LARGE ? 16 : 8; + int outerPaddingPx = dpToPx(outerPadding); + views.setViewPadding( + android.R.id.background, + outerPaddingPx, + outerPaddingPx, + outerPaddingPx, + outerPaddingPx); + + int mediumAvatarSize = getSizeInDp(R.dimen.avatar_size_for_medium); + int maxAvatarSize = getSizeInDp(R.dimen.max_people_avatar_size); + + String text = mContext.getString(R.string.paused_by_dnd); + views.setTextViewText(R.id.text_content, text); + + int textSizeResId = + mLayoutSize == LAYOUT_LARGE + ? R.dimen.content_text_size_for_large + : R.dimen.content_text_size_for_medium; + float textSizePx = mContext.getResources().getDimension(textSizeResId); + views.setTextViewTextSize(R.id.text_content, COMPLEX_UNIT_PX, textSizePx); + int lineHeight = getLineHeightFromResource(textSizeResId); + + int avatarSize; + if (isHorizontal) { + int maxTextHeight = mHeight - outerPadding; + views.setInt(R.id.text_content, "setMaxLines", maxTextHeight / lineHeight); + avatarSize = mediumAvatarSize; + } else { + int iconSize = + getSizeInDp( + mLayoutSize == LAYOUT_SMALL + ? R.dimen.regular_predefined_icon + : R.dimen.largest_predefined_icon); + int heightWithoutIcon = mHeight - 2 * outerPadding - iconSize; + int paddingBetweenElements = + getSizeInDp(R.dimen.padding_between_suppressed_layout_items); + int maxTextWidth = mWidth - outerPadding * 2; + int maxTextHeight = heightWithoutIcon - mediumAvatarSize - paddingBetweenElements * 2; + + int availableAvatarHeight; + int textHeight = estimateTextHeight(text, textSizeResId, maxTextWidth); + if (textHeight <= maxTextHeight) { + // If the text will fit, then display it and deduct its height from the space we + // have for the avatar. + availableAvatarHeight = heightWithoutIcon - textHeight - paddingBetweenElements * 2; + views.setViewVisibility(R.id.text_content, View.VISIBLE); + views.setInt(R.id.text_content, "setMaxLines", maxTextHeight / lineHeight); + views.setContentDescription(R.id.predefined_icon, null); + } else { + // If the height doesn't fit, then hide it. The dnd icon will still show. + availableAvatarHeight = heightWithoutIcon - paddingBetweenElements; + views.setViewVisibility(R.id.text_content, View.GONE); + // If we don't show the dnd text, set it as the content description on the icon + // for a11y. + views.setContentDescription(R.id.predefined_icon, text); + } + + int availableAvatarWidth = mWidth - outerPadding * 2; + avatarSize = + MathUtils.clamp( + /* value= */ Math.min(availableAvatarWidth, availableAvatarHeight), + /* min= */ dpToPx(10), + /* max= */ maxAvatarSize); + + views.setViewLayoutWidth(R.id.predefined_icon, iconSize, COMPLEX_UNIT_DIP); + views.setViewLayoutHeight(R.id.predefined_icon, iconSize, COMPLEX_UNIT_DIP); + views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_qs_dnd_on); + } + + return new RemoteViewsAndSizes(views, avatarSize); + } + + private RemoteViews createMissedCallRemoteViews() { RemoteViews views = setViewForContentLayout(new RemoteViews(mContext.getPackageName(), getLayoutForContent())); @@ -486,8 +628,8 @@ public class PeopleTileViewHelper { views.setImageViewResource(R.id.predefined_icon, R.drawable.ic_phone_missed); if (mLayoutSize == LAYOUT_LARGE) { views.setInt(R.id.content, "setGravity", Gravity.BOTTOM); - views.setViewLayoutHeightDimen(R.id.predefined_icon, R.dimen.large_predefined_icon); - views.setViewLayoutWidthDimen(R.id.predefined_icon, R.dimen.large_predefined_icon); + views.setViewLayoutHeightDimen(R.id.predefined_icon, R.dimen.larger_predefined_icon); + views.setViewLayoutWidthDimen(R.id.predefined_icon, R.dimen.larger_predefined_icon); } setAvailabilityDotPadding(views, R.dimen.availability_dot_notification_padding); return views; @@ -564,6 +706,10 @@ public class PeopleTileViewHelper { views.setViewVisibility(R.id.predefined_icon, View.VISIBLE); views.setTextViewText(R.id.text_content, statusText); + if (status.getActivity() == ACTIVITY_BIRTHDAY) { + setEmojiBackground(views, EMOJI_CAKE); + } + Icon statusIcon = status.getIcon(); if (statusIcon != null) { // No text content styled text on medium or large. @@ -932,6 +1078,14 @@ public class PeopleTileViewHelper { Drawable personDrawable = storyIcon.getPeopleTileDrawable(roundedDrawable, tile.getPackageName(), getUserId(tile), tile.isImportantConversation(), hasNewStory); + + if (isDndBlockingTileData(tile)) { + // If DND is blocking the conversation, then display the icon in grayscale. + ColorMatrix colorMatrix = new ColorMatrix(); + colorMatrix.setSaturation(0); + personDrawable.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); + } + return convertDrawableToBitmap(personDrawable); } @@ -960,4 +1114,69 @@ public class PeopleTileViewHelper { return context.getString(R.string.over_two_weeks_timestamp); } } + + /** + * Estimates the height (in dp) which the text will have given the text size and the available + * width. Returns Integer.MAX_VALUE if the estimation couldn't be obtained, as this is intended + * to be used an estimate of the maximum. + */ + private int estimateTextHeight( + CharSequence text, + @DimenRes int textSizeResId, + int availableWidthDp) { + StaticLayout staticLayout = buildStaticLayout(text, textSizeResId, availableWidthDp); + if (staticLayout == null) { + // Return max value (rather than e.g. -1) so the value can be used with <= bound checks. + return Integer.MAX_VALUE; + } + return pxToDp(staticLayout.getHeight()); + } + + /** + * Builds a StaticLayout for the text given the text size and available width. This can be used + * to obtain information about how TextView will lay out the text. Returns null if any error + * occurred creating a TextView. + */ + @Nullable + private StaticLayout buildStaticLayout( + CharSequence text, + @DimenRes int textSizeResId, + int availableWidthDp) { + try { + TextView textView = new TextView(mContext); + textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, + mContext.getResources().getDimension(textSizeResId)); + textView.setTextAppearance(android.R.style.TextAppearance_DeviceDefault); + TextPaint paint = textView.getPaint(); + return StaticLayout.Builder.obtain( + text, 0, text.length(), paint, dpToPx(availableWidthDp)) + // Simple break strategy avoids hyphenation unless there's a single word longer + // than the line width. We use this break strategy so that we consider text to + // "fit" only if it fits in a nice way (i.e. without hyphenation in the middle + // of words). + .setBreakStrategy(LineBreaker.BREAK_STRATEGY_SIMPLE) + .build(); + } catch (Exception e) { + Log.e(TAG, "Could not create static layout: " + e); + return null; + } + } + + private int dpToPx(float dp) { + return (int) (dp * mDensity); + } + + private int pxToDp(@Px float px) { + return (int) (px / mDensity); + } + + private static final class RemoteViewsAndSizes { + final RemoteViews mRemoteViews; + final int mAvatarSize; + + RemoteViewsAndSizes(RemoteViews remoteViews, int avatarSize) { + mRemoteViews = remoteViews; + mAvatarSize = avatarSize; + } + } } 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 4085df9a8093..62a0df270698 100644 --- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java +++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java @@ -297,8 +297,8 @@ public class PeopleSpaceWidgetManager { Log.e(TAG, "Cannot update invalid widget"); return; } - RemoteViews views = new PeopleTileViewHelper(mContext, tile, appWidgetId, - options, key).getViews(); + RemoteViews views = PeopleTileViewHelper.createRemoteViews(mContext, tile, appWidgetId, + options, key); // Tell the AppWidgetManager to perform an update on the current app widget. mAppWidgetManager.updateAppWidget(appWidgetId, views); @@ -1031,8 +1031,8 @@ public class PeopleSpaceWidgetManager { Optional.empty()); if (DEBUG) Log.i(TAG, "Returning tile preview for shortcutId: " + shortcutId); - return new PeopleTileViewHelper(mContext, augmentedTile, 0, options, - new PeopleTileKey(augmentedTile)).getViews(); + return PeopleTileViewHelper.createRemoteViews(mContext, augmentedTile, 0, options, + new PeopleTileKey(augmentedTile)); } protected final BroadcastReceiver mBaseBroadcastReceiver = new BroadcastReceiver() { diff --git a/packages/SystemUI/src/com/android/systemui/privacy/television/PrivacyChipDrawable.java b/packages/SystemUI/src/com/android/systemui/privacy/television/PrivacyChipDrawable.java new file mode 100644 index 000000000000..e5479badcb0a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/privacy/television/PrivacyChipDrawable.java @@ -0,0 +1,390 @@ +/* + * 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.privacy.television; + +import android.animation.Animator; +import android.animation.AnimatorInflater; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.drawable.Drawable; +import android.util.Log; + +import androidx.annotation.Keep; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.systemui.R; + +/** + * Drawable that can go from being the background of the privacy icons to a small dot. + * The icons are not included. + */ +public class PrivacyChipDrawable extends Drawable { + + private static final String TAG = PrivacyChipDrawable.class.getSimpleName(); + private static final boolean DEBUG = false; + + private float mWidth; + private float mHeight; + private float mMarginEnd; + private float mRadius; + private int mDotAlpha; + private int mBgAlpha; + + private float mTargetWidth; + private final int mMinWidth; + private final int mIconWidth; + private final int mIconPadding; + private final int mBgWidth; + private final int mBgHeight; + private final int mBgRadius; + private final int mDotSize; + + private final AnimatorSet mFadeIn; + private final AnimatorSet mFadeOut; + private final AnimatorSet mCollapse; + private final AnimatorSet mExpand; + private Animator mWidthAnimator; + + private final Paint mChipPaint; + private final Paint mBgPaint; + + private boolean mIsRtl; + + private boolean mIsExpanded = true; + + private PrivacyChipDrawableListener mListener; + + interface PrivacyChipDrawableListener { + void onFadeOutFinished(); + } + + public PrivacyChipDrawable(Context context) { + mChipPaint = new Paint(); + mChipPaint.setStyle(Paint.Style.FILL); + mChipPaint.setColor(context.getColor(R.color.privacy_circle)); + mChipPaint.setAlpha(mDotAlpha); + mChipPaint.setFlags(Paint.ANTI_ALIAS_FLAG); + + mBgPaint = new Paint(); + mBgPaint.setStyle(Paint.Style.FILL); + mBgPaint.setColor(context.getColor(R.color.privacy_chip_dot_bg_tint)); + mBgPaint.setAlpha(mBgAlpha); + mBgPaint.setFlags(Paint.ANTI_ALIAS_FLAG); + + mBgWidth = context.getResources().getDimensionPixelSize(R.dimen.privacy_chip_dot_bg_width); + mBgHeight = context.getResources().getDimensionPixelSize( + R.dimen.privacy_chip_dot_bg_height); + mBgRadius = context.getResources().getDimensionPixelSize( + R.dimen.privacy_chip_dot_bg_radius); + + mMinWidth = context.getResources().getDimensionPixelSize(R.dimen.privacy_chip_min_width); + mIconWidth = context.getResources().getDimensionPixelSize(R.dimen.privacy_chip_icon_size); + mIconPadding = context.getResources().getDimensionPixelSize( + R.dimen.privacy_chip_icon_margin_in_between); + mDotSize = context.getResources().getDimensionPixelSize(R.dimen.privacy_chip_dot_size); + + mWidth = mMinWidth; + mHeight = context.getResources().getDimensionPixelSize(R.dimen.privacy_chip_height); + mRadius = context.getResources().getDimensionPixelSize(R.dimen.privacy_chip_radius); + + mExpand = (AnimatorSet) AnimatorInflater.loadAnimator(context, + R.anim.tv_privacy_chip_expand); + mExpand.setTarget(this); + + mCollapse = (AnimatorSet) AnimatorInflater.loadAnimator(context, + R.anim.tv_privacy_chip_collapse); + mCollapse.setTarget(this); + + mFadeIn = (AnimatorSet) AnimatorInflater.loadAnimator(context, + R.anim.tv_privacy_chip_fade_in); + mFadeIn.setTarget(this); + + mFadeOut = (AnimatorSet) AnimatorInflater.loadAnimator(context, + R.anim.tv_privacy_chip_fade_out); + mFadeOut.setTarget(this); + mFadeOut.addListener(new Animator.AnimatorListener() { + private boolean mCancelled; + + @Override + public void onAnimationStart(Animator animation) { + mCancelled = false; + } + + @Override + public void onAnimationEnd(Animator animation) { + if (!mCancelled && mListener != null) { + if (DEBUG) Log.d(TAG, "Fade-out complete"); + mListener.onFadeOutFinished(); + } + } + + @Override + public void onAnimationCancel(Animator animation) { + mCancelled = true; + } + + @Override + public void onAnimationRepeat(Animator animation) { + // no-op + } + }); + } + + /** + * Pass null to remove listener. + */ + public void setListener(@Nullable PrivacyChipDrawableListener listener) { + this.mListener = listener; + } + + /** + * Call once the view that is showing the drawable is visible to start fading the chip in. + */ + public void startInitialFadeIn() { + if (DEBUG) Log.d(TAG, "initial fade-in"); + mFadeIn.start(); + } + + @Override + public void draw(@NonNull Canvas canvas) { + Rect bounds = getBounds(); + + int centerVertical = (bounds.bottom - bounds.top) / 2; + // Dot background + RectF bgBounds = new RectF( + mIsRtl ? bounds.left : bounds.right - mBgWidth, + centerVertical - mBgHeight / 2f, + mIsRtl ? bounds.left + mBgWidth : bounds.right, + centerVertical + mBgHeight / 2f); + if (DEBUG) Log.v(TAG, "bg: " + bgBounds.toShortString()); + canvas.drawRoundRect(bgBounds, mBgRadius, mBgRadius, mBgPaint); + + // Icon background / dot + RectF greenBounds = new RectF( + mIsRtl ? bounds.left + mMarginEnd : bounds.right - mWidth - mMarginEnd, + centerVertical - mHeight / 2, + mIsRtl ? bounds.left + mWidth + mMarginEnd : bounds.right - mMarginEnd, + centerVertical + mHeight / 2); + if (DEBUG) Log.v(TAG, "green: " + greenBounds.toShortString()); + canvas.drawRoundRect(greenBounds, mRadius, mRadius, mChipPaint); + } + + private void animateToNewTargetWidth(float width) { + if (DEBUG) Log.d(TAG, "new target width: " + width); + if (width != mTargetWidth) { + mTargetWidth = width; + Animator newWidthAnimator = ObjectAnimator.ofFloat(this, "width", mTargetWidth); + newWidthAnimator.start(); + if (mWidthAnimator != null) { + mWidthAnimator.cancel(); + } + mWidthAnimator = newWidthAnimator; + } + } + + private void expand() { + if (DEBUG) Log.d(TAG, "expanding"); + if (mIsExpanded) { + return; + } + mIsExpanded = true; + + mExpand.start(); + mCollapse.cancel(); + } + + /** + * Starts the animation to a dot. + */ + public void collapse() { + if (DEBUG) Log.d(TAG, "collapsing"); + if (!mIsExpanded) { + return; + } + mIsExpanded = false; + + animateToNewTargetWidth(mDotSize); + mCollapse.start(); + mExpand.cancel(); + } + + /** + * Fades out the view if 0 icons are to be shown, expands the chip if it has been collapsed and + * makes the width of the chip adjust to the amount of icons to be shown. + * Should not be called when only the order of the icons was changed as the chip will expand + * again without there being any real update. + * + * @param iconCount Can be 0 to fade out the chip. + */ + public void updateIcons(int iconCount) { + if (DEBUG) Log.d(TAG, "updating icons: " + iconCount); + + // calculate chip size and use it for end value of animation that is specified in code, + // not xml + if (iconCount == 0) { + // fade out if there are no icons + mFadeOut.start(); + + mWidthAnimator.cancel(); + mFadeIn.cancel(); + mExpand.cancel(); + mCollapse.cancel(); + return; + } + + mFadeOut.cancel(); + expand(); + animateToNewTargetWidth(mMinWidth + (iconCount - 1) * (mIconWidth + mIconPadding)); + } + + @Override + public void setAlpha(int alpha) { + setDotAlpha(alpha); + setBgAlpha(alpha); + } + + @Override + public int getAlpha() { + return mDotAlpha; + } + + /** + * Set alpha value the green part of the chip. + */ + @Keep + public void setDotAlpha(int alpha) { + if (DEBUG) Log.v(TAG, "dot alpha updated to: " + alpha); + mDotAlpha = alpha; + mChipPaint.setAlpha(alpha); + } + + @Keep + public int getDotAlpha() { + return mDotAlpha; + } + + /** + * Set alpha value of the background of the chip. + */ + @Keep + public void setBgAlpha(int alpha) { + if (DEBUG) Log.v(TAG, "bg alpha updated to: " + alpha); + mBgAlpha = alpha; + mBgPaint.setAlpha(alpha); + } + + @Keep + public int getBgAlpha() { + return mBgAlpha; + } + + @Override + public void setColorFilter(@Nullable ColorFilter colorFilter) { + // no-op + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } + + /** + * The radius of the green part of the chip, not the background. + */ + @Keep + public void setRadius(float radius) { + mRadius = radius; + invalidateSelf(); + } + + /** + * @return The radius of the green part of the chip, not the background. + */ + @Keep + public float getRadius() { + return mRadius; + } + + /** + * Height of the green part of the chip, not including the background. + */ + @Keep + public void setHeight(float height) { + mHeight = height; + invalidateSelf(); + } + + /** + * @return Height of the green part of the chip, not including the background. + */ + @Keep + public float getHeight() { + return mHeight; + } + + /** + * Width of the green part of the chip, not including the background. + */ + @Keep + public void setWidth(float width) { + mWidth = width; + invalidateSelf(); + } + + /** + * @return Width of the green part of the chip, not including the background. + */ + @Keep + public float getWidth() { + return mWidth; + } + + /** + * Margin at the end of the green part of the chip, so that it will be placed in the middle of + * the rounded rectangle in the background. + */ + @Keep + public void setMarginEnd(float marginEnd) { + mMarginEnd = marginEnd; + invalidateSelf(); + } + + /** + * @return Margin at the end of the green part of the chip, so that it will be placed in the + * middle of the rounded rectangle in the background. + */ + @Keep + public float getMarginEnd() { + return mMarginEnd; + } + + /** + * Sets the layout direction. + */ + public void setRtl(boolean isRtl) { + mIsRtl = isRtl; + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java b/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java index 5ab7bd88e49b..e4f5cde37f1d 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java +++ b/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java @@ -25,9 +25,10 @@ import android.annotation.IntDef; import android.annotation.UiThread; import android.content.Context; import android.content.res.Resources; -import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Looper; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; @@ -38,15 +39,20 @@ import android.view.WindowManager; import android.widget.ImageView; import android.widget.LinearLayout; +import androidx.annotation.NonNull; + import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.privacy.PrivacyChipBuilder; import com.android.systemui.privacy.PrivacyItem; import com.android.systemui.privacy.PrivacyItemController; +import com.android.systemui.privacy.PrivacyType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import javax.inject.Inject; @@ -56,9 +62,10 @@ import javax.inject.Inject; * recording audio, accessing the camera or accessing the location. */ @SysUISingleton -public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemController.Callback { +public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemController.Callback, + PrivacyChipDrawable.PrivacyChipDrawableListener { private static final String TAG = "TvOngoingPrivacyChip"; - static final boolean DEBUG = false; + private static final boolean DEBUG = false; // This title is used in CameraMicIndicatorsPermissionTest and // RecognitionServiceMicIndicatorTest. @@ -68,7 +75,8 @@ public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemControl @IntDef(prefix = {"STATE_"}, value = { STATE_NOT_SHOWN, STATE_APPEARING, - STATE_SHOWN, + STATE_EXPANDED, + STATE_COLLAPSED, STATE_DISAPPEARING }) public @interface State { @@ -76,46 +84,58 @@ public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemControl private static final int STATE_NOT_SHOWN = 0; private static final int STATE_APPEARING = 1; - private static final int STATE_SHOWN = 2; - private static final int STATE_DISAPPEARING = 3; + private static final int STATE_EXPANDED = 2; + private static final int STATE_COLLAPSED = 3; + private static final int STATE_DISAPPEARING = 4; - private static final int ANIMATION_DURATION_MS = 200; + private static final int EXPANDED_DURATION_MS = 4000; + public final int mAnimationDurationMs; private final Context mContext; private final PrivacyItemController mPrivacyItemController; - private View mIndicatorView; + private ViewGroup mIndicatorView; private boolean mViewAndWindowAdded; private ObjectAnimator mAnimator; private boolean mMicCameraIndicatorFlagEnabled; - private boolean mLocationIndicatorEnabled; - private List<PrivacyItem> mPrivacyItems; + private boolean mAllIndicatorsEnabled; + + @NonNull + private List<PrivacyItem> mPrivacyItems = Collections.emptyList(); private LinearLayout mIconsContainer; private final int mIconSize; private final int mIconMarginStart; + private PrivacyChipDrawable mChipDrawable; + + private final Handler mUiThreadHandler = new Handler(Looper.getMainLooper()); + private final Runnable mCollapseRunnable = this::collapseChip; + @State private int mState = STATE_NOT_SHOWN; @Inject public TvOngoingPrivacyChip(Context context, PrivacyItemController privacyItemController) { super(context); - Log.d(TAG, "Privacy chip running without id"); + if (DEBUG) Log.d(TAG, "Privacy chip running"); mContext = context; mPrivacyItemController = privacyItemController; Resources res = mContext.getResources(); - mIconMarginStart = Math.round(res.getDimension(R.dimen.privacy_chip_icon_margin)); + mIconMarginStart = Math.round( + res.getDimension(R.dimen.privacy_chip_icon_margin_in_between)); mIconSize = res.getDimensionPixelSize(R.dimen.privacy_chip_icon_size); + mAnimationDurationMs = res.getInteger(R.integer.privacy_chip_animation_millis); + mMicCameraIndicatorFlagEnabled = privacyItemController.getMicCameraAvailable(); - mLocationIndicatorEnabled = privacyItemController.getLocationAvailable(); + mAllIndicatorsEnabled = privacyItemController.getAllIndicatorsAvailable(); if (DEBUG) { Log.d(TAG, "micCameraIndicators: " + mMicCameraIndicatorFlagEnabled); - Log.d(TAG, "locationIndicators: " + mLocationIndicatorEnabled); + Log.d(TAG, "allIndicators: " + mAllIndicatorsEnabled); } } @@ -125,69 +145,145 @@ public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemControl } @Override - public void onPrivacyItemsChanged(List<PrivacyItem> privacyItems) { + public void onPrivacyItemsChanged(@NonNull List<PrivacyItem> privacyItems) { if (DEBUG) Log.d(TAG, "PrivacyItemsChanged"); - mPrivacyItems = privacyItems; - updateUI(); + + List<PrivacyItem> updatedPrivacyItems = new ArrayList<>(privacyItems); + // Never show the location indicator on tv. + if (updatedPrivacyItems.removeIf( + privacyItem -> privacyItem.getPrivacyType() == PrivacyType.TYPE_LOCATION)) { + if (DEBUG) Log.v(TAG, "Removed the location item"); + } + + if (isChipDisabled()) { + fadeOutIndicator(); + mPrivacyItems = updatedPrivacyItems; + return; + } + + // Do they have the same elements? (order doesn't matter) + if (updatedPrivacyItems.size() == mPrivacyItems.size() + && mPrivacyItems.containsAll(updatedPrivacyItems)) { + if (DEBUG) Log.d(TAG, "List wasn't updated"); + return; + } + + mPrivacyItems = updatedPrivacyItems; + updateChip(); + } + + private void updateChip() { + if (DEBUG) Log.d(TAG, mPrivacyItems.size() + " privacy items"); + + if (mPrivacyItems.isEmpty()) { + if (DEBUG) Log.d(TAG, "removing indicator (state: " + stateToString(mState) + ")"); + fadeOutIndicator(); + return; + } + + if (DEBUG) Log.d(TAG, "Current state: " + stateToString(mState)); + switch (mState) { + case STATE_NOT_SHOWN: + createAndShowIndicator(); + break; + case STATE_APPEARING: + case STATE_EXPANDED: + updateIcons(); + collapseLater(); + break; + case STATE_COLLAPSED: + case STATE_DISAPPEARING: + mState = STATE_EXPANDED; + updateIcons(); + animateIconAppearance(); + break; + } + } + + /** + * Collapse the chip EXPANDED_DURATION_MS from now. + */ + private void collapseLater() { + mUiThreadHandler.removeCallbacks(mCollapseRunnable); + if (DEBUG) Log.d(TAG, "chip will collapse in " + EXPANDED_DURATION_MS + "ms"); + mUiThreadHandler.postDelayed(mCollapseRunnable, EXPANDED_DURATION_MS); + } + + private void collapseChip() { + if (DEBUG) Log.d(TAG, "collapseChip"); + + if (mState != STATE_EXPANDED) { + return; + } + mState = STATE_COLLAPSED; + + if (mChipDrawable != null) { + mChipDrawable.collapse(); + } + animateIconDisappearance(); } @Override public void onFlagMicCameraChanged(boolean flag) { if (DEBUG) Log.d(TAG, "mic/camera indicators enabled: " + flag); mMicCameraIndicatorFlagEnabled = flag; + updateChipOnFlagChanged(); } @Override - public void onFlagLocationChanged(boolean flag) { - if (DEBUG) Log.d(TAG, "location indicators enabled: " + flag); - mLocationIndicatorEnabled = flag; + public void onFlagAllChanged(boolean flag) { + if (DEBUG) Log.d(TAG, "all indicators enabled: " + flag); + mAllIndicatorsEnabled = flag; + updateChipOnFlagChanged(); } - private void updateUI() { - if (DEBUG) Log.d(TAG, mPrivacyItems.size() + " privacy items"); + private boolean isChipDisabled() { + return !(mMicCameraIndicatorFlagEnabled || mAllIndicatorsEnabled); + } - if ((mMicCameraIndicatorFlagEnabled || mLocationIndicatorEnabled) - && !mPrivacyItems.isEmpty()) { - if (mState == STATE_NOT_SHOWN || mState == STATE_DISAPPEARING) { - showIndicator(); - } else { - if (DEBUG) Log.d(TAG, "only updating icons"); - PrivacyChipBuilder builder = new PrivacyChipBuilder(mContext, mPrivacyItems); - setIcons(builder.generateIcons(), mIconsContainer); - mIconsContainer.requestLayout(); - } + private void updateChipOnFlagChanged() { + if (isChipDisabled()) { + fadeOutIndicator(); } else { - hideIndicatorIfNeeded(); + updateChip(); } } @UiThread - private void hideIndicatorIfNeeded() { + private void fadeOutIndicator() { if (mState == STATE_NOT_SHOWN || mState == STATE_DISAPPEARING) return; + mUiThreadHandler.removeCallbacks(mCollapseRunnable); + if (mViewAndWindowAdded) { mState = STATE_DISAPPEARING; - animateDisappearance(); + animateIconDisappearance(); } else { // Appearing animation has not started yet, as we were still waiting for the View to be // laid out. mState = STATE_NOT_SHOWN; removeIndicatorView(); } + if (mChipDrawable != null) { + mChipDrawable.updateIcons(0); + } } @UiThread - private void showIndicator() { + private void createAndShowIndicator() { mState = STATE_APPEARING; + if (mIndicatorView != null || mViewAndWindowAdded) { + removeIndicatorView(); + } + // Inflate the indicator view - mIndicatorView = LayoutInflater.from(mContext).inflate( + mIndicatorView = (ViewGroup) LayoutInflater.from(mContext).inflate( R.layout.tv_ongoing_privacy_chip, null); - // 1. Set alpha to 0. + // 1. Set icon alpha to 0. // 2. Wait until the window is shown and the view is laid out. // 3. Start a "fade in" (alpha) animation. - mIndicatorView.setAlpha(0f); mIndicatorView .getViewTreeObserver() .addOnGlobalLayoutListener( @@ -196,20 +292,35 @@ public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemControl public void onGlobalLayout() { // State could have changed to NOT_SHOWN (if all the recorders are // already gone) - if (mState != STATE_APPEARING) return; + if (mState != STATE_APPEARING) { + return; + } mViewAndWindowAdded = true; // Remove the observer mIndicatorView.getViewTreeObserver().removeOnGlobalLayoutListener( this); - animateAppearance(); + animateIconAppearance(); + mChipDrawable.startInitialFadeIn(); } }); + final boolean isRtl = mContext.getResources().getConfiguration().getLayoutDirection() + == View.LAYOUT_DIRECTION_RTL; + if (DEBUG) Log.d(TAG, "is RTL: " + isRtl); + + mChipDrawable = new PrivacyChipDrawable(mContext); + mChipDrawable.setListener(this); + mChipDrawable.setRtl(isRtl); + ImageView chipBackground = mIndicatorView.findViewById(R.id.chip_drawable); + if (chipBackground != null) { + chipBackground.setImageDrawable(mChipDrawable); + } + mIconsContainer = mIndicatorView.findViewById(R.id.icons_container); - PrivacyChipBuilder builder = new PrivacyChipBuilder(mContext, mPrivacyItems); - setIcons(builder.generateIcons(), mIconsContainer); + mIconsContainer.setAlpha(0f); + updateIcons(); final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( WRAP_CONTENT, @@ -217,19 +328,19 @@ public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemControl WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); - layoutParams.gravity = Gravity.TOP | Gravity.END; + layoutParams.gravity = Gravity.TOP | (isRtl ? Gravity.LEFT : Gravity.RIGHT); layoutParams.setTitle(LAYOUT_PARAMS_TITLE); layoutParams.packageName = mContext.getPackageName(); final WindowManager windowManager = mContext.getSystemService(WindowManager.class); windowManager.addView(mIndicatorView, layoutParams); - } - private void setIcons(List<Drawable> icons, ViewGroup iconsContainer) { - iconsContainer.removeAllViews(); + private void updateIcons() { + List<Drawable> icons = new PrivacyChipBuilder(mContext, mPrivacyItems).generateIcons(); + mIconsContainer.removeAllViews(); for (int i = 0; i < icons.size(); i++) { Drawable icon = icons.get(i); - icon.mutate().setTint(Color.WHITE); + icon.mutate().setTint(mContext.getColor(R.color.privacy_icon_tint)); ImageView imageView = new ImageView(mContext); imageView.setImageDrawable(icon); imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); @@ -241,22 +352,25 @@ public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemControl imageView.setLayoutParams(layoutParams); } } + if (mChipDrawable != null) { + mChipDrawable.updateIcons(icons.size()); + } } - private void animateAppearance() { - animateAlphaTo(1f); + private void animateIconAppearance() { + animateIconAlphaTo(1f); } - private void animateDisappearance() { - animateAlphaTo(0f); + private void animateIconDisappearance() { + animateIconAlphaTo(0f); } - private void animateAlphaTo(final float endValue) { + private void animateIconAlphaTo(float endValue) { if (mAnimator == null) { if (DEBUG) Log.d(TAG, "set up animator"); mAnimator = new ObjectAnimator(); - mAnimator.setTarget(mIndicatorView); + mAnimator.setTarget(mIconsContainer); mAnimator.setProperty(View.ALPHA); mAnimator.addListener(new AnimatorListenerAdapter() { boolean mCancelled; @@ -280,7 +394,7 @@ public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemControl // and then onAnimationEnd(...). We, however, only want to proceed here if the // animation ended "naturally". if (!mCancelled) { - onAnimationFinished(); + onIconAnimationFinished(); } } }); @@ -289,19 +403,37 @@ public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemControl mAnimator.cancel(); } - final float currentValue = mIndicatorView.getAlpha(); + final float currentValue = mIconsContainer.getAlpha(); + if (currentValue == endValue) { + if (DEBUG) Log.d(TAG, "alpha not changing"); + return; + } if (DEBUG) Log.d(TAG, "animate alpha to " + endValue + " from " + currentValue); - mAnimator.setDuration((int) (Math.abs(currentValue - endValue) * ANIMATION_DURATION_MS)); + mAnimator.setDuration(mAnimationDurationMs); mAnimator.setFloatValues(endValue); mAnimator.start(); } - private void onAnimationFinished() { - if (DEBUG) Log.d(TAG, "onAnimationFinished"); + @Override + public void onFadeOutFinished() { + if (DEBUG) Log.d(TAG, "drawable fade-out finished"); + + if (mState == STATE_DISAPPEARING) { + removeIndicatorView(); + mState = STATE_NOT_SHOWN; + } + } + + private void onIconAnimationFinished() { + if (DEBUG) Log.d(TAG, "onAnimationFinished (icon fade)"); + + if (mState == STATE_APPEARING || mState == STATE_EXPANDED) { + collapseLater(); + } if (mState == STATE_APPEARING) { - mState = STATE_SHOWN; + mState = STATE_EXPANDED; } else if (mState == STATE_DISAPPEARING) { removeIndicatorView(); mState = STATE_NOT_SHOWN; @@ -312,14 +444,39 @@ public class TvOngoingPrivacyChip extends SystemUI implements PrivacyItemControl if (DEBUG) Log.d(TAG, "removeIndicatorView"); final WindowManager windowManager = mContext.getSystemService(WindowManager.class); - if (windowManager != null) { + if (windowManager != null && mIndicatorView != null) { windowManager.removeView(mIndicatorView); } mIndicatorView = null; mAnimator = null; + if (mChipDrawable != null) { + mChipDrawable.setListener(null); + mChipDrawable = null; + } + mViewAndWindowAdded = false; } + /** + * Used in debug logs. + */ + private String stateToString(@State int state) { + switch (state) { + case STATE_NOT_SHOWN: + return "NOT_SHOWN"; + case STATE_APPEARING: + return "APPEARING"; + case STATE_EXPANDED: + return "EXPANDED"; + case STATE_COLLAPSED: + return "COLLAPSED"; + case STATE_DISAPPEARING: + return "DISAPPEARING"; + default: + return "INVALID"; + } + } + } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java index edfbed04f70d..74550f26b6e9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java @@ -28,12 +28,8 @@ import android.view.View; import android.view.WindowInsets; import android.widget.FrameLayout; -import androidx.dynamicanimation.animation.FloatPropertyCompat; -import androidx.dynamicanimation.animation.SpringForce; - import com.android.systemui.R; import com.android.systemui.qs.customize.QSCustomizer; -import com.android.wm.shell.animation.PhysicsAnimator; /** * Wrapper view with background which contains {@link QSPanel} and {@link QuickStatusBarHeader} @@ -41,26 +37,10 @@ import com.android.wm.shell.animation.PhysicsAnimator; public class QSContainerImpl extends FrameLayout { private final Point mSizePoint = new Point(); - private static final FloatPropertyCompat<QSContainerImpl> BACKGROUND_BOTTOM = - new FloatPropertyCompat<QSContainerImpl>("backgroundBottom") { - @Override - public float getValue(QSContainerImpl qsImpl) { - return qsImpl.getBackgroundBottom(); - } - - @Override - public void setValue(QSContainerImpl background, float value) { - background.setBackgroundBottom((int) value); - } - }; - private static final PhysicsAnimator.SpringConfig BACKGROUND_SPRING - = new PhysicsAnimator.SpringConfig(SpringForce.STIFFNESS_MEDIUM, - SpringForce.DAMPING_RATIO_LOW_BOUNCY); private int mFancyClippingTop; private int mFancyClippingBottom; private final float[] mFancyClippingRadii = new float[] {0, 0, 0, 0, 0, 0, 0, 0}; private final Path mFancyClippingPath = new Path(); - private int mBackgroundBottom = 0; private int mHeightOverride = -1; private View mQSDetail; private QuickStatusBarHeader mHeader; @@ -71,7 +51,6 @@ public class QSContainerImpl extends FrameLayout { private int mSideMargins; private boolean mQsDisabled; private int mContentPadding = -1; - private boolean mAnimateBottomOnNextLayout; private int mNavBarInset = 0; private boolean mClippingEnabled; @@ -86,11 +65,6 @@ public class QSContainerImpl extends FrameLayout { mQSDetail = findViewById(R.id.qs_detail); mHeader = findViewById(R.id.header); mQSCustomizer = findViewById(R.id.qs_customize); - mHeader.getHeaderQsPanel().setMediaVisibilityChangedListener((visible) -> { - if (mHeader.getHeaderQsPanel().isShown()) { - mAnimateBottomOnNextLayout = true; - } - }); setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO); } @@ -99,20 +73,6 @@ public class QSContainerImpl extends FrameLayout { return false; } - void onMediaVisibilityChanged(boolean qsVisible) { - mAnimateBottomOnNextLayout = qsVisible; - } - - private void setBackgroundBottom(int value) { - // We're saving the bottom separately since otherwise the bottom would be overridden in - // the layout and the animation wouldn't properly start at the old position. - mBackgroundBottom = value; - } - - private float getBackgroundBottom() { - return mBackgroundBottom; - } - @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); @@ -186,8 +146,7 @@ public class QSContainerImpl extends FrameLayout { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); - updateExpansion(mAnimateBottomOnNextLayout /* animate */); - mAnimateBottomOnNextLayout = false; + updateExpansion(); updateClippingPath(); } @@ -230,31 +189,12 @@ public class QSContainerImpl extends FrameLayout { } public void updateExpansion() { - updateExpansion(false /* animate */); - } - - public void updateExpansion(boolean animate) { int height = calculateContainerHeight(); int scrollBottom = calculateContainerBottom(); setBottom(getTop() + height); mQSDetail.setBottom(getTop() + scrollBottom); int qsDetailBottomMargin = ((MarginLayoutParams) mQSDetail.getLayoutParams()).bottomMargin; mQSDetail.setBottom(getTop() + scrollBottom - qsDetailBottomMargin); - updateBackgroundBottom(scrollBottom, animate); - } - - private void updateBackgroundBottom(int height, boolean animated) { - PhysicsAnimator<QSContainerImpl> physicsAnimator = PhysicsAnimator.getInstance(this); - if (physicsAnimator.isPropertyAnimating(BACKGROUND_BOTTOM) || animated) { - // An animation is running or we want to animate - // Let's make sure to set the currentValue again, since the call below might only - // start in the next frame and otherwise we'd flicker - BACKGROUND_BOTTOM.setValue(this, BACKGROUND_BOTTOM.getValue(this)); - physicsAnimator.spring(BACKGROUND_BOTTOM, height, BACKGROUND_SPRING).start(); - } else { - BACKGROUND_BOTTOM.setValue(this, height); - } - } protected int calculateContainerHeight() { @@ -297,7 +237,7 @@ public class QSContainerImpl extends FrameLayout { // start margin of next page). qsPanelController.setPageMargin(mSideMargins); } else if (view == mHeader) { - // No content padding for the header. + quickStatusBarHeaderController.setContentMargins(mContentPadding, mContentPadding); } else { view.setPaddingRelative( mContentPadding, diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java index 3638395be29e..7d61991c910a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java @@ -61,12 +61,6 @@ public class QSContainerImplController extends ViewController<QSContainerImpl> { @Override protected void onViewAttached() { mView.updateResources(mQsPanelController, mQuickStatusBarHeaderController); - mQsPanelController.setMediaVisibilityChangedListener((visible) -> { - if (mQsPanelController.isShown()) { - mView.onMediaVisibilityChanged(true); - } - }); - mConfigurationController.addCallback(mConfigurationListener); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java index 2d0d87dcadee..bcce87a51097 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java @@ -46,6 +46,7 @@ import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer; public class QSDetail extends LinearLayout { @@ -83,6 +84,8 @@ public class QSDetail extends LinearLayout { private boolean mSwitchState; private QSFooter mFooter; + private NotificationsQuickSettingsContainer mContainer; + public QSDetail(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } @@ -115,6 +118,10 @@ public class QSDetail extends LinearLayout { mClipper = new QSDetailClipper(this); } + public void setContainer(NotificationsQuickSettingsContainer container) { + mContainer = container; + } + /** */ public void setQsPanel(QSPanelController panelController, QuickStatusBarHeader header, QSFooter footer) { @@ -242,6 +249,9 @@ public class QSDetail extends LinearLayout { } sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); animateDetailVisibleDiff(x, y, visibleDiff, listener); + if (mContainer != null) { + mContainer.setDetailShowing(showingDetail); + } } protected void animateDetailVisibleDiff(int x, int y, boolean visibleDiff, AnimatorListener listener) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index 7b8a6a0a8d0e..998cff2bb1fd 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -53,6 +53,8 @@ import com.android.systemui.util.InjectionInflationController; import com.android.systemui.util.LifecycleFragment; import com.android.systemui.util.Utils; +import java.util.function.Consumer; + import javax.inject.Inject; import javax.inject.Named; @@ -281,6 +283,11 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca return mLastQSExpansion == 0.0f || mLastQSExpansion == -1; } + @Override + public void setCollapsedMediaVisibilityChangedListener(Consumer<Boolean> listener) { + mQuickQSPanelController.setMediaVisibilityChangedListener(listener); + } + private void setEditLocation(View view) { View edit = view.findViewById(android.R.id.edit); int[] loc = edit.getLocationOnScreen(); @@ -293,6 +300,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca public void setContainer(ViewGroup container) { if (container instanceof NotificationsQuickSettingsContainer) { mQSCustomizerController.setContainer((NotificationsQuickSettingsContainer) container); + mQSDetail.setContainer((NotificationsQuickSettingsContainer) container); } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 0bb0a3f7bad4..db8efd530195 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -46,7 +46,6 @@ import com.android.systemui.util.animation.UniqueObjectHostView; import java.util.ArrayList; import java.util.List; -import java.util.function.Consumer; /** View that represents the quick settings tile panel (when expanded/pulled down). **/ public class QSPanel extends LinearLayout implements Tunable { @@ -105,7 +104,6 @@ public class QSPanel extends LinearLayout implements Tunable { protected QSTileLayout mTileLayout; private int mLastOrientation = -1; private int mMediaTotalBottomMargin; - private Consumer<Boolean> mMediaVisibilityChangedListener; public QSPanel(Context context, AttributeSet attrs) { super(context, attrs); @@ -148,12 +146,6 @@ public class QSPanel extends LinearLayout implements Tunable { } } - protected void onMediaVisibilityChanged(Boolean visible) { - if (mMediaVisibilityChangedListener != null) { - mMediaVisibilityChangedListener.accept(visible); - } - } - /** * Add brightness view above the tile layout. * @@ -425,7 +417,7 @@ public class QSPanel extends LinearLayout implements Tunable { LinearLayout.LayoutParams layoutParams = (LayoutParams) hostView.getLayoutParams(); layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; layoutParams.width = horizontal ? 0 : ViewGroup.LayoutParams.MATCH_PARENT; - layoutParams.weight = horizontal ? 1.2f : 0; + layoutParams.weight = horizontal ? 1f : 0; // Add any bottom margin, such that the total spacing is correct. This is only // necessary if the view isn't horizontal, since otherwise the padding is // carried in the parent of this view (to ensure correct vertical alignment) @@ -667,10 +659,6 @@ public class QSPanel extends LinearLayout implements Tunable { mHeaderContainer = headerContainer; } - public void setMediaVisibilityChangedListener(Consumer<Boolean> visibilityChangedListener) { - mMediaVisibilityChangedListener = visibilityChangedListener; - } - public boolean isListening() { return mListening; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java index ac92d4fe44e2..9810e96ed199 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java @@ -45,8 +45,6 @@ import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.policy.BrightnessMirrorController; import com.android.systemui.tuner.TunerService; -import java.util.function.Consumer; - import javax.inject.Inject; import javax.inject.Named; @@ -289,11 +287,6 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { mView.setPageListener(listener); } - /** */ - public void setMediaVisibilityChangedListener(Consumer<Boolean> visibilityChangedListener) { - mView.setMediaVisibilityChangedListener(visibilityChangedListener); - } - public boolean isShown() { return mView.isShown(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java index 170785ca7aab..77591b50c103 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java @@ -19,6 +19,8 @@ package com.android.systemui.qs; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent; import static com.android.systemui.qs.dagger.QSFragmentModule.QS_USING_MEDIA_PLAYER; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.ComponentName; import android.content.res.Configuration; import android.metrics.LogMaker; @@ -42,6 +44,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; +import java.util.function.Consumer; import java.util.stream.Collectors; import javax.inject.Named; @@ -68,6 +71,8 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr protected final ArrayList<TileRecord> mRecords = new ArrayList<>(); private boolean mShouldUseSplitNotificationShade; + @Nullable + private Consumer<Boolean> mMediaVisibilityChangedListener; private int mLastOrientation; private String mCachedSpecs = ""; private QSTileRevealController mQsTileRevealController; @@ -89,7 +94,9 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr }; private final Function1<Boolean, Unit> mMediaHostVisibilityListener = (visible) -> { - mView.onMediaVisibilityChanged(visible); + if (mMediaVisibilityChangedListener != null) { + mMediaVisibilityChangedListener.accept(visible); + } switchTileLayout(false); return null; }; @@ -136,7 +143,6 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr } mMediaHost.addVisibilityChangeListener(mMediaHostVisibilityListener); - mView.onMediaVisibilityChanged(mMediaHost.getVisible()); mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener); mHost.addCallback(mQSHostCallback); setTiles(); @@ -381,6 +387,13 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr return mView.getTileLayout(); } + /** + * Add a listener for when the media visibility changes. + */ + public void setMediaVisibilityChangedListener(@NonNull Consumer<Boolean> listener) { + mMediaVisibilityChangedListener = listener; + } + /** */ public static final class TileRecord extends QSPanel.Record { public QSTile tile; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java index 3a6f1d5a02ae..7f19d0e6c25c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java @@ -185,15 +185,22 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen final boolean isProfileOwnerOfOrganizationOwnedDevice = mSecurityController.isProfileOwnerOfOrganizationOwnedDevice(); final boolean isParentalControlsEnabled = mSecurityController.isParentalControlsEnabled(); + final boolean isWorkProfileOn = mSecurityController.isWorkProfileOn(); + final boolean hasDisclosableWorkProfilePolicy = hasCACertsInWorkProfile + || vpnNameWorkProfile != null || (hasWorkProfile && isNetworkLoggingEnabled); // Update visibility of footer - mIsVisible = (isDeviceManaged && !isDemoDevice) || hasCACerts || hasCACertsInWorkProfile - || vpnName != null || vpnNameWorkProfile != null - || isProfileOwnerOfOrganizationOwnedDevice || isParentalControlsEnabled - || (hasWorkProfile && isNetworkLoggingEnabled); + mIsVisible = (isDeviceManaged && !isDemoDevice) + || hasCACerts + || vpnName != null + || isProfileOwnerOfOrganizationOwnedDevice + || isParentalControlsEnabled + || (hasDisclosableWorkProfilePolicy && isWorkProfileOn); // Update the view to be untappable if the device is an organization-owned device with a - // managed profile and there is no policy set which requires a privacy disclosure. - if (mIsVisible && isProfileOwnerOfOrganizationOwnedDevice && !isNetworkLoggingEnabled - && !hasCACertsInWorkProfile && vpnNameWorkProfile == null) { + // managed profile and there is either: + // a) no policy set which requires a privacy disclosure. + // b) a specific work policy set but the work profile is turned off. + if (mIsVisible && isProfileOwnerOfOrganizationOwnedDevice + && (!hasDisclosableWorkProfilePolicy || !isWorkProfileOn)) { mRootView.setClickable(false); mRootView.findViewById(R.id.footer_icon).setVisibility(View.GONE); } else { @@ -204,7 +211,8 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen mFooterTextContent = getFooterText(isDeviceManaged, hasWorkProfile, hasCACerts, hasCACertsInWorkProfile, isNetworkLoggingEnabled, vpnName, vpnNameWorkProfile, organizationName, workProfileOrganizationName, - isProfileOwnerOfOrganizationOwnedDevice, isParentalControlsEnabled); + isProfileOwnerOfOrganizationOwnedDevice, isParentalControlsEnabled, + isWorkProfileOn); // Update the icon int footerIconId = R.drawable.ic_info_outline; if (vpnName != null || vpnNameWorkProfile != null) { @@ -236,7 +244,8 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen boolean hasCACerts, boolean hasCACertsInWorkProfile, boolean isNetworkLoggingEnabled, String vpnName, String vpnNameWorkProfile, CharSequence organizationName, CharSequence workProfileOrganizationName, - boolean isProfileOwnerOfOrganizationOwnedDevice, boolean isParentalControlsEnabled) { + boolean isProfileOwnerOfOrganizationOwnedDevice, boolean isParentalControlsEnabled, + boolean isWorkProfileOn) { if (isParentalControlsEnabled) { return mContext.getString(R.string.quick_settings_disclosure_parental_controls); } @@ -280,7 +289,7 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen organizationName); } } // end if(isDeviceManaged) - if (hasCACertsInWorkProfile) { + if (hasCACertsInWorkProfile && isWorkProfileOn) { if (workProfileOrganizationName == null) { return mContext.getString( R.string.quick_settings_disclosure_managed_profile_monitoring); @@ -295,7 +304,7 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen if (vpnName != null && vpnNameWorkProfile != null) { return mContext.getString(R.string.quick_settings_disclosure_vpns); } - if (vpnNameWorkProfile != null) { + if (vpnNameWorkProfile != null && isWorkProfileOn) { return mContext.getString(R.string.quick_settings_disclosure_managed_profile_named_vpn, vpnNameWorkProfile); } @@ -308,7 +317,7 @@ class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListen return mContext.getString(R.string.quick_settings_disclosure_named_vpn, vpnName); } - if (hasWorkProfile && isNetworkLoggingEnabled) { + if (hasWorkProfile && isNetworkLoggingEnabled && isWorkProfileOn) { return mContext.getString( R.string.quick_settings_disclosure_managed_profile_network_activity); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java index cbdcad5cf385..76076f6c2761 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java @@ -177,7 +177,6 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader mView.onAttach(mIconManager, mQSExpansionPathInterpolator); mDemoModeController.addCallback(mDemoModeReceiver); - mHeaderQsPanelController.setContentMargins(0, 0); } @Override @@ -253,6 +252,10 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader return mMicCameraIndicatorsEnabled || mLocationIndicatorsEnabled; } + public void setContentMargins(int marginStart, int marginEnd) { + mHeaderQsPanelController.setContentMargins(marginStart, marginEnd); + } + private static class ClockDemoModeReceiver implements DemoMode { private Clock mClockView; diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java index aa51771864b2..1d791f5d632c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java @@ -57,6 +57,12 @@ public class TileLifecycleManager extends BroadcastReceiver implements private static final String TAG = "TileLifecycleManager"; + private static final int META_DATA_QUERY_FLAGS = + PackageManager.GET_META_DATA + | PackageManager.MATCH_UNINSTALLED_PACKAGES + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE + | PackageManager.MATCH_DIRECT_BOOT_AWARE; + private static final int MSG_ON_ADDED = 0; private static final int MSG_ON_REMOVED = 1; private static final int MSG_ON_CLICK = 2; @@ -130,7 +136,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements public boolean isActiveTile() { try { ServiceInfo info = mPackageManagerAdapter.getServiceInfo(mIntent.getComponent(), - PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.GET_META_DATA); + META_DATA_QUERY_FLAGS); return info.metaData != null && info.metaData.getBoolean(TileService.META_DATA_ACTIVE_TILE, false); } catch (PackageManager.NameNotFoundException e) { @@ -148,7 +154,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements public boolean isToggleableTile() { try { ServiceInfo info = mPackageManagerAdapter.getServiceInfo(mIntent.getComponent(), - PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.GET_META_DATA); + META_DATA_QUERY_FLAGS); return info.metaData != null && info.metaData.getBoolean(TileService.META_DATA_TOGGLEABLE_TILE, false); } catch (PackageManager.NameNotFoundException e) { diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java index c6b5eb7508af..5bb3413595ba 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java @@ -291,19 +291,24 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis ? res.getString(R.string.screenrecord_ongoing_screen_only) : res.getString(R.string.screenrecord_ongoing_screen_and_audio); - Intent stopIntent = getNotificationIntent(this); + PendingIntent pendingIntent = PendingIntent.getService( + this, + REQUEST_CODE, + getNotificationIntent(this), + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + Notification.Action stopAction = new Notification.Action.Builder( + Icon.createWithResource(this, R.drawable.ic_android), + getResources().getString(R.string.screenrecord_stop_label), + pendingIntent).build(); Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.ic_screenrecord) .setContentTitle(notificationTitle) - .setContentText(getResources().getString(R.string.screenrecord_stop_text)) .setUsesChronometer(true) .setColorized(true) .setColor(getResources().getColor(R.color.GM2_red_700)) .setOngoing(true) .setForegroundServiceBehavior(Notification.FOREGROUND_SERVICE_IMMEDIATE) - .setContentIntent( - PendingIntent.getService(this, REQUEST_CODE, stopIntent, - PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE)) + .addAction(stopAction) .addExtras(extras); startForeground(NOTIFICATION_RECORDING_ID, builder.build()); } diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java index 57125f34731c..df766f3625e4 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java @@ -30,9 +30,9 @@ import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.ArrayAdapter; -import android.widget.Button; import android.widget.Spinner; import android.widget.Switch; +import android.widget.TextView; import com.android.systemui.R; import com.android.systemui.settings.UserContextProvider; @@ -78,12 +78,12 @@ public class ScreenRecordDialog extends Activity { setContentView(R.layout.screen_record_dialog); - Button cancelBtn = findViewById(R.id.button_cancel); + TextView cancelBtn = findViewById(R.id.button_cancel); cancelBtn.setOnClickListener(v -> { finish(); }); - Button startBtn = findViewById(R.id.button_start); + TextView startBtn = findViewById(R.id.button_start); startBtn.setOnClickListener(v -> { requestScreenCapture(); finish(); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java b/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java index 4aead817fe8c..55602a98b8c5 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java @@ -111,30 +111,21 @@ class ImageExporter { } /** - * Stores the given Bitmap to a temp file. + * Writes the given Bitmap to outputFile. */ - ListenableFuture<File> exportAsTempFile(Executor executor, Bitmap bitmap) { + ListenableFuture<File> exportToRawFile(Executor executor, Bitmap bitmap, + final File outputFile) { return CallbackToFutureAdapter.getFuture( (completer) -> { executor.execute(() -> { - File cachePath; - try { - cachePath = File.createTempFile("long_screenshot_cache_", ".tmp"); - try (FileOutputStream stream = new FileOutputStream(cachePath)) { - bitmap.compress(mCompressFormat, mQuality, stream); - } catch (IOException e) { - if (cachePath.exists()) { - //noinspection ResultOfMethodCallIgnored - cachePath.delete(); - cachePath = null; - } - completer.setException(e); - } - if (cachePath != null) { - completer.set(cachePath); - } + try (FileOutputStream stream = new FileOutputStream(outputFile)) { + bitmap.compress(mCompressFormat, mQuality, stream); + completer.set(outputFile); } catch (IOException e) { - // Failed to create a new file + if (outputFile.exists()) { + //noinspection ResultOfMethodCallIgnored + outputFile.delete(); + } completer.setException(e); } }); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ImageTileSet.java b/packages/SystemUI/src/com/android/systemui/screenshot/ImageTileSet.java index 730702ec8685..51cc32ad39c1 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ImageTileSet.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ImageTileSet.java @@ -20,6 +20,7 @@ import android.graphics.Bitmap; import android.graphics.HardwareRenderer; import android.graphics.RecordingCanvas; import android.graphics.Rect; +import android.graphics.Region; import android.graphics.RenderNode; import android.graphics.drawable.Drawable; import android.os.Handler; @@ -46,7 +47,6 @@ class ImageTileSet { private static final String TAG = "ImageTileSet"; - private CallbackRegistry<OnBoundsChangedListener, ImageTileSet, Rect> mOnBoundsListeners; private CallbackRegistry<OnContentChangedListener, ImageTileSet, Rect> mContentListeners; @Inject @@ -54,14 +54,6 @@ class ImageTileSet { mHandler = handler; } - interface OnBoundsChangedListener { - /** - * Reports an update to the bounding box that contains all active tiles. These are virtual - * (capture) coordinates which can be either negative or positive. - */ - void onBoundsChanged(int left, int top, int right, int bottom); - } - interface OnContentChangedListener { /** * Mark as dirty and rebuild display list. @@ -70,25 +62,9 @@ class ImageTileSet { } private final List<ImageTile> mTiles = new ArrayList<>(); - private final Rect mBounds = new Rect(); + private final Region mRegion = new Region(); private final Handler mHandler; - void addOnBoundsChangedListener(OnBoundsChangedListener listener) { - if (mOnBoundsListeners == null) { - mOnBoundsListeners = new CallbackRegistry<>( - new NotifierCallback<OnBoundsChangedListener, ImageTileSet, Rect>() { - @Override - public void onNotifyCallback(OnBoundsChangedListener callback, - ImageTileSet sender, - int arg, Rect newBounds) { - callback.onBoundsChanged(newBounds.left, newBounds.top, newBounds.right, - newBounds.bottom); - } - }); - } - mOnBoundsListeners.add(listener); - } - void addOnContentChangedListener(OnContentChangedListener listener) { if (mContentListeners == null) { mContentListeners = new CallbackRegistry<>( @@ -110,14 +86,8 @@ class ImageTileSet { mHandler.post(() -> addTile(tile)); return; } - final Rect newBounds = new Rect(mBounds); - final Rect newRect = tile.getLocation(); mTiles.add(tile); - newBounds.union(newRect); - if (!newBounds.equals(mBounds)) { - mBounds.set(newBounds); - notifyBoundsChanged(mBounds); - } + mRegion.op(tile.getLocation(), mRegion, Region.Op.UNION); notifyContentChanged(); } @@ -127,12 +97,6 @@ class ImageTileSet { } } - private void notifyBoundsChanged(Rect bounds) { - if (mOnBoundsListeners != null) { - mOnBoundsListeners.notifyCallbacks(this, 0, bounds); - } - } - /** * Returns a drawable to paint the combined contents of the tiles. Drawable dimensions are * zero-based and map directly to {@link #getLeft()}, {@link #getTop()}, {@link #getRight()}, @@ -153,6 +117,15 @@ class ImageTileSet { return mTiles.size(); } + /** + * @return the bounding rect around any gaps in the tiles. + */ + Rect getGaps() { + Region difference = new Region(); + difference.op(mRegion.getBounds(), mRegion, Region.Op.DIFFERENCE); + return difference.getBounds(); + } + ImageTile get(int i) { return mTiles.get(i); } @@ -182,41 +155,40 @@ class ImageTileSet { } int getLeft() { - return mBounds.left; + return mRegion.getBounds().left; } int getTop() { - return mBounds.top; + return mRegion.getBounds().top; } int getRight() { - return mBounds.right; + return mRegion.getBounds().right; } int getBottom() { - return mBounds.bottom; + return mRegion.getBounds().bottom; } int getWidth() { - return mBounds.width(); + return mRegion.getBounds().width(); } int getHeight() { - return mBounds.height(); + return mRegion.getBounds().height(); } void clear() { if (mTiles.isEmpty()) { return; } - mBounds.setEmpty(); + mRegion.setEmpty(); Iterator<ImageTile> i = mTiles.iterator(); while (i.hasNext()) { ImageTile next = i.next(); next.close(); i.remove(); } - notifyBoundsChanged(mBounds); notifyContentChanged(); } } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java index f571e417c636..741dddc49378 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java @@ -200,7 +200,6 @@ public class LongScreenshotActivity extends Activity { / (float) mLongScreenshot.getHeight()); mEnterTransitionView.setImageDrawable(drawable); - mEnterTransitionView.getViewTreeObserver().addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { @Override @@ -220,7 +219,6 @@ public class LongScreenshotActivity extends Activity { mCropView.animateEntrance(); mCropView.setVisibility(View.VISIBLE); setButtonsEnabled(true); - mEnterTransitionView.setVisibility(View.GONE); }); }); return true; @@ -228,8 +226,8 @@ public class LongScreenshotActivity extends Activity { }); // Immediately export to temp image file for saved state - mCacheSaveFuture = mImageExporter.exportAsTempFile(mBackgroundExecutor, - mLongScreenshot.toBitmap()); + mCacheSaveFuture = mImageExporter.exportToRawFile(mBackgroundExecutor, + mLongScreenshot.toBitmap(), new File(getCacheDir(), "long_screenshot_cache.png")); mCacheSaveFuture.addListener(() -> { try { // Get the temp file path to persist, used in onSavedInstanceState diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index 2e138362aedb..63ecc0b89783 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -33,6 +33,7 @@ import static java.util.Objects.requireNonNull; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.annotation.Nullable; +import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.ExitTransitionCoordinator; import android.app.ExitTransitionCoordinator.ExitTransitionCallbacks; @@ -253,6 +254,7 @@ public class ScreenshotController { private final DisplayManager mDisplayManager; private final ScrollCaptureController mScrollCaptureController; private final LongScreenshotData mLongScreenshotHolder; + private final boolean mIsLowRamDevice; private ScreenshotView mScreenshotView; private Bitmap mScreenBitmap; @@ -297,7 +299,8 @@ public class ScreenshotController { ImageExporter imageExporter, @Main Executor mainExecutor, ScrollCaptureController scrollCaptureController, - LongScreenshotData longScreenshotHolder) { + LongScreenshotData longScreenshotHolder, + ActivityManager activityManager) { mScreenshotSmartActions = screenshotSmartActions; mNotificationsController = screenshotNotificationsController; mScrollCaptureClient = scrollCaptureClient; @@ -306,6 +309,7 @@ public class ScreenshotController { mMainExecutor = mainExecutor; mScrollCaptureController = scrollCaptureController; mLongScreenshotHolder = longScreenshotHolder; + mIsLowRamDevice = activityManager.isLowRamDevice(); mBgExecutor = Executors.newSingleThreadExecutor(); mDisplayManager = requireNonNull(context.getSystemService(DisplayManager.class)); @@ -486,9 +490,24 @@ public class ScreenshotController { private void takeScreenshotInternal(Consumer<Uri> finisher, Rect crop) { // copy the input Rect, since SurfaceControl.screenshot can mutate it Rect screenRect = new Rect(crop); + Bitmap screenshot = captureScreenshot(crop); + + if (screenshot == null) { + Log.e(TAG, "takeScreenshotInternal: Screenshot bitmap was null"); + mNotificationsController.notifyScreenshotError( + R.string.screenshot_failed_to_capture_text); + if (mCurrentRequestCallback != null) { + mCurrentRequestCallback.reportError(); + } + return; + } + + saveScreenshot(screenshot, finisher, screenRect, Insets.NONE, true); + } + + private Bitmap captureScreenshot(Rect crop) { int width = crop.width(); int height = crop.height(); - Bitmap screenshot = null; final Display display = getDefaultDisplay(); final DisplayAddress address = display.getAddress(); @@ -509,18 +528,7 @@ public class ScreenshotController { SurfaceControl.captureDisplay(captureArgs); screenshot = screenshotBuffer == null ? null : screenshotBuffer.asBitmap(); } - - if (screenshot == null) { - Log.e(TAG, "takeScreenshotInternal: Screenshot bitmap was null"); - mNotificationsController.notifyScreenshotError( - R.string.screenshot_failed_to_capture_text); - if (mCurrentRequestCallback != null) { - mCurrentRequestCallback.reportError(); - } - return; - } - - saveScreenshot(screenshot, finisher, screenRect, Insets.NONE, true); + return screenshot; } private void saveScreenshot(Bitmap screenshot, Consumer<Uri> finisher, Rect screenRect, @@ -617,6 +625,10 @@ public class ScreenshotController { } private void requestScrollCapture() { + if (!allowLongScreenshots()) { + Log.d(TAG, "Long screenshots not supported on this device"); + return; + } mScrollCaptureClient.setHostWindowToken(mWindow.getDecorView().getWindowToken()); if (mLastScrollCaptureRequest != null) { mLastScrollCaptureRequest.cancel(true); @@ -644,45 +656,52 @@ public class ScreenshotController { final ScrollCaptureResponse response = mLastScrollCaptureResponse; mScreenshotView.showScrollChip(/* onClick */ () -> { - mScreenshotView.prepareScrollingTransition(response, mScreenBitmap); - // Clear the reference to prevent close() in dismissScreenshot - mLastScrollCaptureResponse = null; - final ListenableFuture<ScrollCaptureController.LongScreenshot> future = - mScrollCaptureController.run(response); - future.addListener(() -> { - ScrollCaptureController.LongScreenshot longScreenshot; - try { - longScreenshot = future.get(); - } catch (CancellationException | InterruptedException | ExecutionException e) { - Log.e(TAG, "Exception", e); - return; - } + DisplayMetrics displayMetrics = new DisplayMetrics(); + getDefaultDisplay().getRealMetrics(displayMetrics); + Bitmap newScreenshot = captureScreenshot( + new Rect(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels)); + + mScreenshotView.prepareScrollingTransition(response, mScreenBitmap, newScreenshot); + // delay starting scroll capture to make sure the scrim is up before the app moves + mScreenshotView.post(() -> { + // Clear the reference to prevent close() in dismissScreenshot + mLastScrollCaptureResponse = null; + final ListenableFuture<ScrollCaptureController.LongScreenshot> future = + mScrollCaptureController.run(response); + future.addListener(() -> { + ScrollCaptureController.LongScreenshot longScreenshot; + try { + longScreenshot = future.get(); + } catch (CancellationException + | InterruptedException + | ExecutionException e) { + Log.e(TAG, "Exception", e); + return; + } - mLongScreenshotHolder.setLongScreenshot(longScreenshot); - mLongScreenshotHolder.setTransitionDestinationCallback( - (transitionDestination, onTransitionEnd) -> - mScreenshotView.startLongScreenshotTransition( - transitionDestination, onTransitionEnd, - longScreenshot)); - - final Intent intent = new Intent(mContext, LongScreenshotActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - - Pair<ActivityOptions, ExitTransitionCoordinator> transition = - ActivityOptions.startSharedElementAnimation(mWindow, - new ScreenshotExitTransitionCallbacksSupplier(false).get(), - null); - transition.second.startExit(); - mContext.startActivity(intent, transition.first.toBundle()); - RemoteAnimationAdapter runner = new RemoteAnimationAdapter( - SCREENSHOT_REMOTE_RUNNER, 0, 0); - try { - WindowManagerGlobal.getWindowManagerService() - .overridePendingAppTransitionRemote(runner, DEFAULT_DISPLAY); - } catch (Exception e) { - Log.e(TAG, "Error overriding screenshot app transition", e); - } - }, mMainExecutor); + mLongScreenshotHolder.setLongScreenshot(longScreenshot); + mLongScreenshotHolder.setTransitionDestinationCallback( + (transitionDestination, onTransitionEnd) -> + mScreenshotView.startLongScreenshotTransition( + transitionDestination, onTransitionEnd, + longScreenshot)); + + final Intent intent = new Intent(mContext, LongScreenshotActivity.class); + intent.setFlags( + Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + + mContext.startActivity(intent, + ActivityOptions.makeCustomAnimation(mContext, 0, 0).toBundle()); + RemoteAnimationAdapter runner = new RemoteAnimationAdapter( + SCREENSHOT_REMOTE_RUNNER, 0, 0); + try { + WindowManagerGlobal.getWindowManagerService() + .overridePendingAppTransitionRemote(runner, DEFAULT_DISPLAY); + } catch (Exception e) { + Log.e(TAG, "Error overriding screenshot app transition", e); + } + }, mMainExecutor); + }); }); } catch (CancellationException e) { // Ignore @@ -967,6 +986,10 @@ public class ScreenshotController { return mDisplayManager.getDisplay(DEFAULT_DISPLAY); } + private boolean allowLongScreenshots() { + return !mIsLowRamDevice; + } + /** Does the aspect ratio of the bitmap with insets removed match the bounds. */ private static boolean aspectRatiosMatch(Bitmap bitmap, Insets bitmapInsets, Rect screenBounds) { diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java index 669046591170..9fe8c84bc13d 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java @@ -36,8 +36,10 @@ import android.app.ActivityManager; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; +import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.Bitmap; +import android.graphics.BlendMode; import android.graphics.Color; import android.graphics.Insets; import android.graphics.Matrix; @@ -257,10 +259,10 @@ public class ScreenshotView extends FrameLayout implements @Override // ViewTreeObserver.OnComputeInternalInsetsListener public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) { inoutInfo.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION); - inoutInfo.touchableRegion.set(getTouchRegion()); + inoutInfo.touchableRegion.set(getTouchRegion(true)); } - private Region getTouchRegion() { + private Region getTouchRegion(boolean includeScrim) { Region touchRegion = new Region(); final Rect tmpRect = new Rect(); @@ -273,6 +275,11 @@ public class ScreenshotView extends FrameLayout implements mDismissButton.getBoundsOnScreen(tmpRect); touchRegion.op(tmpRect, Region.Op.UNION); + if (includeScrim && mScrollingScrim.getVisibility() == View.VISIBLE) { + mScrollingScrim.getBoundsOnScreen(tmpRect); + touchRegion.op(tmpRect, Region.Op.UNION); + } + if (QuickStepContract.isGesturalMode(mNavMode)) { final WindowManager wm = mContext.getSystemService(WindowManager.class); final WindowMetrics windowMetrics = wm.getCurrentWindowMetrics(); @@ -296,7 +303,7 @@ public class ScreenshotView extends FrameLayout implements if (ev instanceof MotionEvent) { MotionEvent event = (MotionEvent) ev; if (event.getActionMasked() == MotionEvent.ACTION_DOWN - && !getTouchRegion().contains( + && !getTouchRegion(false).contains( (int) event.getRawX(), (int) event.getRawY())) { mCallbacks.onTouchOutside(); } @@ -313,6 +320,10 @@ public class ScreenshotView extends FrameLayout implements @Override // ViewGroup public boolean onInterceptTouchEvent(MotionEvent ev) { + // scrolling scrim should not be swipeable; return early if we're on the scrim + if (!getTouchRegion(false).contains((int) ev.getRawX(), (int) ev.getRawY())) { + return false; + } // always pass through the down event so the swipe handler knows the initial state if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { mSwipeDismissHandler.onTouch(this, ev); @@ -374,10 +385,6 @@ public class ScreenshotView extends FrameLayout implements return mScreenshotPreview; } - View getScrollablePreview() { - return mScrollablePreview; - } - /** * Set up the logger and callback on dismissal. * @@ -453,14 +460,6 @@ public class ScreenshotView extends FrameLayout implements mCornerSizeX / (mOrientationPortrait ? bounds.width() : bounds.height()); final float currentScale = 1 / cornerScale; - mScreenshotPreview.setScaleX(currentScale); - mScreenshotPreview.setScaleY(currentScale); - - if (mAccessibilityManager.isEnabled()) { - mDismissButton.setAlpha(0); - mDismissButton.setVisibility(View.VISIBLE); - } - AnimatorSet dropInAnimation = new AnimatorSet(); ValueAnimator flashInAnimator = ValueAnimator.ofFloat(0, 1); flashInAnimator.setDuration(SCREENSHOT_FLASH_IN_DURATION_MS); @@ -491,6 +490,20 @@ public class ScreenshotView extends FrameLayout implements ValueAnimator toCorner = ValueAnimator.ofFloat(0, 1); toCorner.setDuration(SCREENSHOT_TO_CORNER_Y_DURATION_MS); + + toCorner.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + mScreenshotPreview.setScaleX(currentScale); + mScreenshotPreview.setScaleY(currentScale); + mScreenshotPreview.setVisibility(View.VISIBLE); + if (mAccessibilityManager.isEnabled()) { + mDismissButton.setAlpha(0); + mDismissButton.setVisibility(View.VISIBLE); + } + } + }); + float xPositionPct = SCREENSHOT_TO_CORNER_X_DURATION_MS / (float) SCREENSHOT_TO_CORNER_Y_DURATION_MS; float dismissPct = @@ -534,13 +547,6 @@ public class ScreenshotView extends FrameLayout implements } }); - toCorner.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - mScreenshotPreview.setVisibility(View.VISIBLE); - } - }); - mScreenshotFlash.setAlpha(0f); mScreenshotFlash.setVisibility(View.VISIBLE); @@ -808,8 +814,9 @@ public class ScreenshotView extends FrameLayout implements anim.start(); } - void prepareScrollingTransition(ScrollCaptureResponse response, Bitmap screenBitmap) { - mScrollingScrim.setImageBitmap(screenBitmap); + void prepareScrollingTransition(ScrollCaptureResponse response, Bitmap screenBitmap, + Bitmap newBitmap) { + mScrollingScrim.setImageBitmap(newBitmap); mScrollingScrim.setVisibility(View.VISIBLE); Rect scrollableArea = scrollableAreaOnScreen(response); float scale = mCornerSizeX @@ -829,7 +836,19 @@ public class ScreenshotView extends FrameLayout implements mScrollablePreview.setImageBitmap(screenBitmap); mScrollablePreview.setVisibility(View.VISIBLE); - createScreenshotFadeDismissAnimation(true).start(); + mDismissButton.setVisibility(View.GONE); + mActionsContainer.setVisibility(View.GONE); + mBackgroundProtection.setVisibility(View.GONE); + // set these invisible, but not gone, so that the views are laid out correctly + mActionsContainerBackground.setVisibility(View.INVISIBLE); + mScreenshotPreviewBorder.setVisibility(View.INVISIBLE); + mScreenshotPreview.setVisibility(View.INVISIBLE); + mScrollingScrim.setImageTintBlendMode(BlendMode.SRC_ATOP); + ValueAnimator anim = ValueAnimator.ofFloat(0, .3f); + anim.addUpdateListener(animation -> mScrollingScrim.setImageTintList( + ColorStateList.valueOf(Color.argb((float) animation.getAnimatedValue(), 0, 0, 0)))); + anim.setDuration(200); + anim.start(); } boolean isDismissing() { @@ -845,10 +864,6 @@ public class ScreenshotView extends FrameLayout implements } private void animateDismissal(Animator dismissAnimation) { - if (DEBUG_WINDOW) { - Log.d(TAG, "removing OnComputeInternalInsetsListener"); - } - getViewTreeObserver().removeOnComputeInternalInsetsListener(this); mDismissAnimation = dismissAnimation; mDismissAnimation.addListener(new AnimatorListenerAdapter() { private boolean mCancelled = false; @@ -910,6 +925,7 @@ public class ScreenshotView extends FrameLayout implements mContext.getResources().getString(R.string.screenshot_preview_description)); mScreenshotPreview.setOnClickListener(null); mShareChip.setOnClickListener(null); + mScrollingScrim.setVisibility(View.GONE); mEditChip.setOnClickListener(null); mShareChip.setIsPending(false); mEditChip.setIsPending(false); @@ -932,7 +948,7 @@ public class ScreenshotView extends FrameLayout implements transition.action.actionIntent.send(); // fade out non-preview UI - createScreenshotFadeDismissAnimation(false).start(); + createScreenshotFadeDismissAnimation().start(); } catch (PendingIntent.CanceledException e) { mPendingSharedTransition = false; if (transition.onCancelRunnable != null) { @@ -970,7 +986,7 @@ public class ScreenshotView extends FrameLayout implements return animSet; } - ValueAnimator createScreenshotFadeDismissAnimation(boolean fadePreview) { + ValueAnimator createScreenshotFadeDismissAnimation() { ValueAnimator alphaAnim = ValueAnimator.ofFloat(0, 1); alphaAnim.addUpdateListener(animation -> { float alpha = 1 - animation.getAnimatedFraction(); @@ -979,9 +995,6 @@ public class ScreenshotView extends FrameLayout implements mActionsContainer.setAlpha(alpha); mBackgroundProtection.setAlpha(alpha); mScreenshotPreviewBorder.setAlpha(alpha); - if (fadePreview) { - mScreenshotPreview.setAlpha(alpha); - } }); alphaAnim.setDuration(600); return alphaAnim; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java index 94e314948779..ce6e46937c25 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java @@ -56,6 +56,7 @@ import javax.inject.Inject; public class ScrollCaptureClient { private static final int TILE_SIZE_PX_MAX = 4 * (1024 * 1024); private static final int TILES_PER_PAGE = 2; // increase once b/174571735 is addressed + private static final int MAX_TILES = 30; @VisibleForTesting static final int MATCH_ANY_TASK = ActivityTaskManager.INVALID_TASK_ID; @@ -83,11 +84,12 @@ public class ScrollCaptureClient { int getMaxTiles(); /** - * @return the maximum combined capture height for this session, in pixels. + * Target pixel height for acquisition this session. Session may yield more or less data + * than this, but acquiring this height is considered sufficient for completion. + * + * @return target height in pixels. */ - default int getMaxHeight() { - return getMaxTiles() * getTileHeight(); - } + int getTargetHeight(); /** * @return the height of each image tile @@ -234,11 +236,11 @@ public class ScrollCaptureClient { private final int mTileWidth; private Rect mRequestRect; private boolean mStarted; + private final int mTargetHeight; private ICancellationSignal mCancellationSignal; private final Rect mWindowBounds; private final Rect mBoundsInWindow; - private final int mMaxTiles; private Completer<Session> mStartCompleter; private Completer<CaptureResult> mTileRequestCompleter; @@ -256,7 +258,7 @@ public class ScrollCaptureClient { mTileWidth = mBoundsInWindow.width(); mTileHeight = pxPerTile / mBoundsInWindow.width(); - mMaxTiles = (int) Math.ceil(maxPages * TILES_PER_PAGE); + mTargetHeight = (int) (mBoundsInWindow.height() * maxPages); if (DEBUG_SCROLL) { Log.d(TAG, "boundsInWindow: " + mBoundsInWindow); @@ -285,7 +287,7 @@ public class ScrollCaptureClient { private void start(Completer<Session> completer) { mReader = ImageReader.newInstance(mTileWidth, mTileHeight, PixelFormat.RGBA_8888, - mMaxTiles, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE); + MAX_TILES, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE); mStartCompleter = completer; try { mCancellationSignal = mConnection.startCapture(mReader.getSurface(), this); @@ -410,8 +412,13 @@ public class ScrollCaptureClient { } @Override + public int getTargetHeight() { + return mTargetHeight; + } + + @Override public int getMaxTiles() { - return mMaxTiles; + return MAX_TILES; } } } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java index bbcfdbd99bef..4c1f6a19b96c 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java @@ -199,22 +199,20 @@ public class ScrollCaptureController { Log.d(TAG, "onCaptureResult: " + result + " scrolling " + (mScrollingUp ? "UP" : "DOWN") + " finish on boundary: " + mFinishOnBoundary); boolean emptyResult = result.captured.height() == 0; - boolean partialResult = !emptyResult - && result.captured.height() < result.requested.height(); - boolean finish = false; if (emptyResult) { // Potentially reached a vertical boundary. Extend in the other direction. if (mFinishOnBoundary) { - Log.d(TAG, "Partial/empty: finished!"); - finish = true; + Log.d(TAG, "Empty: finished!"); + finishCapture(); + return; } else { // We hit a boundary, clear the tiles, capture everything in the opposite direction, // then finish. mImageTileSet.clear(); mFinishOnBoundary = true; mScrollingUp = !mScrollingUp; - Log.d(TAG, "Partial/empty: cleared, switch direction to finish"); + Log.d(TAG, "Empty: cleared, switch direction to finish"); } } else { // Got a non-empty result, but may already have enough bitmap data now @@ -223,12 +221,14 @@ public class ScrollCaptureController { Log.d(TAG, "Hit max tiles: finished"); // If we ever hit the max tiles, we've got enough bitmap data to finish // (even if we weren't sure we'd finish on this pass). - finish = true; + finishCapture(); + return; } else { if (mScrollingUp && !mFinishOnBoundary) { // During the initial scroll up, we only want to acquire the portion described // by IDEAL_PORTION_ABOVE. - if (expectedTiles >= mSession.getMaxTiles() * IDEAL_PORTION_ABOVE) { + if (mImageTileSet.getHeight() + result.captured.height() + >= mSession.getTargetHeight() * IDEAL_PORTION_ABOVE) { Log.d(TAG, "Hit ideal portion above: clear and switch direction"); // We got enough above the start point, now see how far down it can go. mImageTileSet.clear(); @@ -246,15 +246,15 @@ public class ScrollCaptureController { + " - " + mImageTileSet.getRight() + "," + mImageTileSet.getBottom() + " (" + mImageTileSet.getWidth() + "x" + mImageTileSet.getHeight() + ")"); - - // Stop when "too tall" - if (mImageTileSet.getHeight() > MAX_HEIGHT) { - Log.d(TAG, "Max height reached."); - finish = true; + Rect gapBounds = mImageTileSet.getGaps(); + if (!gapBounds.isEmpty()) { + Log.d(TAG, "Found gaps in tileset: " + gapBounds + ", requesting " + gapBounds.top); + requestNextTile(gapBounds.top); + return; } - if (finish) { - Log.d(TAG, "Stop."); + if (mImageTileSet.getHeight() >= mSession.getTargetHeight()) { + Log.d(TAG, "Target height reached."); finishCapture(); return; } @@ -268,8 +268,8 @@ public class ScrollCaptureController { : result.requested.bottom; } else { nextTop = (mScrollingUp) - ? result.captured.top - mSession.getTileHeight() - : result.captured.bottom; + ? mImageTileSet.getTop() - mSession.getTileHeight() + : mImageTileSet.getBottom(); } requestNextTile(nextTop); } diff --git a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt index 06c1c6f8cefa..a79316d6f5a9 100644 --- a/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt @@ -32,6 +32,7 @@ import android.widget.ImageView import com.android.internal.app.AlertActivity import com.android.internal.widget.DialogTitle import com.android.systemui.R +import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.statusbar.phone.KeyguardDismissUtil import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController import com.android.systemui.statusbar.policy.KeyguardStateController @@ -46,13 +47,15 @@ import javax.inject.Inject class SensorUseStartedActivity @Inject constructor( private val sensorPrivacyController: IndividualSensorPrivacyController, private val keyguardStateController: KeyguardStateController, - private val keyguardDismissUtil: KeyguardDismissUtil + private val keyguardDismissUtil: KeyguardDismissUtil, + @Background private val bgHandler: Handler ) : AlertActivity(), DialogInterface.OnClickListener { companion object { private val LOG_TAG = SensorUseStartedActivity::class.java.simpleName private const val SUPPRESS_REMINDERS_REMOVAL_DELAY_MILLIS = 2000L + private const val UNLOCK_DELAY_MILLIS = 200L private const val CAMERA = SensorPrivacyManager.Sensors.CAMERA private const val MICROPHONE = SensorPrivacyManager.Sensors.MICROPHONE @@ -179,9 +182,12 @@ class SensorUseStartedActivity @Inject constructor( BUTTON_POSITIVE -> { if (keyguardStateController.isMethodSecure && keyguardStateController.isShowing) { keyguardDismissUtil.executeWhenUnlocked({ - disableSensorPrivacy() + bgHandler.postDelayed({ + disableSensorPrivacy() + }, UNLOCK_DELAY_MILLIS) + false - }, false, false) + }, false, true) } else { disableSensorPrivacy() } @@ -201,7 +207,7 @@ class SensorUseStartedActivity @Inject constructor( sensorPrivacyController .suppressSensorPrivacyReminders(sensorUsePackageName, false) } else { - Handler(mainLooper).postDelayed({ + bgHandler.postDelayed({ sensorPrivacyController .suppressSensorPrivacyReminders(sensorUsePackageName, false) }, SUPPRESS_REMINDERS_REMOVAL_DELAY_MILLIS) @@ -218,7 +224,12 @@ class SensorUseStartedActivity @Inject constructor( } private fun disableSensorPrivacy() { - sensorPrivacyController.setSensorBlocked(sensor, false) + if (sensor == ALL_SENSORS) { + sensorPrivacyController.setSensorBlocked(MICROPHONE, false) + sensorPrivacyController.setSensorBlocked(CAMERA, false) + } else { + sensorPrivacyController.setSensorBlocked(sensor, false) + } unsuppressImmediately = true setResult(RESULT_OK) } diff --git a/packages/SystemUI/src/com/android/systemui/sensorprivacy/television/TvUnblockSensorActivity.java b/packages/SystemUI/src/com/android/systemui/sensorprivacy/television/TvUnblockSensorActivity.java new file mode 100644 index 000000000000..9d101effa99f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/sensorprivacy/television/TvUnblockSensorActivity.java @@ -0,0 +1,145 @@ +/* + * 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.sensorprivacy.television; + +import static android.hardware.SensorPrivacyManager.Sensors.CAMERA; +import static android.hardware.SensorPrivacyManager.Sensors.MICROPHONE; + +import android.hardware.SensorPrivacyManager; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.systemui.R; +import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController; +import com.android.systemui.tv.TvBottomSheetActivity; + +import javax.inject.Inject; + +/** + * Bottom sheet that is shown when the camera/mic sensors are blocked by the global toggle and + * allows the user to re-enable them. + */ +public class TvUnblockSensorActivity extends TvBottomSheetActivity { + + private static final String TAG = TvUnblockSensorActivity.class.getSimpleName(); + + private static final int ALL_SENSORS = Integer.MAX_VALUE; + private int mSensor = -1; + + private final IndividualSensorPrivacyController mSensorPrivacyController; + private IndividualSensorPrivacyController.Callback mSensorPrivacyCallback; + + @Inject + public TvUnblockSensorActivity( + IndividualSensorPrivacyController individualSensorPrivacyController) { + mSensorPrivacyController = individualSensorPrivacyController; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + boolean allSensors = getIntent().getBooleanExtra(SensorPrivacyManager.EXTRA_ALL_SENSORS, + false); + if (allSensors) { + mSensor = ALL_SENSORS; + } else { + mSensor = getIntent().getIntExtra(SensorPrivacyManager.EXTRA_SENSOR, -1); + } + + if (mSensor == -1) { + Log.v(TAG, "Invalid extras"); + finish(); + return; + } + + mSensorPrivacyCallback = (sensor, blocked) -> { + if (mSensor == ALL_SENSORS) { + if (!mSensorPrivacyController.isSensorBlocked(CAMERA) + && !mSensorPrivacyController.isSensorBlocked(MICROPHONE)) { + finish(); + } + } else if (this.mSensor == sensor && !blocked) { + finish(); + } + }; + + initUI(); + } + + private void initUI() { + TextView title = findViewById(R.id.bottom_sheet_title); + TextView content = findViewById(R.id.bottom_sheet_body); + ImageView icon = findViewById(R.id.bottom_sheet_icon); + // mic icon if both icons are shown + ImageView secondIcon = findViewById(R.id.bottom_sheet_second_icon); + Button unblockButton = findViewById(R.id.bottom_sheet_positive_button); + Button cancelButton = findViewById(R.id.bottom_sheet_negative_button); + + switch (mSensor) { + case MICROPHONE: + title.setText(R.string.sensor_privacy_start_use_mic_dialog_title); + content.setText(R.string.sensor_privacy_start_use_mic_dialog_content); + icon.setImageResource(com.android.internal.R.drawable.perm_group_microphone); + secondIcon.setVisibility(View.GONE); + break; + case CAMERA: + title.setText(R.string.sensor_privacy_start_use_camera_dialog_title); + content.setText(R.string.sensor_privacy_start_use_camera_dialog_content); + icon.setImageResource(com.android.internal.R.drawable.perm_group_camera); + secondIcon.setVisibility(View.GONE); + break; + case ALL_SENSORS: + default: + title.setText(R.string.sensor_privacy_start_use_mic_camera_dialog_title); + content.setText(R.string.sensor_privacy_start_use_mic_camera_dialog_content); + icon.setImageResource(com.android.internal.R.drawable.perm_group_camera); + secondIcon.setImageResource(com.android.internal.R.drawable.perm_group_microphone); + break; + } + unblockButton.setText( + com.android.internal.R.string.sensor_privacy_start_use_dialog_turn_on_button); + unblockButton.setOnClickListener(v -> { + if (mSensor == ALL_SENSORS) { + mSensorPrivacyController.setSensorBlocked(CAMERA, false); + mSensorPrivacyController.setSensorBlocked(MICROPHONE, false); + } else { + mSensorPrivacyController.setSensorBlocked(mSensor, false); + } + }); + + cancelButton.setText(android.R.string.cancel); + cancelButton.setOnClickListener(v -> finish()); + } + + @Override + public void onResume() { + super.onResume(); + mSensorPrivacyController.addCallback(mSensorPrivacyCallback); + } + + @Override + public void onPause() { + mSensorPrivacyController.removeCallback(mSensorPrivacyCallback); + super.onPause(); + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java index 8dd6c8926434..15aa2b730adf 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java +++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessSliderView.java @@ -180,6 +180,8 @@ public class BrightnessSliderView extends FrameLayout { * Sets the scale for the progress bar (for brightness_progress_drawable.xml) * * This will only scale the thick progress bar and not the icon inside + * + * Used in {@link com.android.systemui.qs.QSAnimator}. */ public void setSliderScaleY(float scale) { if (scale != mScale) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt index ce796d9789cf..aafeabc7c1a2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt @@ -20,8 +20,10 @@ import android.view.CrossWindowBlurListeners.CROSS_WINDOW_BLUR_SUPPORTED import android.app.ActivityManager import android.content.res.Resources +import android.os.SystemProperties import android.util.IndentingPrintWriter import android.util.MathUtils +import android.view.CrossWindowBlurListeners import android.view.SurfaceControl import android.view.ViewRootImpl import androidx.annotation.VisibleForTesting @@ -37,6 +39,7 @@ import javax.inject.Inject @SysUISingleton open class BlurUtils @Inject constructor( @Main private val resources: Resources, + private val crossWindowBlurListeners: CrossWindowBlurListeners, dumpManager: DumpManager ) : Dumpable { val minBlurRadius = resources.getDimensionPixelSize(R.dimen.min_window_blur_radius) @@ -97,7 +100,9 @@ open class BlurUtils @Inject constructor( * @return {@code true} when supported. */ open fun supportsBlursOnWindows(): Boolean { - return CROSS_WINDOW_BLUR_SUPPORTED && ActivityManager.isHighEndGfx() + return CROSS_WINDOW_BLUR_SUPPORTED && ActivityManager.isHighEndGfx() && + crossWindowBlurListeners.isCrossWindowBlurEnabled() && + !SystemProperties.getBoolean("persist.sysui.disableBlur", false) } override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java index 7e676197ddad..8e5d47f19acd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java @@ -84,4 +84,12 @@ public class FeatureFlags { public boolean isSmartspaceDedupingEnabled() { return isSmartspaceEnabled() && mFlagReader.isEnabled(R.bool.flag_smartspace_deduping); } + + public boolean isNewKeyguardSwipeAnimationEnabled() { + return mFlagReader.isEnabled(R.bool.flag_new_unlock_swipe_animation); + } + + public boolean isSmartSpaceSharedElementTransitionEnabled() { + return mFlagReader.isEnabled(R.bool.flag_smartspace_shared_element_transition); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 0bb702f6c9e4..c09f98dd609f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -885,6 +885,11 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal .isUnlockingWithBiometricAllowed(true /* isStrongBiometric */)) { return; } + + if (biometricSourceType == BiometricSourceType.FACE && shouldSuppressFaceMsg()) { + return; + } + boolean showSwipeToUnlock = msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; if (mStatusBarKeyguardViewManager.isBouncerShowing()) { @@ -912,7 +917,8 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal // The face timeout message is not very actionable, let's ask the user to // manually retry. if (!mStatusBarKeyguardViewManager.isBouncerShowing() - && mKeyguardUpdateMonitor.isUdfpsEnrolled()) { + && mKeyguardUpdateMonitor.isUdfpsEnrolled() + && mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) { // suggest trying fingerprint showTransientIndication(R.string.keyguard_try_fingerprint); } else { @@ -952,7 +958,18 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal || msgId == FingerprintManager.FINGERPRINT_ERROR_USER_CANCELED); } + private boolean shouldSuppressFaceMsg() { + // For dual biometric, don't show face auth messages unless face auth was explicitly + // requested by the user. + return mKeyguardUpdateMonitor.isUdfpsEnrolled() + && mKeyguardUpdateMonitor.isFingerprintDetectionRunning() + && !mKeyguardUpdateMonitor.isFaceAuthUserRequested(); + } + private boolean shouldSuppressFaceError(int msgId, KeyguardUpdateMonitor updateMonitor) { + if (shouldSuppressFaceMsg()) { + return true; + } // Only checking if unlocking with Biometric is allowed (no matter strong or non-strong // as long as primary auth, i.e. PIN/pattern/password, is not required), so it's ok to // pass true for isStrongBiometric to isUnlockingWithBiometricAllowed() to bypass the diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt index ec648ad519a3..5d8bed57563b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt @@ -51,7 +51,7 @@ object LiftReveal : LightRevealEffect { private const val OVAL_INITIAL_WIDTH_PERCENT = 0.5f /** The initial top value of the light oval, in percent of scrim height. */ - private const val OVAL_INITIAL_TOP_PERCENT = 1.05f + private const val OVAL_INITIAL_TOP_PERCENT = 1.1f /** The initial bottom value of the light oval, in percent of scrim height. */ private const val OVAL_INITIAL_BOTTOM_PERCENT = 1.2f diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt index 4a4e990728f3..6f4a73ec4516 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt @@ -18,6 +18,7 @@ import com.android.systemui.ExpandHelper import com.android.systemui.Gefingerpoken import com.android.systemui.R import com.android.systemui.animation.Interpolators +import com.android.systemui.biometrics.UdfpsKeyguardViewController import com.android.systemui.classifier.Classifier import com.android.systemui.classifier.FalsingCollector import com.android.systemui.dagger.SysUISingleton @@ -109,6 +110,11 @@ class LockscreenShadeTransitionController @Inject constructor( private var nextHideKeyguardNeedsNoAnimation = false /** + * The udfpsKeyguardViewController if it exists. + */ + var udfpsKeyguardViewController: UdfpsKeyguardViewController? = null + + /** * The touch helper responsible for the drag down animation. */ val touchHelper = DragDownHelper(falsingManager, falsingCollector, this, context) @@ -291,6 +297,7 @@ class LockscreenShadeTransitionController @Inject constructor( // Fade out all content only visible on the lockscreen notificationPanelController.setKeyguardOnlyContentAlpha(1.0f - scrimProgress) depthController.transitionToFullShadeProgress = scrimProgress + udfpsKeyguardViewController?.setTransitionToFullShadeProgress(scrimProgress) } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java index 0b67e7eeb132..4552138761c0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java @@ -369,7 +369,7 @@ public class NotificationRemoteInputManager implements Dumpable { }); mSmartReplyController.setCallback((entry, reply) -> { StatusBarNotification newSbn = - rebuildNotificationWithRemoteInput(entry, reply, true /* showSpinner */, + rebuildNotificationWithRemoteInputInserted(entry, reply, true /* showSpinner */, null /* mimeType */, null /* uri */); mEntryManager.updateNotification(newSbn, null /* ranking */); }); @@ -638,12 +638,12 @@ public class NotificationRemoteInputManager implements Dumpable { @VisibleForTesting StatusBarNotification rebuildNotificationForCanceledSmartReplies( NotificationEntry entry) { - return rebuildNotificationWithRemoteInput(entry, null /* remoteInputTest */, + return rebuildNotificationWithRemoteInputInserted(entry, null /* remoteInputTest */, false /* showSpinner */, null /* mimeType */, null /* uri */); } @VisibleForTesting - StatusBarNotification rebuildNotificationWithRemoteInput(NotificationEntry entry, + StatusBarNotification rebuildNotificationWithRemoteInputInserted(NotificationEntry entry, CharSequence remoteInputText, boolean showSpinner, String mimeType, Uri uri) { StatusBarNotification sbn = entry.getSbn(); @@ -746,7 +746,7 @@ public class NotificationRemoteInputManager implements Dumpable { } String remoteInputMimeType = entry.remoteInputMimeType; Uri remoteInputUri = entry.remoteInputUri; - StatusBarNotification newSbn = rebuildNotificationWithRemoteInput(entry, + StatusBarNotification newSbn = rebuildNotificationWithRemoteInputInserted(entry, remoteInputText, false /* showSpinner */, remoteInputMimeType, remoteInputUri); entry.onRemoteInputInserted(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt index 89005513d3d0..a2048e21199e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt @@ -93,8 +93,13 @@ class NotificationShadeDepthController @Inject constructor( var shadeAnimation = DepthAnimation() @VisibleForTesting - var globalActionsSpring = DepthAnimation() - var showingHomeControls: Boolean = false + var brightnessMirrorSpring = DepthAnimation() + var brightnessMirrorVisible: Boolean = false + set(value) { + field = value + brightnessMirrorSpring.animateTo(if (value) blurUtils.blurRadiusOfRatio(1f) + else 0) + } var qsPanelExpansion = 0f set(value) { @@ -117,7 +122,7 @@ class NotificationShadeDepthController @Inject constructor( * When launching an app from the shade, the animations progress should affect how blurry the * shade is, overriding the expansion amount. */ - var ignoreShadeBlurUntilHidden: Boolean = false + var blursDisabledForAppLaunch: Boolean = false set(value) { if (field == value) { return @@ -128,6 +133,10 @@ class NotificationShadeDepthController @Inject constructor( if (shadeSpring.radius == 0 && shadeAnimation.radius == 0) { return } + // Do not remove blurs when we're re-enabling them + if (!value) { + return + } shadeSpring.animateTo(0) shadeSpring.finishIfRunning() @@ -169,30 +178,27 @@ class NotificationShadeDepthController @Inject constructor( combinedBlur = max(combinedBlur, blurUtils.blurRadiusOfRatio(transitionToFullShadeProgress)) var shadeRadius = max(combinedBlur, wakeAndUnlockBlurRadius).toFloat() - if (ignoreShadeBlurUntilHidden) { - if (shadeRadius == 0f) { - ignoreShadeBlurUntilHidden = false - } else { - shadeRadius = 0f - } + if (blursDisabledForAppLaunch) { + shadeRadius = 0f } - // Home controls have black background, this means that we should not have blur when they - // are fully visible, otherwise we'll enter Client Composition unnecessarily. - var globalActionsRadius = globalActionsSpring.radius - if (showingHomeControls) { - globalActionsRadius = 0 - } - var blur = max(shadeRadius.toInt(), globalActionsRadius) + var blur = shadeRadius.toInt() // Make blur be 0 if it is necessary to stop blur effect. if (scrimsVisible) { blur = 0 } + val zoomOut = blurUtils.ratioOfBlurRadius(blur) - val opaque = scrimsVisible && !ignoreShadeBlurUntilHidden + if (!blurUtils.supportsBlursOnWindows()) { + blur = 0 + } + + // Brightness slider removes blur, but doesn't affect zooms + blur = (blur * (1f - brightnessMirrorSpring.ratio)).toInt() + + val opaque = scrimsVisible && !blursDisabledForAppLaunch blurUtils.applyBlur(blurRoot?.viewRootImpl ?: root.viewRootImpl, blur, opaque) - val zoomOut = blurUtils.ratioOfBlurRadius(blur) try { if (root.isAttachedToWindow && root.windowToken != null) { wallpaperManager.setWallpaperZoomOut(root.windowToken, zoomOut) @@ -204,6 +210,7 @@ class NotificationShadeDepthController @Inject constructor( } listeners.forEach { it.onWallpaperZoomOutChanged(zoomOut) + it.onBlurRadiusChanged(blur) } notificationShadeWindowController.setBackgroundBlurRadius(blur) } @@ -259,7 +266,7 @@ class NotificationShadeDepthController @Inject constructor( if (isDozing) { shadeSpring.finishIfRunning() shadeAnimation.finishIfRunning() - globalActionsSpring.finishIfRunning() + brightnessMirrorSpring.finishIfRunning() } } @@ -414,19 +421,15 @@ class NotificationShadeDepthController @Inject constructor( !keyguardStateController.isKeyguardFadingAway } - fun updateGlobalDialogVisibility(visibility: Float, dialogView: View?) { - globalActionsSpring.animateTo(blurUtils.blurRadiusOfRatio(visibility), dialogView) - } - override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) { IndentingPrintWriter(pw, " ").let { it.println("StatusBarWindowBlurController:") it.increaseIndent() it.println("shadeRadius: ${shadeSpring.radius}") it.println("shadeAnimation: ${shadeAnimation.radius}") - it.println("globalActionsRadius: ${globalActionsSpring.radius}") + it.println("brightnessMirrorRadius: ${brightnessMirrorSpring.radius}") it.println("wakeAndUnlockBlur: $wakeAndUnlockBlurRadius") - it.println("ignoreShadeBlurUntilHidden: $ignoreShadeBlurUntilHidden") + it.println("blursDisabledForAppLaunch: $blursDisabledForAppLaunch") } } @@ -511,5 +514,8 @@ class NotificationShadeDepthController @Inject constructor( * Current wallpaper zoom out, where 0 is the closest, and 1 the farthest */ fun onWallpaperZoomOutChanged(zoomOut: Float) + + @JvmDefault + fun onBlurRadiusChanged(blurRadius: Int) {} } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java index 3c549f94ad0f..467f27f640f9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java @@ -158,14 +158,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle final int N = activeNotifications.size(); for (int i = 0; i < N; i++) { NotificationEntry ent = activeNotifications.get(i); - final boolean isBubbleNotificationSuppressedFromShade = mBubblesOptional.isPresent() - && mBubblesOptional.get().isBubbleNotificationSuppressedFromShade( - ent.getKey(), ent.getSbn().getGroupKey()); - if (ent.isRowDismissed() || ent.isRowRemoved() - || isBubbleNotificationSuppressedFromShade - || mFgsSectionController.hasEntry(ent)) { - // we don't want to update removed notifications because they could - // temporarily become children if they were isolated before. + if (shouldSuppressActiveNotification(ent)) { continue; } @@ -254,9 +247,11 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle } for (ExpandableNotificationRow viewToRemove : viewsToRemove) { - if (mEntryManager.getPendingOrActiveNotif(viewToRemove.getEntry().getKey()) != null) { + NotificationEntry entry = viewToRemove.getEntry(); + if (mEntryManager.getPendingOrActiveNotif(entry.getKey()) != null + && !shouldSuppressActiveNotification(entry)) { // we are only transferring this notification to its parent, don't generate an - // animation + // animation. If the notification is suppressed, this isn't a transfer. mListContainer.setChildTransferInProgress(true); } if (viewToRemove.isSummaryWithChildren()) { @@ -325,6 +320,23 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle endUpdate(); } + /** + * Should a notification entry from the active list be suppressed and not show? + */ + private boolean shouldSuppressActiveNotification(NotificationEntry ent) { + final boolean isBubbleNotificationSuppressedFromShade = mBubblesOptional.isPresent() + && mBubblesOptional.get().isBubbleNotificationSuppressedFromShade( + ent.getKey(), ent.getSbn().getGroupKey()); + if (ent.isRowDismissed() || ent.isRowRemoved() + || isBubbleNotificationSuppressedFromShade + || mFgsSectionController.hasEntry(ent)) { + // we want to suppress removed notifications because they could + // temporarily become children if they were isolated before. + return true; + } + return false; + } + private void addNotificationChildrenAndSort() { // Let's now add all notification children which are missing boolean orderChanged = false; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt index 9765ace7179f..b34bfad499f8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt @@ -179,7 +179,10 @@ constructor( } override fun onTouchEvent(event: MotionEvent): Boolean { - if (!canHandleMotionEvent()) { + val finishExpanding = (event.action == MotionEvent.ACTION_CANCEL || + event.action == MotionEvent.ACTION_UP) && isExpanding + if (!canHandleMotionEvent() && !finishExpanding) { + // We allow cancellations/finishing to still go through here to clean up the state return false } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java index 924eb263de50..b6aed23e64ee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java @@ -132,6 +132,8 @@ public class RemoteInputController { public void removeRemoteInput(NotificationEntry entry, Object token) { Objects.requireNonNull(entry); if (entry.mRemoteEditImeVisible) return; + // If the view is being removed, this may be called even though we're not active + if (!isRemoteInputActive(entry)) return; pruneWeakThenRemoveAndContains(null /* contains */, entry /* remove */, token); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ExpandAnimationParameters.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ExpandAnimationParameters.kt index f1479a149a41..f19cf5d8d9c7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ExpandAnimationParameters.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ExpandAnimationParameters.kt @@ -22,11 +22,27 @@ class ExpandAnimationParameters( ) var startTranslationZ = 0f + + /** + * The top position of the notification at the start of the animation. This is needed in order + * to keep the notification at its place when launching a notification that is clipped rounded. + */ + var startNotificationTop = 0f var startClipTopAmount = 0 var parentStartClipTopAmount = 0 var progress = 0f var linearProgress = 0f + /** + * The rounded top clipping at the beginning. + */ + var startRoundedTopClipping = 0 + + /** + * The rounded top clipping of the parent notification at the start. + */ + var parentStartRoundedTopClipping = 0 + override val topChange: Int get() { // We need this compensation to ensure that the QS moves in sync. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt index c248670c48db..1bbef2562d21 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt @@ -40,6 +40,11 @@ class NotificationLaunchAnimatorController( private val headsUpManager: HeadsUpManagerPhone, private val notification: ExpandableNotificationRow ) : ActivityLaunchAnimator.Controller { + + companion object { + const val ANIMATION_DURATION_TOP_ROUNDING = 100L + } + private val notificationEntry = notification.entry private val notificationKey = notificationEntry.sbn.key @@ -54,18 +59,37 @@ class NotificationLaunchAnimatorController( val height = max(0, notification.actualHeight - notification.clipBottomAmount) val location = notification.locationOnScreen + val clipStartLocation = notificationListContainer.getTopClippingStartLocation() + val roundedTopClipping = Math.max(clipStartLocation - location[1], 0) + val windowTop = location[1] + roundedTopClipping + val topCornerRadius = if (roundedTopClipping > 0) { + // Because the rounded Rect clipping is complex, we start the top rounding at + // 0, which is pretty close to matching the real clipping. + // We'd have to clipOut the overlaid drawable too with the outer rounded rect in case + // if we'd like to have this perfect, but this is close enough. + 0f + } else { + notification.currentBackgroundRadiusTop + } val params = ExpandAnimationParameters( - top = location[1], + top = windowTop, bottom = location[1] + height, left = location[0], right = location[0] + notification.width, - topCornerRadius = notification.currentBackgroundRadiusTop, + topCornerRadius = topCornerRadius, bottomCornerRadius = notification.currentBackgroundRadiusBottom ) params.startTranslationZ = notification.translationZ + params.startNotificationTop = notification.translationY + params.startRoundedTopClipping = roundedTopClipping params.startClipTopAmount = notification.clipTopAmount if (notification.isChildInGroup) { + params.startNotificationTop += notification.notificationParent.translationY + val parentRoundedClip = Math.max(clipStartLocation + - notification.notificationParent.locationOnScreen[1], 0) + params.parentStartRoundedTopClipping = parentRoundedClip + val parentClip = notification.notificationParent.clipTopAmount params.parentStartClipTopAmount = parentClip diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java index 9f82152eb5ed..96b0e7819c7a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java @@ -51,6 +51,7 @@ import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.SnoozeCriterion; import android.service.notification.StatusBarNotification; import android.util.ArraySet; +import android.view.ContentInfo; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -126,8 +127,12 @@ public final class NotificationEntry extends ListEntry { public int targetSdk; private long lastFullScreenIntentLaunchTime = NOT_LAUNCHED_YET; public CharSequence remoteInputText; + // Mimetype and Uri used to display the image in the notification *after* it has been sent. public String remoteInputMimeType; public Uri remoteInputUri; + // ContentInfo used to keep the attachment permission alive until RemoteInput is sent or + // cancelled. + public ContentInfo remoteInputAttachment; private Notification.BubbleMetadata mBubbleMetadata; private ShortcutInfo mShortcutInfo; 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 fe75739d33c4..93166f39ad62 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 @@ -35,6 +35,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; +import android.graphics.Canvas; import android.graphics.Path; import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.AnimationDrawable; @@ -85,6 +86,7 @@ import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.notification.AboveShelfChangedListener; import com.android.systemui.statusbar.notification.ExpandAnimationParameters; +import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager; @@ -252,6 +254,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private OnExpandClickListener mOnExpandClickListener; private View.OnClickListener mOnAppClickListener; private View.OnClickListener mOnFeedbackClickListener; + private Path mExpandingClipPath; // Listener will be called when receiving a long click event. // Use #setLongPressPosition to optionally assign positional data with the long press. @@ -836,6 +839,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView public void setIsChildInGroup(boolean isChildInGroup, ExpandableNotificationRow parent) { if (mExpandAnimationRunning && !isChildInGroup && mNotificationParent != null) { mNotificationParent.setChildIsExpanding(false); + mNotificationParent.setExpandingClipPath(null); mNotificationParent.setExtraWidthForClipping(0.0f); mNotificationParent.setMinimumHeightForClipping(0); } @@ -2032,7 +2036,22 @@ public class ExpandableNotificationRow extends ActivatableNotificationView setTranslationZ(translationZ); float extraWidthForClipping = params.getWidth() - getWidth(); setExtraWidthForClipping(extraWidthForClipping); - int top = params.getTop(); + int top; + if (params.getStartRoundedTopClipping() > 0) { + // If we were clipping initially, let's interpolate from the start position to the + // top. Otherwise, we just take the top directly. + float expandProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation( + params.getProgress(0, + NotificationLaunchAnimatorController.ANIMATION_DURATION_TOP_ROUNDING)); + float startTop = params.getStartNotificationTop(); + top = (int) Math.min(MathUtils.lerp(startTop, + params.getTop(), expandProgress), + startTop); + } else { + top = params.getTop(); + } + int actualHeight = params.getBottom() - top; + setActualHeight(actualHeight); int startClipTopAmount = params.getStartClipTopAmount(); int clipTopAmount = (int) MathUtils.lerp(startClipTopAmount, 0, params.getProgress()); if (mNotificationParent != null) { @@ -2061,13 +2080,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView setClipTopAmount(clipTopAmount); } setTranslationY(top); - setActualHeight(params.getHeight()); mTopRoundnessDuringExpandAnimation = params.getTopCornerRadius() / mOutlineRadius; mBottomRoundnessDuringExpandAnimation = params.getBottomCornerRadius() / mOutlineRadius; invalidateOutline(); - mBackgroundNormal.setExpandAnimationParams(params); + mBackgroundNormal.setExpandAnimationSize(params.getWidth(), actualHeight); } public void setExpandAnimationRunning(boolean expandAnimationRunning) { @@ -2464,7 +2482,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView protected void onLayout(boolean changed, int left, int top, int right, int bottom) { int intrinsicBefore = getIntrinsicHeight(); super.onLayout(changed, left, top, right, bottom); - if (intrinsicBefore != getIntrinsicHeight() && intrinsicBefore != 0) { + if (intrinsicBefore != getIntrinsicHeight() + && (intrinsicBefore != 0 || getActualHeight() > 0)) { notifyHeightChanged(true /* needsAnimation */); } if (mMenuRow != null && mMenuRow.getMenuView() != null) { @@ -3081,6 +3100,26 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return super.childNeedsClipping(child); } + /** + * Set a clip path to be set while expanding the notification. This is needed to nicely + * clip ourselves during the launch if we were clipped rounded in the beginning + */ + public void setExpandingClipPath(Path path) { + mExpandingClipPath = path; + invalidate(); + } + + @Override + protected void dispatchDraw(Canvas canvas) { + canvas.save(); + if (mExpandingClipPath != null && (mExpandAnimationRunning || mChildIsExpanding)) { + // If we're launching a notification, let's clip if a clip rounded to the clipPath + canvas.clipPath(mExpandingClipPath); + } + super.dispatchDraw(canvas); + canvas.restore(); + } + @Override protected void applyRoundness() { super.applyRoundness(); 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 754de580cd61..0f615aa9356f 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 @@ -240,10 +240,10 @@ public class NotificationBackgroundView extends View { invalidate(); } - /** Set the current expand animation parameters. */ - public void setExpandAnimationParams(ExpandAnimationParameters params) { - mActualHeight = params.getHeight(); - mActualWidth = params.getWidth(); + /** Set the current expand animation size. */ + public void setExpandAnimationSize(int actualWidth, int actualHeight) { + mActualHeight = actualHeight; + mActualWidth = actualWidth; invalidate(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java index 26606cda5582..197920f7be19 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java @@ -72,8 +72,6 @@ public class AmbientState { private boolean mUnlockHintRunning; private boolean mQsCustomizerShowing; private int mIntrinsicPadding; - private int mExpandAnimationTopChange; - private ExpandableNotificationRow mExpandingNotification; private float mHideAmount; private boolean mAppearing; private float mPulseHeight = MAX_PULSE_HEIGHT; @@ -518,22 +516,6 @@ public class AmbientState { return isDozing() && !isPulsing(row.getEntry()); } - public void setExpandAnimationTopChange(int expandAnimationTopChange) { - mExpandAnimationTopChange = expandAnimationTopChange; - } - - public void setExpandingNotification(ExpandableNotificationRow row) { - mExpandingNotification = row; - } - - public ExpandableNotificationRow getExpandingNotification() { - return mExpandingNotification; - } - - public int getExpandAnimationTopChange() { - return mExpandAnimationTopChange; - } - /** * @return {@code true } when shade is completely hidden: in AOD, ambient display or when * bypassing. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java index 2a2e733f78a1..7a5c18896e5f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java @@ -200,4 +200,11 @@ public interface NotificationListContainer extends default void setWillExpand(boolean willExpand) {} void setNotificationActivityStarter(NotificationActivityStarter notificationActivityStarter); + + /** + * @return the start location where we start clipping notifications. + */ + default int getTopClippingStartLocation() { + return 0; + } } 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 9ba04bf2f49f..ba2f555f7929 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 @@ -90,6 +90,7 @@ import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.notification.ExpandAnimationParameters; import com.android.systemui.statusbar.notification.FakeShadowView; import com.android.systemui.statusbar.notification.NotificationActivityStarter; +import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.notification.ShadeViewRefactor; import com.android.systemui.statusbar.notification.ShadeViewRefactor.RefactorComponent; @@ -139,6 +140,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable // adb shell setprop persist.debug.nssl true && adb reboot private static final boolean DEBUG = SystemProperties.getBoolean("persist.debug.nssl", false /* default */); + // TODO(b/187291379) disable again before release + private static final boolean DEBUG_REMOVE_ANIMATION = SystemProperties.getBoolean( + "persist.debug.nssl.dismiss", false /* default */); private static final float RUBBER_BAND_FACTOR_NORMAL = 0.35f; private static final float RUBBER_BAND_FACTOR_AFTER_EXPAND = 0.15f; @@ -196,6 +200,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private int mPaddingBetweenElements; private int mMaxTopPadding; private int mTopPadding; + private boolean mAnimateNextTopPaddingChange; private int mBottomMargin; private int mBottomInset = 0; private float mQsExpansionFraction; @@ -471,6 +476,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private final Path mRoundedClipPath = new Path(); /** + * The clip Path used to clip the launching notification. This may be different + * from the normal path, as the views launch animation could start clipped. + */ + private final Path mLaunchedNotificationClipPath = new Path(); + + /** * Should we use rounded rect clipping right now */ private boolean mShouldUseRoundedRectClipping = false; @@ -493,6 +504,26 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private boolean mLaunchingNotification; /** + * Does the launching notification need to be clipped + */ + private boolean mLaunchingNotificationNeedsToBeClipped; + + /** + * The current launch animation params when launching a notification + */ + private ExpandAnimationParameters mLaunchAnimationParams; + + /** + * Corner radii of the launched notification if it's clipped + */ + private float[] mLaunchedNotificationRadii = new float[8]; + + /** + * The notification that is being launched currently. + */ + private ExpandableNotificationRow mExpandingNotificationRow; + + /** * Do notifications dismiss with normal transitioning */ private boolean mDismissUsingRowTranslationX = true; @@ -1181,16 +1212,18 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) private void setTopPadding(int topPadding, boolean animate) { if (mTopPadding != topPadding) { + boolean shouldAnimate = animate || mAnimateNextTopPaddingChange; mTopPadding = topPadding; updateAlgorithmHeightAndPadding(); updateContentHeight(); - if (animate && mAnimationsEnabled && mIsExpanded) { + if (shouldAnimate && mAnimationsEnabled && mIsExpanded) { mTopPaddingNeedsAnimation = true; mNeedsAnimation = true; } updateStackPosition(); requestChildrenUpdate(); - notifyHeightChangeListener(null, animate); + notifyHeightChangeListener(null, shouldAnimate); + mAnimateNextTopPaddingChange = false; } } @@ -2040,6 +2073,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable int scrollRange = Math.max(0, contentHeight - mMaxLayoutHeight); int imeInset = getImeInset(); scrollRange += Math.min(imeInset, Math.max(0, contentHeight - (getHeight() - imeInset))); + if (scrollRange > 0) { + scrollRange = Math.max(getScrollAmountToScrollBoundary(), scrollRange); + } return scrollRange; } @@ -2647,7 +2683,17 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable */ @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) boolean generateRemoveAnimation(ExpandableView child) { + String key = ""; + if (DEBUG_REMOVE_ANIMATION) { + if (child instanceof ExpandableNotificationRow) { + key = ((ExpandableNotificationRow) child).getEntry().getKey(); + } + Log.d(TAG, "generateRemoveAnimation " + key); + } if (removeRemovedChildFromHeadsUpChangeAnimations(child)) { + if (DEBUG_REMOVE_ANIMATION) { + Log.d(TAG, "removedBecauseOfHeadsUp " + key); + } mAddedHeadsUpChildren.remove(child); return false; } @@ -2656,8 +2702,17 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mClearTransientViewsWhenFinished.add(child); return true; } + if (DEBUG_REMOVE_ANIMATION) { + Log.d(TAG, "generateRemove " + key + + "\nmIsExpanded " + mIsExpanded + + "\nmAnimationsEnabled " + mAnimationsEnabled + + "\n!invisible group " + !isChildInInvisibleGroup(child)); + } if (mIsExpanded && mAnimationsEnabled && !isChildInInvisibleGroup(child)) { if (!mChildrenToAddAnimated.contains(child)) { + if (DEBUG_REMOVE_ANIMATION) { + Log.d(TAG, "needsAnimation = true " + key); + } // Generate Animations mChildrenToRemoveAnimated.add(child); mNeedsAnimation = true; @@ -2679,7 +2734,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable /** * Remove a removed child view from the heads up animations if it was just added there * - * @return whether any child was removed from the list to animate + * @return whether any child was removed from the list to animate and the view was just added */ @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) private boolean removeRemovedChildFromHeadsUpChangeAnimations(View child) { @@ -2698,7 +2753,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable ((ExpandableNotificationRow) child).setHeadsUpAnimatingAway(false); } mTmpList.clear(); - return hasAddEvent; + return hasAddEvent && mAddedHeadsUpChildren.contains(child); } // TODO (b/162832756): remove since this won't happen in new pipeline (we prune groups in @@ -2749,6 +2804,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable * @return the amount of scrolling needed to start clipping notifications. */ private int getScrollAmountToScrollBoundary() { + if (mShouldUseSplitNotificationShade) { + return mSidePaddings; + } return mTopPadding - mQsScrollBoundaryPosition; } @@ -2892,7 +2950,16 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) void setExpandingNotification(ExpandableNotificationRow row) { - mAmbientState.setExpandingNotification(row); + if (mExpandingNotificationRow != null && row == null) { + // Let's unset the clip path being set during launch + mExpandingNotificationRow.setExpandingClipPath(null); + ExpandableNotificationRow parent = mExpandingNotificationRow.getNotificationParent(); + if (parent != null) { + parent.setExpandingClipPath(null); + } + } + mExpandingNotificationRow = row; + updateLaunchedNotificationClipPath(); requestChildrenUpdate(); } @@ -2902,10 +2969,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) public void applyExpandAnimationParams(ExpandAnimationParameters params) { - mAmbientState.setExpandAnimationTopChange(params == null ? 0 : params.getTopChange()); - - // Disable clipping for launches + // Modify the clipping for launching notifications + mLaunchAnimationParams = params; setLaunchingNotification(params != null); + updateLaunchedNotificationClipPath(); requestChildrenUpdate(); } @@ -3143,6 +3210,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable ignoreChildren); mAnimationEvents.add(event); mSwipedOutViews.remove(child); + if (DEBUG_REMOVE_ANIMATION) { + String key = ""; + if (child instanceof ExpandableNotificationRow) { + key = ((ExpandableNotificationRow) child).getEntry().getKey(); + } + Log.d(TAG, "created Remove Event - SwipedOut: " + childWasSwipedOut + " " + key); + } } mChildrenToRemoveAnimated.clear(); } @@ -5353,7 +5427,15 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable return; } mLaunchingNotification = launching; - updateUseRoundedRectClipping(); + mLaunchingNotificationNeedsToBeClipped = mLaunchAnimationParams != null + && (mLaunchAnimationParams.getStartRoundedTopClipping() > 0 + || mLaunchAnimationParams.getParentStartRoundedTopClipping() > 0); + if (!mLaunchingNotificationNeedsToBeClipped || !mLaunchingNotification) { + mLaunchedNotificationClipPath.reset(); + } + // When launching notifications, we're clipping the children individually instead of in + // dispatchDraw + invalidate(); } /** @@ -5363,22 +5445,97 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable // We don't want to clip notifications when QS is expanded, because incoming heads up on // the bottom would be clipped otherwise boolean qsAllowsClipping = mQsExpansionFraction < 0.5f || mShouldUseSplitNotificationShade; - boolean clip = !mLaunchingNotification && mIsExpanded && qsAllowsClipping; + boolean clip = mIsExpanded && qsAllowsClipping; if (clip != mShouldUseRoundedRectClipping) { mShouldUseRoundedRectClipping = clip; invalidate(); } } + /** + * Update the clip path for launched notifications in case they were originally clipped + */ + private void updateLaunchedNotificationClipPath() { + if (!mLaunchingNotificationNeedsToBeClipped || !mLaunchingNotification + || mExpandingNotificationRow == null) { + return; + } + int left = Math.min(mLaunchAnimationParams.getLeft(), mRoundedRectClippingLeft); + int right = Math.max(mLaunchAnimationParams.getRight(), mRoundedRectClippingRight); + int bottom = Math.max(mLaunchAnimationParams.getBottom(), mRoundedRectClippingBottom); + float expandProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation( + mLaunchAnimationParams.getProgress(0, + NotificationLaunchAnimatorController.ANIMATION_DURATION_TOP_ROUNDING)); + int top = (int) Math.min(MathUtils.lerp(mRoundedRectClippingTop, + mLaunchAnimationParams.getTop(), expandProgress), + mRoundedRectClippingTop); + float topRadius = mLaunchAnimationParams.getTopCornerRadius(); + float bottomRadius = mLaunchAnimationParams.getBottomCornerRadius(); + mLaunchedNotificationRadii[0] = topRadius; + mLaunchedNotificationRadii[1] = topRadius; + mLaunchedNotificationRadii[2] = topRadius; + mLaunchedNotificationRadii[3] = topRadius; + mLaunchedNotificationRadii[4] = bottomRadius; + mLaunchedNotificationRadii[5] = bottomRadius; + mLaunchedNotificationRadii[6] = bottomRadius; + mLaunchedNotificationRadii[7] = bottomRadius; + mLaunchedNotificationClipPath.reset(); + mLaunchedNotificationClipPath.addRoundRect(left, top, right, bottom, + mLaunchedNotificationRadii, Path.Direction.CW); + // Offset into notification clip coordinates instead of parent ones. + // This is needed since the notification changes in translationZ, where clipping via + // canvas dispatching won't work. + ExpandableNotificationRow expandingRow = mExpandingNotificationRow; + if (expandingRow.getNotificationParent() != null) { + expandingRow = expandingRow.getNotificationParent(); + } + mLaunchedNotificationClipPath.offset( + -expandingRow.getLeft() - expandingRow.getTranslationX(), + -expandingRow.getTop() - expandingRow.getTranslationY()); + expandingRow.setExpandingClipPath(mLaunchedNotificationClipPath); + if (mShouldUseRoundedRectClipping) { + invalidate(); + } + } + @Override protected void dispatchDraw(Canvas canvas) { - if (mShouldUseRoundedRectClipping) { + if (mShouldUseRoundedRectClipping && !mLaunchingNotification) { + // When launching notifications, we're clipping the children individually instead of in + // dispatchDraw // Let's clip rounded. canvas.clipPath(mRoundedClipPath); } super.dispatchDraw(canvas); } + @Override + protected boolean drawChild(Canvas canvas, View child, long drawingTime) { + if (mShouldUseRoundedRectClipping && mLaunchingNotification) { + // Let's clip children individually during notification launch + canvas.save(); + ExpandableView expandableView = (ExpandableView) child; + Path clipPath; + if (expandableView.isExpandAnimationRunning() + || ((ExpandableView) child).hasExpandingChild()) { + // When launching the notification, it is not clipped by this layout, but by the + // view itself. This is because the view is Translating in Z, where this clipPath + // wouldn't apply. + clipPath = null; + } else { + clipPath = mRoundedClipPath; + } + if (clipPath != null) { + canvas.clipPath(clipPath); + } + boolean result = super.drawChild(canvas, child, drawingTime); + canvas.restore(); + return result; + } else { + return super.drawChild(canvas, child, drawingTime); + } + } + /** * Calculate the total translation needed when dismissing. */ @@ -5393,6 +5550,20 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } /** + * @return the start location where we start clipping notifications. + */ + public int getTopClippingStartLocation() { + return mIsExpanded ? mQsScrollBoundaryPosition : 0; + } + + /** + * Request an animation whenever the toppadding changes next + */ + public void animateNextTopPaddingChange() { + mAnimateNextTopPaddingChange = true; + } + + /** * A listener that is notified when the empty space below the notifications is clicked on */ @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) 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 495eda772219..09afedb6de59 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 @@ -1459,6 +1459,13 @@ public class NotificationStackScrollLayoutController { } /** + * Request an animation whenever the toppadding changes next + */ + public void animateNextTopPaddingChange() { + mView.animateNextTopPaddingChange(); + } + + /** * Enum for UiEvent logged from this class */ enum NotificationPanelEvent implements UiEventLogger.UiEventEnum { @@ -1533,6 +1540,11 @@ public class NotificationStackScrollLayoutController { } @Override + public int getTopClippingStartLocation() { + return mView.getTopClippingStartLocation(); + } + + @Override public View getContainerChildAt(int i) { return mView.getContainerChildAt(i); } 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 8f4a71cf2563..9ce9aa80604e 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 @@ -420,8 +420,9 @@ public class StackScrollAlgorithm { // When pulsing (incoming notification on AOD), innerHeight is 0; clamp all // to shelf start, thereby hiding all notifications (except the first one, which we // later unhide in updatePulsingState) - final int shelfStart = ambientState.getInnerHeight() - - ambientState.getShelf().getIntrinsicHeight(); + final int stackBottom = !ambientState.isShadeExpanded() || ambientState.isDozing() + ? ambientState.getInnerHeight() : (int) ambientState.getStackHeight(); + final int shelfStart = stackBottom - ambientState.getShelf().getIntrinsicHeight(); viewState.yTranslation = Math.min(viewState.yTranslation, shelfStart); if (viewState.yTranslation >= shelfStart) { viewState.hidden = !view.isExpandAnimationRunning() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt index 54ef623e95ab..b148eeba2cf5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt @@ -27,6 +27,7 @@ class ConfigurationControllerImpl(context: Context) : ConfigurationController { private val listeners: MutableList<ConfigurationController.ConfigurationListener> = ArrayList() private val lastConfig = Configuration() private var density: Int = 0 + private var smallestScreenWidth: Int = 0 private var fontScale: Float = 0.toFloat() private val inCarMode: Boolean private var uiMode: Int = 0 @@ -38,6 +39,7 @@ class ConfigurationControllerImpl(context: Context) : ConfigurationController { this.context = context fontScale = currentConfig.fontScale density = currentConfig.densityDpi + smallestScreenWidth = currentConfig.smallestScreenWidthDp inCarMode = currentConfig.uiMode and Configuration.UI_MODE_TYPE_MASK == Configuration.UI_MODE_TYPE_CAR uiMode = currentConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK @@ -72,6 +74,14 @@ class ConfigurationControllerImpl(context: Context) : ConfigurationController { this.fontScale = fontScale } + val smallestScreenWidth = newConfig.smallestScreenWidthDp + if (smallestScreenWidth != this.smallestScreenWidth) { + this.smallestScreenWidth = smallestScreenWidth + listeners.filterForEach({ this.listeners.contains(it) }) { + it.onSmallestScreenWidthChanged() + } + } + val localeList = newConfig.locales if (localeList != this.localeList) { this.localeList = localeList diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java index 96276f46d23d..178974327a75 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java @@ -38,7 +38,7 @@ import java.util.LinkedList; * A view to show hints on Keyguard ("Swipe up to unlock", "Tap again to open"). */ public class KeyguardIndicationTextView extends TextView { - private static final long MSG_DURATION_MILLIS = 1500; + private static final long MSG_MIN_DURATION_MILLIS_DEFAULT = 1500; private long mNextAnimationTime = 0; private boolean mAnimationsEnabled = true; private LinkedList<CharSequence> mMessages = new LinkedList<>(); @@ -104,8 +104,13 @@ public class KeyguardIndicationTextView extends TextView { long delay = Math.max(0, mNextAnimationTime - timeInMillis); setNextAnimationTime(timeInMillis + delay + getFadeOutDuration()); + final long minDurationMillis = + (indication != null && indication.getMinVisibilityMillis() != null) + ? indication.getMinVisibilityMillis() + : MSG_MIN_DURATION_MILLIS_DEFAULT; + if (!text.equals("") || hasIcon) { - setNextAnimationTime(mNextAnimationTime + MSG_DURATION_MILLIS); + setNextAnimationTime(mNextAnimationTime + minDurationMillis); animSetBuilder.before(getInAnimator()); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt index bfe0684b5411..ec2d0364a3a6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt @@ -53,7 +53,7 @@ class KeyguardLiftController constructor( // Not listening anymore since trigger events unregister themselves isListening = false updateListeningState() - keyguardUpdateMonitor.requestFaceAuth() + keyguardUpdateMonitor.requestFaceAuth(true) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java index 41af80e02b5a..cfe95e06fb61 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java @@ -71,6 +71,7 @@ public class NotificationIconAreaController implements private final DozeParameters mDozeParameters; private final Optional<Bubbles> mBubblesOptional; private final StatusBarWindowController mStatusBarWindowController; + private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; private int mIconSize; private int mIconHPadding; @@ -119,7 +120,8 @@ public class NotificationIconAreaController implements Optional<Bubbles> bubblesOptional, DemoModeController demoModeController, DarkIconDispatcher darkIconDispatcher, - StatusBarWindowController statusBarWindowController) { + StatusBarWindowController statusBarWindowController, + UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) { mContrastColorUtil = ContrastColorUtil.getInstance(context); mContext = context; mStatusBarStateController = statusBarStateController; @@ -133,6 +135,7 @@ public class NotificationIconAreaController implements mDemoModeController = demoModeController; mDemoModeController.addCallback(this); mStatusBarWindowController = statusBarWindowController; + mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController; notificationListener.addNotificationSettingsListener(mSettingsListener); initializeNotificationAreaViews(context); @@ -677,7 +680,12 @@ public class NotificationIconAreaController implements } boolean visible = mBypassController.getBypassEnabled() || mWakeUpCoordinator.getNotificationsFullyHidden(); - if (mStatusBarStateController.getState() != StatusBarState.KEYGUARD) { + + // Hide the AOD icons if we're not in the KEYGUARD state unless the screen off animation is + // playing, in which case we want them to be visible since we're animating in the AOD UI and + // will be switching to KEYGUARD shortly. + if (mStatusBarStateController.getState() != StatusBarState.KEYGUARD + && !mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying()) { visible = false; } if (visible && mWakeUpCoordinator.isPulseExpanding()) { 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 f461d944d2c2..1a2b9898398b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -36,9 +36,11 @@ import android.animation.ValueAnimator; import android.app.ActivityManager; import android.app.Fragment; import android.app.StatusBarManager; +import android.content.ContentResolver; import android.content.pm.ResolveInfo; import android.content.res.Configuration; import android.content.res.Resources; +import android.database.ContentObserver; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; @@ -50,10 +52,12 @@ import android.graphics.Region; import android.graphics.drawable.Drawable; import android.hardware.biometrics.BiometricSourceType; import android.os.Bundle; +import android.os.Handler; import android.os.PowerManager; import android.os.SystemClock; import android.os.UserManager; import android.os.VibrationEffect; +import android.provider.Settings; import android.util.Log; import android.util.MathUtils; import android.view.LayoutInflater; @@ -210,6 +214,8 @@ public class NotificationPanelViewController extends PanelViewController { new MyOnHeadsUpChangedListener(); private final HeightListener mHeightListener = new HeightListener(); private final ConfigurationListener mConfigurationListener = new ConfigurationListener(); + private final SettingsChangeObserver mSettingsChangeObserver; + @VisibleForTesting final StatusBarStateListener mStatusBarStateListener = new StatusBarStateListener(); private final BiometricUnlockController mBiometricUnlockController; @@ -551,6 +557,11 @@ public class NotificationPanelViewController extends PanelViewController { private long mNotificationBoundsAnimationDelay; /** + * The duration of the notification bounds animation + */ + private long mNotificationBoundsAnimationDuration; + + /** * Is this a collapse that started on the panel where we should allow the panel to intercept */ private boolean mIsPanelCollapseOnQQS; @@ -594,6 +605,8 @@ public class NotificationPanelViewController extends PanelViewController { private int mScreenCornerRadius; private boolean mQSAnimatingHiddenFromCollapsed; + private final ContentResolver mContentResolver; + private final Executor mUiExecutor; private final SecureSettings mSecureSettings; @@ -635,6 +648,7 @@ public class NotificationPanelViewController extends PanelViewController { @Inject public NotificationPanelViewController(NotificationPanelView view, @Main Resources resources, + @Main Handler handler, LayoutInflater layoutInflater, NotificationWakeUpCoordinator coordinator, PulseExpansionHandler pulseExpansionHandler, DynamicPrivacyController dynamicPrivacyController, @@ -678,6 +692,7 @@ public class NotificationPanelViewController extends PanelViewController { TapAgainViewController tapAgainViewController, NavigationModeController navigationModeController, FragmentService fragmentService, + ContentResolver contentResolver, QuickAccessWalletController quickAccessWalletController, @Main Executor uiExecutor, SecureSettings secureSettings, @@ -704,15 +719,12 @@ public class NotificationPanelViewController extends PanelViewController { mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory; mDepthController = notificationShadeDepthController; mFeatureFlags = featureFlags; + mContentResolver = contentResolver; mKeyguardQsUserSwitchComponentFactory = keyguardQsUserSwitchComponentFactory; mKeyguardUserSwitcherComponentFactory = keyguardUserSwitcherComponentFactory; mQSDetailDisplayer = qsDetailDisplayer; mFragmentService = fragmentService; - mKeyguardUserSwitcherEnabled = mResources.getBoolean( - com.android.internal.R.bool.config_keyguardUserSwitcher); - mKeyguardQsUserSwitchEnabled = - mKeyguardUserSwitcherEnabled && mResources.getBoolean( - R.bool.config_keyguard_user_switch_opens_qs_details); + mSettingsChangeObserver = new SettingsChangeObserver(handler); mShouldUseSplitNotificationShade = Utils.shouldUseSplitNotificationShade(mFeatureFlags, mResources); mView.setWillNotDraw(!DEBUG); @@ -795,6 +807,7 @@ public class NotificationPanelViewController extends PanelViewController { } mMaxKeyguardNotifications = resources.getInteger(R.integer.keyguard_max_notification_count); + updateUserSwitcherFlags(); onFinishInflate(); } @@ -1034,6 +1047,10 @@ public class NotificationPanelViewController extends PanelViewController { view = mLayoutInflater.inflate(layoutId, mView, false); mView.addView(view, index); } else { + // Add the stub back so we can re-inflate it again if necessary + ViewStub stub = new ViewStub(mView.getContext(), layoutId); + stub.setId(stubId); + mView.addView(stub, index); view = null; } } else if (enabled) { @@ -1061,6 +1078,7 @@ public class NotificationPanelViewController extends PanelViewController { updateResources(); // Re-inflate the keyguard user switcher group. + updateUserSwitcherFlags(); boolean isUserSwitcherEnabled = mUserManager.isUserSwitcherEnabled(); boolean showQsUserSwitch = mKeyguardQsUserSwitchEnabled && isUserSwitcherEnabled; boolean showKeyguardUserSwitcher = @@ -1443,7 +1461,6 @@ public class NotificationPanelViewController extends PanelViewController { private void setQsExpansionEnabled() { mQsExpansionEnabled = mQsExpansionEnabledPolicy && mQsExpansionEnabledAmbient; - Log.d(TAG, "Set qsExpansionEnabled: " + mQsExpansionEnabled); if (mQs == null) return; mQs.setHeaderClickable(mQsExpansionEnabled); } @@ -2026,7 +2043,7 @@ public class NotificationPanelViewController extends PanelViewController { // When expanding QS, let's authenticate the user if possible, // this will speed up notification actions. if (height == 0) { - mStatusBar.requestFaceAuth(); + mStatusBar.requestFaceAuth(false); } } @@ -2202,7 +2219,8 @@ public class NotificationPanelViewController extends PanelViewController { private void onStackYChanged(boolean shouldAnimate) { if (mQs != null) { if (shouldAnimate) { - mAnimateNextNotificationBounds = true; + animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_STANDARD, + 0 /* delay */); mNotificationBoundsAnimationDelay = 0; } setQSClippingBounds(); @@ -2281,8 +2299,7 @@ public class NotificationPanelViewController extends PanelViewController { final int startBottom = mKeyguardStatusAreaClipBounds.bottom; mQsClippingAnimation = ValueAnimator.ofFloat(0.0f, 1.0f); mQsClippingAnimation.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); - mQsClippingAnimation.setDuration( - StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE); + mQsClippingAnimation.setDuration(mNotificationBoundsAnimationDuration); mQsClippingAnimation.setStartDelay(mNotificationBoundsAnimationDelay); mQsClippingAnimation.addUpdateListener(animation -> { float fraction = animation.getAnimatedFraction(); @@ -2458,8 +2475,10 @@ public class NotificationPanelViewController extends PanelViewController { * shade. 0.0f means we're not transitioning yet. */ public void setTransitionToFullShadeAmount(float pxAmount, boolean animate, long delay) { - mAnimateNextNotificationBounds = animate && !mShouldUseSplitNotificationShade; - mNotificationBoundsAnimationDelay = delay; + if (animate && !mShouldUseSplitNotificationShade) { + animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE, + delay); + } float endPosition = 0; if (pxAmount > 0.0f) { @@ -3164,7 +3183,7 @@ public class NotificationPanelViewController extends PanelViewController { case KEYGUARD: if (!mDozingOnDown) { if (mKeyguardBypassController.getBypassEnabled()) { - mUpdateMonitor.requestFaceAuth(); + mUpdateMonitor.requestFaceAuth(true); } else { mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_HINT, 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */); @@ -3458,7 +3477,6 @@ public class NotificationPanelViewController extends PanelViewController { mQs.setPanelView(mHeightListener); mQs.setExpandClickListener(mOnClickListener); mQs.setHeaderClickable(mQsExpansionEnabled); - mQs.setTranslateWhileExpanding(mShouldUseSplitNotificationShade); updateQSPulseExpansion(); mQs.setOverscrolling(mStackScrollerOverscrolling); mQs.setTranslateWhileExpanding(mShouldUseSplitNotificationShade); @@ -3472,6 +3490,13 @@ public class NotificationPanelViewController extends PanelViewController { mHeightListener.onQsHeightChanged(); } }); + mQs.setCollapsedMediaVisibilityChangedListener((visible) -> { + if (mQs.getHeader().isShown()) { + animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_STANDARD, + 0 /* delay */); + mNotificationStackScrollLayoutController.animateNextTopPaddingChange(); + } + }); mLockscreenShadeTransitionController.setQS(mQs); mNotificationStackScrollLayoutController.setQsContainer((ViewGroup) mQs.getView()); updateQsExpansion(); @@ -3488,6 +3513,12 @@ public class NotificationPanelViewController extends PanelViewController { } }; + private void animateNextNotificationBounds(long duration, long delay) { + mAnimateNextNotificationBounds = true; + mNotificationBoundsAnimationDuration = duration; + mNotificationBoundsAnimationDelay = delay; + } + @Override public void setTouchAndAnimationDisabled(boolean disabled) { super.setTouchAndAnimationDisabled(disabled); @@ -3809,8 +3840,13 @@ public class NotificationPanelViewController extends PanelViewController { expand(true /* animate */); } initDownStates(event); - if (!mIsExpanding && !shouldQuickSettingsIntercept(mDownX, mDownY, 0) - && mPulseExpansionHandler.onTouchEvent(event)) { + + // If pulse is expanding already, let's give it the touch. There are situations + // where the panel starts expanding even though we're also pulsing + boolean pulseShouldGetTouch = (!mIsExpanding + && !shouldQuickSettingsIntercept(mDownX, mDownY, 0)) + || mPulseExpansionHandler.isExpanding(); + if (pulseShouldGetTouch && mPulseExpansionHandler.onTouchEvent(event)) { // We're expanding all the other ones shouldn't get this anymore return true; } @@ -3874,6 +3910,26 @@ public class NotificationPanelViewController extends PanelViewController { return false; } + private void updateUserSwitcherFlags() { + mKeyguardUserSwitcherEnabled = mResources.getBoolean( + com.android.internal.R.bool.config_keyguardUserSwitcher); + mKeyguardQsUserSwitchEnabled = + mKeyguardUserSwitcherEnabled && mResources.getBoolean( + R.bool.config_keyguard_user_switch_opens_qs_details); + } + + private void registerSettingsChangeListener() { + mContentResolver.registerContentObserver( + Settings.Global.getUriFor(Settings.Global.USER_SWITCHER_ENABLED), + /* notifyForDescendants */ false, + mSettingsChangeObserver + ); + } + + private void unregisterSettingsChangeListener() { + mContentResolver.unregisterContentObserver(mSettingsChangeObserver); + } + private class OnHeightChangedListener implements ExpandableView.OnHeightChangedListener { @Override public void onHeightChanged(ExpandableView view, boolean needsAnimation) { @@ -4195,6 +4251,15 @@ public class NotificationPanelViewController extends PanelViewController { } @Override + public void onSmallestScreenWidthChanged() { + if (DEBUG) Log.d(TAG, "onSmallestScreenWidthChanged"); + + // Can affect multi-user switcher visibility as it depends on screen size by default: + // it is enabled only for devices with large screens (see config_keyguardUserSwitcher) + reInflateViews(); + } + + @Override public void onOverlayChanged() { if (DEBUG) Log.d(TAG, "onOverlayChanged"); reInflateViews(); @@ -4207,6 +4272,21 @@ public class NotificationPanelViewController extends PanelViewController { } } + private class SettingsChangeObserver extends ContentObserver { + + SettingsChangeObserver(Handler handler) { + super(handler); + } + + @Override + public void onChange(boolean selfChange) { + if (DEBUG) Log.d(TAG, "onSettingsChanged"); + + // Can affect multi-user switcher visibility + reInflateViews(); + } + } + private class StatusBarStateListener implements StateListener { @Override public void onStateChanged(int statusBarState) { @@ -4322,10 +4402,12 @@ public class NotificationPanelViewController extends PanelViewController { mConfigurationListener.onThemeChanged(); mFalsingManager.addTapListener(mFalsingTapListener); mKeyguardIndicationController.init(); + registerSettingsChangeListener(); } @Override public void onViewDetachedFromWindow(View v) { + unregisterSettingsChangeListener(); mFragmentService.getFragmentHostManager(mView) .removeTagListener(QS.TAG, mFragmentListener); mStatusBarStateController.removeCallback(mStatusBarStateListener); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java index c95879650049..98fb6f32f0bc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java @@ -99,6 +99,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW mCallbacks = Lists.newArrayList(); private final SysuiColorExtractor mColorExtractor; + private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; private float mFaceAuthDisplayBrightness = LayoutParams.BRIGHTNESS_OVERRIDE_NONE; @Inject @@ -110,7 +111,8 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW KeyguardBypassController keyguardBypassController, SysuiColorExtractor colorExtractor, DumpManager dumpManager, - KeyguardStateController keyguardStateController) { + KeyguardStateController keyguardStateController, + UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) { mContext = context; mWindowManager = windowManager; mActivityManager = activityManager; @@ -121,6 +123,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW mKeyguardViewMediator = keyguardViewMediator; mKeyguardBypassController = keyguardBypassController; mColorExtractor = colorExtractor; + mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController; dumpManager.registerDumpable(getClass().getName(), this); mLockScreenDisplayTimeout = context.getResources() @@ -300,7 +303,11 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW private void applyFocusableFlag(State state) { boolean panelFocusable = state.mNotificationShadeFocusable && state.mPanelExpanded; if (state.mBouncerShowing && (state.mKeyguardOccluded || state.mKeyguardNeedsInput) - || ENABLE_REMOTE_INPUT && state.mRemoteInputActive) { + || ENABLE_REMOTE_INPUT && state.mRemoteInputActive + // Make the panel focusable if we're doing the screen off animation, since the light + // reveal scrim is drawing in the panel and should consume touch events so that they + // don't go to the app behind. + || mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying()) { mLpChanged.flags &= ~LayoutParams.FLAG_NOT_FOCUSABLE; mLpChanged.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM; } else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) { 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 1cb0be0efc90..ed8fb31aea32 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java @@ -47,6 +47,8 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout private View mKeyguardStatusBar; private boolean mQsExpanded; private boolean mCustomizerAnimating; + private boolean mCustomizing; + private boolean mDetailShowing; private int mBottomPadding; private int mStackScrollerMargin; @@ -140,7 +142,18 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout } public void setCustomizerShowing(boolean isShowing) { - if (isShowing) { + mCustomizing = isShowing; + updateBottomMargin(); + mStackScroller.setQsCustomizerShowing(isShowing); + } + + public void setDetailShowing(boolean isShowing) { + mDetailShowing = isShowing; + updateBottomMargin(); + } + + private void updateBottomMargin() { + if (mCustomizing || mDetailShowing) { // Clear out bottom paddings/margins so the qs customization can be full height. setPadding(0, 0, 0, 0); setBottomMargin(mStackScroller, 0); @@ -148,7 +161,6 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout setPadding(0, 0, 0, mBottomPadding); setBottomMargin(mStackScroller, mStackScrollerMargin); } - mStackScroller.setQsCustomizerShowing(isShowing); } private void setBottomMargin(View v, int bottomMargin) { 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 3f07785520cf..61a0d637e79d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -1723,9 +1723,9 @@ public class StatusBar extends SystemUI implements DemoMode, /** * Asks {@link KeyguardUpdateMonitor} to run face auth. */ - public void requestFaceAuth() { + public void requestFaceAuth(boolean userInitiatedRequest) { if (!mKeyguardStateController.canDismissLockScreen()) { - mKeyguardUpdateMonitor.requestFaceAuth(); + mKeyguardUpdateMonitor.requestFaceAuth(userInitiatedRequest); } } @@ -2112,8 +2112,8 @@ public class StatusBar extends SystemUI implements DemoMode, } @Override - public void disableKeyguardBlurs() { - mMainThreadHandler.post(mKeyguardViewMediator::disableBlursUntilHidden); + public void setBlursDisabledForAppLaunch(boolean disabled) { + mKeyguardViewMediator.setBlursDisabledForAppLaunch(disabled); } public boolean isDeviceInVrMode() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt index 9a04d39c4e9e..6b00dd4b49e8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt @@ -57,7 +57,7 @@ class UnlockedScreenOffAnimationController @Inject constructor( private val lightRevealAnimator = ValueAnimator.ofFloat(1f, 0f).apply { duration = LIGHT_REVEAL_ANIMATION_DURATION - interpolator = Interpolators.FAST_OUT_SLOW_IN_REVERSE + interpolator = Interpolators.LINEAR addUpdateListener { lightRevealScrim.revealAmount = it.animatedValue as Float } addListener(object : AnimatorListenerAdapter() { override fun onAnimationCancel(animation: Animator?) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt index b295f6659f81..c20730e1b4a4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt @@ -25,6 +25,7 @@ import android.content.Intent import android.util.Log import android.view.View import android.widget.Chronometer +import androidx.annotation.VisibleForTesting import com.android.internal.jank.InteractionJankMonitor import com.android.systemui.R import com.android.systemui.animation.ActivityLaunchAnimator @@ -85,7 +86,7 @@ class OngoingCallController @Inject constructor( val newOngoingCallInfo = CallNotificationInfo( entry.sbn.key, entry.sbn.notification.`when`, - entry.sbn.notification.contentIntent.intent, + entry.sbn.notification.contentIntent?.intent, entry.sbn.uid, entry.sbn.notification.extras.getInt( Notification.EXTRA_CALL_TYPE, -1) == CALL_TYPE_ONGOING @@ -122,6 +123,7 @@ class OngoingCallController @Inject constructor( * Should only be called from [CollapsedStatusBarFragment]. */ fun setChipView(chipView: View) { + tearDownChipView() this.chipView = chipView if (hasOngoingCall()) { updateChip() @@ -165,8 +167,7 @@ class OngoingCallController @Inject constructor( val currentCallNotificationInfo = callNotificationInfo ?: return val currentChipView = chipView - val timeView = - currentChipView?.findViewById<Chronometer>(R.id.ongoing_call_chip_time) + val timeView = currentChipView?.getTimeView() val backgroundView = currentChipView?.findViewById<View>(R.id.ongoing_call_chip_background) @@ -176,14 +177,17 @@ class OngoingCallController @Inject constructor( systemClock.elapsedRealtime() timeView.start() - currentChipView.setOnClickListener { - logger.logChipClicked() - activityStarter.postStartActivityDismissingKeyguard( - currentCallNotificationInfo.intent, 0, - ActivityLaunchAnimator.Controller.fromView( - backgroundView, - InteractionJankMonitor.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP) - ) + currentCallNotificationInfo.intent?.let { intent -> + currentChipView.setOnClickListener { + logger.logChipClicked() + activityStarter.postStartActivityDismissingKeyguard( + intent, + 0, + ActivityLaunchAnimator.Controller.fromView( + backgroundView, + InteractionJankMonitor.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP) + ) + } } setUpUidObserver(currentCallNotificationInfo) @@ -245,16 +249,23 @@ class OngoingCallController @Inject constructor( private fun removeChip() { callNotificationInfo = null + tearDownChipView() mListeners.forEach { l -> l.onOngoingCallStateChanged(animate = true) } if (uidObserver != null) { iActivityManager.unregisterUidObserver(uidObserver) } } + /** Tear down anything related to the chip view to prevent leaks. */ + @VisibleForTesting + fun tearDownChipView() = chipView?.getTimeView()?.stop() + + private fun View.getTimeView(): Chronometer? = this.findViewById(R.id.ongoing_call_chip_time) + private data class CallNotificationInfo( val key: String, val callStartTime: Long, - val intent: Intent, + val intent: Intent?, val uid: Int, /** True if the call is currently ongoing (as opposed to incoming, screening, etc.). */ val isOngoing: Boolean diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java index 399c8500ab48..a0edc7c494bc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java @@ -74,11 +74,13 @@ public class BrightnessMirrorController mBrightnessMirror.setVisibility(View.VISIBLE); mVisibilityCallback.accept(true); mNotificationPanel.setPanelAlpha(0, true /* animate */); + mDepthController.setBrightnessMirrorVisible(true); } public void hideMirror() { mVisibilityCallback.accept(false); mNotificationPanel.setPanelAlpha(255, true /* animate */); + mDepthController.setBrightnessMirrorVisible(false); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java index 0a6cf7be736f..c2bd87c6276f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java @@ -33,6 +33,7 @@ public interface ConfigurationController extends CallbackController<Configuratio interface ConfigurationListener { default void onConfigChanged(Configuration newConfig) {} default void onDensityOrFontScaleChanged() {} + default void onSmallestScreenWidthChanged() {} default void onOverlayChanged() {} default void onUiModeChanged() {} default void onThemeChanged() {} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java index e6c4e82cec7b..b18dfd2866c4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -20,7 +20,6 @@ import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import android.annotation.Nullable; import android.app.ActivityManager; import android.app.Notification; import android.app.PendingIntent; @@ -38,7 +37,6 @@ import android.graphics.Rect; import android.graphics.drawable.GradientDrawable; import android.net.Uri; import android.os.Bundle; -import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.text.Editable; @@ -72,13 +70,13 @@ import android.widget.ProgressBar; import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.android.internal.graphics.ColorUtils; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.nano.MetricsProto; -import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.ContrastColorUtil; import com.android.systemui.Dependency; import com.android.systemui.R; @@ -111,8 +109,8 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene private final SendButtonTextWatcher mTextWatcher; private final TextView.OnEditorActionListener mEditorActionHandler; - private final NotificationRemoteInputManager mRemoteInputManager; private final UiEventLogger mUiEventLogger; + private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler; private final List<OnFocusChangeListener> mEditTextFocusChangeListeners = new ArrayList<>(); private final List<OnSendRemoteInputListener> mOnSendListeners = new ArrayList<>(); private RemoteEditText mEditText; @@ -123,9 +121,6 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene private RemoteInput[] mRemoteInputs; private RemoteInput mRemoteInput; private RemoteInputController mController; - private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler; - - private IStatusBarService mStatusBarManagerService; private NotificationEntry mEntry; @@ -134,7 +129,6 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene private int mRevealCx; private int mRevealCy; private int mRevealR; - private ContentInfo mAttachment; private boolean mColorized; private int mTint; @@ -143,7 +137,6 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene private NotificationViewWrapper mWrapper; private Consumer<Boolean> mOnVisibilityChangedListener; private NotificationRemoteInputManager.BouncerChecker mBouncerChecker; - private LinearLayout mContentView; private ImageView mDelete; private ImageView mDeleteBg; @@ -174,10 +167,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mTextWatcher = new SendButtonTextWatcher(); mEditorActionHandler = new EditorActionHandler(); mRemoteInputQuickSettingsDisabler = Dependency.get(RemoteInputQuickSettingsDisabler.class); - mRemoteInputManager = Dependency.get(NotificationRemoteInputManager.class); mUiEventLogger = Dependency.get(UiEventLogger.class); - mStatusBarManagerService = IStatusBarService.Stub.asInterface( - ServiceManager.getService(Context.STATUS_BAR_SERVICE)); TypedArray ta = getContext().getTheme().obtainStyledAttributes(new int[]{ com.android.internal.R.attr.colorAccent, com.android.internal.R.attr.colorSurface, @@ -266,8 +256,8 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mDeleteBg.setImageTintBlendMode(BlendMode.SRC_IN); mDelete.setImageTintBlendMode(BlendMode.SRC_IN); mDelete.setOnClickListener(v -> setAttachment(null)); - mContentView = findViewById(R.id.remote_input_content); - mContentView.setBackground(mContentBackground); + LinearLayout contentView = findViewById(R.id.remote_input_content); + contentView.setBackground(mContentBackground); mEditText = findViewById(R.id.remote_input_text); mEditText.setInnerFocusable(false); mEditText.setWindowInsetsAnimationCallback( @@ -293,15 +283,19 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene } private void setAttachment(ContentInfo item) { - if (mAttachment != null) { + if (mEntry.remoteInputAttachment != null && mEntry.remoteInputAttachment != item) { // We need to release permissions when sending the attachment to the target // app or if it is deleted by the user. When sending to the target app, we // can safely release permissions as soon as the call to // `mController.grantInlineReplyUriPermission` is made (ie, after the grant // to the target app has been created). - mAttachment.releasePermissions(); + mEntry.remoteInputAttachment.releasePermissions(); + } + mEntry.remoteInputAttachment = item; + if (item != null) { + mEntry.remoteInputUri = item.getClip().getItemAt(0).getUri(); + mEntry.remoteInputMimeType = item.getClip().getDescription().getMimeType(0); } - mAttachment = item; View attachment = findViewById(R.id.remote_input_content_container); ImageView iconView = findViewById(R.id.remote_input_attachment_image); iconView.setImageDrawable(null); @@ -323,10 +317,9 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene * @return returns intent with granted URI permissions that should be used immediately */ private Intent prepareRemoteInput() { - if (mAttachment == null) return prepareRemoteInputFromText(); - return prepareRemoteInputFromData( - mAttachment.getClip().getDescription().getMimeType(0), - mAttachment.getClip().getItemAt(0).getUri()); + return mEntry.remoteInputAttachment == null + ? prepareRemoteInputFromText() + : prepareRemoteInputFromData(mEntry.remoteInputMimeType, mEntry.remoteInputUri); } private Intent prepareRemoteInputFromText() { @@ -337,7 +330,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene results); mEntry.remoteInputText = mEditText.getText().toString(); - // TODO(b/188646667): store attachment to entry + setAttachment(null); mEntry.remoteInputUri = null; mEntry.remoteInputMimeType = null; @@ -363,7 +356,8 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene RemoteInput.addResultsToIntent(mRemoteInputs, fillInIntent, bundle); - CharSequence attachmentText = mAttachment.getClip().getDescription().getLabel(); + CharSequence attachmentText = + mEntry.remoteInputAttachment.getClip().getDescription().getLabel(); CharSequence attachmentLabel = TextUtils.isEmpty(attachmentText) ? mContext.getString(R.string.remote_input_image_insertion_text) @@ -374,14 +368,11 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene : "\"" + attachmentLabel + "\" " + mEditText.getText(); mEntry.remoteInputText = fullText; - // TODO(b/188646667): store attachment to entry - mEntry.remoteInputMimeType = contentType; - mEntry.remoteInputUri = data; // mirror prepareRemoteInputFromText for text input if (mEntry.editedSuggestionInfo == null) { RemoteInput.setResultsSource(fillInIntent, RemoteInput.SOURCE_FREE_FORM_INPUT); - } else if (mAttachment == null) { + } else if (mEntry.remoteInputAttachment == null) { RemoteInput.setResultsSource(fillInIntent, RemoteInput.SOURCE_CHOICE); } @@ -437,6 +428,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mEntry.getSbn().getUid(), mEntry.getSbn().getPackageName(), mEntry.getSbn().getInstanceId()); } + setAttachment(null); } @@ -477,7 +469,6 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene private void onDefocus(boolean animate, boolean logClose) { mController.removeRemoteInput(mEntry, mToken); mEntry.remoteInputText = mEditText.getText(); - // TODO(b/188646667): store attachment to entry // During removal, we get reattached and lose focus. Not hiding in that // case to prevent flicker. @@ -565,7 +556,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mEntry.editedSuggestionInfo = editedSuggestionInfo; if (editedSuggestionInfo != null) { mEntry.remoteInputText = editedSuggestionInfo.originalText; - // TODO(b/188646667): store attachment to entry + mEntry.remoteInputAttachment = null; } } @@ -608,7 +599,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mEditText.setSelection(mEditText.length()); mEditText.requestFocus(); mController.addRemoteInput(mEntry, mToken); - // TODO(b/188646667): restore attachment from entry + setAttachment(mEntry.remoteInputAttachment); mRemoteInputQuickSettingsDisabler.setRemoteInputActive(true); @@ -631,7 +622,6 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene private void reset() { mResetting = true; mEntry.remoteInputTextWhenReset = SpannedString.valueOf(mEditText.getText()); - // TODO(b/188646667): store attachment at time of reset to entry mEditText.getText().clear(); mEditText.setEnabled(true); @@ -640,7 +630,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mController.removeSpinning(mEntry.getKey(), mToken); updateSendButton(); onDefocus(false /* animate */, false /* logClose */); - // TODO(b/188646667): clear attachment + setAttachment(null); mResetting = false; } @@ -657,7 +647,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene } private void updateSendButton() { - mSendButton.setEnabled(mEditText.length() != 0 || mAttachment != null); + mSendButton.setEnabled(mEditText.length() != 0 || mEntry.remoteInputAttachment != null); } public void close() { @@ -857,7 +847,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene && event.getAction() == KeyEvent.ACTION_DOWN; if (isSoftImeEvent || isKeyboardEnterKey) { - if (mEditText.length() > 0 || mAttachment != null) { + if (mEditText.length() > 0 || mEntry.remoteInputAttachment != null) { sendRemoteInput(prepareRemoteInput()); } // Consume action to prevent IME from closing. @@ -928,7 +918,6 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene // our focus, so we'll need to save our text here. if (mRemoteInputView != null) { mRemoteInputView.mEntry.remoteInputText = getText(); - // TODO(b/188646667): store attachment to entry } } return; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java index e76b8035cd59..2a93844acd5b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java @@ -28,6 +28,8 @@ public interface SecurityController extends CallbackController<SecurityControlle boolean isDeviceManaged(); boolean hasProfileOwner(); boolean hasWorkProfile(); + /** Whether the work profile is turned on. */ + boolean isWorkProfileOn(); /** Whether this device is organization-owned with a work profile **/ boolean isProfileOwnerOfOrganizationOwnedDevice(); String getDeviceOwnerName(); @@ -57,7 +59,6 @@ public interface SecurityController extends CallbackController<SecurityControlle /** Label for admin */ CharSequence getLabel(DeviceAdminInfo info); - public interface SecurityControllerCallback { void onStateChanged(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java index 4afb86b1a810..3e661df802a6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java @@ -211,6 +211,12 @@ public class SecurityControllerImpl extends CurrentUserTracker implements Securi } @Override + public boolean isWorkProfileOn() { + final UserHandle userHandle = UserHandle.of(getWorkProfileUserId(mCurrentUserId)); + return userHandle != null && !mUserManager.isQuietModeEnabled(userHandle); + } + + @Override public boolean isProfileOwnerOfOrganizationOwnedDevice() { return mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java index 1ebb9ddc0262..14190d86cea5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -1012,15 +1012,16 @@ public class UserSwitcherController implements Dumpable { public ExitGuestDialog(Context context, int guestId, int targetId) { super(context); - setTitle(mGuestUserAutoCreated ? R.string.guest_reset_guest_dialog_title + setTitle(mGuestUserAutoCreated + ? com.android.settingslib.R.string.guest_reset_guest_dialog_title : R.string.guest_exit_guest_dialog_title); setMessage(context.getString(R.string.guest_exit_guest_dialog_message)); setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(android.R.string.cancel), this); setButton(DialogInterface.BUTTON_POSITIVE, - context.getString( - mGuestUserAutoCreated ? R.string.guest_reset_guest_dialog_remove - : R.string.guest_exit_guest_dialog_remove), this); + context.getString(mGuestUserAutoCreated + ? com.android.settingslib.R.string.guest_reset_guest_confirm_button + : R.string.guest_exit_guest_dialog_remove), this); SystemUIDialog.setWindowOnTop(this); setCanceledOnTouchOutside(false); mGuestId = guestId; diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java index ca1f55e95ff4..11ddbd045cd4 100644 --- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java @@ -241,7 +241,7 @@ public class ThemeOverlayController extends SystemUI implements Dumpable { @Override public void onReceive(Context context, Intent intent) { boolean newWorkProfile = Intent.ACTION_MANAGED_PROFILE_ADDED.equals(intent.getAction()); - boolean userStarted = Intent.ACTION_USER_STARTED.equals(intent.getAction()); + boolean userStarted = Intent.ACTION_USER_SWITCHED.equals(intent.getAction()); boolean isManagedProfile = mUserManager.isManagedProfile( intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); if (userStarted || newWorkProfile) { @@ -288,7 +288,7 @@ public class ThemeOverlayController extends SystemUI implements Dumpable { public void start() { if (DEBUG) Log.d(TAG, "Start"); final IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_USER_STARTED); + filter.addAction(Intent.ACTION_USER_SWITCHED); filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); filter.addAction(Intent.ACTION_WALLPAPER_CHANGED); mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, mMainExecutor, diff --git a/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java index c5e35a497956..8b394bfe35b7 100644 --- a/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java +++ b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java @@ -16,13 +16,18 @@ package com.android.systemui.toast; +import static android.content.pm.ApplicationInfo.FLAG_SYSTEM; +import static android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; + import android.animation.Animator; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UserIdInt; import android.app.Application; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; @@ -53,7 +58,7 @@ public class SystemUIToast implements ToastPlugin.Toast { final ToastPlugin.Toast mPluginToast; private final String mPackageName; - private final int mUserId; + @UserIdInt private final int mUserId; private final LayoutInflater mLayoutInflater; final int mDefaultX = 0; @@ -74,7 +79,7 @@ public class SystemUIToast implements ToastPlugin.Toast { } SystemUIToast(LayoutInflater layoutInflater, Context context, CharSequence text, - ToastPlugin.Toast pluginToast, String packageName, int userId, + ToastPlugin.Toast pluginToast, String packageName, @UserIdInt int userId, int orientation) { mLayoutInflater = layoutInflater; mContext = context; @@ -248,6 +253,15 @@ public class SystemUIToast implements ToastPlugin.Toast { return null; } + final Context userContext; + try { + userContext = context.createPackageContextAsUser("android", + 0, new UserHandle(userId)); + } catch (NameNotFoundException e) { + Log.e(TAG, "Could not create user package context"); + return null; + } + final ApplicationsState appState = ApplicationsState.getInstance((Application) context.getApplicationContext()); if (!appState.isUserAdded(userId)) { @@ -255,9 +269,11 @@ public class SystemUIToast implements ToastPlugin.Toast { + "packageName=" + packageName); return null; } + + final PackageManager packageManager = userContext.getPackageManager(); final AppEntry appEntry = appState.getEntry(packageName, userId); if (appEntry == null || appEntry.info == null - || !ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER.filterApp(appEntry)) { + || !showApplicationIcon(appEntry.info, packageManager)) { return null; } @@ -265,7 +281,20 @@ public class SystemUIToast implements ToastPlugin.Toast { UserHandle user = UserHandle.getUserHandleForUid(appInfo.uid); IconFactory iconFactory = IconFactory.obtain(context); Bitmap iconBmp = iconFactory.createBadgedIconBitmap( - appInfo.loadUnbadgedIcon(context.getPackageManager()), user, true).icon; + appInfo.loadUnbadgedIcon(packageManager), user, true).icon; return new BitmapDrawable(context.getResources(), iconBmp); } + + private static boolean showApplicationIcon(ApplicationInfo appInfo, + PackageManager packageManager) { + if (hasFlag(appInfo.flags, FLAG_UPDATED_SYSTEM_APP)) { + return packageManager.getLaunchIntentForPackage(appInfo.packageName) + != null; + } + return !hasFlag(appInfo.flags, FLAG_SYSTEM); + } + + private static boolean hasFlag(int flags, int flag) { + return (flags & flag) != 0; + } } diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvBottomSheetActivity.java b/packages/SystemUI/src/com/android/systemui/tv/TvBottomSheetActivity.java new file mode 100644 index 000000000000..2b7a33260248 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/tv/TvBottomSheetActivity.java @@ -0,0 +1,98 @@ +/* + * 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.tv; + +import android.app.Activity; +import android.graphics.PixelFormat; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.Gravity; +import android.view.WindowManager; + +import com.android.systemui.R; + +import java.util.function.Consumer; + +/** + * Generic bottom sheet with up to two icons in the beginning and two buttons. + */ +public abstract class TvBottomSheetActivity extends Activity { + + private static final String TAG = TvBottomSheetActivity.class.getSimpleName(); + private Drawable mBackgroundWithBlur; + private Drawable mBackgroundWithoutBlur; + + private final Consumer<Boolean> mBlurConsumer = this::onBlurChanged; + + private void onBlurChanged(boolean enabled) { + Log.v(TAG, "blur enabled: " + enabled); + getWindow().setBackgroundDrawable(enabled ? mBackgroundWithBlur : mBackgroundWithoutBlur); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.tv_bottom_sheet); + + overridePendingTransition(R.anim.tv_bottom_sheet_enter, 0); + + mBackgroundWithBlur = getResources() + .getDrawable(R.drawable.bottom_sheet_background_with_blur); + mBackgroundWithoutBlur = getResources().getDrawable(R.drawable.bottom_sheet_background); + + DisplayMetrics metrics = getResources().getDisplayMetrics(); + int screenWidth = metrics.widthPixels; + int screenHeight = metrics.heightPixels; + int marginPx = getResources().getDimensionPixelSize(R.dimen.bottom_sheet_margin); + + WindowManager.LayoutParams windowParams = getWindow().getAttributes(); + windowParams.width = screenWidth - marginPx * 2; + windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT; + windowParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; + windowParams.horizontalMargin = 0f; + windowParams.verticalMargin = (float) marginPx / screenHeight; + windowParams.format = PixelFormat.TRANSPARENT; + windowParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG; + windowParams.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; + windowParams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; + getWindow().setAttributes(windowParams); + getWindow().setElevation(getWindow().getElevation() + 5); + getWindow().setBackgroundBlurRadius(getResources().getDimensionPixelSize( + R.dimen.bottom_sheet_background_blur_radius)); + } + + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + getWindowManager().addCrossWindowBlurEnabledListener(mBlurConsumer); + } + + @Override + public void onDetachedFromWindow() { + getWindowManager().removeCrossWindowBlurEnabledListener(mBlurConsumer); + super.onDetachedFromWindow(); + } + + @Override + public void finish() { + super.finish(); + overridePendingTransition(0, R.anim.tv_bottom_sheet_exit); + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt b/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt index dc86d5893adb..3b64f9f953c3 100644 --- a/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt +++ b/packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt @@ -16,6 +16,7 @@ package com.android.systemui.util +import android.content.pm.ActivityInfo import android.content.res.Resources import android.graphics.Rect import android.graphics.drawable.Drawable @@ -64,6 +65,10 @@ class RoundedCornerProgressDrawable @JvmOverloads constructor( return RoundedCornerState(super.getConstantState()!!) } + override fun getChangingConfigurations(): Int { + return super.getChangingConfigurations() or ActivityInfo.CONFIG_DENSITY + } + private class RoundedCornerState(private val wrappedState: ConstantState) : ConstantState() { override fun newDrawable(): Drawable { return newDrawable(null, null) diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java b/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java index 7f3756244629..11e7df8bd85f 100644 --- a/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java +++ b/packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java @@ -36,12 +36,13 @@ public class SensorModule { try { return thresholdSensorBuilder .setSensorDelay(SensorManager.SENSOR_DELAY_NORMAL) - .setSensorResourceId(R.string.proximity_sensor_type) + .setSensorResourceId(R.string.proximity_sensor_type, true) .setThresholdResourceId(R.dimen.proximity_sensor_threshold) .setThresholdLatchResourceId(R.dimen.proximity_sensor_threshold_latch) .build(); } catch (IllegalStateException e) { - Sensor defaultSensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); + Sensor defaultSensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY, + true); return thresholdSensorBuilder .setSensor(defaultSensor) .setThresholdValue(defaultSensor != null ? defaultSensor.getMaximumRange() : 0) @@ -55,7 +56,7 @@ public class SensorModule { ThresholdSensorImpl.Builder thresholdSensorBuilder) { try { return thresholdSensorBuilder - .setSensorResourceId(R.string.proximity_sensor_secondary_type) + .setSensorResourceId(R.string.proximity_sensor_secondary_type, true) .setThresholdResourceId(R.dimen.proximity_sensor_secondary_threshold) .setThresholdLatchResourceId(R.dimen.proximity_sensor_secondary_threshold_latch) .build(); diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorImpl.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorImpl.java index 31c307297066..d10cf9b180c3 100644 --- a/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorImpl.java +++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorImpl.java @@ -230,14 +230,16 @@ class ThresholdSensorImpl implements ThresholdSensor { mExecution = execution; } - Builder setSensorDelay(int sensorDelay) { mSensorDelay = sensorDelay; return this; } - - Builder setSensorResourceId(int sensorResourceId) { - setSensorType(mResources.getString(sensorResourceId)); + /** + * If requiresWakeUp is false, the first sensor with sensorType (regardless of whether the + * sensor is a wakeup sensor or not) will be set. + */ + Builder setSensorResourceId(int sensorResourceId, boolean requireWakeUp) { + setSensorType(mResources.getString(sensorResourceId), requireWakeUp); return this; } @@ -259,8 +261,12 @@ class ThresholdSensorImpl implements ThresholdSensor { return this; } - Builder setSensorType(String sensorType) { - Sensor sensor = findSensorByType(sensorType); + /** + * If requiresWakeUp is false, the first sensor with sensorType (regardless of whether the + * sensor is a wakeup sensor or not) will be set. + */ + Builder setSensorType(String sensorType, boolean requireWakeUp) { + Sensor sensor = findSensorByType(sensorType, requireWakeUp); if (sensor != null) { setSensor(sensor); } @@ -310,7 +316,8 @@ class ThresholdSensorImpl implements ThresholdSensor { mThresholdValue, mThresholdLatchValue, mSensorDelay); } - private Sensor findSensorByType(String sensorType) { + @VisibleForTesting + Sensor findSensorByType(String sensorType, boolean requireWakeUp) { if (sensorType.isEmpty()) { return null; } @@ -320,7 +327,9 @@ class ThresholdSensorImpl implements ThresholdSensor { for (Sensor s : sensorList) { if (sensorType.equals(s.getStringType())) { sensor = s; - break; + if (!requireWakeUp || sensor.isWakeUpSensor()) { + break; + } } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java index ab4b1f10132c..e57059894786 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java @@ -128,7 +128,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa private final MediaSessions mMediaSessions; protected C mCallbacks = new C(); private final State mState = new State(); - protected final MediaSessionsCallbacks mMediaSessionsCallbacksW = new MediaSessionsCallbacks(); + protected final MediaSessionsCallbacks mMediaSessionsCallbacksW; private final Optional<Vibrator> mVibrator; private final boolean mHasVibrator; private boolean mShowA11yStream; @@ -179,6 +179,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa mWorkerLooper = theadFactory.buildLooperOnNewThread( VolumeDialogControllerImpl.class.getSimpleName()); mWorker = new W(mWorkerLooper); + mMediaSessionsCallbacksW = new MediaSessionsCallbacks(mContext); mMediaSessions = createMediaSessions(mContext, mWorkerLooper, mMediaSessionsCallbacksW); mAudio = audioManager; mNoMan = notificationManager; @@ -1148,83 +1149,98 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa private final HashMap<Token, Integer> mRemoteStreams = new HashMap<>(); private int mNextStream = DYNAMIC_STREAM_START_INDEX; + private final boolean mShowRemoteSessions; + + public MediaSessionsCallbacks(Context context) { + mShowRemoteSessions = context.getResources().getBoolean( + com.android.internal.R.bool.config_volumeShowRemoteSessions); + } @Override public void onRemoteUpdate(Token token, String name, PlaybackInfo pi) { - addStream(token, "onRemoteUpdate"); + if (mShowRemoteSessions) { + addStream(token, "onRemoteUpdate"); - int stream = 0; - synchronized (mRemoteStreams) { - stream = mRemoteStreams.get(token); - } - Slog.d(TAG, "onRemoteUpdate: stream: " + stream + " volume: " + pi.getCurrentVolume()); - boolean changed = mState.states.indexOfKey(stream) < 0; - final StreamState ss = streamStateW(stream); - ss.dynamic = true; - ss.levelMin = 0; - ss.levelMax = pi.getMaxVolume(); - if (ss.level != pi.getCurrentVolume()) { - ss.level = pi.getCurrentVolume(); - changed = true; - } - if (!Objects.equals(ss.remoteLabel, name)) { - ss.name = -1; - ss.remoteLabel = name; - changed = true; - } - if (changed) { - Log.d(TAG, "onRemoteUpdate: " + name + ": " + ss.level + " of " + ss.levelMax); - mCallbacks.onStateChanged(mState); + int stream = 0; + synchronized (mRemoteStreams) { + stream = mRemoteStreams.get(token); + } + Slog.d(TAG, + "onRemoteUpdate: stream: " + stream + " volume: " + pi.getCurrentVolume()); + boolean changed = mState.states.indexOfKey(stream) < 0; + final StreamState ss = streamStateW(stream); + ss.dynamic = true; + ss.levelMin = 0; + ss.levelMax = pi.getMaxVolume(); + if (ss.level != pi.getCurrentVolume()) { + ss.level = pi.getCurrentVolume(); + changed = true; + } + if (!Objects.equals(ss.remoteLabel, name)) { + ss.name = -1; + ss.remoteLabel = name; + changed = true; + } + if (changed) { + Log.d(TAG, "onRemoteUpdate: " + name + ": " + ss.level + " of " + ss.levelMax); + mCallbacks.onStateChanged(mState); + } } } @Override public void onRemoteVolumeChanged(Token token, int flags) { - addStream(token, "onRemoteVolumeChanged"); - int stream = 0; - synchronized (mRemoteStreams) { - stream = mRemoteStreams.get(token); - } - final boolean showUI = shouldShowUI(flags); - Slog.d(TAG, "onRemoteVolumeChanged: stream: " + stream + " showui? " + showUI); - boolean changed = updateActiveStreamW(stream); - if (showUI) { - changed |= checkRoutedToBluetoothW(AudioManager.STREAM_MUSIC); - } - if (changed) { - Slog.d(TAG, "onRemoteChanged: updatingState"); - mCallbacks.onStateChanged(mState); - } - if (showUI) { - mCallbacks.onShowRequested(Events.SHOW_REASON_REMOTE_VOLUME_CHANGED); + if (mShowRemoteSessions) { + addStream(token, "onRemoteVolumeChanged"); + int stream = 0; + synchronized (mRemoteStreams) { + stream = mRemoteStreams.get(token); + } + final boolean showUI = shouldShowUI(flags); + Slog.d(TAG, "onRemoteVolumeChanged: stream: " + stream + " showui? " + showUI); + boolean changed = updateActiveStreamW(stream); + if (showUI) { + changed |= checkRoutedToBluetoothW(AudioManager.STREAM_MUSIC); + } + if (changed) { + Slog.d(TAG, "onRemoteChanged: updatingState"); + mCallbacks.onStateChanged(mState); + } + if (showUI) { + mCallbacks.onShowRequested(Events.SHOW_REASON_REMOTE_VOLUME_CHANGED); + } } } @Override public void onRemoteRemoved(Token token) { - int stream = 0; - synchronized (mRemoteStreams) { - if (!mRemoteStreams.containsKey(token)) { - Log.d(TAG, "onRemoteRemoved: stream doesn't exist, " - + "aborting remote removed for token:" + token.toString()); - return; + if (mShowRemoteSessions) { + int stream = 0; + synchronized (mRemoteStreams) { + if (!mRemoteStreams.containsKey(token)) { + Log.d(TAG, "onRemoteRemoved: stream doesn't exist, " + + "aborting remote removed for token:" + token.toString()); + return; + } + stream = mRemoteStreams.get(token); } - stream = mRemoteStreams.get(token); - } - mState.states.remove(stream); - if (mState.activeStream == stream) { - updateActiveStreamW(-1); + mState.states.remove(stream); + if (mState.activeStream == stream) { + updateActiveStreamW(-1); + } + mCallbacks.onStateChanged(mState); } - mCallbacks.onStateChanged(mState); } public void setStreamVolume(int stream, int level) { - final Token t = findToken(stream); - if (t == null) { - Log.w(TAG, "setStreamVolume: No token found for stream: " + stream); - return; + if (mShowRemoteSessions) { + final Token t = findToken(stream); + if (t == null) { + Log.w(TAG, "setStreamVolume: No token found for stream: " + stream); + return; + } + mMediaSessions.setVolume(t, level); } - mMediaSessions.setVolume(t, level); } private Token findToken(int stream) { diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index 407b248cee44..5de7846a820e 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -1127,7 +1127,12 @@ public class VolumeDialogImpl implements VolumeDialog, .alpha(0.f) .setStartDelay(0) .setDuration(mDialogHideAnimationDurationMs) - .withEndAction(() -> mODICaptionsTooltipView.setVisibility(INVISIBLE)) + .withEndAction(() -> { + // It might have been nulled out by tryToRemoveCaptionsTooltip. + if (mODICaptionsTooltipView != null) { + mODICaptionsTooltipView.setVisibility(INVISIBLE); + } + }) .start(); } } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 3d4da270dd44..fc0214a565f2 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -64,6 +64,7 @@ import android.os.Handler; import android.os.IRemoteCallback; import android.os.UserHandle; import android.os.UserManager; +import android.os.Vibrator; import android.telephony.ServiceState; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; @@ -108,6 +109,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; + @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @@ -168,6 +170,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { private TelephonyListenerManager mTelephonyListenerManager; @Mock private FeatureFlags mFeatureFlags; + @Mock + private Vibrator mVibrator; @Captor private ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor; // Direct executor @@ -569,7 +573,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { // Stop scanning when bouncer becomes visible setKeyguardBouncerVisibility(true); clearInvocations(mFaceManager); - mKeyguardUpdateMonitor.requestFaceAuth(); + mKeyguardUpdateMonitor.requestFaceAuth(true); verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt()); } @@ -638,6 +642,45 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { } @Test + public void testFaceAndFingerprintLockout_onlyFace() { + mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mTestableLooper.processAllMessages(); + mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true); + + mKeyguardUpdateMonitor.mFaceAuthenticationCallback + .onAuthenticationError(FaceManager.FACE_ERROR_LOCKOUT_PERMANENT, ""); + + verify(mLockPatternUtils, never()).requireStrongAuth(anyInt(), anyInt()); + } + + @Test + public void testFaceAndFingerprintLockout_onlyFingerprint() { + mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mTestableLooper.processAllMessages(); + mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true); + + mKeyguardUpdateMonitor.mFingerprintAuthenticationCallback + .onAuthenticationError(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT, ""); + + verify(mLockPatternUtils, never()).requireStrongAuth(anyInt(), anyInt()); + } + + + @Test + public void testFaceAndFingerprintLockout() { + mKeyguardUpdateMonitor.dispatchStartedWakingUp(); + mTestableLooper.processAllMessages(); + mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true); + + mKeyguardUpdateMonitor.mFaceAuthenticationCallback + .onAuthenticationError(FaceManager.FACE_ERROR_LOCKOUT_PERMANENT, ""); + mKeyguardUpdateMonitor.mFingerprintAuthenticationCallback + .onAuthenticationError(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT, ""); + + verify(mLockPatternUtils).requireStrongAuth(anyInt(), anyInt()); + } + + @Test public void testGetUserCanSkipBouncer_whenFace() { int user = KeyguardUpdateMonitor.getCurrentUser(); mKeyguardUpdateMonitor.onFaceAuthenticated(user, true /* isStrongBiometric */); @@ -979,7 +1022,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { mBroadcastDispatcher, mDumpManager, mRingerModeTracker, mBackgroundExecutor, mStatusBarStateController, mLockPatternUtils, - mAuthController, mTelephonyListenerManager, mFeatureFlags); + mAuthController, mTelephonyListenerManager, mFeatureFlags, + mVibrator); setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java index 5b50e897e254..62370313e5ae 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java @@ -25,6 +25,8 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import android.content.Context; +import android.content.ContextWrapper; import android.os.UserHandle; import android.provider.Settings; import android.testing.AndroidTestingRunner; @@ -39,6 +41,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.accessibility.AccessibilityButtonModeObserver; import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -58,6 +61,7 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { @Rule public MockitoRule mockito = MockitoJUnit.rule(); + private Context mContextWrapper; private KeyguardUpdateMonitor mKeyguardUpdateMonitor; private AccessibilityFloatingMenuController mController; private AccessibilityButtonTargetsObserver mTargetsObserver; @@ -66,6 +70,16 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardCallbackCaptor; private KeyguardUpdateMonitorCallback mKeyguardCallback; + @Before + public void setUp() throws Exception { + mContextWrapper = new ContextWrapper(mContext) { + @Override + public Context createContextAsUser(UserHandle user, int flags) { + return getBaseContext(); + } + }; + } + @Test public void initController_registerListeners() { mController = setUpController(); @@ -105,7 +119,7 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { public void onKeyguardVisibilityChanged_showing_destroyWidget() { enableAccessibilityFloatingMenuConfig(); mController = setUpController(); - mController.mFloatingMenu = new AccessibilityFloatingMenu(mContext); + mController.mFloatingMenu = new AccessibilityFloatingMenu(mContextWrapper); captureKeyguardUpdateMonitorCallback(); mKeyguardCallback.onUserUnlocked(); @@ -131,7 +145,7 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { final int fakeUserId = 1; enableAccessibilityFloatingMenuConfig(); mController = setUpController(); - mController.mFloatingMenu = new AccessibilityFloatingMenu(mContext); + mController.mFloatingMenu = new AccessibilityFloatingMenu(mContextWrapper); captureKeyguardUpdateMonitorCallback(); mKeyguardCallback.onUserSwitching(fakeUserId); @@ -144,7 +158,7 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { final int fakeUserId = 1; enableAccessibilityFloatingMenuConfig(); mController = setUpController(); - mController.mFloatingMenu = new AccessibilityFloatingMenu(mContext); + mController.mFloatingMenu = new AccessibilityFloatingMenu(mContextWrapper); captureKeyguardUpdateMonitorCallback(); mKeyguardCallback.onUserUnlocked(); mKeyguardCallback.onKeyguardVisibilityChanged(true); @@ -172,7 +186,7 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { @Test public void onAccessibilityButtonModeChanged_floatingModeAndHasButtonTargets_showWidget() { - Settings.Secure.putStringForUser(mContext.getContentResolver(), + Settings.Secure.putStringForUser(mContextWrapper.getContentResolver(), Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, TEST_A11Y_BTN_TARGETS, UserHandle.USER_CURRENT); mController = setUpController(); @@ -184,7 +198,7 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { @Test public void onAccessibilityButtonModeChanged_floatingModeAndNoButtonTargets_destroyWidget() { - Settings.Secure.putStringForUser(mContext.getContentResolver(), + Settings.Secure.putStringForUser(mContextWrapper.getContentResolver(), Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, "", UserHandle.USER_CURRENT); mController = setUpController(); @@ -195,7 +209,7 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { @Test public void onAccessibilityButtonModeChanged_navBarModeAndHasButtonTargets_destroyWidget() { - Settings.Secure.putStringForUser(mContext.getContentResolver(), + Settings.Secure.putStringForUser(mContextWrapper.getContentResolver(), Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, TEST_A11Y_BTN_TARGETS, UserHandle.USER_CURRENT); mController = setUpController(); @@ -207,7 +221,7 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { @Test public void onAccessibilityButtonModeChanged_navBarModeAndNoButtonTargets_destroyWidget() { - Settings.Secure.putStringForUser(mContext.getContentResolver(), + Settings.Secure.putStringForUser(mContextWrapper.getContentResolver(), Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, "", UserHandle.USER_CURRENT); mController = setUpController(); @@ -218,7 +232,7 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { @Test public void onAccessibilityButtonTargetsChanged_floatingModeAndHasButtonTargets_showWidget() { - Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.putIntForUser(mContextWrapper.getContentResolver(), Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU, UserHandle.USER_CURRENT); mController = setUpController(); @@ -230,7 +244,7 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { @Test public void onAccessibilityButtonTargetsChanged_floatingModeAndNoButtonTargets_destroyWidget() { - Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.putIntForUser(mContextWrapper.getContentResolver(), Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU, UserHandle.USER_CURRENT); mController = setUpController(); @@ -242,7 +256,7 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { @Test public void onAccessibilityButtonTargetsChanged_navBarModeAndHasButtonTargets_destroyWidget() { - Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.putIntForUser(mContextWrapper.getContentResolver(), Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR, UserHandle.USER_CURRENT); mController = setUpController(); @@ -254,7 +268,7 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { @Test public void onAccessibilityButtonTargetsChanged_navBarModeAndNoButtonTargets_destroyWidget() { - Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.putIntForUser(mContextWrapper.getContentResolver(), Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR, UserHandle.USER_CURRENT); mController = setUpController(); @@ -269,15 +283,15 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase { mModeObserver = spy(Dependency.get(AccessibilityButtonModeObserver.class)); mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class); - return new AccessibilityFloatingMenuController(mContext, mTargetsObserver, + return new AccessibilityFloatingMenuController(mContextWrapper, mTargetsObserver, mModeObserver, mKeyguardUpdateMonitor); } private void enableAccessibilityFloatingMenuConfig() { - Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.putIntForUser(mContextWrapper.getContentResolver(), Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU, UserHandle.USER_CURRENT); - Settings.Secure.putStringForUser(mContext.getContentResolver(), + Settings.Secure.putStringForUser(mContextWrapper.getContentResolver(), Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, TEST_A11Y_BTN_TARGETS, UserHandle.USER_CURRENT); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt index 2c7d291033b3..d01cdd45181f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt @@ -11,7 +11,6 @@ import android.os.Looper import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import android.view.IRemoteAnimationFinishedCallback -import android.view.IRemoteAnimationRunner import android.view.RemoteAnimationAdapter import android.view.RemoteAnimationTarget import android.view.SurfaceControl @@ -20,19 +19,21 @@ import android.widget.LinearLayout import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.eq import junit.framework.Assert.assertFalse import junit.framework.Assert.assertNotNull import junit.framework.Assert.assertNull import junit.framework.Assert.assertTrue import junit.framework.AssertionFailedError +import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.Mock +import org.mockito.Mockito.`when` import org.mockito.Mockito.never -import org.mockito.Mockito.spy import org.mockito.Mockito.verify import org.mockito.Spy import org.mockito.junit.MockitoJUnit @@ -43,13 +44,18 @@ import kotlin.concurrent.thread @RunWithLooper class ActivityLaunchAnimatorTest : SysuiTestCase() { private val launchContainer = LinearLayout(mContext) - private val keyguardHandler = TestLaunchAnimatorKeyguardHandler(isOnKeyguard = false) + @Mock lateinit var keyguardHandler: ActivityLaunchAnimator.KeyguardHandler @Spy private val controller = TestLaunchAnimatorController(launchContainer) @Mock lateinit var iCallback: IRemoteAnimationFinishedCallback - private val activityLaunchAnimator = ActivityLaunchAnimator(keyguardHandler, mContext) + private lateinit var activityLaunchAnimator: ActivityLaunchAnimator @get:Rule val rule = MockitoJUnit.rule() + @Before + fun setup() { + activityLaunchAnimator = ActivityLaunchAnimator(keyguardHandler, mContext) + } + private fun startIntentWithAnimation( animator: ActivityLaunchAnimator = this.activityLaunchAnimator, controller: ActivityLaunchAnimator.Controller? = this.controller, @@ -110,7 +116,7 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { @Test fun animatesIfActivityIsAlreadyOpenAndIsOnKeyguard() { - val keyguardHandler = spy(TestLaunchAnimatorKeyguardHandler(isOnKeyguard = true)) + `when`(keyguardHandler.isOnKeyguard()).thenReturn(true) val animator = ActivityLaunchAnimator(keyguardHandler, context) val willAnimateCaptor = ArgumentCaptor.forClass(Boolean::class.java) @@ -123,7 +129,6 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { waitForIdleSync() verify(controller).onIntentStarted(willAnimateCaptor.capture()) - verify(keyguardHandler).disableKeyguardBlurs() verify(keyguardHandler).hideKeyguardWithAnimation(any()) assertTrue(willAnimateCaptor.value) @@ -166,6 +171,7 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { val runner = activityLaunchAnimator.createRunner(controller) runner.onAnimationStart(0, arrayOf(fakeWindow()), emptyArray(), emptyArray(), iCallback) waitForIdleSync() + verify(keyguardHandler).setBlursDisabledForAppLaunch(eq(true)) verify(controller).onLaunchAnimationStart(anyBoolean()) } @@ -185,20 +191,6 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { } } -private class TestLaunchAnimatorKeyguardHandler( - private val isOnKeyguard: Boolean -) : ActivityLaunchAnimator.KeyguardHandler { - override fun isOnKeyguard(): Boolean = isOnKeyguard - - override fun disableKeyguardBlurs() { - // Do nothing - } - - override fun hideKeyguardWithAnimation(runner: IRemoteAnimationRunner) { - // Do nothing. - } -} - /** * A simple implementation of [ActivityLaunchAnimator.Controller] which throws if it is called * outside of the main thread. diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index 41f987727860..25722e1c956b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -53,8 +53,11 @@ import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; +import com.android.systemui.util.concurrency.Execution; +import com.android.systemui.util.concurrency.FakeExecution; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; @@ -74,7 +77,7 @@ import java.util.Optional; @SmallTest @RunWith(AndroidTestingRunner.class) -@RunWithLooper +@RunWithLooper(setAsMainLooper = true) public class UdfpsControllerTest extends SysuiTestCase { // Use this for inputs going into SystemUI. Use UdfpsController.mUdfpsSensorId for things @@ -88,6 +91,7 @@ public class UdfpsControllerTest extends SysuiTestCase { private UdfpsController mUdfpsController; // Dependencies + private Execution mExecution; @Mock private LayoutInflater mLayoutInflater; @Mock @@ -117,9 +121,13 @@ public class UdfpsControllerTest extends SysuiTestCase { @Mock private AccessibilityManager mAccessibilityManager; @Mock + private LockscreenShadeTransitionController mLockscreenShadeTransitionController; + @Mock private ScreenLifecycle mScreenLifecycle; @Mock private Vibrator mVibrator; + @Mock + private UdfpsHapticsSimulator mUdfpsHapticsSimulator; private FakeExecutor mFgExecutor; @@ -142,6 +150,8 @@ public class UdfpsControllerTest extends SysuiTestCase { @Before public void setUp() { setUpResources(); + mExecution = new FakeExecution(); + when(mLayoutInflater.inflate(R.layout.udfps_view, null, false)).thenReturn(mUdfpsView); final List<FingerprintSensorPropertiesInternal> props = new ArrayList<>(); @@ -163,6 +173,7 @@ public class UdfpsControllerTest extends SysuiTestCase { mFgExecutor = new FakeExecutor(new FakeSystemClock()); mUdfpsController = new UdfpsController( mContext, + mExecution, mLayoutInflater, mFingerprintManager, mWindowManager, @@ -176,8 +187,10 @@ public class UdfpsControllerTest extends SysuiTestCase { mFalsingManager, mPowerManager, mAccessibilityManager, + mLockscreenShadeTransitionController, mScreenLifecycle, mVibrator, + mUdfpsHapticsSimulator, Optional.of(mHbmProvider)); verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture()); mOverlayController = mOverlayCaptor.getValue(); @@ -334,7 +347,7 @@ public class UdfpsControllerTest extends SysuiTestCase { moveEvent.recycle(); // THEN click haptic is played - verify(mVibrator).vibrate(mUdfpsController.mEffectClick, + verify(mVibrator).vibrate(mUdfpsController.EFFECT_CLICK, UdfpsController.VIBRATION_SONIFICATION_ATTRIBUTES); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java index 5923de6719a8..f62587c6e87c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java @@ -35,6 +35,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; @@ -65,6 +66,8 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase { @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; @Mock + private LockscreenShadeTransitionController mLockscreenShadeTransitionController; + @Mock private DumpManager mDumpManager; @Mock private DelayableExecutor mExecutor; @@ -106,6 +109,7 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase { mExecutor, mDumpManager, mKeyguardViewMediator, + mLockscreenShadeTransitionController, mUdfpsController); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java index adc8ffc1d633..578c2d976cce 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java @@ -57,7 +57,6 @@ import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.model.SysUiState; import com.android.systemui.plugins.GlobalActions; import com.android.systemui.settings.UserContextProvider; -import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -99,7 +98,6 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase { @Mock private TrustManager mTrustManager; @Mock private IActivityManager mActivityManager; @Mock private MetricsLogger mMetricsLogger; - @Mock private NotificationShadeDepthController mDepthController; @Mock private SysuiColorExtractor mColorExtractor; @Mock private IStatusBarService mStatusBarService; @Mock private NotificationShadeWindowController mNotificationShadeWindowController; @@ -147,7 +145,6 @@ public class GlobalActionsDialogLiteTest extends SysuiTestCase { mActivityManager, null, mMetricsLogger, - mDepthController, mColorExtractor, mStatusBarService, mNotificationShadeWindowController, 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 e5c104e7d377..2fa67cc0be60 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java @@ -64,7 +64,6 @@ import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.GlobalActions; import com.android.systemui.plugins.GlobalActionsPanelPlugin; import com.android.systemui.settings.UserTracker; -import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -111,7 +110,6 @@ public class GlobalActionsDialogTest extends SysuiTestCase { @Mock private TrustManager mTrustManager; @Mock private IActivityManager mActivityManager; @Mock private MetricsLogger mMetricsLogger; - @Mock private NotificationShadeDepthController mDepthController; @Mock private SysuiColorExtractor mColorExtractor; @Mock private IStatusBarService mStatusBarService; @Mock private NotificationShadeWindowController mNotificationShadeWindowController; @@ -161,7 +159,6 @@ public class GlobalActionsDialogTest extends SysuiTestCase { mActivityManager, null, mMetricsLogger, - mDepthController, mColorExtractor, mStatusBarService, mNotificationShadeWindowController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt index 2d19f7dd4706..c9d41900b996 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt @@ -232,6 +232,7 @@ public class MediaControlPanelTest : SysuiTestCase() { emptyList(), PACKAGE, session.getSessionToken(), null, device, true, null) player.bindPlayer(state, PACKAGE) assertThat(seamlessText.getText()).isEqualTo(DEVICE_NAME) + assertThat(seamless.contentDescription).isEqualTo(DEVICE_NAME) assertThat(seamless.isEnabled()).isTrue() } @@ -251,13 +252,15 @@ public class MediaControlPanelTest : SysuiTestCase() { @Test fun bindNullDevice() { + val fallbackString = context.getResources().getString( + com.android.internal.R.string.ext_media_seamless_action) player.attachPlayer(holder) val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(), emptyList(), PACKAGE, session.getSessionToken(), null, null, true, null) player.bindPlayer(state, PACKAGE) assertThat(seamless.isEnabled()).isTrue() - assertThat(seamlessText.getText()).isEqualTo(context.getResources().getString( - com.android.internal.R.string.ext_media_seamless_action)) + assertThat(seamlessText.getText()).isEqualTo(fallbackString) + assertThat(seamless.contentDescription).isEqualTo(fallbackString) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt index ef8d322ca2ec..ba4fc0aba81d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt @@ -22,14 +22,24 @@ import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Ignore +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.mockito.Mock import org.mockito.Mockito.mock +import org.mockito.junit.MockitoJUnit @SmallTest @RunWith(AndroidTestingRunner::class) public class MediaPlayerDataTest : SysuiTestCase() { + @Mock + private lateinit var playerIsPlaying: MediaControlPanel + + @JvmField + @Rule + val mockito = MockitoJUnit.rule() + companion object { val LOCAL = true val RESUMPTION = true @@ -44,7 +54,6 @@ public class MediaPlayerDataTest : SysuiTestCase() { @Test fun addPlayingThenRemote() { - val playerIsPlaying = mock(MediaControlPanel::class.java) val dataIsPlaying = createMediaData("app1", PLAYING, LOCAL, !RESUMPTION) val playerIsRemote = mock(MediaControlPanel::class.java) @@ -83,7 +92,6 @@ public class MediaPlayerDataTest : SysuiTestCase() { @Test fun fullOrderTest() { - val playerIsPlaying = mock(MediaControlPanel::class.java) val dataIsPlaying = createMediaData("app1", PLAYING, LOCAL, !RESUMPTION) val playerIsPlayingAndRemote = mock(MediaControlPanel::class.java) @@ -115,6 +123,26 @@ public class MediaPlayerDataTest : SysuiTestCase() { playerUndetermined).inOrder() } + @Test + fun testMoveMediaKeysAround() { + val keyA = "a" + val keyB = "b" + + val data = createMediaData("app1", PLAYING, LOCAL, !RESUMPTION) + + MediaPlayerData.addMediaPlayer(keyA, data, playerIsPlaying) + MediaPlayerData.addMediaPlayer(keyB, data, playerIsPlaying) + + assertThat(MediaPlayerData.players()).hasSize(2) + + MediaPlayerData.moveIfExists(keyA, keyB) + + assertThat(MediaPlayerData.players()).hasSize(1) + + assertThat(MediaPlayerData.getMediaPlayer(keyA)).isNull() + assertThat(MediaPlayerData.getMediaPlayer(keyB)).isNotNull() + } + private fun createMediaData( app: String, isPlaying: Boolean?, diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java index 6e216428992f..2c686618a361 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java @@ -135,8 +135,6 @@ public class MediaOutputAdapterTest extends SysuiTestCase { mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0); assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE); @@ -154,8 +152,6 @@ public class MediaOutputAdapterTest extends SysuiTestCase { mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0); assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE); @@ -176,9 +172,25 @@ public class MediaOutputAdapterTest extends SysuiTestCase { assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_1); + } + + @Test + public void onBindViewHolder_bindConnectedDevice_withSelectableDevice_showAddIcon() { + when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(mMediaDevices); + mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0); + assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(mViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_1); + } + + @Test + public void onBindViewHolder_bindConnectedDevice_withoutSelectableDevice_hideAddIcon() { + when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(new ArrayList<>()); + mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0); + + assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.GONE); + assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.GONE); } @Test @@ -245,8 +257,6 @@ public class MediaOutputAdapterTest extends SysuiTestCase { assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_1); } @@ -263,8 +273,6 @@ public class MediaOutputAdapterTest extends SysuiTestCase { assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE); assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mViewHolder.mTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_1); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java index 589ae2e7f4f4..9bd07b88417d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java @@ -155,6 +155,7 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase { @Test public void refresh_notInDragging_verifyUpdateAdapter() { + when(mMediaOutputBaseAdapter.getCurrentActivePosition()).thenReturn(-1); when(mMediaOutputBaseAdapter.isDragging()).thenReturn(false); mMediaOutputBaseDialogImpl.refresh(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java index da63b8a3ca4b..d2527c679a13 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java @@ -52,8 +52,10 @@ import com.android.systemui.model.SysUiState; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; +import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationRemoteInputManager; +import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; @@ -104,11 +106,13 @@ public class NavigationBarControllerTest extends SysuiTestCase { () -> mock(StatusBar.class), mock(ShadeController.class), mock(NotificationRemoteInputManager.class), + mock(NotificationShadeDepthController.class), mock(SystemActions.class), Dependency.get(Dependency.MAIN_HANDLER), mock(UiEventLogger.class), mock(NavigationBarOverlayController.class), - mock(ConfigurationController.class))); + mock(ConfigurationController.class), + mock(UserTracker.class))); initializeNavigationBars(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java index 4ec45b444c46..a570675b442e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java @@ -76,8 +76,10 @@ import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; +import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationRemoteInputManager; +import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; @@ -273,10 +275,12 @@ public class NavigationBarTest extends SysuiTestCase { () -> mock(StatusBar.class), mock(ShadeController.class), mock(NotificationRemoteInputManager.class), + mock(NotificationShadeDepthController.class), mock(SystemActions.class), mHandler, mock(NavigationBarOverlayController.class), - mUiEventLogger)); + mUiEventLogger, + mock(UserTracker.class))); } private void processAllMessages() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java index 67505c42ef9a..e4e8cf0b0802 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java @@ -26,8 +26,6 @@ import static android.app.people.PeopleSpaceTile.BLOCK_CONVERSATIONS; import static android.app.people.PeopleSpaceTile.SHOW_CONTACTS; import static android.app.people.PeopleSpaceTile.SHOW_IMPORTANT_CONVERSATIONS; import static android.app.people.PeopleSpaceTile.SHOW_STARRED_CONTACTS; -import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT; -import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH; import static com.android.systemui.people.PeopleSpaceUtils.STARRED_CONTACT; import static com.android.systemui.people.PeopleSpaceUtils.VALID_CONTACT; @@ -35,7 +33,6 @@ import static com.android.systemui.people.PeopleSpaceUtils.VALID_CONTACT; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -49,7 +46,6 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.drawable.Icon; import android.net.Uri; -import android.os.Bundle; import android.os.UserHandle; import android.testing.AndroidTestingRunner; import android.util.DisplayMetrics; @@ -137,15 +133,14 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { @Mock private PackageManager mPackageManager; - private Bundle mOptions; + private int mWidth; + private int mHeight; private PeopleTileViewHelper mPeopleTileViewHelper; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mOptions = new Bundle(); - when(mMockContext.getString(R.string.birthday_status)).thenReturn( mContext.getString(R.string.birthday_status)); when(mMockContext.getPackageManager()).thenReturn(mPackageManager); @@ -160,25 +155,24 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { TextView textView = mock(TextView.class); when(textView.getLineHeight()).thenReturn(16); when(mPackageManager.getApplicationIcon(anyString())).thenReturn(null); - mPeopleTileViewHelper = getPeopleTileViewHelper( - PERSON_TILE, mOptions); + + mWidth = getSizeInDp(R.dimen.default_width); + mHeight = getSizeInDp(R.dimen.default_height); + mPeopleTileViewHelper = getPeopleTileViewHelper(PERSON_TILE); } @Test public void testCreateRemoteViewsWithLastInteractionTimeUnderOneDayHidden() { - RemoteViews views = getPeopleTileViewHelper( - PERSON_TILE_WITHOUT_NOTIFICATION, mOptions).getViews(); + RemoteViews views = getPeopleTileViewHelper(PERSON_TILE_WITHOUT_NOTIFICATION).getViews(); View result = views.apply(mContext, null); // Not showing last interaction. assertEquals(View.GONE, result.findViewById(R.id.last_interaction).getVisibility()); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_large)); - mOptions.putInt(OPTION_APPWIDGET_MAX_HEIGHT, - getSizeInDp(R.dimen.required_height_for_large)); + mWidth = getSizeInDp(R.dimen.required_width_for_large); + mHeight = getSizeInDp(R.dimen.required_height_for_large); RemoteViews largeView = getPeopleTileViewHelper( - PERSON_TILE_WITHOUT_NOTIFICATION, mOptions).getViews(); + PERSON_TILE_WITHOUT_NOTIFICATION).getViews(); View largeResult = largeView.apply(mContext, null); // Not showing last interaction. @@ -214,8 +208,7 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { PeopleSpaceTile tileWithLastInteraction = PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setLastInteractionTimestamp( 123445L).build(); - RemoteViews views = getPeopleTileViewHelper( - tileWithLastInteraction, mOptions).getViews(); + RemoteViews views = getPeopleTileViewHelper(tileWithLastInteraction).getViews(); View result = views.apply(mContext, null); TextView name = (TextView) result.findViewById(R.id.name); @@ -231,10 +224,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { // No status. assertThat((View) result.findViewById(R.id.text_content)).isNull(); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_medium) - 1); - RemoteViews smallView = getPeopleTileViewHelper( - tileWithLastInteraction, mOptions).getViews(); + mWidth = getSizeInDp(R.dimen.required_width_for_medium) - 1; + RemoteViews smallView = getPeopleTileViewHelper(tileWithLastInteraction).getViews(); View smallResult = smallView.apply(mContext, null); // Show name over predefined icon. @@ -246,12 +237,10 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { assertEquals(View.GONE, smallResult.findViewById(R.id.messages_count).getVisibility()); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_large)); - mOptions.putInt(OPTION_APPWIDGET_MAX_HEIGHT, - getSizeInDp(R.dimen.required_height_for_large)); + mWidth = getSizeInDp(R.dimen.required_width_for_large); + mHeight = getSizeInDp(R.dimen.required_height_for_large); RemoteViews largeView = getPeopleTileViewHelper( - tileWithLastInteraction, mOptions).getViews(); + tileWithLastInteraction).getViews(); View largeResult = largeView.apply(mContext, null); name = (TextView) largeResult.findViewById(R.id.name); @@ -276,8 +265,7 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { new ConversationStatus.Builder( PERSON_TILE_WITHOUT_NOTIFICATION.getId(), ACTIVITY_GAME).build())).build(); - RemoteViews views = getPeopleTileViewHelper( - tileWithAvailabilityAndNewStory, mOptions).getViews(); + RemoteViews views = getPeopleTileViewHelper(tileWithAvailabilityAndNewStory).getViews(); View result = views.apply(mContext, null); TextView name = (TextView) result.findViewById(R.id.name); @@ -291,10 +279,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { // No status. assertThat((View) result.findViewById(R.id.text_content)).isNull(); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_medium) - 1); - RemoteViews smallView = getPeopleTileViewHelper( - tileWithAvailabilityAndNewStory, mOptions).getViews(); + mWidth = getSizeInDp(R.dimen.required_width_for_medium) - 1; + RemoteViews smallView = getPeopleTileViewHelper(tileWithAvailabilityAndNewStory).getViews(); View smallResult = smallView.apply(mContext, null); // Show name rather than game type. @@ -306,12 +292,9 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { // No messages count. assertEquals(View.GONE, smallResult.findViewById(R.id.messages_count).getVisibility()); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_large)); - mOptions.putInt(OPTION_APPWIDGET_MAX_HEIGHT, - getSizeInDp(R.dimen.required_height_for_large)); - RemoteViews largeView = getPeopleTileViewHelper( - tileWithAvailabilityAndNewStory, mOptions).getViews(); + mWidth = getSizeInDp(R.dimen.required_width_for_large); + mHeight = getSizeInDp(R.dimen.required_height_for_large); + RemoteViews largeView = getPeopleTileViewHelper(tileWithAvailabilityAndNewStory).getViews(); View largeResult = largeView.apply(mContext, null); name = (TextView) largeResult.findViewById(R.id.name); @@ -334,8 +317,7 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { NEW_STORY_WITH_AVAILABILITY, new ConversationStatus.Builder( PERSON_TILE_WITHOUT_NOTIFICATION.getId(), ACTIVITY_BIRTHDAY).build())).build(); - RemoteViews views = getPeopleTileViewHelper( - tileWithStatusTemplate, mOptions).getViews(); + RemoteViews views = getPeopleTileViewHelper(tileWithStatusTemplate).getViews(); View result = views.apply(mContext, null); TextView name = (TextView) result.findViewById(R.id.name); @@ -352,10 +334,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { assertEquals(statusContent.getText(), mContext.getString(R.string.birthday_status)); assertThat(statusContent.getMaxLines()).isEqualTo(2); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_medium) - 1); - RemoteViews smallView = getPeopleTileViewHelper( - tileWithStatusTemplate, mOptions).getViews(); + mWidth = getSizeInDp(R.dimen.required_width_for_medium) - 1; + RemoteViews smallView = getPeopleTileViewHelper(tileWithStatusTemplate).getViews(); View smallResult = smallView.apply(mContext, null); // Show icon instead of name. @@ -368,12 +348,9 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { // No messages count. assertEquals(View.GONE, smallResult.findViewById(R.id.messages_count).getVisibility()); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_large)); - mOptions.putInt(OPTION_APPWIDGET_MAX_HEIGHT, - getSizeInDp(R.dimen.required_height_for_large)); - RemoteViews largeView = getPeopleTileViewHelper( - tileWithStatusTemplate, mOptions).getViews(); + mWidth = getSizeInDp(R.dimen.required_width_for_large); + mHeight = getSizeInDp(R.dimen.required_height_for_large); + RemoteViews largeView = getPeopleTileViewHelper(tileWithStatusTemplate).getViews(); View largeResult = largeView.apply(mContext, null); name = (TextView) largeResult.findViewById(R.id.name); @@ -398,8 +375,7 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setStatuses( Arrays.asList(GAME_STATUS, NEW_STORY_WITH_AVAILABILITY)).build(); - RemoteViews views = getPeopleTileViewHelper( - tileWithStatusTemplate, mOptions).getViews(); + RemoteViews views = getPeopleTileViewHelper(tileWithStatusTemplate).getViews(); View result = views.apply(mContext, null); TextView name = (TextView) result.findViewById(R.id.name); @@ -417,10 +393,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { assertEquals(statusContent.getText(), GAME_DESCRIPTION); assertThat(statusContent.getMaxLines()).isEqualTo(2); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_medium) - 1); - RemoteViews smallView = getPeopleTileViewHelper( - tileWithStatusTemplate, mOptions).getViews(); + mWidth = getSizeInDp(R.dimen.required_width_for_medium) - 1; + RemoteViews smallView = getPeopleTileViewHelper(tileWithStatusTemplate).getViews(); View smallResult = smallView.apply(mContext, null); // Show icon instead of name. @@ -433,12 +407,9 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { // No messages count. assertEquals(View.GONE, smallResult.findViewById(R.id.messages_count).getVisibility()); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_large)); - mOptions.putInt(OPTION_APPWIDGET_MAX_HEIGHT, - getSizeInDp(R.dimen.required_height_for_large)); - RemoteViews largeView = getPeopleTileViewHelper( - tileWithStatusTemplate, mOptions).getViews(); + mWidth = getSizeInDp(R.dimen.required_width_for_large); + mHeight = getSizeInDp(R.dimen.required_height_for_large); + RemoteViews largeView = getPeopleTileViewHelper(tileWithStatusTemplate).getViews(); View largeResult = largeView.apply(mContext, null); name = (TextView) largeResult.findViewById(R.id.name); @@ -467,7 +438,7 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { ACTIVITY_ANNIVERSARY).setDescription("Anniversary").setAvailability( AVAILABILITY_AVAILABLE).setIcon(mIcon).build())).build(); RemoteViews views = getPeopleTileViewHelper( - tileWithIconInStatusTemplate, mOptions).getViews(); + tileWithIconInStatusTemplate).getViews(); View result = views.apply(mContext, null); assertEquals(View.GONE, result.findViewById(R.id.subtext).getVisibility()); @@ -483,12 +454,9 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { assertEquals(statusContent.getText(), "Anniversary"); assertThat(statusContent.getMaxLines()).isEqualTo(1); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_large)); - mOptions.putInt(OPTION_APPWIDGET_MAX_HEIGHT, - getSizeInDp(R.dimen.required_height_for_large)); - RemoteViews largeView = getPeopleTileViewHelper( - tileWithIconInStatusTemplate, mOptions).getViews(); + mWidth = getSizeInDp(R.dimen.required_width_for_large); + mHeight = getSizeInDp(R.dimen.required_height_for_large); + RemoteViews largeView = getPeopleTileViewHelper(tileWithIconInStatusTemplate).getViews(); View largeResult = largeView.apply(mContext, null); assertEquals(View.GONE, largeResult.findViewById(R.id.subtext).getVisibility()); @@ -513,8 +481,7 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { PeopleSpaceTile tile = PERSON_TILE.toBuilder() .setIsPackageSuspended(true) .build(); - RemoteViews views = getPeopleTileViewHelper( - tile, mOptions).getViews(); + RemoteViews views = getPeopleTileViewHelper(tile).getViews(); View result = views.apply(mContext, null); assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout); @@ -525,8 +492,7 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { PeopleSpaceTile tile = PERSON_TILE.toBuilder() .setIsUserQuieted(true) .build(); - RemoteViews views = getPeopleTileViewHelper( - tile, mOptions).getViews(); + RemoteViews views = getPeopleTileViewHelper(tile).getViews(); View result = views.apply(mContext, null); assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_work_profile_quiet_layout); @@ -537,89 +503,100 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { PeopleSpaceTile tileWithDndBlocking = PERSON_TILE.toBuilder() .setNotificationPolicyState(BLOCK_CONVERSATIONS) .build(); - RemoteViews views = getPeopleTileViewHelper( - tileWithDndBlocking, mOptions).getViews(); + RemoteViews views = getPeopleTileViewHelper(tileWithDndBlocking).getViews(); View result = views.apply(mContext, null); - assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout); + assertResourcesEqual( + result.getSourceLayoutResId(), + R.layout.people_tile_with_suppression_detail_content_horizontal); tileWithDndBlocking = PERSON_TILE.toBuilder() .setNotificationPolicyState(BLOCK_CONVERSATIONS) .setCanBypassDnd(true) .build(); - views = getPeopleTileViewHelper( - tileWithDndBlocking, mOptions).getViews(); + views = getPeopleTileViewHelper(tileWithDndBlocking).getViews(); result = views.apply(mContext, null); - assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout); + assertResourcesNotEqual( + result.getSourceLayoutResId(), + R.layout.people_tile_with_suppression_detail_content_horizontal); tileWithDndBlocking = PERSON_TILE.toBuilder() .setNotificationPolicyState(SHOW_IMPORTANT_CONVERSATIONS) .build(); - views = getPeopleTileViewHelper( - tileWithDndBlocking, mOptions).getViews(); + views = getPeopleTileViewHelper(tileWithDndBlocking).getViews(); result = views.apply(mContext, null); - assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout); + assertResourcesEqual( + result.getSourceLayoutResId(), + R.layout.people_tile_with_suppression_detail_content_horizontal); tileWithDndBlocking = PERSON_TILE.toBuilder() .setNotificationPolicyState(SHOW_IMPORTANT_CONVERSATIONS) .setIsImportantConversation(true) .build(); - views = getPeopleTileViewHelper( - tileWithDndBlocking, mOptions).getViews(); + views = getPeopleTileViewHelper(tileWithDndBlocking).getViews(); result = views.apply(mContext, null); - assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout); + assertResourcesNotEqual( + result.getSourceLayoutResId(), + R.layout.people_tile_with_suppression_detail_content_horizontal); tileWithDndBlocking = PERSON_TILE.toBuilder() .setNotificationPolicyState(SHOW_STARRED_CONTACTS) .setContactAffinity(VALID_CONTACT) .build(); - views = getPeopleTileViewHelper( - tileWithDndBlocking, mOptions).getViews(); + views = getPeopleTileViewHelper(tileWithDndBlocking).getViews(); result = views.apply(mContext, null); - assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout); + assertResourcesEqual( + result.getSourceLayoutResId(), + R.layout.people_tile_with_suppression_detail_content_horizontal); tileWithDndBlocking = PERSON_TILE.toBuilder() .setNotificationPolicyState(SHOW_STARRED_CONTACTS) .setContactAffinity(STARRED_CONTACT) .build(); - views = getPeopleTileViewHelper( - tileWithDndBlocking, mOptions).getViews(); + views = getPeopleTileViewHelper(tileWithDndBlocking).getViews(); result = views.apply(mContext, null); - assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout); + assertResourcesNotEqual( + result.getSourceLayoutResId(), + R.layout.people_tile_with_suppression_detail_content_horizontal); tileWithDndBlocking = PERSON_TILE.toBuilder() .setNotificationPolicyState(SHOW_CONTACTS) .setContactAffinity(STARRED_CONTACT) .build(); - views = getPeopleTileViewHelper( - tileWithDndBlocking, mOptions).getViews(); + views = getPeopleTileViewHelper(tileWithDndBlocking).getViews(); result = views.apply(mContext, null); - assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout); + assertResourcesNotEqual( + result.getSourceLayoutResId(), + R.layout.people_tile_with_suppression_detail_content_horizontal); tileWithDndBlocking = PERSON_TILE.toBuilder() .setNotificationPolicyState(SHOW_CONTACTS) .setContactAffinity(VALID_CONTACT) .build(); - views = getPeopleTileViewHelper( - tileWithDndBlocking, mOptions).getViews(); + views = getPeopleTileViewHelper(tileWithDndBlocking).getViews(); result = views.apply(mContext, null); - assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout); + assertResourcesNotEqual( + result.getSourceLayoutResId(), + R.layout.people_tile_with_suppression_detail_content_horizontal); tileWithDndBlocking = PERSON_TILE.toBuilder() .setNotificationPolicyState(SHOW_CONTACTS) .build(); - views = getPeopleTileViewHelper( - tileWithDndBlocking, mOptions).getViews(); + views = getPeopleTileViewHelper(tileWithDndBlocking).getViews(); result = views.apply(mContext, null); - assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_suppressed_layout); + assertResourcesEqual( + result.getSourceLayoutResId(), + R.layout.people_tile_with_suppression_detail_content_horizontal); + assertThat(result.<TextView>findViewById(R.id.text_content).getText().toString()) + .isEqualTo(mContext.getString(R.string.paused_by_dnd)); } @Test @@ -629,8 +606,7 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { .setNotificationCategory(CATEGORY_MISSED_CALL) .setNotificationContent(MISSED_CALL) .build(); - RemoteViews views = getPeopleTileViewHelper( - tileWithMissedCallNotification, mOptions).getViews(); + RemoteViews views = getPeopleTileViewHelper(tileWithMissedCallNotification).getViews(); View result = views.apply(mContext, null); TextView name = (TextView) result.findViewById(R.id.name); @@ -647,10 +623,9 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { assertEquals(statusContent.getText(), MISSED_CALL); assertThat(statusContent.getMaxLines()).isEqualTo(2); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_medium) - 1); + mWidth = getSizeInDp(R.dimen.required_width_for_medium) - 1; RemoteViews smallView = getPeopleTileViewHelper( - tileWithMissedCallNotification, mOptions).getViews(); + tileWithMissedCallNotification).getViews(); View smallResult = smallView.apply(mContext, null); // Show icon instead of name. @@ -662,12 +637,9 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { // No messages count. assertEquals(View.GONE, smallResult.findViewById(R.id.messages_count).getVisibility()); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_large)); - mOptions.putInt(OPTION_APPWIDGET_MAX_HEIGHT, - getSizeInDp(R.dimen.required_height_for_large)); - RemoteViews largeView = getPeopleTileViewHelper( - tileWithMissedCallNotification, mOptions).getViews(); + mWidth = getSizeInDp(R.dimen.required_width_for_large); + mHeight = getSizeInDp(R.dimen.required_height_for_large); + RemoteViews largeView = getPeopleTileViewHelper(tileWithMissedCallNotification).getViews(); View largeResult = largeView.apply(mContext, null); name = (TextView) largeResult.findViewById(R.id.name); @@ -693,7 +665,7 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { .setStatuses(Arrays.asList(GAME_STATUS, NEW_STORY_WITH_AVAILABILITY)).build(); RemoteViews views = getPeopleTileViewHelper( - tileWithStatusAndNotification, mOptions).getViews(); + tileWithStatusAndNotification).getViews(); View result = views.apply(mContext, null); TextView name = (TextView) result.findViewById(R.id.name); @@ -714,10 +686,9 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { // Has a single message, no count shown. assertEquals(View.GONE, result.findViewById(R.id.messages_count).getVisibility()); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_medium) - 1); + mWidth = getSizeInDp(R.dimen.required_width_for_medium) - 1; RemoteViews smallView = getPeopleTileViewHelper( - tileWithStatusAndNotification, mOptions).getViews(); + tileWithStatusAndNotification).getViews(); View smallResult = smallView.apply(mContext, null); // Show icon instead of name. @@ -731,12 +702,10 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { // Has a single message, no count shown. assertEquals(View.GONE, smallResult.findViewById(R.id.messages_count).getVisibility()); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_large)); - mOptions.putInt(OPTION_APPWIDGET_MAX_HEIGHT, - getSizeInDp(R.dimen.required_height_for_large)); + mWidth = getSizeInDp(R.dimen.required_width_for_large); + mHeight = getSizeInDp(R.dimen.required_height_for_large); RemoteViews largeView = getPeopleTileViewHelper( - tileWithStatusAndNotification, mOptions).getViews(); + tileWithStatusAndNotification).getViews(); View largeResult = largeView.apply(mContext, null); name = (TextView) largeResult.findViewById(R.id.name); @@ -767,7 +736,7 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { .setStatuses(Arrays.asList(GAME_STATUS, NEW_STORY_WITH_AVAILABILITY)).build(); RemoteViews views = getPeopleTileViewHelper( - tileWithStatusAndNotification, mOptions).getViews(); + tileWithStatusAndNotification).getViews(); View result = views.apply(mContext, null); TextView name = (TextView) result.findViewById(R.id.name); @@ -791,10 +760,9 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { // Has a single message, no count shown. assertEquals(View.GONE, result.findViewById(R.id.messages_count).getVisibility()); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_medium) - 1); + mWidth = getSizeInDp(R.dimen.required_width_for_medium) - 1; RemoteViews smallView = getPeopleTileViewHelper( - tileWithStatusAndNotification, mOptions).getViews(); + tileWithStatusAndNotification).getViews(); View smallResult = smallView.apply(mContext, null); // Show icon instead of name. @@ -808,12 +776,10 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { // Has a single message, no count shown. assertEquals(View.GONE, smallResult.findViewById(R.id.messages_count).getVisibility()); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_large)); - mOptions.putInt(OPTION_APPWIDGET_MAX_HEIGHT, - getSizeInDp(R.dimen.required_height_for_large)); + mWidth = getSizeInDp(R.dimen.required_width_for_large); + mHeight = getSizeInDp(R.dimen.required_height_for_large); RemoteViews largeView = getPeopleTileViewHelper( - tileWithStatusAndNotification, mOptions).getViews(); + tileWithStatusAndNotification).getViews(); View largeResult = largeView.apply(mContext, null); name = (TextView) largeResult.findViewById(R.id.name); @@ -848,7 +814,7 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { NEW_STORY_WITH_AVAILABILITY)) .setMessagesCount(2).build(); RemoteViews views = getPeopleTileViewHelper( - tileWithStatusAndNotification, mOptions).getViews(); + tileWithStatusAndNotification).getViews(); View result = views.apply(mContext, null); TextView name = (TextView) result.findViewById(R.id.name); @@ -868,10 +834,9 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { // Has two messages, show count. assertEquals(View.VISIBLE, result.findViewById(R.id.messages_count).getVisibility()); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_medium) - 1); + mWidth = getSizeInDp(R.dimen.required_width_for_medium) - 1; RemoteViews smallView = getPeopleTileViewHelper( - tileWithStatusAndNotification, mOptions).getViews(); + tileWithStatusAndNotification).getViews(); View smallResult = smallView.apply(mContext, null); // Show icon instead of name. @@ -885,12 +850,10 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { // Has two messages, show count. assertEquals(View.VISIBLE, smallResult.findViewById(R.id.messages_count).getVisibility()); - mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH, - getSizeInDp(R.dimen.required_width_for_large)); - mOptions.putInt(OPTION_APPWIDGET_MAX_HEIGHT, - getSizeInDp(R.dimen.required_height_for_large)); + mWidth = getSizeInDp(R.dimen.required_width_for_large); + mHeight = getSizeInDp(R.dimen.required_height_for_large); RemoteViews largeView = getPeopleTileViewHelper( - tileWithStatusAndNotification, mOptions).getViews(); + tileWithStatusAndNotification).getViews(); View largeResult = largeView.apply(mContext, null); name = (TextView) largeResult.findViewById(R.id.name); @@ -1064,8 +1027,26 @@ public class PeopleTileViewHelperTest extends SysuiTestCase { / mContext.getResources().getDisplayMetrics().density); } - private PeopleTileViewHelper getPeopleTileViewHelper(PeopleSpaceTile tile, Bundle options) { - return new PeopleTileViewHelper(mContext, tile, 0, options, + private PeopleTileViewHelper getPeopleTileViewHelper( + PeopleSpaceTile tile) { + return new PeopleTileViewHelper(mContext, tile, 0, mWidth, mHeight, new PeopleTileKey(tile.getId(), 0, tile.getPackageName())); } + + private void assertResourcesEqual(int expected, int actual) { + assertThat(getResourceName(actual)).isEqualTo(getResourceName(expected)); + } + + private void assertResourcesNotEqual(int expected, int actual) { + assertThat(getResourceName(actual)).isNotEqualTo(getResourceName(expected)); + } + + private String getResourceName(int resId) { + Resources resources = mContext.getResources(); + try { + return resources.getResourceEntryName(resId); + } catch (Resources.NotFoundException e) { + return String.valueOf(resId); + } + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java index 7caf0ddf6bea..770cf2ca0331 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java @@ -204,6 +204,8 @@ public class QSSecurityFooterTest extends SysuiTestCase { public void testTappableView_profileOwnerOfOrgOwnedDevice_networkLoggingEnabled() { when(mSecurityController.isProfileOwnerOfOrganizationOwnedDevice()).thenReturn(true); when(mSecurityController.isNetworkLoggingEnabled()).thenReturn(true); + when(mSecurityController.isWorkProfileOn()).thenReturn(true); + when(mSecurityController.hasWorkProfile()).thenReturn(true); mFooter.refreshState(); @@ -213,6 +215,19 @@ public class QSSecurityFooterTest extends SysuiTestCase { } @Test + public void testUntappableView_profileOwnerOfOrgOwnedDevice_workProfileOff() { + when(mSecurityController.isProfileOwnerOfOrganizationOwnedDevice()).thenReturn(true); + when(mSecurityController.isNetworkLoggingEnabled()).thenReturn(true); + when(mSecurityController.isWorkProfileOn()).thenReturn(false); + + mFooter.refreshState(); + + TestableLooper.get(this).processAllMessages(); + assertFalse(mRootView.isClickable()); + assertEquals(View.GONE, mRootView.findViewById(R.id.footer_icon).getVisibility()); + } + + @Test public void testNetworkLoggingEnabled_deviceOwner() { when(mSecurityController.isDeviceManaged()).thenReturn(true); when(mSecurityController.isNetworkLoggingEnabled()).thenReturn(true); @@ -237,9 +252,10 @@ public class QSSecurityFooterTest extends SysuiTestCase { } @Test - public void testNetworkLoggingEnabled_managedProfileOwner() { + public void testNetworkLoggingEnabled_managedProfileOwner_workProfileOn() { when(mSecurityController.hasWorkProfile()).thenReturn(true); when(mSecurityController.isNetworkLoggingEnabled()).thenReturn(true); + when(mSecurityController.isWorkProfileOn()).thenReturn(true); mFooter.refreshState(); TestableLooper.get(this).processAllMessages(); @@ -249,6 +265,17 @@ public class QSSecurityFooterTest extends SysuiTestCase { } @Test + public void testNetworkLoggingEnabled_managedProfileOwner_workProfileOff() { + when(mSecurityController.hasWorkProfile()).thenReturn(true); + when(mSecurityController.isNetworkLoggingEnabled()).thenReturn(true); + when(mSecurityController.isWorkProfileOn()).thenReturn(false); + mFooter.refreshState(); + + TestableLooper.get(this).processAllMessages(); + assertEquals("", mFooterText.getText()); + } + + @Test public void testManagedCACertsInstalled() { when(mSecurityController.isDeviceManaged()).thenReturn(true); when(mSecurityController.hasCACertInCurrentUser()).thenReturn(true); @@ -326,9 +353,10 @@ public class QSSecurityFooterTest extends SysuiTestCase { } @Test - public void testWorkProfileCACertsInstalled() { + public void testWorkProfileCACertsInstalled_workProfileOn() { when(mSecurityController.isDeviceManaged()).thenReturn(false); when(mSecurityController.hasCACertInWorkProfile()).thenReturn(true); + when(mSecurityController.isWorkProfileOn()).thenReturn(true); mFooter.refreshState(); TestableLooper.get(this).processAllMessages(); @@ -350,6 +378,17 @@ public class QSSecurityFooterTest extends SysuiTestCase { } @Test + public void testWorkProfileCACertsInstalled_workProfileOff() { + when(mSecurityController.isDeviceManaged()).thenReturn(false); + when(mSecurityController.hasCACertInWorkProfile()).thenReturn(true); + when(mSecurityController.isWorkProfileOn()).thenReturn(false); + mFooter.refreshState(); + + TestableLooper.get(this).processAllMessages(); + assertEquals("", mFooterText.getText()); + } + + @Test public void testCACertsInstalled() { when(mSecurityController.isDeviceManaged()).thenReturn(false); when(mSecurityController.hasCACertInCurrentUser()).thenReturn(true); @@ -375,9 +414,10 @@ public class QSSecurityFooterTest extends SysuiTestCase { } @Test - public void testWorkProfileVpnEnabled() { + public void testWorkProfileVpnEnabled_workProfileOn() { when(mSecurityController.isVpnEnabled()).thenReturn(true); when(mSecurityController.getWorkProfileVpnName()).thenReturn(VPN_PACKAGE_2); + when(mSecurityController.isWorkProfileOn()).thenReturn(true); mFooter.refreshState(); TestableLooper.get(this).processAllMessages(); @@ -389,6 +429,17 @@ public class QSSecurityFooterTest extends SysuiTestCase { } @Test + public void testWorkProfileVpnEnabled_workProfileOff() { + when(mSecurityController.isVpnEnabled()).thenReturn(true); + when(mSecurityController.getWorkProfileVpnName()).thenReturn(VPN_PACKAGE_2); + when(mSecurityController.isWorkProfileOn()).thenReturn(false); + mFooter.refreshState(); + + TestableLooper.get(this).processAllMessages(); + assertEquals("", mFooterText.getText()); + } + + @Test public void testProfileOwnerOfOrganizationOwnedDeviceNoName() { when(mSecurityController.isProfileOwnerOfOrganizationOwnedDevice()).thenReturn(true); diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSession.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSession.java index 9c68f0d8a7ff..478658eb232d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSession.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSession.java @@ -57,16 +57,19 @@ class FakeSession implements ScrollCaptureClient.Session { private int mScrollDelta; private int mPageHeight; + private int mTargetHeight; FakeSession(int pageHeight, float maxPages, int tileHeight, int visiblePageTop, - int visiblePageBottom, int availableTop, int availableBottom) { + int visiblePageBottom, int availableTop, int availableBottom, + int maxTiles) { mPageHeight = pageHeight; mTileHeight = tileHeight; mAvailable = new Rect(0, availableTop, getPageWidth(), availableBottom); mAvailableTop = new Rect(mAvailable); mAvailableTop.inset(0, 0, 0, pageHeight); mVisiblePage = new Rect(0, visiblePageTop, getPageWidth(), visiblePageBottom); - mMaxTiles = (int) Math.ceil((pageHeight * maxPages) / mTileHeight); + mTargetHeight = (int) (pageHeight * maxPages); + mMaxTiles = maxTiles; } private static Image mockImage() { @@ -158,6 +161,11 @@ class FakeSession implements ScrollCaptureClient.Session { } @Override + public int getTargetHeight() { + return mTargetHeight; + } + + @Override public int getTileHeight() { return mTileHeight; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSessionTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSessionTest.java index 2520af94380c..4c8a4b0f8f61 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSessionTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/FakeSessionTest.java @@ -42,21 +42,6 @@ import org.junit.runner.RunWith; @RunWith(AndroidTestingRunner.class) public class FakeSessionTest extends SysuiTestCase { @Test - public void testMaxTiles() { - FakeSession session = new FakeSession( - /* pageHeight */ 100, - /* maxPages */ 2.25f, - /* tileHeight */ 10, - /* visiblePageTop */ 0, - /* visiblePageBottom */ 100, - /* availableTop */ -250, - /* availableBottom */ 250); - - // (pageHeight * maxPages) / tileHeight - assertEquals("getMaxTiles()", 23, session.getMaxTiles()); - } - - @Test public void testNonEmptyResult_hasImage() { FakeSession session = new FakeSession( /* pageHeight */ 100, @@ -65,7 +50,8 @@ public class FakeSessionTest extends SysuiTestCase { /* visiblePageTop */ 0, /* visiblePageBottom */ 100, /* availableTop */ 0, - /* availableBottom */ 100); + /* availableBottom */ 100, + /* max Tiles */ 30); ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(0)); assertNotNull("result.image", result.image); assertNotNull("result.image.getHardwareBuffer()", result.image.getHardwareBuffer()); @@ -80,7 +66,8 @@ public class FakeSessionTest extends SysuiTestCase { /* visiblePageTop */ 0, /* visiblePageBottom */ 100, /* availableTop */ 0, - /* availableBottom */ 100); + /* availableBottom */ 100, + /* max Tiles */ 30); ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(-100)); assertNull("result.image", result.image); } @@ -94,7 +81,8 @@ public class FakeSessionTest extends SysuiTestCase { /* visiblePageTop */ 0, /* visiblePageBottom */ 100, /* availableTop */ -250, - /* availableBottom */ 250); + /* availableBottom */ 250, + /* max Tiles */ 30); ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(0)); assertEquals("requested top", 0, result.requested.top); @@ -113,7 +101,8 @@ public class FakeSessionTest extends SysuiTestCase { /* visiblePageTop */ 0, /* visiblePageBottom */ 100, /* availableTop */ -250, - /* availableBottom */ 250); + /* availableBottom */ 250, + /* max Tiles */ 30); ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(90)); assertEquals("requested top", 90, result.requested.top); @@ -132,7 +121,8 @@ public class FakeSessionTest extends SysuiTestCase { /* visiblePageTop */ 0, /* visiblePageBottom */ 100, /* availableTop */ -250, - /* availableBottom */ 250); + /* availableBottom */ 250, + /* max Tiles */ 30); ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(-100)); assertEquals("requested top", -100, result.requested.top); @@ -151,7 +141,8 @@ public class FakeSessionTest extends SysuiTestCase { /* visiblePageTop */ 0, /* visiblePageBottom */ 100, /* availableTop */ -250, - /* availableBottom */ 250); + /* availableBottom */ 250, + /* max Tiles */ 30); ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(150)); assertEquals("requested top", 150, result.requested.top); @@ -170,7 +161,8 @@ public class FakeSessionTest extends SysuiTestCase { /* visiblePageTop */ 0, /* visiblePageBottom */ 100, /* availableTop */ -100, - /* availableBottom */ 100); + /* availableBottom */ 100, + /* max Tiles */ 30); ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(-125)); assertEquals("requested top", -125, result.requested.top); @@ -189,7 +181,8 @@ public class FakeSessionTest extends SysuiTestCase { /* visiblePageTop */ 0, /* visiblePageBottom */ 100, /* availableTop */ -100, - /* availableBottom */ 100); + /* availableBottom */ 100, + /* max Tiles */ 30); ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(75)); assertEquals("requested top", 75, result.requested.top); @@ -211,7 +204,8 @@ public class FakeSessionTest extends SysuiTestCase { /* visiblePageTop */ 25, // <<-- /* visiblePageBottom */ 100, /* availableTop */ -150, - /* availableBottom */ 150); + /* availableBottom */ 150, + /* max Tiles */ 30); ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(-150)); assertEquals("requested top", -150, result.requested.top); @@ -233,7 +227,8 @@ public class FakeSessionTest extends SysuiTestCase { /* visiblePageTop */ 0, /* visiblePageBottom */ 75, /* availableTop */ -150, - /* availableBottom */ 150); + /* availableBottom */ 150, + /* max Tiles */ 30); ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(50)); assertEquals("requested top", 50, result.requested.top); @@ -252,7 +247,8 @@ public class FakeSessionTest extends SysuiTestCase { /* visiblePageTop */ 0, /* visiblePageBottom */ 100, /* availableTop */ -100, - /* availableBottom */ 200); + /* availableBottom */ 200, + /* max Tiles */ 30); ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(-150)); assertTrue("captured rect is empty", result.captured.isEmpty()); } @@ -266,7 +262,8 @@ public class FakeSessionTest extends SysuiTestCase { /* visiblePageTop */ 0, /* visiblePageBottom */ 100, /* availableTop */ -100, - /* availableBottom */ 200); + /* availableBottom */ 200, + /* max Tiles */ 30); ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(200)); assertTrue("captured rect is empty", result.captured.isEmpty()); } @@ -280,7 +277,8 @@ public class FakeSessionTest extends SysuiTestCase { /* visiblePageTop */ 60, // <<--- /* visiblePageBottom */ 0, /* availableTop */ -150, - /* availableBottom */ 150); + /* availableBottom */ 150, + /* max Tiles */ 30); ScrollCaptureClient.CaptureResult result = getUnchecked(session.requestTile(0)); assertEquals("requested top", 0, result.requested.top); diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java index 5bab1bcddb6a..10c878a92745 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureControllerTest.java @@ -92,14 +92,16 @@ public class ScrollCaptureControllerTest extends SysuiTestCase { // Each tile is cropped to the visible page size, which is inset 5px from the TOP // requested result // 0, 50 5, 50 - // -45, 5 -40, 5 <-- clear previous / top - // 5, 55 5, 55 (not cropped, target is positioned fully within visible range) - // 55, 105 55, 105 - // 105, 155 105, 155 - // 155, 205 155, 205 <-- bottom - - assertEquals("top", -40, screenshot.getTop()); - assertEquals("bottom", 205, screenshot.getBottom()); + // -45, 5 -40, 5 + // -90, -40 -85, -40 <-- clear previous / top + // -40, 10 -40, 10 (not cropped, target is positioned fully within visible range) + // 10, 60 10, 60 + // 60, 110 60, 110 + // 110, 160 110, 160 + // 160, 210 160, 210 <-- bottom + + assertEquals("top", -85, screenshot.getTop()); + assertEquals("bottom", 210, screenshot.getBottom()); } @Test @@ -119,13 +121,14 @@ public class ScrollCaptureControllerTest extends SysuiTestCase { // requested result // 0, 50 0, 50 // not cropped, positioned within visible range // -50, 0 -50, 0 <-- clear previous/reverse - // 0, 50 - 0, 45 // target now positioned at page bottom, bottom cropped + // 0, 50 0, 45 // target now positioned at page bottom, bottom cropped // 45, 95, 45, 90 // 90, 140, 140, 135 - // 135, 185 185, 180 <-- bottom + // 135, 185 185, 180 + // 180, 230 180, 225 <-- bottom assertEquals("top", -50, screenshot.getTop()); - assertEquals("bottom", 180, screenshot.getBottom()); + assertEquals("bottom", 225, screenshot.getBottom()); } @Test @@ -265,7 +268,8 @@ public class ScrollCaptureControllerTest extends SysuiTestCase { mLocalVisibleBottom = mPageHeight; } Session session = new FakeSession(mPageHeight, mMaxPages, mTileHeight, - mLocalVisibleTop, mLocalVisibleBottom, mAvailableTop, mAvailableBottom); + mLocalVisibleTop, mLocalVisibleBottom, mAvailableTop, mAvailableBottom, + /* maxTiles */ 30); ScrollCaptureClient client = mock(ScrollCaptureClient.class); when(client.start(/* response */ any(), /* maxPages */ anyFloat())) .thenReturn(immediateFuture(session)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt index 7c7d2dc16c03..2b44d8bbd364 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt @@ -17,6 +17,7 @@ package com.android.systemui.statusbar import android.content.res.Resources +import android.view.CrossWindowBlurListeners import android.view.SurfaceControl import android.view.ViewRootImpl import androidx.test.filters.SmallTest @@ -37,11 +38,13 @@ class BlurUtilsTest : SysuiTestCase() { @Mock lateinit var resources: Resources @Mock lateinit var dumpManager: DumpManager @Mock lateinit var transaction: SurfaceControl.Transaction + @Mock lateinit var corssWindowBlurListeners: CrossWindowBlurListeners lateinit var blurUtils: BlurUtils @Before fun setup() { MockitoAnnotations.initMocks(this) + `when`(corssWindowBlurListeners.isCrossWindowBlurEnabled).thenReturn(true) blurUtils = TestableBlurUtils() } @@ -71,7 +74,7 @@ class BlurUtilsTest : SysuiTestCase() { verify(transaction).apply() } - inner class TestableBlurUtils() : BlurUtils(resources, dumpManager) { + inner class TestableBlurUtils() : BlurUtils(resources, corssWindowBlurListeners, dumpManager) { override fun supportsBlursOnWindows(): Boolean { return true } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java index 35c92b6e4941..8e949e7d1e37 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java @@ -161,7 +161,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase { String mimeType = "image/jpeg"; String text = "image inserted"; StatusBarNotification newSbn = - mRemoteInputManager.rebuildNotificationWithRemoteInput( + mRemoteInputManager.rebuildNotificationWithRemoteInputInserted( mEntry, text, false, mimeType, uri); RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() .extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); @@ -174,7 +174,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase { @Test public void testRebuildWithRemoteInput_noExistingInputNoSpinner() { StatusBarNotification newSbn = - mRemoteInputManager.rebuildNotificationWithRemoteInput( + mRemoteInputManager.rebuildNotificationWithRemoteInputInserted( mEntry, "A Reply", false, null, null); RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() .extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); @@ -189,7 +189,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase { @Test public void testRebuildWithRemoteInput_noExistingInputWithSpinner() { StatusBarNotification newSbn = - mRemoteInputManager.rebuildNotificationWithRemoteInput( + mRemoteInputManager.rebuildNotificationWithRemoteInputInserted( mEntry, "A Reply", true, null, null); RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() .extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); @@ -205,14 +205,14 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase { public void testRebuildWithRemoteInput_withExistingInput() { // Setup a notification entry with 1 remote input. StatusBarNotification newSbn = - mRemoteInputManager.rebuildNotificationWithRemoteInput( + mRemoteInputManager.rebuildNotificationWithRemoteInputInserted( mEntry, "A Reply", false, null, null); NotificationEntry entry = new NotificationEntryBuilder() .setSbn(newSbn) .build(); // Try rebuilding to add another reply. - newSbn = mRemoteInputManager.rebuildNotificationWithRemoteInput( + newSbn = mRemoteInputManager.rebuildNotificationWithRemoteInputInserted( entry, "Reply 2", true, null, null); RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() .extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); @@ -228,14 +228,14 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase { String mimeType = "image/jpeg"; String text = "image inserted"; StatusBarNotification newSbn = - mRemoteInputManager.rebuildNotificationWithRemoteInput( + mRemoteInputManager.rebuildNotificationWithRemoteInputInserted( mEntry, text, false, mimeType, uri); NotificationEntry entry = new NotificationEntryBuilder() .setSbn(newSbn) .build(); // Try rebuilding to add another reply. - newSbn = mRemoteInputManager.rebuildNotificationWithRemoteInput( + newSbn = mRemoteInputManager.rebuildNotificationWithRemoteInputInserted( entry, "Reply 2", true, null, null); RemoteInputHistoryItem[] messages = (RemoteInputHistoryItem[]) newSbn.getNotification() .extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt index 61c3835a88d2..d6c27978e61e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt @@ -47,6 +47,7 @@ import org.mockito.Mockito.anyString import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.doThrow import org.mockito.Mockito.never +import org.mockito.Mockito.reset import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.junit.MockitoJUnit @@ -70,7 +71,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { @Mock private lateinit var windowToken: IBinder @Mock private lateinit var shadeSpring: NotificationShadeDepthController.DepthAnimation @Mock private lateinit var shadeAnimation: NotificationShadeDepthController.DepthAnimation - @Mock private lateinit var globalActionsSpring: NotificationShadeDepthController.DepthAnimation + @Mock private lateinit var brightnessSpring: NotificationShadeDepthController.DepthAnimation @Mock private lateinit var listener: NotificationShadeDepthController.DepthListener @Mock private lateinit var dozeParameters: DozeParameters @Captor private lateinit var scrimVisibilityCaptor: ArgumentCaptor<Consumer<Int>> @@ -90,7 +91,11 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { `when`(blurUtils.blurRadiusOfRatio(anyFloat())).then { answer -> (answer.arguments[0] as Float * maxBlur).toInt() } - `when`(blurUtils.minBlurRadius).thenReturn(0) + `when`(blurUtils.ratioOfBlurRadius(anyInt())).then { answer -> + answer.arguments[0] as Int / maxBlur.toFloat() + } + `when`(blurUtils.supportsBlursOnWindows()).thenReturn(true) + `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur) `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur) notificationShadeDepthController = NotificationShadeDepthController( @@ -99,7 +104,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { notificationShadeWindowController, dozeParameters, dumpManager) notificationShadeDepthController.shadeSpring = shadeSpring notificationShadeDepthController.shadeAnimation = shadeAnimation - notificationShadeDepthController.globalActionsSpring = globalActionsSpring + notificationShadeDepthController.brightnessMirrorSpring = brightnessSpring notificationShadeDepthController.root = root val captor = ArgumentCaptor.forClass(StatusBarStateController.StateListener::class.java) @@ -191,24 +196,21 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { } @Test - fun updateGlobalDialogVisibility_animatesBlur() { - notificationShadeDepthController.updateGlobalDialogVisibility(0.5f, root) - verify(globalActionsSpring).animateTo(eq(maxBlur / 2), eq(root)) - } - - @Test - fun updateGlobalDialogVisibility_appliesBlur_withoutHomeControls() { - `when`(globalActionsSpring.radius).thenReturn(maxBlur) - notificationShadeDepthController.updateBlurCallback.doFrame(0) - verify(blurUtils).applyBlur(any(), eq(maxBlur), eq(false)) - } + fun setFullShadeTransition_appliesBlur_onlyIfSupported() { + reset(blurUtils) + `when`(blurUtils.blurRadiusOfRatio(anyFloat())).then { answer -> + (answer.arguments[0] as Float * maxBlur).toInt() + } + `when`(blurUtils.ratioOfBlurRadius(anyInt())).then { answer -> + answer.arguments[0] as Int / maxBlur.toFloat() + } + `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur) + `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur) - @Test - fun updateGlobalDialogVisibility_appliesBlur_unlessHomeControls() { - notificationShadeDepthController.showingHomeControls = true - `when`(globalActionsSpring.radius).thenReturn(maxBlur) + notificationShadeDepthController.transitionToFullShadeProgress = 1f notificationShadeDepthController.updateBlurCallback.doFrame(0) verify(blurUtils).applyBlur(any(), eq(0), eq(false)) + verify(wallpaperManager).setWallpaperZoomOut(any(), eq(1f)) } @Test @@ -239,7 +241,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { fun updateBlurCallback_ignoreShadeBlurUntilHidden_overridesZoom() { `when`(shadeSpring.radius).thenReturn(maxBlur) `when`(shadeAnimation.radius).thenReturn(maxBlur) - notificationShadeDepthController.ignoreShadeBlurUntilHidden = true + notificationShadeDepthController.blursDisabledForAppLaunch = true notificationShadeDepthController.updateBlurCallback.doFrame(0) verify(blurUtils).applyBlur(any(), eq(0), eq(false)) } @@ -261,16 +263,42 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() { @Test fun ignoreShadeBlurUntilHidden_schedulesFrame() { - notificationShadeDepthController.ignoreShadeBlurUntilHidden = true + notificationShadeDepthController.blursDisabledForAppLaunch = true verify(choreographer).postFrameCallback( eq(notificationShadeDepthController.updateBlurCallback)) } @Test + fun brightnessMirrorVisible_whenVisible() { + notificationShadeDepthController.brightnessMirrorVisible = true + verify(brightnessSpring).animateTo(eq(maxBlur), any()) + } + + @Test + fun brightnessMirrorVisible_whenHidden() { + notificationShadeDepthController.brightnessMirrorVisible = false + verify(brightnessSpring).animateTo(eq(0), any()) + } + + @Test + fun brightnessMirror_hidesShadeBlur() { + // Brightness mirror is fully visible + `when`(brightnessSpring.ratio).thenReturn(1f) + // And shade is blurred + `when`(shadeSpring.radius).thenReturn(maxBlur) + `when`(shadeAnimation.radius).thenReturn(maxBlur) + + notificationShadeDepthController.updateBlurCallback.doFrame(0) + verify(notificationShadeWindowController).setBackgroundBlurRadius(eq(0)) + verify(wallpaperManager).setWallpaperZoomOut(any(), eq(1f)) + verify(blurUtils).applyBlur(eq(viewRootImpl), eq(0), eq(false)) + } + + @Test fun ignoreShadeBlurUntilHidden_whennNull_ignoresIfShadeHasNoBlur() { `when`(shadeSpring.radius).thenReturn(0) `when`(shadeAnimation.radius).thenReturn(0) - notificationShadeDepthController.ignoreShadeBlurUntilHidden = true + notificationShadeDepthController.blursDisabledForAppLaunch = true verify(shadeSpring, never()).animateTo(anyInt(), any()) verify(shadeAnimation, never()).animateTo(anyInt(), any()) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java index 5f8eb9e06c68..25aa93aa37c2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java @@ -66,6 +66,8 @@ public class NotificationIconAreaControllerTest extends SysuiTestCase { DarkIconDispatcher mDarkIconDispatcher; @Mock StatusBarWindowController mStatusBarWindowController; + @Mock + UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; private NotificationIconAreaController mController; @Mock private Bubbles mBubbles; @@ -87,7 +89,8 @@ public class NotificationIconAreaControllerTest extends SysuiTestCase { Optional.of(mBubbles), mDemoModeController, mDarkIconDispatcher, - mStatusBarWindowController); + mStatusBarWindowController, + mUnlockedScreenOffAnimationController); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index 2d51683c8ae5..2693b949f6ff 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -26,9 +26,12 @@ import static com.android.systemui.statusbar.notification.ViewGroupFadeHelper.re import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -37,9 +40,13 @@ import static org.mockito.Mockito.when; import android.annotation.IdRes; import android.app.ActivityManager; +import android.content.ContentResolver; import android.content.res.Configuration; import android.content.res.Resources; +import android.database.ContentObserver; import android.hardware.biometrics.BiometricSourceType; +import android.os.Handler; +import android.os.Looper; import android.os.PowerManager; import android.os.UserManager; import android.testing.AndroidTestingRunner; @@ -50,6 +57,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewPropertyAnimator; +import android.view.ViewStub; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; @@ -60,6 +68,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.testing.UiEventLoggerFake; +import com.android.internal.util.CollectionUtils; import com.android.internal.util.LatencyTracker; import com.android.keyguard.KeyguardClockSwitch; import com.android.keyguard.KeyguardClockSwitchController; @@ -140,6 +149,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { private KeyguardBottomAreaView mKeyguardBottomArea; @Mock private KeyguardBottomAreaView mQsFrame; + private KeyguardStatusView mKeyguardStatusView; @Mock private ViewGroup mBigClockContainer; @Mock @@ -153,6 +163,10 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private KeyguardStatusBarView mKeyguardStatusBar; @Mock + private View mUserSwitcherView; + @Mock + private ViewStub mUserSwitcherStubView; + @Mock private HeadsUpTouchHelper.Callback mHeadsUpCallback; @Mock private PanelBar mPanelBar; @@ -204,7 +218,6 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private KeyguardClockSwitch mKeyguardClockSwitch; private PanelViewController.TouchHandler mTouchHandler; - @Mock private ConfigurationController mConfigurationController; @Mock private MediaHierarchyManager mMediaHiearchyManager; @@ -265,6 +278,8 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private SecureSettings mSecureSettings; @Mock + private ContentResolver mContentResolver; + @Mock private TapAgainViewController mTapAgainViewController; @Mock private KeyguardIndicationController mKeyguardIndicationController; @@ -287,6 +302,9 @@ public class NotificationPanelViewTest extends SysuiTestCase { MockitoAnnotations.initMocks(this); mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger); + mKeyguardStatusView = new KeyguardStatusView(mContext); + mKeyguardStatusView.setId(R.id.keyguard_status_view); + when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false); when(mHeadsUpCallback.getContext()).thenReturn(mContext); when(mView.getResources()).thenReturn(mResources); @@ -301,6 +319,9 @@ public class NotificationPanelViewTest extends SysuiTestCase { when(mResources.getDimensionPixelSize(R.dimen.notification_panel_width)).thenReturn(400); when(mView.getContext()).thenReturn(getContext()); when(mView.findViewById(R.id.keyguard_header)).thenReturn(mKeyguardStatusBar); + when(mView.findViewById(R.id.keyguard_user_switcher_view)).thenReturn(mUserSwitcherView); + when(mView.findViewById(R.id.keyguard_user_switcher_stub)).thenReturn( + mUserSwitcherStubView); when(mView.findViewById(R.id.keyguard_clock_container)).thenReturn(mKeyguardClockSwitch); when(mView.findViewById(R.id.notification_stack_scroller)) .thenReturn(mNotificationStackScrollLayout); @@ -320,7 +341,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mNotificationContainerParent = new NotificationsQuickSettingsContainer(getContext(), null); mNotificationContainerParent.addView(newViewWithId(R.id.qs_frame)); mNotificationContainerParent.addView(newViewWithId(R.id.notification_stack_scroller)); - mNotificationContainerParent.addView(newViewWithId(R.id.keyguard_status_view)); + mNotificationContainerParent.addView(mKeyguardStatusView); when(mView.findViewById(R.id.notification_container_parent)) .thenReturn(mNotificationContainerParent); when(mFragmentService.getFragmentHostManager(mView)).thenReturn(mFragmentHostManager); @@ -348,6 +369,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mFalsingManager, mLockscreenShadeTransitionController, new FalsingCollectorFake()); + mConfigurationController = new ConfigurationControllerImpl(mContext); when(mKeyguardStatusViewComponentFactory.build(any())) .thenReturn(mKeyguardStatusViewComponent); when(mKeyguardStatusViewComponent.getKeyguardClockSwitchController()) @@ -358,10 +380,16 @@ public class NotificationPanelViewTest extends SysuiTestCase { .thenReturn(mKeyguardStatusBarViewComponent); when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController()) .thenReturn(mKeyguardStatusBarViewController); + when(mLayoutInflater.inflate(eq(R.layout.keyguard_status_view), any(), anyBoolean())) + .thenReturn(mKeyguardStatusView); + when(mLayoutInflater.inflate(eq(R.layout.keyguard_bottom_area), any(), anyBoolean())) + .thenReturn(mKeyguardBottomArea); reset(mView); + mNotificationPanelViewController = new NotificationPanelViewController(mView, mResources, + new Handler(Looper.getMainLooper()), mLayoutInflater, coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController, mFalsingManager, new FalsingCollectorFake(), @@ -395,6 +423,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mTapAgainViewController, mNavigationModeController, mFragmentService, + mContentResolver, mQuickAccessWalletController, new FakeExecutor(new FakeSystemClock()), mSecureSettings, @@ -549,6 +578,38 @@ public class NotificationPanelViewTest extends SysuiTestCase { } @Test + public void testDisableUserSwitcherAfterEnabling_returnsViewStubToTheViewHierarchy() { + givenViewAttached(); + when(mResources.getBoolean( + com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true); + updateMultiUserSetting(true); + clearInvocations(mView); + + updateMultiUserSetting(false); + + ArgumentCaptor<View> captor = ArgumentCaptor.forClass(View.class); + verify(mView, atLeastOnce()).addView(captor.capture(), anyInt()); + final View userSwitcherStub = CollectionUtils.find(captor.getAllValues(), + view -> view.getId() == R.id.keyguard_user_switcher_stub); + assertThat(userSwitcherStub).isNotNull(); + assertThat(userSwitcherStub).isInstanceOf(ViewStub.class); + } + + @Test + public void testChangeSmallestScreenWidthAndUserSwitchEnabled_inflatesUserSwitchView() { + givenViewAttached(); + when(mView.findViewById(R.id.keyguard_user_switcher_view)).thenReturn(null); + updateSmallestScreenWidth(300); + when(mResources.getBoolean( + com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true); + when(mUserManager.isUserSwitcherEnabled()).thenReturn(true); + + updateSmallestScreenWidth(800); + + verify(mUserSwitcherStubView).inflate(); + } + + @Test public void testSplitShadeLayout_isAlignedToGuideline() { enableSplitShade(); @@ -682,6 +743,12 @@ public class NotificationPanelViewTest extends SysuiTestCase { return mFalsingManager.getTapListeners().get(0); } + private void givenViewAttached() { + for (View.OnAttachStateChangeListener listener : mOnAttachStateChangeListeners) { + listener.onViewAttachedToWindow(mView); + } + } + private View newViewWithId(int id) { View view = new View(mContext); view.setId(id); @@ -704,6 +771,21 @@ public class NotificationPanelViewTest extends SysuiTestCase { mNotificationPanelViewController.updateResources(); } + private void updateMultiUserSetting(boolean enabled) { + when(mUserManager.isUserSwitcherEnabled()).thenReturn(enabled); + final ArgumentCaptor<ContentObserver> observerCaptor = + ArgumentCaptor.forClass(ContentObserver.class); + verify(mContentResolver) + .registerContentObserver(any(), anyBoolean(), observerCaptor.capture()); + observerCaptor.getValue().onChange(/* selfChange */ false); + } + + private void updateSmallestScreenWidth(int smallestScreenWidthDp) { + Configuration configuration = new Configuration(); + configuration.smallestScreenWidthDp = smallestScreenWidthDp; + mConfigurationController.onConfigurationChanged(configuration); + } + private void onTouchEvent(MotionEvent ev) { mTouchHandler.onTouch(mView, ev); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java index 9fe47eceff1b..b03712c2d997 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java @@ -72,6 +72,7 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { @Mock ColorExtractor.GradientColors mGradientColors; @Mock private DumpManager mDumpManager; @Mock private KeyguardStateController mKeyguardStateController; + @Mock private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; @Captor private ArgumentCaptor<WindowManager.LayoutParams> mLayoutParameters; private NotificationShadeWindowControllerImpl mNotificationShadeWindowController; @@ -85,7 +86,8 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext, mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController, mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController, - mColorExtractor, mDumpManager, mKeyguardStateController); + mColorExtractor, mDumpManager, mKeyguardStateController, + mUnlockedScreenOffAnimationController); mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView); mNotificationShadeWindowController.attach(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt index ca3cff98b78c..c81d46898ff9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt @@ -40,23 +40,24 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener import com.android.systemui.util.concurrency.FakeExecutor -import com.android.systemui.util.time.FakeSystemClock import com.android.systemui.util.mockito.any +import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat +import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor -import org.mockito.ArgumentMatchers.* +import org.mockito.ArgumentMatchers.anyBoolean +import org.mockito.ArgumentMatchers.nullable import org.mockito.Mock import org.mockito.Mockito.`when` import org.mockito.Mockito.eq import org.mockito.Mockito.mock import org.mockito.Mockito.never +import org.mockito.Mockito.reset import org.mockito.Mockito.times import org.mockito.Mockito.verify -import org.mockito.Mockito.reset - import org.mockito.MockitoAnnotations private const val CALL_UID = 900 @@ -117,6 +118,11 @@ class OngoingCallControllerTest : SysuiTestCase() { .thenReturn(PROC_STATE_INVISIBLE) } + @After + fun tearDown() { + controller.tearDownChipView() + } + @Test fun onEntryUpdated_isOngoingCallNotif_listenerNotified() { notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry()) @@ -140,6 +146,13 @@ class OngoingCallControllerTest : SysuiTestCase() { .onOngoingCallStateChanged(anyBoolean()) } + /** Regression test for b/191472854. */ + @Test + fun onEntryUpdated_notifHasNullContentIntent_noCrash() { + notifCollectionListener.onEntryUpdated( + createCallNotifEntry(ongoingCallStyle, nullContentIntent = true)) + } + /** * If a call notification is never added before #onEntryRemoved is called, then the listener * should never be notified. @@ -357,14 +370,22 @@ class OngoingCallControllerTest : SysuiTestCase() { private fun createScreeningCallNotifEntry() = createCallNotifEntry(screeningCallStyle) - private fun createCallNotifEntry(callStyle: Notification.CallStyle): NotificationEntry { + private fun createCallNotifEntry( + callStyle: Notification.CallStyle, + nullContentIntent: Boolean = false + ): NotificationEntry { val notificationEntryBuilder = NotificationEntryBuilder() notificationEntryBuilder.modifyNotification(context).style = callStyle - - val contentIntent = mock(PendingIntent::class.java) - `when`(contentIntent.intent).thenReturn(mock(Intent::class.java)) - notificationEntryBuilder.modifyNotification(context).setContentIntent(contentIntent) notificationEntryBuilder.setUid(CALL_UID) + + if (nullContentIntent) { + notificationEntryBuilder.modifyNotification(context).setContentIntent(null) + } else { + val contentIntent = mock(PendingIntent::class.java) + `when`(contentIntent.intent).thenReturn(mock(Intent::class.java)) + notificationEntryBuilder.modifyNotification(context).setContentIntent(contentIntent) + } + return notificationEntryBuilder.build() } diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java index 208790b24d8a..1a24c113a0df 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java @@ -415,13 +415,6 @@ public class ThemeOverlayControllerTest extends SysuiTestCase { } @Test - public void onUserSwitch_setsTheme() { - mBroadcastReceiver.getValue().onReceive(null, - new Intent(Intent.ACTION_USER_STARTED)); - verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any()); - } - - @Test public void onProfileAdded_setsTheme() { mBroadcastReceiver.getValue().onReceive(null, new Intent(Intent.ACTION_MANAGED_PROFILE_ADDED)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeSensorManager.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeSensorManager.java index 27b225e3c4fa..6e73827fedfb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeSensorManager.java +++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/FakeSensorManager.java @@ -60,7 +60,7 @@ public class FakeSensorManager extends SensorManager { public FakeSensorManager(Context context) throws Exception { Sensor proxSensor = context.getSystemService(SensorManager.class) - .getDefaultSensor(Sensor.TYPE_PROXIMITY); + .getDefaultSensor(Sensor.TYPE_PROXIMITY, true); if (proxSensor == null) { // No prox? Let's create a fake one! proxSensor = diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ThresholdSensorImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ThresholdSensorImplTest.java index 12765679a7f3..125063a7adc4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ThresholdSensorImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ThresholdSensorImplTest.java @@ -16,10 +16,15 @@ package com.android.systemui.util.sensors; +import static android.hardware.Sensor.TYPE_ALL; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import android.hardware.Sensor; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; @@ -33,6 +38,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.List; + @SmallTest @RunWith(AndroidTestingRunner.class) public class ThresholdSensorImplTest extends SysuiTestCase { @@ -60,6 +67,79 @@ public class ThresholdSensorImplTest extends SysuiTestCase { } @Test + public void testRegistersWakeUpProxSensor_givenWakeUpExistsAfterNonWakeup() { + // GIVEN sensor manager with two prox sensors (one non-wakeup, one wakeup) + final String sensorTypeProx = "prox"; + AsyncSensorManager mockSensorManager = mock(AsyncSensorManager.class); + + Sensor mockNonWakeupProx = mock(Sensor.class); + when(mockNonWakeupProx.isWakeUpSensor()).thenReturn(false); + when(mockNonWakeupProx.getStringType()).thenReturn(sensorTypeProx); + + Sensor mockWakeupProx = mock(Sensor.class); + when(mockWakeupProx.isWakeUpSensor()).thenReturn(true); + when(mockWakeupProx.getStringType()).thenReturn(sensorTypeProx); + + when(mockSensorManager.getSensorList(TYPE_ALL)).thenReturn( + List.of(mockNonWakeupProx, mockWakeupProx)); + + // WHEN we build a threshold sensor by type + ThresholdSensorImpl.Builder thresholdSensorBuilder = new ThresholdSensorImpl.Builder( + null, mockSensorManager, new FakeExecution()); + Sensor proxSensor = thresholdSensorBuilder.findSensorByType(sensorTypeProx, true); + + // THEN the prox sensor used is the wakeup sensor + assertEquals(mockWakeupProx, proxSensor); + } + + @Test + public void testRegistersWakeUpProxSensor_givenNonWakeUpExistsAfterWakeup() { + // GIVEN sensor manager with two prox sensors (one wakeup, one non-wakeup) + final String sensorTypeProx = "prox"; + AsyncSensorManager mockSensorManager = mock(AsyncSensorManager.class); + + Sensor mockNonWakeupProx = mock(Sensor.class); + when(mockNonWakeupProx.isWakeUpSensor()).thenReturn(false); + when(mockNonWakeupProx.getStringType()).thenReturn(sensorTypeProx); + + Sensor mockWakeupProx = mock(Sensor.class); + when(mockWakeupProx.isWakeUpSensor()).thenReturn(true); + when(mockWakeupProx.getStringType()).thenReturn(sensorTypeProx); + + when(mockSensorManager.getSensorList(TYPE_ALL)).thenReturn( + List.of(mockWakeupProx, mockNonWakeupProx)); + + // WHEN we build a threshold sensor by type + ThresholdSensorImpl.Builder thresholdSensorBuilder = new ThresholdSensorImpl.Builder( + null, mockSensorManager, new FakeExecution()); + Sensor proxSensor = thresholdSensorBuilder.findSensorByType(sensorTypeProx, true); + + // THEN the prox sensor used is the wakeup sensor + assertEquals(mockWakeupProx, proxSensor); + } + + @Test + public void testRegistersNonWakeUpProxSensor_givenNonWakeUpOnly() { + // GIVEN sensor manager with one non-wakeup prox sensor + final String sensorTypeProx = "prox"; + AsyncSensorManager mockSensorManager = mock(AsyncSensorManager.class); + + Sensor mockNonWakeupProx = mock(Sensor.class); + when(mockNonWakeupProx.isWakeUpSensor()).thenReturn(false); + when(mockNonWakeupProx.getStringType()).thenReturn(sensorTypeProx); + + when(mockSensorManager.getSensorList(TYPE_ALL)).thenReturn(List.of(mockNonWakeupProx)); + + // WHEN we build a threshold sensor by type + ThresholdSensorImpl.Builder thresholdSensorBuilder = new ThresholdSensorImpl.Builder( + null, mockSensorManager, new FakeExecution()); + Sensor proxSensor = thresholdSensorBuilder.findSensorByType(sensorTypeProx, true); + + // THEN the prox sensor used is the one available (non-wakeup) + assertEquals(mockNonWakeupProx, proxSensor); + } + + @Test public void testSingleListener() { TestableListener listener = new TestableListener(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java index 3640bcd64c14..d5348dc39832 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java +++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeSecurityController.java @@ -44,6 +44,11 @@ public class FakeSecurityController extends BaseLeakChecker<SecurityControllerCa } @Override + public boolean isWorkProfileOn() { + return false; + } + + @Override public boolean isProfileOwnerOfOrganizationOwnedDevice() { return false; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index 9fa35f8bd9f6..eb9206daec13 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -98,6 +98,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationShadeWindowControllerImpl; import com.android.systemui.statusbar.phone.NotificationShadeWindowView; import com.android.systemui.statusbar.phone.ShadeController; +import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.HeadsUpManager; @@ -233,6 +234,8 @@ public class BubblesTest extends SysuiTestCase { private ShellTaskOrganizer mShellTaskOrganizer; @Mock private KeyguardStateController mKeyguardStateController; + @Mock + private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; private TestableBubblePositioner mPositioner; @@ -255,7 +258,8 @@ public class BubblesTest extends SysuiTestCase { mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext, mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController, mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController, - mColorExtractor, mDumpManager, mKeyguardStateController); + mColorExtractor, mDumpManager, mKeyguardStateController, + mUnlockedScreenOffAnimationController); mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView); mNotificationShadeWindowController.attach(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java index 55cc8bb1780d..24a5b3a42bb4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java @@ -81,6 +81,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationShadeWindowControllerImpl; import com.android.systemui.statusbar.phone.NotificationShadeWindowView; import com.android.systemui.statusbar.phone.ShadeController; +import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.HeadsUpManager; @@ -197,6 +198,8 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase { private ShellTaskOrganizer mShellTaskOrganizer; @Mock private KeyguardStateController mKeyguardStateController; + @Mock + private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; private TestableBubblePositioner mPositioner; @@ -218,7 +221,8 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase { mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext, mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController, mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController, - mColorExtractor, mDumpManager, mKeyguardStateController); + mColorExtractor, mDumpManager, mKeyguardStateController, + mUnlockedScreenOffAnimationController); mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView); mNotificationShadeWindowController.attach(); diff --git a/packages/services/CameraExtensionsProxy/AndroidManifest.xml b/packages/services/CameraExtensionsProxy/AndroidManifest.xml index e5f460e593b3..d35689413749 100644 --- a/packages/services/CameraExtensionsProxy/AndroidManifest.xml +++ b/packages/services/CameraExtensionsProxy/AndroidManifest.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.camera"> + package="com.android.cameraextensions"> <application android:label="@string/app_name" diff --git a/packages/services/CameraExtensionsProxy/src/com/android/camera/CameraExtensionsProxyService.java b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java index 7b9ca2ddc345..ab3643c2a911 100644 --- a/packages/services/CameraExtensionsProxy/src/com/android/camera/CameraExtensionsProxyService.java +++ b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java @@ -13,11 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.camera; +package com.android.cameraextensions; import android.app.Service; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.graphics.GraphicBuffer; import android.graphics.Rect; import android.hardware.camera2.CameraAccessException; @@ -42,6 +43,7 @@ import android.hardware.camera2.extension.IRequestProcessorImpl; import android.hardware.camera2.extension.IRequestUpdateProcessorImpl; import android.hardware.camera2.extension.IImageCaptureExtenderImpl; import android.hardware.camera2.extension.IImageProcessorImpl; +import android.hardware.camera2.extension.IInitializeSessionCallback; import android.hardware.camera2.extension.ISessionProcessorImpl; import android.hardware.camera2.extension.LatencyRange; import android.hardware.camera2.extension.OutputConfigId; @@ -57,6 +59,7 @@ import android.hardware.HardwareBuffer; import android.hardware.camera2.impl.PhysicalCaptureResultInfo; import android.media.Image; import android.media.ImageReader; +import android.os.Binder; import android.os.ConditionVariable; import android.os.Handler; import android.os.HandlerExecutor; @@ -176,6 +179,7 @@ public class CameraExtensionsProxyService extends Service { private long mCurrentClientCount = 0; private ArraySet<Long> mActiveClients = new ArraySet<>(); + private IInitializeSessionCallback mInitializeCb = null; // Singleton instance private static final CameraExtensionManagerGlobal GLOBAL_CAMERA_MANAGER = @@ -328,6 +332,40 @@ public class CameraExtensionsProxyService extends Service { } } } + + private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() { + @Override + public void binderDied() { + synchronized (mLock) { + mInitializeCb = null; + } + } + }; + + public boolean initializeSession(IInitializeSessionCallback cb) { + synchronized (mLock) { + if (mInitializeCb == null) { + mInitializeCb = cb; + try { + mInitializeCb.asBinder().linkToDeath(mDeathRecipient, 0); + } catch (RemoteException e) { + e.printStackTrace(); + } + } else { + return false; + } + } + return true; + } + + public void releaseSession() { + synchronized (mLock) { + if (mInitializeCb != null) { + mInitializeCb.asBinder().unlinkToDeath(mDeathRecipient, 0); + mInitializeCb = null; + } + } + } } /** @@ -353,6 +391,26 @@ public class CameraExtensionsProxyService extends Service { /** * @hide */ + public static boolean initializeSession(IInitializeSessionCallback cb) { + if (!EXTENSIONS_PRESENT) { + return false; + } + return CameraExtensionManagerGlobal.get().initializeSession(cb); + } + + /** + * @hide + */ + public static void releaseSession() { + if (!EXTENSIONS_PRESENT) { + return; + } + CameraExtensionManagerGlobal.get().releaseSession(); + } + + /** + * @hide + */ public static Pair<PreviewExtenderImpl, ImageCaptureExtenderImpl> initializeExtension( int extensionType) { switch (extensionType) { @@ -538,6 +596,39 @@ public class CameraExtensionsProxyService extends Service { CameraExtensionsProxyService.unregisterClient(clientId); } + private boolean checkCameraPermission() { + int allowed = CameraExtensionsProxyService.this.checkPermission( + android.Manifest.permission.CAMERA, Binder.getCallingPid(), + Binder.getCallingUid()); + return (PackageManager.PERMISSION_GRANTED == allowed); + } + + @Override + public void initializeSession(IInitializeSessionCallback cb) { + try { + if (!checkCameraPermission()) { + Log.i(TAG, "Camera permission required for initializing capture session"); + cb.onFailure(); + return; + } + + if (CameraExtensionsProxyService.initializeSession(cb)) { + cb.onSuccess(); + } else { + cb.onFailure(); + } + } catch (RemoteException e) { + Log.e(TAG, "Client doesn't respond!"); + } + } + + @Override + public void releaseSession() { + if (checkCameraPermission()) { + CameraExtensionsProxyService.releaseSession(); + } + } + @Override public boolean advancedExtensionsSupported() { return ADVANCED_API_SUPPORTED; diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index acbf4875ae8d..5aec6aa99c12 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -409,6 +409,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku // If the set of providers has been modified, notify each active AppWidgetHost scheduleNotifyGroupHostsForProvidersChangedLocked(userId); + // Possibly notify any new components of widget id changes + mBackupRestoreController.widgetComponentsChanged(userId); } } } @@ -2471,8 +2473,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } @Override - public void restoreStarting(int userId) { - mBackupRestoreController.restoreStarting(userId); + public void systemRestoreStarting(int userId) { + mBackupRestoreController.systemRestoreStarting(userId); } @Override @@ -2481,8 +2483,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } @Override - public void restoreFinished(int userId) { - mBackupRestoreController.restoreFinished(userId); + public void systemRestoreFinished(int userId) { + mBackupRestoreController.systemRestoreFinished(userId); } @SuppressWarnings("deprecation") @@ -4272,6 +4274,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku private final HashMap<Host, ArrayList<RestoreUpdateRecord>> mUpdatesByHost = new HashMap<>(); + @GuardedBy("mLock") + private boolean mHasSystemRestoreFinished; + public List<String> getWidgetParticipants(int userId) { if (DEBUG) { Slog.i(TAG, "Getting widget participants for user: " + userId); @@ -4375,12 +4380,13 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku return stream.toByteArray(); } - public void restoreStarting(int userId) { + public void systemRestoreStarting(int userId) { if (DEBUG) { - Slog.i(TAG, "Restore starting for user: " + userId); + Slog.i(TAG, "System restore starting for user: " + userId); } synchronized (mLock) { + mHasSystemRestoreFinished = false; // We're starting a new "system" restore operation, so any widget restore // state that we see from here on is intended to replace the current // widget configuration of any/all of the affected apps. @@ -4542,26 +4548,90 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } } - // Called once following the conclusion of a restore operation. This is when we + // Called once following the conclusion of a system restore operation. This is when we // send out updates to apps involved in widget-state restore telling them about - // the new widget ID space. - public void restoreFinished(int userId) { + // the new widget ID space. Apps that are not yet installed will be notifed when they are. + public void systemRestoreFinished(int userId) { if (DEBUG) { - Slog.i(TAG, "restoreFinished for " + userId); + Slog.i(TAG, "systemRestoreFinished for " + userId); } + synchronized (mLock) { + mHasSystemRestoreFinished = true; + maybeSendWidgetRestoreBroadcastsLocked(userId); + } + } - final UserHandle userHandle = new UserHandle(userId); + // Called when widget components (hosts or providers) are added or changed. If system + // restore has completed, we use this opportunity to tell the apps to update to the new + // widget ID space. If system restore is still in progress, we delay the updates until + // the end, to allow all participants to restore their state before updating widget IDs. + public void widgetComponentsChanged(int userId) { synchronized (mLock) { - // Build the providers' broadcasts and send them off - Set<Map.Entry<Provider, ArrayList<RestoreUpdateRecord>>> providerEntries - = mUpdatesByProvider.entrySet(); - for (Map.Entry<Provider, ArrayList<RestoreUpdateRecord>> e : providerEntries) { - // For each provider there's a list of affected IDs - Provider provider = e.getKey(); + if (mHasSystemRestoreFinished) { + maybeSendWidgetRestoreBroadcastsLocked(userId); + } + } + } + + // Called following the conclusion of a restore operation and when widget components + // are added or changed. This is when we send out updates to apps involved in widget-state + // restore telling them about the new widget ID space. + @GuardedBy("mLock") + private void maybeSendWidgetRestoreBroadcastsLocked(int userId) { + if (DEBUG) { + Slog.i(TAG, "maybeSendWidgetRestoreBroadcasts for " + userId); + } + + final UserHandle userHandle = new UserHandle(userId); + // Build the providers' broadcasts and send them off + Set<Map.Entry<Provider, ArrayList<RestoreUpdateRecord>>> providerEntries + = mUpdatesByProvider.entrySet(); + for (Map.Entry<Provider, ArrayList<RestoreUpdateRecord>> e : providerEntries) { + // For each provider there's a list of affected IDs + Provider provider = e.getKey(); + if (provider.zombie) { + // Provider not installed, we can't send them broadcasts yet. + // We'll be called again when the provider is installed. + continue; + } + ArrayList<RestoreUpdateRecord> updates = e.getValue(); + final int pending = countPendingUpdates(updates); + if (DEBUG) { + Slog.i(TAG, "Provider " + provider + " pending: " + pending); + } + if (pending > 0) { + int[] oldIds = new int[pending]; + int[] newIds = new int[pending]; + final int N = updates.size(); + int nextPending = 0; + for (int i = 0; i < N; i++) { + RestoreUpdateRecord r = updates.get(i); + if (!r.notified) { + r.notified = true; + oldIds[nextPending] = r.oldId; + newIds[nextPending] = r.newId; + nextPending++; + if (DEBUG) { + Slog.i(TAG, " " + r.oldId + " => " + r.newId); + } + } + } + sendWidgetRestoreBroadcastLocked( + AppWidgetManager.ACTION_APPWIDGET_RESTORED, + provider, null, oldIds, newIds, userHandle); + } + } + + // same thing per host + Set<Map.Entry<Host, ArrayList<RestoreUpdateRecord>>> hostEntries + = mUpdatesByHost.entrySet(); + for (Map.Entry<Host, ArrayList<RestoreUpdateRecord>> e : hostEntries) { + Host host = e.getKey(); + if (host.id.uid != UNKNOWN_UID) { ArrayList<RestoreUpdateRecord> updates = e.getValue(); final int pending = countPendingUpdates(updates); if (DEBUG) { - Slog.i(TAG, "Provider " + provider + " pending: " + pending); + Slog.i(TAG, "Host " + host + " pending: " + pending); } if (pending > 0) { int[] oldIds = new int[pending]; @@ -4581,43 +4651,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } } sendWidgetRestoreBroadcastLocked( - AppWidgetManager.ACTION_APPWIDGET_RESTORED, - provider, null, oldIds, newIds, userHandle); - } - } - - // same thing per host - Set<Map.Entry<Host, ArrayList<RestoreUpdateRecord>>> hostEntries - = mUpdatesByHost.entrySet(); - for (Map.Entry<Host, ArrayList<RestoreUpdateRecord>> e : hostEntries) { - Host host = e.getKey(); - if (host.id.uid != UNKNOWN_UID) { - ArrayList<RestoreUpdateRecord> updates = e.getValue(); - final int pending = countPendingUpdates(updates); - if (DEBUG) { - Slog.i(TAG, "Host " + host + " pending: " + pending); - } - if (pending > 0) { - int[] oldIds = new int[pending]; - int[] newIds = new int[pending]; - final int N = updates.size(); - int nextPending = 0; - for (int i = 0; i < N; i++) { - RestoreUpdateRecord r = updates.get(i); - if (!r.notified) { - r.notified = true; - oldIds[nextPending] = r.oldId; - newIds[nextPending] = r.newId; - nextPending++; - if (DEBUG) { - Slog.i(TAG, " " + r.oldId + " => " + r.newId); - } - } - } - sendWidgetRestoreBroadcastLocked( - AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED, - null, host, oldIds, newIds, userHandle); - } + AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED, + null, host, oldIds, newIds, userHandle); } } } diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java index 312cde6c5152..de5f47dd5dbb 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java @@ -662,6 +662,26 @@ public final class AutofillManagerService return false; } + /** + * Requests a count of saved passwords from the current service. + * + * @return {@code true} if the request succeeded + */ + // Called by Shell command + boolean requestSavedPasswordCount(@UserIdInt int userId, @NonNull IResultReceiver receiver) { + enforceCallingPermissionForManagement(); + synchronized (mLock) { + final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); + if (service != null) { + service.requestSavedPasswordCount(receiver); + return true; + } else if (sVerbose) { + Slog.v(TAG, "requestSavedPasswordCount(): no service for " + userId); + } + } + return false; + } + private void setLoggingLevelsLocked(boolean debug, boolean verbose) { com.android.server.autofill.Helper.sDebug = debug; android.view.autofill.Helper.sDebug = debug; diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index a80efc461176..5f2d4e82883c 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -76,6 +76,7 @@ import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.internal.os.IResultReceiver; import com.android.server.LocalServices; import com.android.server.autofill.AutofillManagerService.AutofillCompatState; import com.android.server.autofill.AutofillManagerService.DisabledInfoCache; @@ -1181,6 +1182,15 @@ final class AutofillManagerServiceImpl } @GuardedBy("mLock") + void requestSavedPasswordCount(IResultReceiver receiver) { + RemoteFillService remoteService = + new RemoteFillService( + getContext(), mInfo.getServiceInfo().getComponentName(), mUserId, + /* callbacks= */ null, mMaster.isInstantServiceAllowed()); + remoteService.onSavedPasswordCountRequest(receiver); + } + + @GuardedBy("mLock") @Nullable RemoteAugmentedAutofillService getRemoteAugmentedAutofillServiceLocked() { if (mRemoteAugmentedAutofillService == null) { final String serviceName = mMaster.mAugmentedAutofillResolver.getServiceName(mUserId); diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java index 68e6290c987a..1eaa59a0871a 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java @@ -17,6 +17,7 @@ package com.android.server.autofill; import static android.service.autofill.AutofillFieldClassificationService.EXTRA_SCORES; +import static android.service.autofill.AutofillService.EXTRA_RESULT; import static com.android.server.autofill.AutofillManagerService.RECEIVER_BUNDLE_EXTRA_SESSIONS; @@ -89,6 +90,9 @@ public final class AutofillManagerServiceShellCommand extends ShellCommand { pw.println(" get bind-instant-service-allowed"); pw.println(" Gets whether binding to services provided by instant apps is allowed"); pw.println(""); + pw.println(" get saved-password-count"); + pw.println(" Gets the number of saved passwords in the current service."); + pw.println(""); pw.println(" set log_level [off | debug | verbose]"); pw.println(" Sets the Autofill log level."); pw.println(""); @@ -145,6 +149,8 @@ public final class AutofillManagerServiceShellCommand extends ShellCommand { return getBindInstantService(pw); case "default-augmented-service-enabled": return getDefaultAugmentedServiceEnabled(pw); + case "saved-password-count": + return getSavedPasswordCount(pw); default: pw.println("Invalid set: " + what); return -1; @@ -342,6 +348,25 @@ public final class AutofillManagerServiceShellCommand extends ShellCommand { return 0; } + private int getSavedPasswordCount(PrintWriter pw) { + final int userId = getNextIntArgRequired(); + CountDownLatch latch = new CountDownLatch(1); + IResultReceiver resultReceiver = new IResultReceiver.Stub() { + @Override + public void send(int resultCode, Bundle resultData) { + pw.println("resultCode=" + resultCode); + if (resultCode == 0 && resultData != null) { + pw.println("value=" + resultData.getInt(EXTRA_RESULT)); + } + latch.countDown(); + } + }; + if (mService.requestSavedPasswordCount(userId, resultReceiver)) { + waitForLatch(pw, latch); + } + return 0; + } + private int requestDestroy(PrintWriter pw) { if (!isNextArgSessions(pw)) { return -1; diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java index b0755ac836e0..94872b09cd36 100644 --- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java +++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java @@ -41,6 +41,7 @@ import android.util.Slog; import com.android.internal.infra.AbstractRemoteService; import com.android.internal.infra.ServiceConnector; +import com.android.internal.os.IResultReceiver; import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; @@ -225,6 +226,10 @@ final class RemoteFillService extends ServiceConnector.Impl<IAutoFillService> { })); } + void onSavedPasswordCountRequest(IResultReceiver receiver) { + run(service -> service.onSavedPasswordCountRequest(receiver)); + } + public void destroy() { unbind(); } diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java index 261ebe69a15e..f07bac8cd762 100644 --- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java +++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java @@ -381,7 +381,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { // If we're starting a full-system restore, set up to begin widget ID remapping if (mIsSystemRestore) { - AppWidgetBackupBridge.restoreStarting(mUserId); + AppWidgetBackupBridge.systemRestoreStarting(mUserId); } try { @@ -1133,8 +1133,10 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { restoreAgentTimeoutMillis); } - // Kick off any work that may be needed regarding app widget restores - AppWidgetBackupBridge.restoreFinished(mUserId); + if (mIsSystemRestore) { + // Kick off any work that may be needed regarding app widget restores + AppWidgetBackupBridge.systemRestoreFinished(mUserId); + } // If this was a full-system restore, record the ancestral // dataset information diff --git a/services/companion/java/com/android/server/companion/OWNERS b/services/companion/java/com/android/server/companion/OWNERS index da723b3b67da..734d8b6c5f43 100644 --- a/services/companion/java/com/android/server/companion/OWNERS +++ b/services/companion/java/com/android/server/companion/OWNERS @@ -1 +1 @@ -eugenesusla@google.com
\ No newline at end of file +include /core/java/android/companion/OWNERS
\ No newline at end of file diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java index 92996241a3a6..f7ddd2922b25 100644 --- a/services/core/java/android/content/pm/PackageManagerInternal.java +++ b/services/core/java/android/content/pm/PackageManagerInternal.java @@ -1151,6 +1151,8 @@ public abstract class PackageManagerInternal implements PackageSettingsSnapshotP /** * Deletes the OAT artifacts of a package. + * @param packageName a specific package + * @return the number of freed bytes or -1 if there was an error in the process. */ - public abstract void deleteOatArtifactsOfPackage(String packageName); + public abstract long deleteOatArtifactsOfPackage(String packageName); } diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java index f85e91a6096a..c07d6690e5a0 100644 --- a/services/core/java/com/android/server/SensorPrivacyService.java +++ b/services/core/java/com/android/server/SensorPrivacyService.java @@ -17,6 +17,8 @@ package com.android.server; import static android.Manifest.permission.MANAGE_SENSOR_PRIVACY; +import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA; +import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; import static android.app.ActivityManager.RunningServiceInfo; import static android.app.ActivityManager.RunningTaskInfo; import static android.app.ActivityManager.getCurrentUser; @@ -40,6 +42,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; +import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.ActivityTaskManager; import android.app.AppOpsManager; @@ -83,6 +86,7 @@ import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import android.telephony.emergency.EmergencyNumber; import android.text.Html; +import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; @@ -156,6 +160,7 @@ public final class SensorPrivacyService extends SystemService { private final SensorPrivacyServiceImpl mSensorPrivacyServiceImpl; private final UserManagerInternal mUserManagerInternal; private final ActivityManager mActivityManager; + private final ActivityManagerInternal mActivityManagerInternal; private final ActivityTaskManager mActivityTaskManager; private final AppOpsManager mAppOpsManager; private final AppOpsManagerInternal mAppOpsManagerInternal; @@ -177,6 +182,7 @@ public final class SensorPrivacyService extends SystemService { mAppOpsManagerInternal = getLocalService(AppOpsManagerInternal.class); mUserManagerInternal = getLocalService(UserManagerInternal.class); mActivityManager = context.getSystemService(ActivityManager.class); + mActivityManagerInternal = getLocalService(ActivityManagerInternal.class); mActivityTaskManager = context.getSystemService(ActivityTaskManager.class); mTelephonyManager = context.getSystemService(TelephonyManager.class); mSensorPrivacyServiceImpl = new SensorPrivacyServiceImpl(); @@ -427,11 +433,33 @@ public final class SensorPrivacyService extends SystemService { } } - VoiceInteractionManagerInternal voiceInteractionManagerInternal = - LocalServices.getService(VoiceInteractionManagerInternal.class); + String inputMethodComponent = Settings.Secure.getString(mContext.getContentResolver(), + Settings.Secure.DEFAULT_INPUT_METHOD); + String inputMethodPackageName = null; + if (inputMethodComponent != null) { + inputMethodPackageName = ComponentName.unflattenFromString( + inputMethodComponent).getPackageName(); + } + int capability = mActivityManagerInternal.getUidCapability(uid); + + if (sensor == MICROPHONE) { + VoiceInteractionManagerInternal voiceInteractionManagerInternal = + LocalServices.getService(VoiceInteractionManagerInternal.class); + if (voiceInteractionManagerInternal != null + && voiceInteractionManagerInternal.hasActiveSession(packageName)) { + enqueueSensorUseReminderDialogAsync(-1, user, packageName, sensor); + return; + } + + if (TextUtils.equals(packageName, inputMethodPackageName) + && (capability & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) != 0) { + enqueueSensorUseReminderDialogAsync(-1, user, packageName, sensor); + return; + } + } - if (sensor == MICROPHONE && voiceInteractionManagerInternal != null - && voiceInteractionManagerInternal.hasActiveSession(packageName)) { + if (sensor == CAMERA && TextUtils.equals(packageName, inputMethodPackageName) + && (capability & PROCESS_CAPABILITY_FOREGROUND_CAMERA) != 0) { enqueueSensorUseReminderDialogAsync(-1, user, packageName, sensor); return; } diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java index 26ecee8f21ab..70176a0fefeb 100644 --- a/services/core/java/com/android/server/VpnManagerService.java +++ b/services/core/java/com/android/server/VpnManagerService.java @@ -38,6 +38,7 @@ import android.net.VpnManager; import android.net.VpnService; import android.net.util.NetdService; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.INetworkManagementService; @@ -348,9 +349,17 @@ public class VpnManagerService extends IVpnManager.Stub { /** * Start legacy VPN, controlling native daemons as needed. Creates a * secondary thread to perform connection work, returning quickly. + * + * Legacy VPN is deprecated starting from Android S. So this API shouldn't be called if the + * initial SDK version of device is Android S+. Otherwise, UnsupportedOperationException will be + * thrown. */ + @SuppressWarnings("AndroidFrameworkCompatChange") // This is not an app-visible API. @Override public void startLegacyVpn(VpnProfile profile) { + if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.S) { + throw new UnsupportedOperationException("Legacy VPN is deprecated"); + } int user = UserHandle.getUserId(mDeps.getCallingUid()); // Note that if the caller is not system (uid >= Process.FIRST_APPLICATION_UID), // the code might not work well since getActiveNetwork might return null if the uid is diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java index 0f9a6fa2a8da..fcd049f1c494 100644 --- a/services/core/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -676,7 +676,7 @@ public class Watchdog { final UUID errorId; if (mTraceErrorLogger.isAddErrorIdEnabled()) { errorId = mTraceErrorLogger.generateErrorId(); - mTraceErrorLogger.addErrorIdToTrace(errorId); + mTraceErrorLogger.addErrorIdToTrace("system_server", errorId); } else { errorId = null; } diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 5e388d94869d..58a1ead3ed1d 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -328,23 +328,11 @@ public final class ActiveServices { * Watch for apps being put into forced app standby, so we can step their fg * services down. */ - class ForcedStandbyListener implements AppStateTracker.ForcedAppStandbyListener { + class ForcedStandbyListener implements AppStateTracker.ServiceStateListener { @Override - public void updateForceAppStandbyForUidPackage(int uid, String packageName, - boolean standby) { + public void stopForegroundServicesForUidPackage(final int uid, final String packageName) { synchronized (mAm) { - if (standby) { - stopAllForegroundServicesLocked(uid, packageName); - } - mAm.mProcessList.updateForceAppStandbyForUidPackageLocked( - uid, packageName, standby); - } - } - - @Override - public void updateForcedAppStandbyForAllApps() { - synchronized (mAm) { - mAm.mProcessList.updateForcedAppStandbyForAllAppsLocked(); + stopAllForegroundServicesLocked(uid, packageName); } } } @@ -530,7 +518,7 @@ public final class ActiveServices { void systemServicesReady() { AppStateTracker ast = LocalServices.getService(AppStateTracker.class); - ast.addForcedAppStandbyListener(new ForcedStandbyListener()); + ast.addServiceStateListener(new ForcedStandbyListener()); mAppWidgetManagerInternal = LocalServices.getService(AppWidgetManagerInternal.class); setAllowListWhileInUsePermissionInFgs(); } @@ -1976,7 +1964,7 @@ public final class ActiveServices { r.foregroundId = 0; r.foregroundNoti = null; } else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) { - r.stripForegroundServiceFlagFromNotification(); + dropFgsNotificationStateLocked(r); if ((flags & Service.STOP_FOREGROUND_DETACH) != 0) { r.foregroundId = 0; r.foregroundNoti = null; @@ -4225,9 +4213,10 @@ public final class ActiveServices { } r.isForeground = false; + r.mFgsNotificationWasDeferred = false; + dropFgsNotificationStateLocked(r); r.foregroundId = 0; r.foregroundNoti = null; - r.mFgsNotificationWasDeferred = false; resetFgsRestrictionLocked(r); // Clear start entries. @@ -4291,6 +4280,35 @@ public final class ActiveServices { smap.ensureNotStartingBackgroundLocked(r); } + private void dropFgsNotificationStateLocked(ServiceRecord r) { + // If this is the only FGS using this notification, clear its FGS flag + boolean shared = false; + final ServiceMap smap = mServiceMap.get(r.userId); + if (smap != null) { + // Is any other FGS using this notification? + final int numServices = smap.mServicesByInstanceName.size(); + for (int i = 0; i < numServices; i++) { + final ServiceRecord sr = smap.mServicesByInstanceName.valueAt(i); + if (sr == r) { + continue; + } + if (sr.isForeground + && r.foregroundId == sr.foregroundId + && r.appInfo.packageName.equals(sr.appInfo.packageName)) { + shared = true; + break; + } + } + } else { + Slog.wtf(TAG, "FGS " + r + " not found!"); + } + + // No other FGS is sharing this notification, so we're done with it + if (!shared) { + r.stripForegroundServiceFlagFromNotification(); + } + } + void removeConnectionLocked(ConnectionRecord c, ProcessRecord skipApp, ActivityServiceConnectionsHolder skipAct, boolean enqueueOomAdj) { IBinder binder = c.conn.asBinder(); @@ -6165,8 +6183,10 @@ public final class ActiveServices { && code != REASON_UID_VISIBLE; } - // TODO: remove this notification after feature development is done private void showFgsBgRestrictedNotificationLocked(ServiceRecord r) { + if (!mAm.mConstants.mFgsStartRestrictionNotificationEnabled /* default is false */) { + return; + } final Context context = mAm.mContext; final String title = "Foreground Service BG-Launch Restricted"; final String content = "App restricted: " + r.mRecentCallingPackage; diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java index 0d19efc20785..530f918833ad 100644 --- a/services/core/java/com/android/server/am/ActivityManagerConstants.java +++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java @@ -52,8 +52,7 @@ final class ActivityManagerConstants extends ContentObserver { private static final String TAG = "ActivityManagerConstants"; // Key names stored in the settings value. - static final String KEY_BACKGROUND_SETTLE_TIME = "background_settle_time"; - + private static final String KEY_BACKGROUND_SETTLE_TIME = "background_settle_time"; private static final String KEY_FGSERVICE_MIN_SHOWN_TIME = "fgservice_min_shown_time"; private static final String KEY_FGSERVICE_MIN_REPORT_TIME @@ -109,10 +108,10 @@ final class ActivityManagerConstants extends ContentObserver { static final String KEY_FG_TO_BG_FGS_GRACE_DURATION = "fg_to_bg_fgs_grace_duration"; static final String KEY_FGS_START_FOREGROUND_TIMEOUT = "fgs_start_foreground_timeout"; static final String KEY_FGS_ATOM_SAMPLE_RATE = "fgs_atom_sample_rate"; - static final String KEY_KILL_FAS_CACHED_IDLE = "kill_fas_cached_idle"; static final String KEY_FGS_ALLOW_OPT_OUT = "fgs_allow_opt_out"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 32; + private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000; private static final long DEFAULT_FGSERVICE_MIN_SHOWN_TIME = 2*1000; private static final long DEFAULT_FGSERVICE_MIN_REPORT_TIME = 3*1000; private static final long DEFAULT_FGSERVICE_SCREEN_ON_BEFORE_TIME = 1*1000; @@ -153,10 +152,6 @@ final class ActivityManagerConstants extends ContentObserver { private static final long DEFAULT_FG_TO_BG_FGS_GRACE_DURATION = 5 * 1000; private static final int DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS = 10 * 1000; private static final float DEFAULT_FGS_ATOM_SAMPLE_RATE = 1; // 100 % - - static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60 * 1000; - static final boolean DEFAULT_KILL_FAS_CACHED_IDLE = true; - /** * Same as {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED} */ @@ -198,6 +193,13 @@ final class ActivityManagerConstants extends ContentObserver { "default_fgs_starts_restriction_enabled"; /** + * Default value for mFgsStartRestrictionNotificationEnabled if not explicitly set in + * Settings.Global. + */ + private static final String KEY_DEFAULT_FGS_STARTS_RESTRICTION_NOTIFICATION_ENABLED = + "default_fgs_starts_restriction_notification_enabled"; + + /** * Default value for mFgsStartRestrictionCheckCallerTargetSdk if not explicitly set in * Settings.Global. */ @@ -432,6 +434,10 @@ final class ActivityManagerConstants extends ContentObserver { // at all. volatile boolean mFlagFgsStartRestrictionEnabled = true; + // Whether to display a notification when a service is restricted from startForeground due to + // foreground service background start restriction. + volatile boolean mFgsStartRestrictionNotificationEnabled = false; + /** * Indicates whether the foreground service background start restriction is enabled for * caller app that is targeting S+. @@ -490,12 +496,6 @@ final class ActivityManagerConstants extends ContentObserver { volatile float mFgsAtomSampleRate = DEFAULT_FGS_ATOM_SAMPLE_RATE; /** - * Whether or not to kill apps in force-app-standby state and it's cached, its UID state is - * idle. - */ - volatile boolean mKillForceAppStandByAndCachedIdle = DEFAULT_KILL_FAS_CACHED_IDLE; - - /** * Whether to allow "opt-out" from the foreground service restrictions. * (https://developer.android.com/about/versions/12/foreground-services) */ @@ -652,6 +652,9 @@ final class ActivityManagerConstants extends ContentObserver { case KEY_DEFAULT_FGS_STARTS_RESTRICTION_ENABLED: updateFgsStartsRestriction(); break; + case KEY_DEFAULT_FGS_STARTS_RESTRICTION_NOTIFICATION_ENABLED: + updateFgsStartsRestrictionNotification(); + break; case KEY_DEFAULT_FGS_STARTS_RESTRICTION_CHECK_CALLER_TARGET_SDK: updateFgsStartsRestrictionCheckCallerTargetSdk(); break; @@ -706,9 +709,6 @@ final class ActivityManagerConstants extends ContentObserver { case KEY_FGS_ATOM_SAMPLE_RATE: updateFgsAtomSamplePercent(); break; - case KEY_KILL_FAS_CACHED_IDLE: - updateKillFasCachedIdle(); - break; case KEY_FGS_ALLOW_OPT_OUT: updateFgsAllowOptOut(); break; @@ -953,6 +953,13 @@ final class ActivityManagerConstants extends ContentObserver { /*defaultValue*/ true); } + private void updateFgsStartsRestrictionNotification() { + mFgsStartRestrictionNotificationEnabled = DeviceConfig.getBoolean( + DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + KEY_DEFAULT_FGS_STARTS_RESTRICTION_NOTIFICATION_ENABLED, + /*defaultValue*/ false); + } + private void updateFgsStartsRestrictionCheckCallerTargetSdk() { mFgsStartRestrictionCheckCallerTargetSdk = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, @@ -1044,13 +1051,6 @@ final class ActivityManagerConstants extends ContentObserver { DEFAULT_FGS_ATOM_SAMPLE_RATE); } - private void updateKillFasCachedIdle() { - mKillForceAppStandByAndCachedIdle = DeviceConfig.getBoolean( - DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - KEY_KILL_FAS_CACHED_IDLE, - DEFAULT_KILL_FAS_CACHED_IDLE); - } - private void updateFgsAllowOptOut() { mFgsAllowOptOut = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, @@ -1272,6 +1272,9 @@ final class ActivityManagerConstants extends ContentObserver { pw.print("="); pw.println(mFlagBackgroundFgsStartRestrictionEnabled); pw.print(" "); pw.print(KEY_DEFAULT_FGS_STARTS_RESTRICTION_ENABLED); pw.print("="); pw.println(mFlagFgsStartRestrictionEnabled); + pw.print(" "); pw.print(KEY_DEFAULT_FGS_STARTS_RESTRICTION_NOTIFICATION_ENABLED); + pw.print("="); + pw.println(mFgsStartRestrictionNotificationEnabled); pw.print(" "); pw.print(KEY_DEFAULT_FGS_STARTS_RESTRICTION_CHECK_CALLER_TARGET_SDK); pw.print("="); pw.println(mFgsStartRestrictionCheckCallerTargetSdk); pw.print(" "); pw.print(KEY_FGS_ATOM_SAMPLE_RATE); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 2de091bb34bf..3b0a68ca29ca 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5684,6 +5684,16 @@ public class ActivityManagerService extends IActivityManager.Stub if (pid == MY_PID) { return PackageManager.PERMISSION_GRANTED; } + try { + if (uid != 0) { // bypass the root + final String[] packageNames = getPackageManager().getPackagesForUid(uid); + if (ArrayUtils.isEmpty(packageNames)) { + // The uid is not existed or not visible to the caller. + return PackageManager.PERMISSION_DENIED; + } + } + } catch (RemoteException e) { + } return mUgmInternal.checkUriPermission(new GrantUri(userId, uri, modeFlags), uid, modeFlags) ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED; } @@ -14372,10 +14382,6 @@ public class ActivityManagerService extends IActivityManager.Stub final int capability = uidRec != null ? uidRec.getSetCapability() : 0; final boolean ephemeral = uidRec != null ? uidRec.isEphemeral() : isEphemeralLocked(uid); - if (uidRec != null && uidRec.isIdle() && (change & UidRecord.CHANGE_IDLE) != 0) { - mProcessList.killAppIfForceStandbyAndCachedIdleLocked(uidRec); - } - if (uidRec != null && !uidRec.isIdle() && (change & UidRecord.CHANGE_GONE) != 0) { // If this uid is going away, and we haven't yet reported it is gone, // then do so now. @@ -16323,6 +16329,17 @@ public class ActivityManagerService extends IActivityManager.Stub return mConstants.mPushMessagingOverQuotaBehavior; } } + + @Override + public int getUidCapability(int uid) { + synchronized (ActivityManagerService.this) { + UidRecord uidRecord = mProcessList.getUidRecordLOSP(uid); + if (uidRecord == null) { + throw new IllegalArgumentException("uid record for " + uid + " not found"); + } + return uidRecord.getCurCapability(); + } + } } long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 08f6f1e6e46e..7d9d78969ca9 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -126,7 +126,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub Watchdog.Monitor { static final String TAG = "BatteryStatsService"; static final boolean DBG = false; - private static final boolean BATTERY_USAGE_STORE_ENABLED = true; + private static final boolean BATTERY_USAGE_STORE_ENABLED = false; private static IBatteryStats sService; @@ -784,6 +784,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub bus = getBatteryUsageStats(List.of(powerProfileQuery)).get(0); break; case FrameworkStatsLog.BATTERY_USAGE_STATS_BEFORE_RESET: + if (!BATTERY_USAGE_STORE_ENABLED) { + return StatsManager.PULL_SKIP; + } + final long sessionStart = mBatteryUsageStatsStore .getLastBatteryUsageStatsBeforeResetAtomPullTimestamp(); final long sessionEnd = mStats.getStartClockTime(); diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 966e746b3c73..317b7757c239 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -203,8 +203,6 @@ public final class CachedAppOptimizer { updateMinOomAdjThrottle(); } else if (KEY_COMPACT_THROTTLE_MAX_OOM_ADJ.equals(name)) { updateMaxOomAdjThrottle(); - } else if (KEY_FREEZER_DEBOUNCE_TIMEOUT.equals(name)) { - updateFreezerDebounceTimeout(); } } } @@ -344,7 +342,6 @@ public final class CachedAppOptimizer { updateUseFreezer(); updateMinOomAdjThrottle(); updateMaxOomAdjThrottle(); - updateFreezerDebounceTimeout(); } } @@ -656,6 +653,7 @@ public final class CachedAppOptimizer { || DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT, KEY_USE_FREEZER, DEFAULT_USE_FREEZER)) { mUseFreezer = isFreezerSupported(); + updateFreezerDebounceTimeout(); } final boolean useFreezer = mUseFreezer; @@ -834,7 +832,8 @@ public final class CachedAppOptimizer { @GuardedBy("mPhenotypeFlagLock") private void updateFreezerDebounceTimeout() { - mFreezerDebounceTimeout = DeviceConfig.getLong(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + mFreezerDebounceTimeout = DeviceConfig.getLong( + DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT, KEY_FREEZER_DEBOUNCE_TIMEOUT, DEFAULT_FREEZER_DEBOUNCE_TIMEOUT); if (mFreezerDebounceTimeout < 0) { diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index aef402ac3213..6cebf47ec8c2 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -2835,8 +2835,6 @@ public class OomAdjuster { + " target=" + state.getAdjTarget() + " capability=" + item.capability); } - mProcessList.killAppIfForceStandbyAndCachedIdleLocked(app); - return success; } diff --git a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java index b2266f6c54e6..4455fd06e88a 100644 --- a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java +++ b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java @@ -267,7 +267,7 @@ class ProcessErrorStateRecord { if (mService.mTraceErrorLogger.isAddErrorIdEnabled()) { errorId = mService.mTraceErrorLogger.generateErrorId(); - mService.mTraceErrorLogger.addErrorIdToTrace(errorId); + mService.mTraceErrorLogger.addErrorIdToTrace(mApp.processName, errorId); } else { errorId = null; } diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 8ebc987a59f4..fd9a53695e6c 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -125,7 +125,6 @@ import com.android.internal.os.Zygote; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.MemInfoReader; -import com.android.server.AppStateTracker; import com.android.server.LocalServices; import com.android.server.ServiceThread; import com.android.server.SystemConfig; @@ -2370,12 +2369,6 @@ public final class ProcessList { allowlistedAppDataInfoMap = null; } - AppStateTracker ast = LocalServices.getService(AppStateTracker.class); - if (ast != null) { - app.mState.setForcedAppStandby(ast.isAppInForcedAppStandby( - app.info.uid, app.info.packageName)); - } - final Process.ProcessStartResult startResult; boolean regularZygote = false; if (hostingRecord.usesWebviewZygote()) { @@ -4698,10 +4691,10 @@ public final class ProcessList { final ApplicationInfo ai = AppGlobals.getPackageManager() .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId); if (ai != null) { - app.getThread().scheduleApplicationInfoChanged(ai); if (ai.packageName.equals(app.info.packageName)) { app.info = ai; } + app.getThread().scheduleApplicationInfoChanged(ai); targetProcesses.add(app.getWindowProcessController()); } } catch (RemoteException e) { @@ -4712,8 +4705,7 @@ public final class ProcessList { }); } - mService.mActivityTaskManager.updateAssetConfiguration( - updateFrameworkRes ? null : targetProcesses); + mService.mActivityTaskManager.updateAssetConfiguration(targetProcesses, updateFrameworkRes); } @GuardedBy("mService") @@ -5008,55 +5000,6 @@ public final class ProcessList { return true; } - @GuardedBy("mService") - void updateForceAppStandbyForUidPackageLocked(int uid, String packageName, boolean standby) { - final UidRecord uidRec = getUidRecordLOSP(uid); - if (uidRec != null) { - uidRec.forEachProcess(app -> { - if (TextUtils.equals(app.info.packageName, packageName)) { - app.mState.setForcedAppStandby(standby); - killAppIfForceStandbyAndCachedIdleLocked(app); - } - }); - } - } - - @GuardedBy("mService") - void updateForcedAppStandbyForAllAppsLocked() { - if (!mService.mConstants.mKillForceAppStandByAndCachedIdle) { - return; - } - final AppStateTracker ast = LocalServices.getService(AppStateTracker.class); - for (int i = mLruProcesses.size() - 1; i >= 0; i--) { - final ProcessRecord app = mLruProcesses.get(i); - final boolean standby = ast.isAppInForcedAppStandby( - app.info.uid, app.info.packageName); - app.mState.setForcedAppStandby(standby); - if (standby) { - killAppIfForceStandbyAndCachedIdleLocked(app); - } - } - } - - @GuardedBy("mService") - void killAppIfForceStandbyAndCachedIdleLocked(ProcessRecord app) { - final UidRecord uidRec = app.getUidRecord(); - if (mService.mConstants.mKillForceAppStandByAndCachedIdle - && uidRec != null && uidRec.isIdle() - && !app.mState.shouldNotKillOnForcedAppStandbyAndIdle() - && app.isCached() && app.mState.isForcedAppStandby()) { - app.killLocked("cached idle & forced-app-standby", - ApplicationExitInfo.REASON_OTHER, - ApplicationExitInfo.SUBREASON_CACHED_IDLE_FORCED_APP_STANDBY, - true); - } - } - - @GuardedBy("mService") - void killAppIfForceStandbyAndCachedIdleLocked(UidRecord uidRec) { - uidRec.forEachProcess(app -> killAppIfForceStandbyAndCachedIdleLocked(app)); - } - /** * Called by ActivityManagerService when a process died. */ diff --git a/services/core/java/com/android/server/am/ProcessStateRecord.java b/services/core/java/com/android/server/am/ProcessStateRecord.java index 5dbd71a48623..c113bc2ecb4f 100644 --- a/services/core/java/com/android/server/am/ProcessStateRecord.java +++ b/services/core/java/com/android/server/am/ProcessStateRecord.java @@ -302,12 +302,6 @@ final class ProcessStateRecord { private int mAllowStartFgsState = PROCESS_STATE_NONEXISTENT; /** - * Whether or not this process has been in forced-app-standby state. - */ - @GuardedBy("mService") - private boolean mForcedAppStandby; - - /** * Debugging: primary thing impacting oom_adj. */ @GuardedBy("mService") @@ -1126,16 +1120,6 @@ final class ProcessStateRecord { } @GuardedBy("mService") - void setForcedAppStandby(boolean standby) { - mForcedAppStandby = standby; - } - - @GuardedBy("mService") - boolean isForcedAppStandby() { - return mForcedAppStandby; - } - - @GuardedBy("mService") void updateLastInvisibleTime(boolean hasVisibleActivities) { if (hasVisibleActivities) { mLastInvisibleTime = Long.MAX_VALUE; @@ -1203,8 +1187,7 @@ final class ProcessStateRecord { pw.print(" pendingUiClean="); pw.println(mApp.mProfile.hasPendingUiClean()); } pw.print(prefix); pw.print("cached="); pw.print(mCached); - pw.print(" empty="); pw.print(mEmpty); - pw.print(" forcedAppStandby="); pw.println(mForcedAppStandby); + pw.print(" empty="); pw.println(mEmpty); if (mServiceB) { pw.print(prefix); pw.print("serviceb="); pw.print(mServiceB); pw.print(" serviceHighRam="); pw.println(mServiceHighRam); diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 141f081ab9a7..804e442bc8de 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -20,6 +20,7 @@ import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; import static android.os.PowerExemptionManager.REASON_DENIED; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOREGROUND_SERVICE; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; @@ -928,13 +929,17 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN public void postNotification() { final int appUid = appInfo.uid; final int appPid = app.getPid(); - if (foregroundId != 0 && foregroundNoti != null) { + if (isForeground && foregroundNoti != null) { // Do asynchronous communication with notification manager to // avoid deadlocks. final String localPackageName = packageName; final int localForegroundId = foregroundId; final Notification _foregroundNoti = foregroundNoti; final ServiceRecord record = this; + if (DEBUG_FOREGROUND_SERVICE) { + Slog.d(TAG, "Posting notification " + _foregroundNoti + + " for foreground service " + this); + } ams.mHandler.post(new Runnable() { public void run() { NotificationManagerInternal nm = LocalServices.getService( @@ -1066,10 +1071,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN } public void stripForegroundServiceFlagFromNotification() { - if (foregroundId == 0) { - return; - } - final int localForegroundId = foregroundId; final int localUserId = userId; final String localPackageName = packageName; diff --git a/services/core/java/com/android/server/am/TraceErrorLogger.java b/services/core/java/com/android/server/am/TraceErrorLogger.java index 55f571560a5b..c65810097433 100644 --- a/services/core/java/com/android/server/am/TraceErrorLogger.java +++ b/services/core/java/com/android/server/am/TraceErrorLogger.java @@ -46,10 +46,12 @@ public class TraceErrorLogger { * can be uniquely identified. We also add the same id to the dropbox entry of the error, so * that we can join the trace and the error server-side. * - * @param errorId The unique id with which to tag the trace. + * @param processName The process name to include in the error id. + * @param errorId The unique id with which to tag the trace. */ - public void addErrorIdToTrace(UUID errorId) { - Trace.traceCounter(Trace.TRACE_TAG_ACTIVITY_MANAGER, COUNTER_PREFIX + errorId.toString(), + public void addErrorIdToTrace(String processName, UUID errorId) { + Trace.traceCounter(Trace.TRACE_TAG_ACTIVITY_MANAGER, + COUNTER_PREFIX + processName + "#" + errorId.toString(), PLACEHOLDER_VALUE); } } diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java index 697f6fa8eea8..ae1cd51e11f0 100644 --- a/services/core/java/com/android/server/app/GameManagerService.java +++ b/services/core/java/com/android/server/app/GameManagerService.java @@ -21,10 +21,18 @@ import static android.content.Intent.ACTION_PACKAGE_CHANGED; import static android.content.Intent.ACTION_PACKAGE_REMOVED; import static com.android.server.wm.CompatModePackages.DOWNSCALED; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_30; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_35; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_40; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_45; import static com.android.server.wm.CompatModePackages.DOWNSCALE_50; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_55; import static com.android.server.wm.CompatModePackages.DOWNSCALE_60; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_65; import static com.android.server.wm.CompatModePackages.DOWNSCALE_70; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_75; import static com.android.server.wm.CompatModePackages.DOWNSCALE_80; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_85; import static com.android.server.wm.CompatModePackages.DOWNSCALE_90; import android.Manifest; @@ -213,6 +221,39 @@ public final class GameManagerService extends IGameManagerService.Stub { } } + // Turn the raw string to the corresponding CompatChange id. + static long getCompatChangeId(String raw) { + switch (raw) { + case "0.3": + return DOWNSCALE_30; + case "0.35": + return DOWNSCALE_35; + case "0.4": + return DOWNSCALE_40; + case "0.45": + return DOWNSCALE_45; + case "0.5": + return DOWNSCALE_50; + case "0.55": + return DOWNSCALE_55; + case "0.6": + return DOWNSCALE_60; + case "0.65": + return DOWNSCALE_65; + case "0.7": + return DOWNSCALE_70; + case "0.75": + return DOWNSCALE_75; + case "0.8": + return DOWNSCALE_80; + case "0.85": + return DOWNSCALE_85; + case "0.9": + return DOWNSCALE_90; + } + return 0; + } + /** * GamePackageConfiguration manages all game mode config details for its associated package. */ @@ -331,19 +372,7 @@ public final class GameManagerService extends IGameManagerService.Stub { * Get the corresponding compat change id for the current scaling string. */ public long getCompatChangeId() { - switch (mScaling) { - case "0.5": - return DOWNSCALE_50; - case "0.6": - return DOWNSCALE_60; - case "0.7": - return DOWNSCALE_70; - case "0.8": - return DOWNSCALE_80; - case "0.9": - return DOWNSCALE_90; - } - return 0; + return GameManagerService.getCompatChangeId(mScaling); } } @@ -663,10 +692,18 @@ public final class GameManagerService extends IGameManagerService.Stub { Slog.i(TAG, "Enabling downscale: " + scaleId + " for " + packageName); final ArrayMap<Long, PackageOverride> overrides = new ArrayMap<>(); overrides.put(DOWNSCALED, COMPAT_ENABLED); + overrides.put(DOWNSCALE_30, COMPAT_DISABLED); + overrides.put(DOWNSCALE_35, COMPAT_DISABLED); + overrides.put(DOWNSCALE_40, COMPAT_DISABLED); + overrides.put(DOWNSCALE_45, COMPAT_DISABLED); overrides.put(DOWNSCALE_50, COMPAT_DISABLED); + overrides.put(DOWNSCALE_55, COMPAT_DISABLED); overrides.put(DOWNSCALE_60, COMPAT_DISABLED); + overrides.put(DOWNSCALE_65, COMPAT_DISABLED); overrides.put(DOWNSCALE_70, COMPAT_DISABLED); + overrides.put(DOWNSCALE_75, COMPAT_DISABLED); overrides.put(DOWNSCALE_80, COMPAT_DISABLED); + overrides.put(DOWNSCALE_85, COMPAT_DISABLED); overrides.put(DOWNSCALE_90, COMPAT_DISABLED); overrides.put(scaleId, COMPAT_ENABLED); final CompatibilityOverrideConfig changeConfig = new CompatibilityOverrideConfig( diff --git a/services/core/java/com/android/server/app/GameManagerShellCommand.java b/services/core/java/com/android/server/app/GameManagerShellCommand.java index 2074ffae1030..699f9e2d99f8 100644 --- a/services/core/java/com/android/server/app/GameManagerShellCommand.java +++ b/services/core/java/com/android/server/app/GameManagerShellCommand.java @@ -16,6 +16,21 @@ package com.android.server.app; +import static com.android.server.wm.CompatModePackages.DOWNSCALED; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_30; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_35; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_40; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_45; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_50; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_55; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_60; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_65; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_70; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_75; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_80; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_85; +import static com.android.server.wm.CompatModePackages.DOWNSCALE_90; + import android.app.ActivityManager; import android.app.GameManager; import android.app.IGameManagerService; @@ -27,7 +42,6 @@ import android.util.ArraySet; import com.android.internal.compat.CompatibilityChangeConfig; import com.android.server.compat.PlatformCompat; -import com.android.server.wm.CompatModePackages; import java.io.PrintWriter; import java.util.Set; @@ -43,12 +57,21 @@ public class GameManagerShellCommand extends ShellCommand { public GameManagerShellCommand() {} private static final ArraySet<Long> DOWNSCALE_CHANGE_IDS = new ArraySet<>(new Long[]{ - CompatModePackages.DOWNSCALED, - CompatModePackages.DOWNSCALE_90, - CompatModePackages.DOWNSCALE_80, - CompatModePackages.DOWNSCALE_70, - CompatModePackages.DOWNSCALE_60, - CompatModePackages.DOWNSCALE_50}); + DOWNSCALED, + DOWNSCALE_90, + DOWNSCALE_85, + DOWNSCALE_80, + DOWNSCALE_75, + DOWNSCALE_70, + DOWNSCALE_65, + DOWNSCALE_60, + DOWNSCALE_55, + DOWNSCALE_50, + DOWNSCALE_45, + DOWNSCALE_40, + DOWNSCALE_35, + DOWNSCALE_30, + }); @Override public int onCommand(String cmd) { @@ -62,32 +85,9 @@ public class GameManagerShellCommand extends ShellCommand { final String ratio = getNextArgRequired(); final String packageName = getNextArgRequired(); - final long changeId; - switch (ratio) { - case "0.5": - changeId = CompatModePackages.DOWNSCALE_50; - break; - case "0.6": - changeId = CompatModePackages.DOWNSCALE_60; - break; - case "0.7": - changeId = CompatModePackages.DOWNSCALE_70; - break; - case "0.8": - changeId = CompatModePackages.DOWNSCALE_80; - break; - case "0.9": - changeId = CompatModePackages.DOWNSCALE_90; - break; - case "disable": - changeId = 0; - break; - default: - changeId = -1; - pw.println("Invalid scaling ratio '" + ratio + "'"); - break; - } - if (changeId == -1) { + final long changeId = GameManagerService.getCompatChangeId(ratio); + if (changeId == 0 && !ratio.equals("disable")) { + pw.println("Invalid scaling ratio '" + ratio + "'"); break; } @@ -96,10 +96,10 @@ public class GameManagerShellCommand extends ShellCommand { if (changeId == 0) { disabled = DOWNSCALE_CHANGE_IDS; } else { - enabled.add(CompatModePackages.DOWNSCALED); + enabled.add(DOWNSCALED); enabled.add(changeId); disabled = DOWNSCALE_CHANGE_IDS.stream() - .filter(it -> it != CompatModePackages.DOWNSCALED && it != changeId) + .filter(it -> it != DOWNSCALED && it != changeId) .collect(Collectors.toSet()); } @@ -204,7 +204,7 @@ public class GameManagerShellCommand extends ShellCommand { pw.println("Game manager (game) commands:"); pw.println(" help"); pw.println(" Print this help text."); - pw.println(" downscale [0.5|0.6|0.7|0.8|0.9|disable] <PACKAGE_NAME>"); + pw.println(" downscale [0.3|0.35|0.4|0.45|0.5|0.55|0.6|0.65|0.7|0.75|0.8|0.85|0.9|disable] <PACKAGE_NAME>"); pw.println(" Force app to run at the specified scaling ratio."); pw.println(" mode [--user <USER_ID>] [1|2|3|standard|performance|battery] <PACKAGE_NAME>"); pw.println(" Force app to run in the specified game mode, if supported."); diff --git a/services/core/java/com/android/server/apphibernation/AppHibernationService.java b/services/core/java/com/android/server/apphibernation/AppHibernationService.java index 4cb2e9b5cb97..7f1402d83a0c 100644 --- a/services/core/java/com/android/server/apphibernation/AppHibernationService.java +++ b/services/core/java/com/android/server/apphibernation/AppHibernationService.java @@ -456,7 +456,9 @@ public final class AppHibernationService extends SystemService { private void hibernatePackageGlobally(@NonNull String packageName, GlobalLevelState state) { Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "hibernatePackageGlobally"); if (mOatArtifactDeletionEnabled) { - mPackageManagerInternal.deleteOatArtifactsOfPackage(packageName); + state.savedByte = Math.max( + mPackageManagerInternal.deleteOatArtifactsOfPackage(packageName), + 0); } state.hibernated = true; Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); @@ -469,6 +471,7 @@ public final class AppHibernationService extends SystemService { private void unhibernatePackageGlobally(@NonNull String packageName, GlobalLevelState state) { Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "unhibernatePackageGlobally"); state.hibernated = false; + state.savedByte = 0; state.lastUnhibernatedMs = System.currentTimeMillis(); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } @@ -943,6 +946,9 @@ public final class AppHibernationService extends SystemService { } private final class StatsPullAtomCallbackImpl implements StatsPullAtomCallback { + + private static final int MEGABYTE_IN_BYTES = 1000000; + @Override public int onPullAtom(int atomTag, @NonNull List<StatsEvent> data) { if (!isAppHibernationEnabled() @@ -969,12 +975,21 @@ public final class AppHibernationService extends SystemService { break; case FrameworkStatsLog.GLOBAL_HIBERNATED_APPS: int hibernatedAppCount = 0; + long storage_saved_byte = 0; synchronized (mLock) { for (GlobalLevelState state : mGlobalHibernationStates.values()) { - if (state.hibernated) hibernatedAppCount++; + if (state.hibernated) { + hibernatedAppCount++; + storage_saved_byte += state.savedByte; + } } } - data.add(FrameworkStatsLog.buildStatsEvent(atomTag, hibernatedAppCount)); + data.add( + FrameworkStatsLog.buildStatsEvent( + atomTag, + hibernatedAppCount, + storage_saved_byte / MEGABYTE_IN_BYTES) + ); break; default: return StatsManager.PULL_SKIP; diff --git a/services/core/java/com/android/server/apphibernation/GlobalLevelHibernationProto.java b/services/core/java/com/android/server/apphibernation/GlobalLevelHibernationProto.java index 79e995b038fa..018d6023f083 100644 --- a/services/core/java/com/android/server/apphibernation/GlobalLevelHibernationProto.java +++ b/services/core/java/com/android/server/apphibernation/GlobalLevelHibernationProto.java @@ -41,6 +41,7 @@ final class GlobalLevelHibernationProto implements ProtoReadWriter<List<GlobalLe GlobalLevelState state = data.get(i); stream.write(GlobalLevelHibernationStateProto.PACKAGE_NAME, state.packageName); stream.write(GlobalLevelHibernationStateProto.HIBERNATED, state.hibernated); + stream.write(GlobalLevelHibernationStateProto.SAVED_BYTE, state.savedByte); stream.end(token); } } @@ -66,6 +67,10 @@ final class GlobalLevelHibernationProto implements ProtoReadWriter<List<GlobalLe state.hibernated = stream.readBoolean(GlobalLevelHibernationStateProto.HIBERNATED); break; + case (int) GlobalLevelHibernationStateProto.SAVED_BYTE: + state.savedByte = + stream.readLong(GlobalLevelHibernationStateProto.SAVED_BYTE); + break; default: Slog.w(TAG, "Undefined field in proto: " + stream.getFieldNumber()); } diff --git a/services/core/java/com/android/server/apphibernation/GlobalLevelState.java b/services/core/java/com/android/server/apphibernation/GlobalLevelState.java index f4433a7fa5f6..104ecbc17d8a 100644 --- a/services/core/java/com/android/server/apphibernation/GlobalLevelState.java +++ b/services/core/java/com/android/server/apphibernation/GlobalLevelState.java @@ -29,6 +29,8 @@ final class GlobalLevelState { public String packageName; public boolean hibernated; + // The number of saved bytes from the current hibernation. It will be 0 if not in hibernation. + public long savedByte; @CurrentTimeMillisLong public long lastUnhibernatedMs; @@ -37,6 +39,7 @@ final class GlobalLevelState { return "GlobalLevelState{" + "packageName='" + packageName + '\'' + ", hibernated=" + hibernated + '\'' + + ", savedByte=" + savedByte + '\'' + ", lastUnhibernated=" + DATE_FORMAT.format(lastUnhibernatedMs) + '}'; } diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 12aad21428c6..122880c19951 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -19,11 +19,13 @@ package com.android.server.appop; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; +import static android.app.AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE; import static android.app.AppOpsManager.CALL_BACK_ON_SWITCHED_OP; import static android.app.AppOpsManager.FILTER_BY_ATTRIBUTION_TAG; import static android.app.AppOpsManager.FILTER_BY_OP_NAMES; import static android.app.AppOpsManager.FILTER_BY_PACKAGE_NAME; import static android.app.AppOpsManager.FILTER_BY_UID; +import static android.app.AppOpsManager.HISTORY_FLAG_GET_ATTRIBUTION_CHAINS; import static android.app.AppOpsManager.HistoricalOpsRequestFilter; import static android.app.AppOpsManager.KEY_BG_STATE_SETTLE_TIME; import static android.app.AppOpsManager.KEY_FG_SERVICE_STATE_SETTLE_TIME; @@ -130,6 +132,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.os.storage.StorageManagerInternal; +import android.permission.PermissionManager; import android.provider.Settings; import android.util.ArrayMap; import android.util.ArraySet; @@ -200,8 +203,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Scanner; +import java.util.Set; import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; public class AppOpsService extends IAppOpsService.Stub { @@ -2345,8 +2348,9 @@ public class AppOpsService extends IAppOpsService.Stub { boolean isCallerSystem = Binder.getCallingPid() == Process.myPid(); boolean isCallerPermissionController; try { - isCallerPermissionController = pm.getPackageUid( - mContext.getPackageManager().getPermissionControllerPackageName(), 0) + isCallerPermissionController = pm.getPackageUidAsUser( + mContext.getPackageManager().getPermissionControllerPackageName(), 0, + UserHandle.getUserId(Binder.getCallingUid())) == Binder.getCallingUid(); } catch (PackageManager.NameNotFoundException doesNotHappen) { return; @@ -2364,10 +2368,21 @@ public class AppOpsService extends IAppOpsService.Stub { final String[] opNamesArray = (opNames != null) ? opNames.toArray(new String[opNames.size()]) : null; + Set<String> attributionChainExemptPackages = null; + if ((dataType & HISTORY_FLAG_GET_ATTRIBUTION_CHAINS) != 0) { + attributionChainExemptPackages = + PermissionManager.getIndicatorExemptedPackages(mContext); + } + + final String[] chainExemptPkgArray = attributionChainExemptPackages != null + ? attributionChainExemptPackages.toArray( + new String[attributionChainExemptPackages.size()]) : null; + // Must not hold the appops lock mHandler.post(PooledLambda.obtainRunnable(HistoricalRegistry::getHistoricalOps, mHistoricalRegistry, uid, packageName, attributionTag, opNamesArray, dataType, - filter, beginTimeMillis, endTimeMillis, flags, callback).recycleOnUse()); + filter, beginTimeMillis, endTimeMillis, flags, chainExemptPkgArray, + callback).recycleOnUse()); } @Override @@ -2384,10 +2399,21 @@ public class AppOpsService extends IAppOpsService.Stub { final String[] opNamesArray = (opNames != null) ? opNames.toArray(new String[opNames.size()]) : null; + Set<String> attributionChainExemptPackages = null; + if ((dataType & HISTORY_FLAG_GET_ATTRIBUTION_CHAINS) != 0) { + attributionChainExemptPackages = + PermissionManager.getIndicatorExemptedPackages(mContext); + } + + final String[] chainExemptPkgArray = attributionChainExemptPackages != null + ? attributionChainExemptPackages.toArray( + new String[attributionChainExemptPackages.size()]) : null; + // Must not hold the appops lock mHandler.post(PooledLambda.obtainRunnable(HistoricalRegistry::getHistoricalOpsFromDiskRaw, mHistoricalRegistry, uid, packageName, attributionTag, opNamesArray, dataType, - filter, beginTimeMillis, endTimeMillis, flags, callback).recycleOnUse()); + filter, beginTimeMillis, endTimeMillis, flags, chainExemptPkgArray, + callback).recycleOnUse()); } @Override @@ -3379,21 +3405,11 @@ public class AppOpsService extends IAppOpsService.Stub { boolean shouldCollectMessage) { PackageVerificationResult pvr; try { - boolean isLocOrActivity = code == AppOpsManager.OP_FINE_LOCATION - || code == AppOpsManager.OP_FINE_LOCATION_SOURCE - || code == AppOpsManager.OP_ACTIVITY_RECOGNITION - || code == AppOpsManager.OP_ACTIVITY_RECOGNITION_SOURCE; - pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName, - isLocOrActivity); + pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName); boolean wasNull = attributionTag == null; if (!pvr.isAttributionTagValid) { attributionTag = null; } - if (attributionTag == null && isLocOrActivity - && packageName.equals("com.google.android.gms")) { - Slog.i("AppOpsDebug", "null tag on location or activity op " + code - + " for " + packageName + ", was overridden: " + !wasNull, new Exception()); - } } catch (SecurityException e) { Slog.e(TAG, "noteOperation", e); return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag, @@ -3845,7 +3861,8 @@ public class AppOpsService extends IAppOpsService.Stub { final boolean isSelfBlame = Binder.getCallingUid() == proxiedUid; final boolean isProxyTrusted = mContext.checkPermission( Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid) - == PackageManager.PERMISSION_GRANTED || isSelfBlame; + == PackageManager.PERMISSION_GRANTED || isSelfBlame + || attributionChainId != ATTRIBUTION_CHAIN_ID_NONE; String resolvedProxiedPackageName = AppOpsManager.resolvePackageName(proxiedUid, proxiedPackageName); @@ -3900,20 +3917,10 @@ public class AppOpsService extends IAppOpsService.Stub { int attributionChainId, boolean dryRun) { PackageVerificationResult pvr; try { - boolean isLocOrActivity = code == AppOpsManager.OP_FINE_LOCATION - || code == AppOpsManager.OP_FINE_LOCATION_SOURCE - || code == AppOpsManager.OP_ACTIVITY_RECOGNITION - || code == AppOpsManager.OP_ACTIVITY_RECOGNITION_SOURCE; - pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName, - isLocOrActivity); + pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName); if (!pvr.isAttributionTagValid) { attributionTag = null; } - if (attributionTag == null && isLocOrActivity - && packageName.equals("com.google.android.gms")) { - Slog.i("AppOpsDebug", "null tag on location or activity op " - + code + " for " + packageName, new Exception()); - } } catch (SecurityException e) { Slog.e(TAG, "startOperation", e); return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag, @@ -4008,6 +4015,12 @@ public class AppOpsService extends IAppOpsService.Stub { @Override public void finishOperation(IBinder clientId, int code, int uid, String packageName, String attributionTag) { + mCheckOpsDelegateDispatcher.finishOperation(clientId, code, uid, packageName, + attributionTag); + } + + private void finishOperationImpl(IBinder clientId, int code, int uid, String packageName, + String attributionTag) { verifyIncomingUid(uid); verifyIncomingOp(code); verifyIncomingPackage(packageName, UserHandle.getUserId(uid)); @@ -4465,11 +4478,11 @@ public class AppOpsService extends IAppOpsService.Stub { } /** - * @see #verifyAndGetBypass(int, String, String, String, boolean) + * @see #verifyAndGetBypass(int, String, String, String) */ private @NonNull PackageVerificationResult verifyAndGetBypass(int uid, String packageName, @Nullable String attributionTag) { - return verifyAndGetBypass(uid, packageName, attributionTag, null, false); + return verifyAndGetBypass(uid, packageName, attributionTag, null); } /** @@ -4486,7 +4499,7 @@ public class AppOpsService extends IAppOpsService.Stub { * attribution tag is valid */ private @NonNull PackageVerificationResult verifyAndGetBypass(int uid, String packageName, - @Nullable String attributionTag, @Nullable String proxyPackageName, boolean extraLog) { + @Nullable String attributionTag, @Nullable String proxyPackageName) { if (uid == Process.ROOT_UID) { // For backwards compatibility, don't check package name for root UID. return new PackageVerificationResult(null, @@ -4533,20 +4546,6 @@ public class AppOpsService extends IAppOpsService.Stub { AndroidPackage pkg = pmInt.getPackage(packageName); if (pkg != null) { isAttributionTagValid = isAttributionInPackage(pkg, attributionTag); - if (packageName.equals("com.google.android.gms") && extraLog) { - if (isAttributionTagValid && attributionTag != null) { - Slog.i("AppOpsDebug", "tag " + attributionTag + " found in " - + packageName); - } else { - ArrayList<String> tagList = new ArrayList<>(); - for (int i = 0; i < pkg.getAttributions().size(); i++) { - tagList.add(pkg.getAttributions().get(i).tag); - } - Slog.i("AppOpsDebug", "tag " + attributionTag + " missing from " - + packageName + ", tags: " + tagList); - } - } - pkgUid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid())); bypass = getBypassforPackage(pkg); } @@ -5190,8 +5189,6 @@ public class AppOpsService extends IAppOpsService.Stub { } static class Shell extends ShellCommand { - static final AtomicInteger sAttributionChainIds = new AtomicInteger(0); - final IAppOpsService mInterface; final AppOpsService mInternal; @@ -5661,8 +5658,7 @@ public class AppOpsService extends IAppOpsService.Stub { shell.mInterface.startOperation(shell.mToken, shell.op, shell.packageUid, shell.packageName, shell.attributionTag, true, true, "appops start shell command", true, - AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR, - shell.sAttributionChainIds.incrementAndGet()); + AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR, ATTRIBUTION_CHAIN_ID_NONE); } else { return -1; } @@ -7617,6 +7613,29 @@ public class AppOpsService extends IAppOpsService.Stub { attributionChainId, AppOpsService.this::startProxyOperationImpl); } + public void finishOperation(IBinder clientId, int code, int uid, String packageName, + String attributionTag) { + if (mPolicy != null) { + if (mCheckOpsDelegate != null) { + mPolicy.finishOperation(clientId, code, uid, packageName, attributionTag, + this::finishDelegateOperationImpl); + } else { + mPolicy.finishOperation(clientId, code, uid, packageName, attributionTag, + AppOpsService.this::finishOperationImpl); + } + } else if (mCheckOpsDelegate != null) { + finishDelegateOperationImpl(clientId, code, uid, packageName, attributionTag); + } else { + finishOperationImpl(clientId, code, uid, packageName, attributionTag); + } + } + + private void finishDelegateOperationImpl(IBinder clientId, int code, int uid, + String packageName, String attributionTag) { + mCheckOpsDelegate.finishOperation(clientId, code, uid, packageName, attributionTag, + AppOpsService.this::finishOperationImpl); + } + public void finishProxyOperation(int code, @NonNull AttributionSource attributionSource, boolean skipProxyOperation) { if (mPolicy != null) { diff --git a/services/core/java/com/android/server/appop/DiscreteRegistry.java b/services/core/java/com/android/server/appop/DiscreteRegistry.java index 1e32129dcee1..0439660f0c97 100644 --- a/services/core/java/com/android/server/appop/DiscreteRegistry.java +++ b/services/core/java/com/android/server/appop/DiscreteRegistry.java @@ -17,6 +17,8 @@ package com.android.server.appop; import static android.app.AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE; +import static android.app.AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR; +import static android.app.AppOpsManager.ATTRIBUTION_FLAG_RECEIVER; import static android.app.AppOpsManager.FILTER_BY_ATTRIBUTION_TAG; import static android.app.AppOpsManager.FILTER_BY_OP_NAMES; import static android.app.AppOpsManager.FILTER_BY_PACKAGE_NAME; @@ -72,6 +74,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Objects; +import java.util.Set; /** * This class manages information about recent accesses to ops for permission usage timeline. @@ -270,13 +274,19 @@ final class DiscreteRegistry { long beginTimeMillis, long endTimeMillis, @AppOpsManager.HistoricalOpsRequestFilter int filter, int uidFilter, @Nullable String packageNameFilter, @Nullable String[] opNamesFilter, - @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter) { + @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter, + Set<String> attributionExemptPkgs) { + boolean assembleChains = attributionExemptPkgs != null; DiscreteOps discreteOps = getAllDiscreteOps(); + ArrayMap<Integer, AttributionChain> attributionChains = new ArrayMap<>(); + if (assembleChains) { + attributionChains = createAttributionChains(discreteOps, attributionExemptPkgs); + } beginTimeMillis = max(beginTimeMillis, Instant.now().minus(sDiscreteHistoryCutoff, ChronoUnit.MILLIS).toEpochMilli()); discreteOps.filter(beginTimeMillis, endTimeMillis, filter, uidFilter, packageNameFilter, - opNamesFilter, attributionTagFilter, flagsFilter); - discreteOps.applyToHistoricalOps(result); + opNamesFilter, attributionTagFilter, flagsFilter, attributionChains); + discreteOps.applyToHistoricalOps(result, attributionChains); return; } @@ -317,13 +327,56 @@ final class DiscreteRegistry { } finally { try { stream.close(); - } catch (IOException e) { } + } catch (IOException e) { + } } } else { return 0; } } + private ArrayMap<Integer, AttributionChain> createAttributionChains( + DiscreteOps discreteOps, Set<String> attributionExemptPkgs) { + ArrayMap<Integer, AttributionChain> chains = new ArrayMap<>(); + int nUids = discreteOps.mUids.size(); + for (int uidNum = 0; uidNum < nUids; uidNum++) { + ArrayMap<String, DiscretePackageOps> pkgs = discreteOps.mUids.valueAt(uidNum).mPackages; + int uid = discreteOps.mUids.keyAt(uidNum); + int nPackages = pkgs.size(); + for (int pkgNum = 0; pkgNum < nPackages; pkgNum++) { + ArrayMap<Integer, DiscreteOp> ops = pkgs.valueAt(pkgNum).mPackageOps; + String pkg = pkgs.keyAt(pkgNum); + int nOps = ops.size(); + for (int opNum = 0; opNum < nOps; opNum++) { + ArrayMap<String, List<DiscreteOpEvent>> attrOps = + ops.valueAt(opNum).mAttributedOps; + int op = ops.keyAt(opNum); + int nAttrOps = attrOps.size(); + for (int attrOpNum = 0; attrOpNum < nAttrOps; attrOpNum++) { + List<DiscreteOpEvent> opEvents = attrOps.valueAt(attrOpNum); + String attributionTag = attrOps.keyAt(attrOpNum); + int nOpEvents = opEvents.size(); + for (int opEventNum = 0; opEventNum < nOpEvents; opEventNum++) { + DiscreteOpEvent event = opEvents.get(opEventNum); + if (event == null + || event.mAttributionChainId == ATTRIBUTION_CHAIN_ID_NONE) { + continue; + } + + if (!chains.containsKey(event.mAttributionChainId)) { + chains.put(event.mAttributionChainId, + new AttributionChain(attributionExemptPkgs)); + } + chains.get(event.mAttributionChainId) + .addEvent(pkg, uid, attributionTag, op, event); + } + } + } + } + } + return chains; + } + private void readDiscreteOpsFromDisk(DiscreteOps discreteOps) { synchronized (mOnDiskLock) { long beginTimeMillis = Instant.now().minus(sDiscreteHistoryCutoff, @@ -389,7 +442,7 @@ final class DiscreteRegistry { String[] opNamesFilter = dumpOp == OP_NONE ? null : new String[]{AppOpsManager.opToPublicName(dumpOp)}; discreteOps.filter(0, Instant.now().toEpochMilli(), filter, uidFilter, packageNameFilter, - opNamesFilter, attributionTagFilter, OP_FLAGS_ALL); + opNamesFilter, attributionTagFilter, OP_FLAGS_ALL, new ArrayMap<>()); pw.print(prefix); pw.print("Largest chain id: "); pw.print(mDiscreteOps.mLargestChainId); @@ -419,6 +472,134 @@ final class DiscreteRegistry { } } + /** + * Represents a chain of usages, each attributing its usage to the one before it + */ + private static final class AttributionChain { + private static final class OpEvent { + String mPkgName; + int mUid; + String mAttributionTag; + int mOpCode; + DiscreteOpEvent mOpEvent; + + OpEvent(String pkgName, int uid, String attributionTag, int opCode, + DiscreteOpEvent event) { + mPkgName = pkgName; + mUid = uid; + mAttributionTag = attributionTag; + mOpCode = opCode; + mOpEvent = event; + } + + public boolean matches(String pkgName, int uid, String attributionTag, int opCode, + DiscreteOpEvent event) { + return Objects.equals(pkgName, mPkgName) && mUid == uid + && Objects.equals(attributionTag, mAttributionTag) && mOpCode == opCode + && mOpEvent.mAttributionChainId == event.mAttributionChainId + && mOpEvent.mAttributionFlags == event.mAttributionFlags + && mOpEvent.mNoteTime == event.mNoteTime; + } + + public boolean packageOpEquals(OpEvent other) { + return Objects.equals(other.mPkgName, mPkgName) && other.mUid == mUid + && Objects.equals(other.mAttributionTag, mAttributionTag) + && mOpCode == other.mOpCode; + } + + public boolean equalsExceptDuration(OpEvent other) { + if (other.mOpEvent.mNoteDuration == mOpEvent.mNoteDuration) { + return false; + } + return packageOpEquals(other) && mOpEvent.equalsExceptDuration(other.mOpEvent); + } + } + + ArrayList<OpEvent> mChain = new ArrayList<>(); + Set<String> mExemptPkgs; + OpEvent mStartEvent = null; + OpEvent mLastVisibleEvent = null; + + AttributionChain(Set<String> exemptPkgs) { + mExemptPkgs = exemptPkgs; + } + + boolean isComplete() { + return !mChain.isEmpty() && getStart() != null && isEnd(mChain.get(mChain.size() - 1)); + } + + boolean isStart(String pkgName, int uid, String attributionTag, int op, + DiscreteOpEvent opEvent) { + if (mStartEvent == null || opEvent == null) { + return false; + } + return mStartEvent.matches(pkgName, uid, attributionTag, op, opEvent); + } + + private OpEvent getStart() { + return mChain.isEmpty() || !isStart(mChain.get(0)) ? null : mChain.get(0); + } + + private OpEvent getLastVisible() { + // Search all nodes but the first one, which is the start node + for (int i = mChain.size() - 1; i > 0; i--) { + OpEvent event = mChain.get(i); + if (!mExemptPkgs.contains(event.mPkgName)) { + return event; + } + } + return null; + } + + void addEvent(String pkgName, int uid, String attributionTag, int op, + DiscreteOpEvent opEvent) { + OpEvent event = new OpEvent(pkgName, uid, attributionTag, op, opEvent); + + // check if we have a matching event, without duration, replacing duration otherwise + for (int i = 0; i < mChain.size(); i++) { + OpEvent item = mChain.get(i); + if (item.equalsExceptDuration(event)) { + if (event.mOpEvent.mNoteDuration != -1) { + item.mOpEvent = event.mOpEvent; + } + return; + } + } + + if (mChain.isEmpty() || isEnd(event)) { + mChain.add(event); + } else if (isStart(event)) { + mChain.add(0, event); + + } else { + for (int i = 0; i < mChain.size(); i++) { + OpEvent currEvent = mChain.get(i); + if ((!isStart(currEvent) + && currEvent.mOpEvent.mNoteTime > event.mOpEvent.mNoteTime) + || i == mChain.size() - 1 && isEnd(currEvent)) { + mChain.add(i, event); + break; + } else if (i == mChain.size() - 1) { + mChain.add(event); + break; + } + } + } + mStartEvent = isComplete() ? getStart() : null; + mLastVisibleEvent = isComplete() ? getLastVisible() : null; + } + + private boolean isEnd(OpEvent event) { + return event != null + && (event.mOpEvent.mAttributionFlags & ATTRIBUTION_FLAG_ACCESSOR) != 0; + } + + private boolean isStart(OpEvent event) { + return event != null + && (event.mOpEvent.mAttributionFlags & ATTRIBUTION_FLAG_RECEIVER) != 0; + } + } + private final class DiscreteOps { ArrayMap<Integer, DiscreteUidOps> mUids; int mChainIdOffset; @@ -448,25 +629,27 @@ final class DiscreteRegistry { @Nullable String attributionTag, @AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState, long accessTime, long accessDuration, @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) { + int offsetChainId = attributionChainId; if (attributionChainId != ATTRIBUTION_CHAIN_ID_NONE) { - attributionChainId += mChainIdOffset; - if (attributionChainId < 0) { - attributionChainId -= mChainIdOffset; - mChainIdOffset = 0; - mLargestChainId = attributionChainId; - } - if (attributionChainId > mLargestChainId) { - mLargestChainId = attributionChainId; + offsetChainId = attributionChainId + mChainIdOffset; + if (offsetChainId > mLargestChainId) { + mLargestChainId = offsetChainId; + } else if (offsetChainId < 0) { + // handle overflow + offsetChainId = 0; + mLargestChainId = 0; + mChainIdOffset = -1 * attributionChainId; } } getOrCreateDiscreteUidOps(uid).addDiscreteAccess(op, packageName, attributionTag, flags, - uidState, accessTime, accessDuration, attributionFlags, attributionChainId); + uidState, accessTime, accessDuration, attributionFlags, offsetChainId); } private void filter(long beginTimeMillis, long endTimeMillis, @AppOpsManager.HistoricalOpsRequestFilter int filter, int uidFilter, @Nullable String packageNameFilter, @Nullable String[] opNamesFilter, - @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter) { + @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter, + ArrayMap<Integer, AttributionChain> attributionChains) { if ((filter & FILTER_BY_UID) != 0) { ArrayMap<Integer, DiscreteUidOps> uids = new ArrayMap<>(); uids.put(uidFilter, getOrCreateDiscreteUidOps(uidFilter)); @@ -475,7 +658,8 @@ final class DiscreteRegistry { int nUids = mUids.size(); for (int i = nUids - 1; i >= 0; i--) { mUids.valueAt(i).filter(beginTimeMillis, endTimeMillis, filter, packageNameFilter, - opNamesFilter, attributionTagFilter, flagsFilter); + opNamesFilter, attributionTagFilter, flagsFilter, mUids.keyAt(i), + attributionChains); if (mUids.valueAt(i).isEmpty()) { mUids.removeAt(i); } @@ -498,10 +682,11 @@ final class DiscreteRegistry { } } - private void applyToHistoricalOps(AppOpsManager.HistoricalOps result) { + private void applyToHistoricalOps(AppOpsManager.HistoricalOps result, + ArrayMap<Integer, AttributionChain> attributionChains) { int nUids = mUids.size(); for (int i = 0; i < nUids; i++) { - mUids.valueAt(i).applyToHistory(result, mUids.keyAt(i)); + mUids.valueAt(i).applyToHistory(result, mUids.keyAt(i), attributionChains); } } @@ -668,7 +853,8 @@ final class DiscreteRegistry { private void filter(long beginTimeMillis, long endTimeMillis, @AppOpsManager.HistoricalOpsRequestFilter int filter, @Nullable String packageNameFilter, @Nullable String[] opNamesFilter, - @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter) { + @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter, + int currentUid, ArrayMap<Integer, AttributionChain> attributionChains) { if ((filter & FILTER_BY_PACKAGE_NAME) != 0) { ArrayMap<String, DiscretePackageOps> packages = new ArrayMap<>(); packages.put(packageNameFilter, getOrCreateDiscretePackageOps(packageNameFilter)); @@ -677,7 +863,8 @@ final class DiscreteRegistry { int nPackages = mPackages.size(); for (int i = nPackages - 1; i >= 0; i--) { mPackages.valueAt(i).filter(beginTimeMillis, endTimeMillis, filter, opNamesFilter, - attributionTagFilter, flagsFilter); + attributionTagFilter, flagsFilter, currentUid, mPackages.keyAt(i), + attributionChains); if (mPackages.valueAt(i).isEmpty()) { mPackages.removeAt(i); } @@ -712,10 +899,12 @@ final class DiscreteRegistry { return result; } - private void applyToHistory(AppOpsManager.HistoricalOps result, int uid) { + private void applyToHistory(AppOpsManager.HistoricalOps result, int uid, + @NonNull ArrayMap<Integer, AttributionChain> attributionChains) { int nPackages = mPackages.size(); for (int i = 0; i < nPackages; i++) { - mPackages.valueAt(i).applyToHistory(result, uid, mPackages.keyAt(i)); + mPackages.valueAt(i).applyToHistory(result, uid, mPackages.keyAt(i), + attributionChains); } } @@ -783,7 +972,8 @@ final class DiscreteRegistry { private void filter(long beginTimeMillis, long endTimeMillis, @AppOpsManager.HistoricalOpsRequestFilter int filter, @Nullable String[] opNamesFilter, @Nullable String attributionTagFilter, - @AppOpsManager.OpFlags int flagsFilter) { + @AppOpsManager.OpFlags int flagsFilter, int currentUid, String currentPkgName, + ArrayMap<Integer, AttributionChain> attributionChains) { int nOps = mPackageOps.size(); for (int i = nOps - 1; i >= 0; i--) { int opId = mPackageOps.keyAt(i); @@ -793,7 +983,8 @@ final class DiscreteRegistry { continue; } mPackageOps.valueAt(i).filter(beginTimeMillis, endTimeMillis, filter, - attributionTagFilter, flagsFilter); + attributionTagFilter, flagsFilter, currentUid, currentPkgName, + mPackageOps.keyAt(i), attributionChains); if (mPackageOps.valueAt(i).isEmpty()) { mPackageOps.removeAt(i); } @@ -817,11 +1008,12 @@ final class DiscreteRegistry { } private void applyToHistory(AppOpsManager.HistoricalOps result, int uid, - @NonNull String packageName) { + @NonNull String packageName, + @NonNull ArrayMap<Integer, AttributionChain> attributionChains) { int nPackageOps = mPackageOps.size(); for (int i = 0; i < nPackageOps; i++) { mPackageOps.valueAt(i).applyToHistory(result, uid, packageName, - mPackageOps.keyAt(i)); + mPackageOps.keyAt(i), attributionChains); } } @@ -880,7 +1072,9 @@ final class DiscreteRegistry { private void filter(long beginTimeMillis, long endTimeMillis, @AppOpsManager.HistoricalOpsRequestFilter int filter, - @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter) { + @Nullable String attributionTagFilter, @AppOpsManager.OpFlags int flagsFilter, + int currentUid, String currentPkgName, int currentOp, + ArrayMap<Integer, AttributionChain> attributionChains) { if ((filter & FILTER_BY_ATTRIBUTION_TAG) != 0) { ArrayMap<String, List<DiscreteOpEvent>> attributedOps = new ArrayMap<>(); attributedOps.put(attributionTagFilter, @@ -892,7 +1086,9 @@ final class DiscreteRegistry { for (int i = nTags - 1; i >= 0; i--) { String tag = mAttributedOps.keyAt(i); List<DiscreteOpEvent> list = mAttributedOps.valueAt(i); - list = filterEventsList(list, beginTimeMillis, endTimeMillis, flagsFilter); + list = filterEventsList(list, beginTimeMillis, endTimeMillis, flagsFilter, + currentUid, currentPkgName, currentOp, mAttributedOps.keyAt(i), + attributionChains); mAttributedOps.put(tag, list); if (list.size() == 0) { mAttributedOps.removeAt(i); @@ -954,7 +1150,8 @@ final class DiscreteRegistry { } private void applyToHistory(AppOpsManager.HistoricalOps result, int uid, - @NonNull String packageName, int op) { + @NonNull String packageName, int op, + @NonNull ArrayMap<Integer, AttributionChain> attributionChains) { int nOps = mAttributedOps.size(); for (int i = 0; i < nOps; i++) { String tag = mAttributedOps.keyAt(i); @@ -962,9 +1159,21 @@ final class DiscreteRegistry { int nEvents = events.size(); for (int j = 0; j < nEvents; j++) { DiscreteOpEvent event = events.get(j); + AppOpsManager.OpEventProxyInfo proxy = null; + if (event.mAttributionChainId != ATTRIBUTION_CHAIN_ID_NONE + && attributionChains != null) { + AttributionChain chain = attributionChains.get(event.mAttributionChainId); + if (chain != null && chain.isComplete() + && chain.isStart(packageName, uid, tag, op, event) + && chain.mLastVisibleEvent != null) { + AttributionChain.OpEvent proxyEvent = chain.mLastVisibleEvent; + proxy = new AppOpsManager.OpEventProxyInfo(proxyEvent.mUid, + proxyEvent.mPkgName, proxyEvent.mAttributionTag); + } + } result.addDiscreteAccess(op, uid, packageName, tag, event.mUidState, event.mOpFlag, discretizeTimeStamp(event.mNoteTime), - discretizeDuration(event.mNoteDuration)); + discretizeDuration(event.mNoteDuration), proxy); } } } @@ -1059,6 +1268,13 @@ final class DiscreteRegistry { mAttributionChainId = attributionChainId; } + public boolean equalsExceptDuration(DiscreteOpEvent o) { + return mNoteTime == o.mNoteTime && mUidState == o.mUidState && mOpFlag == o.mOpFlag + && mAttributionFlags == o.mAttributionFlags + && mAttributionChainId == o.mAttributionChainId; + + } + private void dump(@NonNull PrintWriter pw, @NonNull SimpleDateFormat sdf, @NonNull Date date, @NonNull String prefix) { pw.print(prefix); @@ -1141,11 +1357,20 @@ final class DiscreteRegistry { } private static List<DiscreteOpEvent> filterEventsList(List<DiscreteOpEvent> list, - long beginTimeMillis, long endTimeMillis, @AppOpsManager.OpFlags int flagsFilter) { + long beginTimeMillis, long endTimeMillis, @AppOpsManager.OpFlags int flagsFilter, + int currentUid, String currentPackageName, int currentOp, String currentAttrTag, + ArrayMap<Integer, AttributionChain> attributionChains) { int n = list.size(); List<DiscreteOpEvent> result = new ArrayList<>(n); for (int i = 0; i < n; i++) { DiscreteOpEvent event = list.get(i); + AttributionChain chain = attributionChains.get(event.mAttributionChainId); + // If we have an attribution chain, and this event isn't the beginning node, remove it + if (chain != null && !chain.isStart(currentPackageName, currentUid, currentAttrTag, + currentOp, event) && chain.isComplete() + && event.mAttributionChainId != ATTRIBUTION_CHAIN_ID_NONE) { + continue; + } if ((event.mOpFlag & flagsFilter) != 0 && event.mNoteTime + event.mNoteDuration > beginTimeMillis && event.mNoteTime < endTimeMillis) { diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java index 62472b5f1d75..2c68aaf4f3e5 100644 --- a/services/core/java/com/android/server/appop/HistoricalRegistry.java +++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java @@ -370,7 +370,7 @@ final class HistoricalRegistry { @Nullable String attributionTag, @Nullable String[] opNames, @OpHistoryFlags int historyFlags, @HistoricalOpsRequestFilter int filter, long beginTimeMillis, long endTimeMillis, @OpFlags int flags, - @NonNull RemoteCallback callback) { + String[] attributionExemptedPackages, @NonNull RemoteCallback callback) { if (!isApiEnabled()) { callback.sendResult(new Bundle()); return; @@ -396,7 +396,7 @@ final class HistoricalRegistry { if ((historyFlags & HISTORY_FLAG_DISCRETE) != 0) { mDiscreteRegistry.addFilteredDiscreteOpsToHistoricalOps(result, beginTimeMillis, endTimeMillis, filter, uid, packageName, opNames, attributionTag, - flags); + flags, new ArraySet<>(attributionExemptedPackages)); } final Bundle payload = new Bundle(); @@ -407,7 +407,8 @@ final class HistoricalRegistry { void getHistoricalOps(int uid, @Nullable String packageName, @Nullable String attributionTag, @Nullable String[] opNames, @OpHistoryFlags int historyFlags, @HistoricalOpsRequestFilter int filter, long beginTimeMillis, long endTimeMillis, - @OpFlags int flags, @NonNull RemoteCallback callback) { + @OpFlags int flags, @Nullable String[] attributionExemptPkgs, + @NonNull RemoteCallback callback) { if (!isApiEnabled()) { callback.sendResult(new Bundle()); return; @@ -429,7 +430,8 @@ final class HistoricalRegistry { if ((historyFlags & HISTORY_FLAG_DISCRETE) != 0) { mDiscreteRegistry.addFilteredDiscreteOpsToHistoricalOps(result, beginTimeMillis, - endTimeMillis, filter, uid, packageName, opNames, attributionTag, flags); + endTimeMillis, filter, uid, packageName, opNames, attributionTag, flags, + new ArraySet<>(attributionExemptPkgs)); } if ((historyFlags & HISTORY_FLAG_AGGREGATE) != 0) { diff --git a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java index fbf249237415..c8fb80ac3928 100644 --- a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java @@ -17,7 +17,6 @@ package com.android.server.biometrics.sensors; import android.annotation.NonNull; -import android.annotation.Nullable; import android.content.Context; import android.hardware.biometrics.BiometricConstants; import android.media.AudioAttributes; @@ -27,7 +26,6 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.VibrationEffect; import android.os.Vibrator; -import android.text.TextUtils; import android.util.Slog; /** @@ -39,24 +37,18 @@ public abstract class AcquisitionClient<T> extends HalClientMonitor<T> implement private static final String TAG = "Biometrics/AcquisitionClient"; - private static final AudioAttributes VIBRATION_SONFICATION_ATTRIBUTES = + private static final AudioAttributes VIBRATION_SONIFICATION_ATTRIBUTES = new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) .build(); - private final VibrationEffect mEffectTick = VibrationEffect.get(VibrationEffect.EFFECT_TICK); - private final VibrationEffect mEffectTextureTick = - VibrationEffect.get(VibrationEffect.EFFECT_TEXTURE_TICK); - private final VibrationEffect mEffectClick = VibrationEffect.get(VibrationEffect.EFFECT_CLICK); - private final VibrationEffect mEffectHeavy = - VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK); - private final VibrationEffect mDoubleClick = + private static final VibrationEffect SUCCESS_VIBRATION_EFFECT = + VibrationEffect.get(VibrationEffect.EFFECT_CLICK); + private static final VibrationEffect ERROR_VIBRATION_EFFECT = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK); private final PowerManager mPowerManager; - private final VibrationEffect mSuccessVibrationEffect; - private final VibrationEffect mErrorVibrationEffect; private boolean mShouldSendErrorToClient = true; private boolean mAlreadyCancelled; @@ -72,8 +64,6 @@ public abstract class AcquisitionClient<T> extends HalClientMonitor<T> implement super(context, lazyDaemon, token, listener, userId, owner, cookie, sensorId, statsModality, statsAction, statsClient); mPowerManager = context.getSystemService(PowerManager.class); - mSuccessVibrationEffect = mEffectClick; - mErrorVibrationEffect = mDoubleClick; } @Override @@ -192,47 +182,31 @@ public abstract class AcquisitionClient<T> extends HalClientMonitor<T> implement mPowerManager.userActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0); } - protected @NonNull VibrationEffect getSuccessVibrationEffect() { - return mSuccessVibrationEffect; + protected boolean successHapticsEnabled() { + return true; } - protected @NonNull VibrationEffect getErrorVibrationEffect() { - return mErrorVibrationEffect; + protected boolean errorHapticsEnabled() { + return true; } protected final void vibrateSuccess() { + if (!successHapticsEnabled()) { + return; + } Vibrator vibrator = getContext().getSystemService(Vibrator.class); if (vibrator != null) { - vibrator.vibrate(getSuccessVibrationEffect(), VIBRATION_SONFICATION_ATTRIBUTES); + vibrator.vibrate(SUCCESS_VIBRATION_EFFECT, VIBRATION_SONIFICATION_ATTRIBUTES); } } protected final void vibrateError() { + if (!errorHapticsEnabled()) { + return; + } Vibrator vibrator = getContext().getSystemService(Vibrator.class); if (vibrator != null) { - vibrator.vibrate(getErrorVibrationEffect(), VIBRATION_SONFICATION_ATTRIBUTES); - } - } - - protected final @NonNull VibrationEffect getVibration(@Nullable String effect, - @NonNull VibrationEffect defaultEffect) { - if (TextUtils.isEmpty(effect)) { - return defaultEffect; - } - - switch (effect.toLowerCase()) { - case "click": - return mEffectClick; - case "heavy": - return mEffectHeavy; - case "texture_tick": - return mEffectTextureTick; - case "tick": - return mEffectTick; - case "double_click": - return mDoubleClick; - default: - return defaultEffect; + vibrator.vibrate(ERROR_VIBRATION_EFFECT, VIBRATION_SONIFICATION_ATTRIBUTES); } } } diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java index 86688287cc9d..cf545f37bd43 100644 --- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java @@ -22,7 +22,6 @@ import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.TaskStackListener; import android.content.ComponentName; -import android.content.ContentResolver; import android.content.Context; import android.content.pm.ApplicationInfo; import android.hardware.biometrics.BiometricAuthenticator; @@ -31,8 +30,6 @@ import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricsProtoEnums; import android.os.IBinder; import android.os.RemoteException; -import android.os.VibrationEffect; -import android.provider.Settings; import android.security.KeyStore; import android.util.EventLog; import android.util.Slog; @@ -59,14 +56,12 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> private final LockoutTracker mLockoutTracker; private final boolean mIsRestricted; private final boolean mAllowBackgroundAuthentication; - @NonNull private final ContentResolver mContentResolver; protected final long mOperationId; private long mStartTimeMs; protected boolean mAuthAttempted; - private final boolean mCustomHaptics; public AuthenticationClient(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, @@ -85,10 +80,6 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> mLockoutTracker = lockoutTracker; mIsRestricted = restricted; mAllowBackgroundAuthentication = allowBackgroundAuthentication; - - mContentResolver = context.getContentResolver(); - mCustomHaptics = Settings.Global.getInt(mContentResolver, - "fp_custom_success_error", 0) == 1; } public @LockoutTracker.LockoutMode int handleFailedAttempt(int userId) { @@ -342,25 +333,4 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T> public boolean interruptsPrecedingClients() { return true; } - - @Override - protected @NonNull VibrationEffect getSuccessVibrationEffect() { - if (!mCustomHaptics) { - return super.getSuccessVibrationEffect(); - } - - return getVibration(Settings.Global.getString(mContentResolver, - "fp_success_type"), super.getSuccessVibrationEffect()); - } - - @Override - protected @NonNull VibrationEffect getErrorVibrationEffect() { - if (!mCustomHaptics) { - return super.getErrorVibrationEffect(); - } - - return getVibration(Settings.Global.getString(mContentResolver, - "fp_error_type"), super.getErrorVibrationEffect()); - - } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/ReEnrollNotificationUtils.java b/services/core/java/com/android/server/biometrics/sensors/BiometricNotificationUtils.java index f35a5208f6ed..1f1309d4c48c 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/ReEnrollNotificationUtils.java +++ b/services/core/java/com/android/server/biometrics/sensors/BiometricNotificationUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.biometrics.sensors.face; +package com.android.server.biometrics.sensors; import android.annotation.NonNull; import android.app.Notification; @@ -27,11 +27,18 @@ import android.os.UserHandle; import com.android.internal.R; -public class ReEnrollNotificationUtils { +/** + * Biometric notification helper class. + */ +public class BiometricNotificationUtils { - private static final String NOTIFICATION_TAG = "FaceService"; + private static final String RE_ENROLL_NOTIFICATION_TAG = "FaceService"; + private static final String BAD_CALIBRATION_NOTIFICATION_TAG = "FingerprintService"; private static final int NOTIFICATION_ID = 1; + /** + * Shows a face re-enrollment notification. + */ public static void showReEnrollmentNotification(@NonNull Context context) { final NotificationManager notificationManager = context.getSystemService(NotificationManager.class); @@ -52,6 +59,42 @@ public class ReEnrollNotificationUtils { final String channelName = "FaceEnrollNotificationChannel"; + showNotificationHelper(context, name, title, content, pendingIntent, channelName, + RE_ENROLL_NOTIFICATION_TAG); + } + + /** + * Shows a fingerprint bad calibration notification. + */ + public static void showBadCalibrationNotification(@NonNull Context context) { + final NotificationManager notificationManager = + context.getSystemService(NotificationManager.class); + + final String name = + context.getString(R.string.fingerprint_recalibrate_notification_name); + final String title = + context.getString(R.string.fingerprint_recalibrate_notification_title); + final String content = + context.getString(R.string.fingerprint_recalibrate_notification_content); + + final Intent intent = new Intent("android.settings.FINGERPRINT_SETTINGS"); + intent.setPackage("com.android.settings"); + + final PendingIntent pendingIntent = PendingIntent.getActivityAsUser(context, + 0 /* requestCode */, intent, PendingIntent.FLAG_IMMUTABLE /* flags */, + null /* options */, UserHandle.CURRENT); + + final String channelName = "FingerprintBadCalibrationNotificationChannel"; + + showNotificationHelper(context, name, title, content, pendingIntent, channelName, + BAD_CALIBRATION_NOTIFICATION_TAG); + } + + private static void showNotificationHelper(Context context, String name, String title, + String content, PendingIntent pendingIntent, String channelName, + String notificationTag) { + final NotificationManager notificationManager = + context.getSystemService(NotificationManager.class); final NotificationChannel channel = new NotificationChannel(channelName, name, NotificationManager.IMPORTANCE_HIGH); final Notification notification = new Notification.Builder(context, channelName) @@ -68,15 +111,28 @@ public class ReEnrollNotificationUtils { .build(); notificationManager.createNotificationChannel(channel); - notificationManager.notifyAsUser(NOTIFICATION_TAG, - NOTIFICATION_ID, notification, + notificationManager.notifyAsUser(notificationTag, NOTIFICATION_ID, notification, UserHandle.CURRENT); } - public static void cancelNotification(@NonNull Context context) { + /** + * Cancels a face re-enrollment notification + */ + public static void cancelReEnrollNotification(@NonNull Context context) { final NotificationManager notificationManager = context.getSystemService(NotificationManager.class); - notificationManager.cancelAsUser(NOTIFICATION_TAG, NOTIFICATION_ID, UserHandle.CURRENT); + notificationManager.cancelAsUser(RE_ENROLL_NOTIFICATION_TAG, NOTIFICATION_ID, + UserHandle.CURRENT); + } + + /** + * Cancels a fingerprint bad calibration notification + */ + public static void cancelBadCalibrationNotification(@NonNull Context context) { + final NotificationManager notificationManager = + context.getSystemService(NotificationManager.class); + notificationManager.cancelAsUser(BAD_CALIBRATION_NOTIFICATION_TAG, NOTIFICATION_ID, + UserHandle.CURRENT); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java index aa507901ab78..b52cb70d90e3 100644 --- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java +++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java @@ -110,11 +110,21 @@ public class BiometricScheduler { @Nullable final BaseClientMonitor.Callback mClientCallback; @OperationState int mState; - Operation(@NonNull BaseClientMonitor clientMonitor, - @Nullable BaseClientMonitor.Callback callback) { - this.mClientMonitor = clientMonitor; - this.mClientCallback = callback; - mState = STATE_WAITING_IN_QUEUE; + Operation( + @NonNull BaseClientMonitor clientMonitor, + @Nullable BaseClientMonitor.Callback callback + ) { + this(clientMonitor, callback, STATE_WAITING_IN_QUEUE); + } + + protected Operation( + @NonNull BaseClientMonitor clientMonitor, + @Nullable BaseClientMonitor.Callback callback, + @OperationState int state + ) { + mClientMonitor = clientMonitor; + mClientCallback = callback; + mState = state; } public boolean isHalOperation() { diff --git a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java index f015a80d338d..c4c98e362a43 100644 --- a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java +++ b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java @@ -50,16 +50,26 @@ public class UserAwareBiometricScheduler extends BiometricScheduler { @NonNull private final CurrentUserRetriever mCurrentUserRetriever; @NonNull private final UserSwitchCallback mUserSwitchCallback; - @NonNull @VisibleForTesting final ClientFinishedCallback mClientFinishedCallback; - @Nullable private StopUserClient<?> mStopUserClient; - @VisibleForTesting - class ClientFinishedCallback implements BaseClientMonitor.Callback { + private class ClientFinishedCallback implements BaseClientMonitor.Callback { + private final BaseClientMonitor mOwner; + + ClientFinishedCallback(BaseClientMonitor owner) { + mOwner = owner; + } + @Override public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, boolean success) { mHandler.post(() -> { - Slog.d(getTag(), "[Client finished] " + clientMonitor + ", success: " + success); + if (mOwner == clientMonitor && mOwner == mCurrentOperation.mClientMonitor) { + Slog.d(getTag(), "[Client finished] " + + clientMonitor + ", success: " + success); + mCurrentOperation = null; + } else { + Slog.e(getTag(), "[Client finished, but not current operation], actual: " + + mCurrentOperation + ", expected: " + mOwner); + } startNextOperationIfIdle(); }); @@ -76,7 +86,6 @@ public class UserAwareBiometricScheduler extends BiometricScheduler { mCurrentUserRetriever = currentUserRetriever; mUserSwitchCallback = userSwitchCallback; - mClientFinishedCallback = new ClientFinishedCallback(); } public UserAwareBiometricScheduler(@NonNull String tag, @@ -112,17 +121,27 @@ public class UserAwareBiometricScheduler extends BiometricScheduler { } else if (currentUserId == UserHandle.USER_NULL) { final BaseClientMonitor startClient = mUserSwitchCallback.getStartUserClient(nextUserId); + final ClientFinishedCallback finishedCallback = + new ClientFinishedCallback(startClient); + Slog.d(getTag(), "[Starting User] " + startClient); - startClient.start(mClientFinishedCallback); + startClient.start(finishedCallback); + mCurrentOperation = new Operation( + startClient, finishedCallback, Operation.STATE_STARTED); } else { if (mStopUserClient != null) { Slog.d(getTag(), "[Waiting for StopUser] " + mStopUserClient); } else { mStopUserClient = mUserSwitchCallback .getStopUserClient(currentUserId); + final ClientFinishedCallback finishedCallback = + new ClientFinishedCallback(mStopUserClient); + Slog.d(getTag(), "[Stopping User] current: " + currentUserId + ", next: " + nextUserId + ". " + mStopUserClient); - mStopUserClient.start(mClientFinishedCallback); + mStopUserClient.start(finishedCallback); + mCurrentOperation = new Operation( + mStopUserClient, finishedCallback, Operation.STATE_STARTED); } } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java index 2adf5f98cee5..db927b227d9a 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java @@ -33,18 +33,17 @@ import android.hardware.face.FaceAuthenticationFrame; import android.hardware.face.FaceManager; import android.os.IBinder; import android.os.RemoteException; -import android.os.VibrationEffect; import android.provider.Settings; import android.util.Slog; import com.android.internal.R; import com.android.server.biometrics.Utils; import com.android.server.biometrics.sensors.AuthenticationClient; +import com.android.server.biometrics.sensors.BiometricNotificationUtils; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.LockoutCache; import com.android.server.biometrics.sensors.LockoutConsumer; import com.android.server.biometrics.sensors.LockoutTracker; -import com.android.server.biometrics.sensors.face.ReEnrollNotificationUtils; import com.android.server.biometrics.sensors.face.UsageStats; import java.util.ArrayList; @@ -182,7 +181,7 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements } break; case BiometricConstants.BIOMETRIC_ERROR_RE_ENROLL: - ReEnrollNotificationUtils.showReEnrollmentNotification(getContext()); + BiometricNotificationUtils.showReEnrollmentNotification(getContext()); break; default: break; @@ -264,22 +263,16 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements } @Override - protected @NonNull VibrationEffect getSuccessVibrationEffect() { - if (!mCustomHaptics) { - return super.getSuccessVibrationEffect(); - } - - return getVibration(Settings.Global.getString(mContentResolver, - "face_success_type"), super.getSuccessVibrationEffect()); + protected boolean successHapticsEnabled() { + return mCustomHaptics + ? Settings.Global.getInt(mContentResolver, "face_success_enabled", 1) == 0 + : super.successHapticsEnabled(); } @Override - protected @NonNull VibrationEffect getErrorVibrationEffect() { - if (!mCustomHaptics) { - return super.getErrorVibrationEffect(); - } - - return getVibration(Settings.Global.getString(mContentResolver, - "face_error_type"), super.getErrorVibrationEffect()); + protected boolean errorHapticsEnabled() { + return mCustomHaptics + ? Settings.Global.getInt(mContentResolver, "face_error_enabled", 1) == 0 + : super.errorHapticsEnabled(); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java index ff68aa87dbbb..0400e2257321 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java @@ -37,11 +37,11 @@ import android.util.Slog; import com.android.internal.R; import com.android.server.biometrics.HardwareAuthTokenUtils; import com.android.server.biometrics.Utils; +import com.android.server.biometrics.sensors.BiometricNotificationUtils; import com.android.server.biometrics.sensors.BiometricUtils; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.EnrollClient; import com.android.server.biometrics.sensors.face.FaceUtils; -import com.android.server.biometrics.sensors.face.ReEnrollNotificationUtils; import java.io.IOException; import java.util.ArrayList; @@ -92,7 +92,7 @@ public class FaceEnrollClient extends EnrollClient<ISession> { public void start(@NonNull Callback callback) { super.start(callback); - ReEnrollNotificationUtils.cancelNotification(getContext()); + BiometricNotificationUtils.cancelReEnrollNotification(getContext()); } @NonNull diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGenerateChallengeClient.java index d76036bf432d..7cdeebb87fec 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGenerateChallengeClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGenerateChallengeClient.java @@ -52,7 +52,13 @@ public class FaceGenerateChallengeClient extends GenerateChallengeClient<ISessio void onChallengeGenerated(int sensorId, int userId, long challenge) { try { - getListener().onChallengeGenerated(sensorId, userId, challenge); + final ClientMonitorCallbackConverter listener = getListener(); + if (listener == null) { + Slog.e(TAG, "Listener is null in onChallengeGenerated"); + mCallback.onClientFinished(this, false /* success */); + return; + } + listener.onChallengeGenerated(sensorId, userId, challenge); mCallback.onClientFinished(this, true /* success */); } catch (RemoteException e) { Slog.e(TAG, "Unable to send challenge", e); diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java index a5bb0f430609..26c5bca7f726 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java @@ -57,6 +57,7 @@ import com.android.server.biometrics.Utils; import com.android.server.biometrics.sensors.AcquisitionClient; import com.android.server.biometrics.sensors.AuthenticationConsumer; import com.android.server.biometrics.sensors.BaseClientMonitor; +import com.android.server.biometrics.sensors.BiometricNotificationUtils; import com.android.server.biometrics.sensors.BiometricScheduler; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.EnumerateConsumer; @@ -68,7 +69,6 @@ import com.android.server.biometrics.sensors.PerformanceTracker; import com.android.server.biometrics.sensors.RemovalConsumer; import com.android.server.biometrics.sensors.face.FaceUtils; import com.android.server.biometrics.sensors.face.LockoutHalImpl; -import com.android.server.biometrics.sensors.face.ReEnrollNotificationUtils; import com.android.server.biometrics.sensors.face.ServiceProvider; import com.android.server.biometrics.sensors.face.UsageStats; @@ -574,7 +574,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { mHandler.post(() -> { scheduleUpdateActiveUserWithoutHandler(userId); - ReEnrollNotificationUtils.cancelNotification(mContext); + BiometricNotificationUtils.cancelReEnrollNotification(mContext); final FaceEnrollClient client = new FaceEnrollClient(mContext, mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken, @@ -866,7 +866,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { private void scheduleUpdateActiveUserWithoutHandler(int targetUserId) { final boolean hasEnrolled = !getEnrolledFaces(mSensorId, targetUserId).isEmpty(); final FaceUpdateActiveUserClient client = new FaceUpdateActiveUserClient(mContext, - mLazyDaemon, targetUserId, mContext.getOpPackageName(), mSensorId, mCurrentUserId, + mLazyDaemon, targetUserId, mContext.getOpPackageName(), mSensorId, hasEnrolled, mAuthenticatorIds); mScheduler.scheduleClientMonitor(client, new BaseClientMonitor.Callback() { @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java index 01dd18fb5cf0..6c0adafcf2ee 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java @@ -28,16 +28,15 @@ import android.hardware.biometrics.face.V1_0.IBiometricsFace; import android.hardware.face.FaceManager; import android.os.IBinder; import android.os.RemoteException; -import android.os.VibrationEffect; import android.provider.Settings; import android.util.Slog; import com.android.internal.R; import com.android.server.biometrics.Utils; import com.android.server.biometrics.sensors.AuthenticationClient; +import com.android.server.biometrics.sensors.BiometricNotificationUtils; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.LockoutTracker; -import com.android.server.biometrics.sensors.face.ReEnrollNotificationUtils; import com.android.server.biometrics.sensors.face.UsageStats; import java.util.ArrayList; @@ -195,7 +194,7 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> { mLastAcquire = acquireInfo; if (acquireInfo == FaceManager.FACE_ACQUIRED_RECALIBRATE) { - ReEnrollNotificationUtils.showReEnrollmentNotification(getContext()); + BiometricNotificationUtils.showReEnrollmentNotification(getContext()); } final boolean shouldSend = shouldSend(acquireInfo, vendorCode); @@ -203,22 +202,16 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> { } @Override - protected @NonNull VibrationEffect getSuccessVibrationEffect() { - if (!mCustomHaptics) { - return super.getSuccessVibrationEffect(); - } - - return getVibration(Settings.Global.getString(mContentResolver, - "face_success_type"), super.getSuccessVibrationEffect()); + protected boolean successHapticsEnabled() { + return mCustomHaptics + ? Settings.Global.getInt(mContentResolver, "face_success_enabled", 1) == 0 + : super.successHapticsEnabled(); } @Override - protected @NonNull VibrationEffect getErrorVibrationEffect() { - if (!mCustomHaptics) { - return super.getErrorVibrationEffect(); - } - - return getVibration(Settings.Global.getString(mContentResolver, - "face_error_type"), super.getErrorVibrationEffect()); + protected boolean errorHapticsEnabled() { + return mCustomHaptics + ? Settings.Global.getInt(mContentResolver, "face_error_enabled", 1) == 0 + : super.errorHapticsEnabled(); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceUpdateActiveUserClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceUpdateActiveUserClient.java index 70e20339ce98..5343d0d17273 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceUpdateActiveUserClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceUpdateActiveUserClient.java @@ -34,38 +34,23 @@ public class FaceUpdateActiveUserClient extends HalClientMonitor<IBiometricsFace private static final String TAG = "FaceUpdateActiveUserClient"; private static final String FACE_DATA_DIR = "facedata"; - private final int mCurrentUserId; private final boolean mHasEnrolledBiometrics; @NonNull private final Map<Integer, Long> mAuthenticatorIds; FaceUpdateActiveUserClient(@NonNull Context context, - @NonNull LazyDaemon<IBiometricsFace> lazyDaemon, int userId, @NonNull String owner, - int sensorId, int currentUserId, boolean hasEnrolledBIometrics, + @NonNull LazyDaemon<IBiometricsFace> lazyDaemon, int userId, @NonNull String owner, + int sensorId, boolean hasEnrolledBiometrics, @NonNull Map<Integer, Long> authenticatorIds) { super(context, lazyDaemon, null /* token */, null /* listener */, userId, owner, 0 /* cookie */, sensorId, BiometricsProtoEnums.MODALITY_UNKNOWN, BiometricsProtoEnums.ACTION_UNKNOWN, BiometricsProtoEnums.CLIENT_UNKNOWN); - mCurrentUserId = currentUserId; - mHasEnrolledBiometrics = hasEnrolledBIometrics; + mHasEnrolledBiometrics = hasEnrolledBiometrics; mAuthenticatorIds = authenticatorIds; } @Override public void start(@NonNull Callback callback) { super.start(callback); - - if (mCurrentUserId == getTargetUserId()) { - Slog.d(TAG, "Already user: " + mCurrentUserId + ", refreshing authenticatorId"); - try { - mAuthenticatorIds.put(getTargetUserId(), mHasEnrolledBiometrics - ? getFreshDaemon().getAuthenticatorId().value : 0L); - } catch (RemoteException e) { - Slog.e(TAG, "Unable to refresh authenticatorId", e); - } - callback.onClientFinished(this, true /* success */); - return; - } - startHalOperation(); } @@ -85,7 +70,10 @@ public class FaceUpdateActiveUserClient extends HalClientMonitor<IBiometricsFace } try { - getFreshDaemon().setActiveUser(getTargetUserId(), storePath.getAbsolutePath()); + final IBiometricsFace daemon = getFreshDaemon(); + daemon.setActiveUser(getTargetUserId(), storePath.getAbsolutePath()); + mAuthenticatorIds.put(getTargetUserId(), + mHasEnrolledBiometrics ? daemon.getAuthenticatorId().value : 0L); mCallback.onClientFinished(this, true /* success */); } catch (RemoteException e) { Slog.e(TAG, "Failed to setActiveUser: " + e); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java index 3c9d802cb4b1..1825eda1375a 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java @@ -19,6 +19,7 @@ package com.android.server.biometrics.sensors.fingerprint.aidl; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.TaskStackListener; +import android.content.ContentResolver; import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricFingerprintConstants; @@ -29,10 +30,12 @@ import android.hardware.biometrics.fingerprint.ISession; import android.hardware.fingerprint.IUdfpsOverlayController; import android.os.IBinder; import android.os.RemoteException; +import android.provider.Settings; import android.util.Slog; import com.android.server.biometrics.Utils; import com.android.server.biometrics.sensors.AuthenticationClient; +import com.android.server.biometrics.sensors.BiometricNotificationUtils; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.LockoutCache; import com.android.server.biometrics.sensors.LockoutConsumer; @@ -54,6 +57,9 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp @Nullable private final IUdfpsOverlayController mUdfpsOverlayController; @Nullable private ICancellationSignal mCancellationSignal; + @NonNull private final ContentResolver mContentResolver; + private final boolean mCustomHaptics; + FingerprintAuthenticationClient(@NonNull Context context, @NonNull LazyDaemon<ISession> lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId, @@ -68,6 +74,10 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp lockoutCache, allowBackgroundAuthentication); mLockoutCache = lockoutCache; mUdfpsOverlayController = udfpsOverlayController; + + mContentResolver = context.getContentResolver(); + mCustomHaptics = Settings.Global.getInt(mContentResolver, + "fp_custom_success_error", 0) == 1; } @NonNull @@ -102,6 +112,10 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp public void onError(int errorCode, int vendorCode) { super.onError(errorCode, vendorCode); + if (errorCode == BiometricFingerprintConstants.FINGERPRINT_ERROR_BAD_CALIBARTION) { + BiometricNotificationUtils.showBadCalibrationNotification(getContext()); + } + UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); } @@ -178,6 +192,9 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp } catch (RemoteException e) { Slog.e(TAG, "Remote exception", e); } + + UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); + mCallback.onClientFinished(this, false /* success */); } @Override @@ -192,5 +209,22 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp } catch (RemoteException e) { Slog.e(TAG, "Remote exception", e); } + + UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); + mCallback.onClientFinished(this, false /* success */); + } + + @Override + protected boolean successHapticsEnabled() { + return mCustomHaptics + ? Settings.Global.getInt(mContentResolver, "fp_success_enabled", 1) == 0 + : super.successHapticsEnabled(); + } + + @Override + protected boolean errorHapticsEnabled() { + return mCustomHaptics + ? Settings.Global.getInt(mContentResolver, "fp_error_enabled", 1) == 0 + : super.errorHapticsEnabled(); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java index 11849661693b..646b988545be 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java @@ -35,6 +35,7 @@ import android.os.RemoteException; import android.util.Slog; import com.android.server.biometrics.HardwareAuthTokenUtils; +import com.android.server.biometrics.sensors.BiometricNotificationUtils; import com.android.server.biometrics.sensors.BiometricUtils; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.EnrollClient; @@ -150,6 +151,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps { UdfpsHelper.getReasonFromEnrollReason(mEnrollReason), mUdfpsOverlayController, this); SidefpsHelper.showOverlay(mSidefpsController); + BiometricNotificationUtils.cancelBadCalibrationNotification(getContext()); try { mCancellationSignal = getFreshDaemon().enroll( HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken)); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGenerateChallengeClient.java index 6d0148190a60..4f54f8ade7c0 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGenerateChallengeClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGenerateChallengeClient.java @@ -53,7 +53,13 @@ class FingerprintGenerateChallengeClient extends GenerateChallengeClient<ISessio void onChallengeGenerated(int sensorId, int userId, long challenge) { try { - getListener().onChallengeGenerated(sensorId, userId, challenge); + final ClientMonitorCallbackConverter listener = getListener(); + if (listener == null) { + Slog.e(TAG, "Listener is null in onChallengeGenerated"); + mCallback.onClientFinished(this, false /* success */); + return; + } + listener.onChallengeGenerated(sensorId, userId, challenge); mCallback.onClientFinished(this, true /* success */); } catch (RemoteException e) { Slog.e(TAG, "Unable to send challenge", e); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java index 45e35e34b62b..01136d619a26 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java @@ -32,6 +32,7 @@ import android.util.Slog; import com.android.server.biometrics.Utils; import com.android.server.biometrics.sensors.AuthenticationClient; +import com.android.server.biometrics.sensors.BiometricNotificationUtils; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.LockoutTracker; import com.android.server.biometrics.sensors.fingerprint.Udfps; @@ -111,6 +112,10 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi public void onError(int errorCode, int vendorCode) { super.onError(errorCode, vendorCode); + if (errorCode == BiometricFingerprintConstants.FINGERPRINT_ERROR_BAD_CALIBARTION) { + BiometricNotificationUtils.showBadCalibrationNotification(getContext()); + } + UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController); } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java index a28a3f6bd5c3..eba445f7e7b4 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java @@ -31,6 +31,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; +import com.android.server.biometrics.sensors.BiometricNotificationUtils; import com.android.server.biometrics.sensors.BiometricUtils; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.EnrollClient; @@ -97,6 +98,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint UdfpsHelper.getReasonFromEnrollReason(mEnrollReason), mUdfpsOverlayController, this); SidefpsHelper.showOverlay(mSidefpsController); + BiometricNotificationUtils.cancelBadCalibrationNotification(getContext()); try { // GroupId was never used. In fact, groupId is always the same as userId. getFreshDaemon().enroll(mHardwareAuthToken, getTargetUserId(), mTimeoutSec); diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java index c2375351aee9..de6e494a5581 100644 --- a/services/core/java/com/android/server/compat/CompatConfig.java +++ b/services/core/java/com/android/server/compat/CompatConfig.java @@ -603,6 +603,10 @@ final class CompatConfig { try (InputStream in = new BufferedInputStream(new FileInputStream(overridesFile))) { Overrides overrides = com.android.server.compat.overrides.XmlParser.read(in); + if (overrides == null) { + Slog.w(TAG, "Parsing " + overridesFile.getPath() + " failed"); + return; + } for (ChangeOverrides changeOverrides : overrides.getChangeOverrides()) { long changeId = changeOverrides.getChangeId(); CompatChange compatChange = mChanges.get(changeId); diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java index 19e858c25c41..0d317f4ba164 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -36,6 +36,7 @@ import android.content.pm.PackageManagerInternal; import android.net.Uri; import android.os.Binder; import android.os.Build; +import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.util.Slog; @@ -359,7 +360,7 @@ public class PlatformCompat extends IPlatformCompat.Stub { private ApplicationInfo getApplicationInfo(String packageName, int userId) { return LocalServices.getService(PackageManagerInternal.class).getApplicationInfo( - packageName, 0, userId, userId); + packageName, 0, Process.myUid(), userId); } private void killPackage(String packageName) { diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 182a038d10f7..0decd3393672 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -1528,8 +1528,14 @@ public final class DisplayManagerService extends SystemService { if (requestedModeId == 0 && requestedRefreshRate != 0) { // Scan supported modes returned by display.getInfo() to find a mode with the same // size as the default display mode but with the specified refresh rate instead. - requestedModeId = display.getDisplayInfoLocked().findDefaultModeByRefreshRate( - requestedRefreshRate).getModeId(); + Display.Mode mode = display.getDisplayInfoLocked().findDefaultModeByRefreshRate( + requestedRefreshRate); + if (mode != null) { + requestedModeId = mode.getModeId(); + } else { + Slog.e(TAG, "Couldn't find a mode for the requestedRefreshRate: " + + requestedRefreshRate + " on Display: " + displayId); + } } mDisplayModeDirector.getAppRequestObserver().setAppRequest( displayId, requestedModeId, requestedMaxRefreshRate); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java index 505e743ed9a1..a2cb78d27a57 100755 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java @@ -23,6 +23,7 @@ import android.hardware.hdmi.HdmiDeviceInfo; import android.hardware.hdmi.IHdmiControlCallback; import android.hardware.input.InputManager; import android.hardware.tv.cec.V1_0.SendMessageResult; +import android.media.AudioManager; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -685,6 +686,9 @@ abstract class HdmiCecLocalDevice { Message.obtain(mHandler, MSG_USER_CONTROL_RELEASE_TIMEOUT), FOLLOWER_SAFETY_TIMEOUT); return Constants.HANDLED; + } else if (params.length > 0) { + // Handle CEC UI commands that are not mapped to an Android keycode + return handleUnmappedCecKeycode(params[0]); } return Constants.ABORT_INVALID_OPERAND; @@ -692,6 +696,21 @@ abstract class HdmiCecLocalDevice { @ServiceThreadOnly @Constants.HandleMessageResult + protected int handleUnmappedCecKeycode(int cecKeycode) { + if (cecKeycode == HdmiCecKeycode.CEC_KEYCODE_MUTE_FUNCTION) { + mService.getAudioManager().adjustStreamVolume(AudioManager.STREAM_MUSIC, + AudioManager.ADJUST_MUTE, AudioManager.FLAG_SHOW_UI); + return Constants.HANDLED; + } else if (cecKeycode == HdmiCecKeycode.CEC_KEYCODE_RESTORE_VOLUME_FUNCTION) { + mService.getAudioManager().adjustStreamVolume(AudioManager.STREAM_MUSIC, + AudioManager.ADJUST_UNMUTE, AudioManager.FLAG_SHOW_UI); + return Constants.HANDLED; + } + return Constants.ABORT_INVALID_OPERAND; + } + + @ServiceThreadOnly + @Constants.HandleMessageResult protected int handleUserControlReleased() { assertRunOnServiceThread(); mHandler.removeMessages(MSG_USER_CONTROL_RELEASE_TIMEOUT); diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java index aeb1893c78b6..e6210b2a8cc9 100644 --- a/services/core/java/com/android/server/location/LocationManagerService.java +++ b/services/core/java/com/android/server/location/LocationManagerService.java @@ -45,6 +45,7 @@ import android.app.PendingIntent; import android.app.compat.CompatChanges; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.location.Criteria; import android.location.GeocoderParams; import android.location.Geofence; @@ -91,6 +92,7 @@ import android.util.IndentingPrintWriter; import android.util.Log; import com.android.internal.annotations.GuardedBy; +import com.android.internal.util.ArrayUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.Preconditions; import com.android.server.FgThread; @@ -134,6 +136,8 @@ import com.android.server.location.provider.PassiveLocationProvider; import com.android.server.location.provider.PassiveLocationProviderManager; import com.android.server.location.provider.StationaryThrottlingLocationProvider; import com.android.server.location.provider.proxy.ProxyLocationProvider; +import com.android.server.location.settings.LocationSettings; +import com.android.server.location.settings.LocationUserSettings; import com.android.server.pm.permission.LegacyPermissionManagerInternal; import java.io.FileDescriptor; @@ -270,6 +274,8 @@ public class LocationManagerService extends ILocationManager.Stub implements mGeofenceManager = new GeofenceManager(mContext, injector); + mInjector.getLocationSettings().registerLocationUserSettingsListener( + this::onLocationUserSettingsChanged); mInjector.getSettingsHelper().addOnLocationEnabledChangedListener( this::onLocationModeChanged); mInjector.getSettingsHelper().addIgnoreSettingsAllowlistChangedListener( @@ -476,6 +482,25 @@ public class LocationManagerService extends ILocationManager.Stub implements } } + private void onLocationUserSettingsChanged(int userId, LocationUserSettings oldSettings, + LocationUserSettings newSettings) { + if (oldSettings.isAdasGnssLocationEnabled() != newSettings.isAdasGnssLocationEnabled()) { + boolean enabled = newSettings.isAdasGnssLocationEnabled(); + + if (D) { + Log.d(TAG, "[u" + userId + "] adas gnss location enabled = " + enabled); + } + + EVENT_LOG.logAdasLocationEnabled(userId, enabled); + + Intent intent = new Intent(LocationManager.ACTION_ADAS_GNSS_ENABLED_CHANGED) + .putExtra(LocationManager.EXTRA_ADAS_GNSS_ENABLED, enabled) + .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY) + .addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); + } + } + private void onLocationModeChanged(int userId) { boolean enabled = mInjector.getSettingsHelper().isLocationEnabled(userId); LocationManager.invalidateLocalLocationEnabledCaches(); @@ -661,7 +686,7 @@ public class LocationManagerService extends ILocationManager.Stub implements // clients in the system process must have an attribution tag set Preconditions.checkState(identity.getPid() != Process.myPid() || attributionTag != null); - request = validateLocationRequest(request, identity); + request = validateLocationRequest(provider, request, identity); LocationProviderManager manager = getLocationProviderManager(provider); Preconditions.checkArgument(manager != null, @@ -687,7 +712,7 @@ public class LocationManagerService extends ILocationManager.Stub implements new IllegalArgumentException()); } - request = validateLocationRequest(request, identity); + request = validateLocationRequest(provider, request, identity); LocationProviderManager manager = getLocationProviderManager(provider); Preconditions.checkArgument(manager != null, @@ -725,7 +750,7 @@ public class LocationManagerService extends ILocationManager.Stub implements } } - request = validateLocationRequest(request, identity); + request = validateLocationRequest(provider, request, identity); LocationProviderManager manager = getLocationProviderManager(provider); Preconditions.checkArgument(manager != null, @@ -734,33 +759,27 @@ public class LocationManagerService extends ILocationManager.Stub implements manager.registerLocationRequest(request, identity, permissionLevel, pendingIntent); } - private LocationRequest validateLocationRequest(LocationRequest request, + private LocationRequest validateLocationRequest(String provider, LocationRequest request, CallerIdentity identity) { + // validate unsanitized request if (!request.getWorkSource().isEmpty()) { mContext.enforceCallingOrSelfPermission( permission.UPDATE_DEVICE_STATS, "setting a work source requires " + permission.UPDATE_DEVICE_STATS); } - if (request.isHiddenFromAppOps()) { - mContext.enforceCallingOrSelfPermission( - permission.UPDATE_APP_OPS_STATS, - "hiding from app ops requires " + permission.UPDATE_APP_OPS_STATS); - } - if (request.isLocationSettingsIgnored()) { - mContext.enforceCallingOrSelfPermission( - permission.WRITE_SECURE_SETTINGS, - "ignoring location settings requires " + permission.WRITE_SECURE_SETTINGS); - } + // sanitize request LocationRequest.Builder sanitized = new LocationRequest.Builder(request); - if (CompatChanges.isChangeEnabled(LOW_POWER_EXCEPTIONS, Binder.getCallingUid())) { - if (request.isLowPower()) { - mContext.enforceCallingOrSelfPermission( - permission.LOCATION_HARDWARE, - "low power request requires " + permission.LOCATION_HARDWARE); - } - } else { + if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) + && GPS_PROVIDER.equals(provider) + && ArrayUtils.contains(mContext.getResources().getStringArray( + com.android.internal.R.array.config_locationDriverAssistancePackageNames), + identity.getPackageName())) { + sanitized.setAdasGnssBypass(true); + } + + if (!CompatChanges.isChangeEnabled(LOW_POWER_EXCEPTIONS, Binder.getCallingUid())) { if (mContext.checkCallingPermission(permission.LOCATION_HARDWARE) != PERMISSION_GRANTED) { sanitized.setLowPower(false); @@ -786,7 +805,52 @@ public class LocationManagerService extends ILocationManager.Stub implements } sanitized.setWorkSource(workSource); - return sanitized.build(); + request = sanitized.build(); + + // validate sanitized request + boolean isLocationProvider = mLocalService.isProvider(null, identity); + + if (request.isLowPower() && CompatChanges.isChangeEnabled(LOW_POWER_EXCEPTIONS, + identity.getUid())) { + mContext.enforceCallingOrSelfPermission( + permission.LOCATION_HARDWARE, + "low power request requires " + permission.LOCATION_HARDWARE); + } + if (request.isHiddenFromAppOps()) { + mContext.enforceCallingOrSelfPermission( + permission.UPDATE_APP_OPS_STATS, + "hiding from app ops requires " + permission.UPDATE_APP_OPS_STATS); + } + if (request.isAdasGnssBypass()) { + if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { + throw new IllegalArgumentException( + "adas gnss bypass requests are only allowed on automotive devices"); + } + if (!GPS_PROVIDER.equals(provider)) { + throw new IllegalArgumentException( + "adas gnss bypass requests are only allowed on the \"gps\" provider"); + } + if (!ArrayUtils.contains(mContext.getResources().getStringArray( + com.android.internal.R.array.config_locationDriverAssistancePackageNames), + identity.getPackageName())) { + throw new SecurityException( + "only verified adas packages may use adas gnss bypass requests"); + } + if (!isLocationProvider) { + mContext.enforceCallingOrSelfPermission( + permission.WRITE_SECURE_SETTINGS, + "adas gnss bypass requires " + permission.WRITE_SECURE_SETTINGS); + } + } + if (request.isLocationSettingsIgnored()) { + if (!isLocationProvider) { + mContext.enforceCallingOrSelfPermission( + permission.WRITE_SECURE_SETTINGS, + "ignoring location settings requires " + permission.WRITE_SECURE_SETTINGS); + } + } + + return request; } @Override @@ -834,7 +898,7 @@ public class LocationManagerService extends ILocationManager.Stub implements // clients in the system process must have an attribution tag set Preconditions.checkArgument(identity.getPid() != Process.myPid() || attributionTag != null); - request = validateLastLocationRequest(request); + request = validateLastLocationRequest(provider, request, identity); LocationProviderManager manager = getLocationProviderManager(provider); if (manager == null) { @@ -844,16 +908,58 @@ public class LocationManagerService extends ILocationManager.Stub implements return manager.getLastLocation(request, identity, permissionLevel); } - private LastLocationRequest validateLastLocationRequest(LastLocationRequest request) { + private LastLocationRequest validateLastLocationRequest(String provider, + LastLocationRequest request, + CallerIdentity identity) { + // sanitize request + LastLocationRequest.Builder sanitized = new LastLocationRequest.Builder(request); + + if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) + && GPS_PROVIDER.equals(provider) + && ArrayUtils.contains(mContext.getResources().getStringArray( + com.android.internal.R.array.config_locationDriverAssistancePackageNames), + identity.getPackageName())) { + sanitized.setAdasGnssBypass(true); + } + + request = sanitized.build(); + + // validate request + boolean isLocationProvider = mLocalService.isProvider(null, identity); + if (request.isHiddenFromAppOps()) { mContext.enforceCallingOrSelfPermission( permission.UPDATE_APP_OPS_STATS, "hiding from app ops requires " + permission.UPDATE_APP_OPS_STATS); } + + if (request.isAdasGnssBypass()) { + if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { + throw new IllegalArgumentException( + "adas gnss bypass requests are only allowed on automotive devices"); + } + if (!GPS_PROVIDER.equals(provider)) { + throw new IllegalArgumentException( + "adas gnss bypass requests are only allowed on the \"gps\" provider"); + } + if (!ArrayUtils.contains(mContext.getResources().getStringArray( + com.android.internal.R.array.config_locationDriverAssistancePackageNames), + identity.getPackageName())) { + throw new SecurityException( + "only verified adas packages may use adas gnss bypass requests"); + } + if (!isLocationProvider) { + mContext.enforceCallingOrSelfPermission( + permission.WRITE_SECURE_SETTINGS, + "adas gnss bypass requires " + permission.WRITE_SECURE_SETTINGS); + } + } if (request.isLocationSettingsIgnored()) { - mContext.enforceCallingOrSelfPermission( - permission.WRITE_SECURE_SETTINGS, - "ignoring location settings requires " + permission.WRITE_SECURE_SETTINGS); + if (!isLocationProvider) { + mContext.enforceCallingOrSelfPermission( + permission.WRITE_SECURE_SETTINGS, + "ignoring location settings requires " + permission.WRITE_SECURE_SETTINGS); + } } return request; @@ -1126,6 +1232,24 @@ public class LocationManagerService extends ILocationManager.Stub implements } @Override + public void setAdasGnssLocationEnabledForUser(boolean enabled, int userId) { + userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), + userId, false, false, "setAdasGnssLocationEnabledForUser", null); + + mContext.enforceCallingOrSelfPermission(permission.WRITE_SECURE_SETTINGS, null); + + mInjector.getLocationSettings().updateUserSettings(userId, + settings -> settings.withAdasGnssLocationEnabled(enabled)); + } + + @Override + public boolean isAdasGnssLocationEnabledForUser(int userId) { + userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), + userId, false, false, "isAdasGnssLocationEnabledForUser", null); + return mInjector.getLocationSettings().getUserSettings(userId).isAdasGnssLocationEnabled(); + } + + @Override public boolean isProviderEnabledForUser(String provider, int userId) { return mLocalService.isProviderEnabledForUser(provider, userId); } @@ -1555,11 +1679,12 @@ public class LocationManagerService extends ILocationManager.Stub implements } } - private static class SystemInjector implements Injector { + private static final class SystemInjector implements Injector { private final Context mContext; private final UserInfoHelper mUserInfoHelper; + private final LocationSettings mLocationSettings; private final AlarmHelper mAlarmHelper; private final SystemAppOpsHelper mAppOpsHelper; private final SystemLocationPermissionsHelper mLocationPermissionsHelper; @@ -1584,6 +1709,7 @@ public class LocationManagerService extends ILocationManager.Stub implements mContext = context; mUserInfoHelper = userInfoHelper; + mLocationSettings = new LocationSettings(context); mAlarmHelper = new SystemAlarmHelper(context); mAppOpsHelper = new SystemAppOpsHelper(context); mLocationPermissionsHelper = new SystemLocationPermissionsHelper(context, @@ -1621,6 +1747,11 @@ public class LocationManagerService extends ILocationManager.Stub implements } @Override + public LocationSettings getLocationSettings() { + return mLocationSettings; + } + + @Override public AlarmHelper getAlarmHelper() { return mAlarmHelper; } diff --git a/services/core/java/com/android/server/location/LocationShellCommand.java b/services/core/java/com/android/server/location/LocationShellCommand.java index 937849309f96..b65338d9691d 100644 --- a/services/core/java/com/android/server/location/LocationShellCommand.java +++ b/services/core/java/com/android/server/location/LocationShellCommand.java @@ -17,6 +17,7 @@ package com.android.server.location; import android.content.Context; +import android.content.pm.PackageManager; import android.location.Criteria; import android.location.Location; import android.location.provider.ProviderProperties; @@ -60,6 +61,14 @@ class LocationShellCommand extends BasicShellCommandHandler { handleSetLocationEnabled(); return 0; } + case "is-adas-gnss-location-enabled": { + handleIsAdasGnssLocationEnabled(); + return 0; + } + case "set-adas-gnss-location-enabled": { + handleSetAdasGnssLocationEnabled(); + return 0; + } case "providers": { String command = getNextArgRequired(); return parseProvidersCommand(command); @@ -134,6 +143,52 @@ class LocationShellCommand extends BasicShellCommandHandler { mService.setLocationEnabledForUser(enabled, userId); } + private void handleIsAdasGnssLocationEnabled() { + if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { + throw new IllegalStateException("command only recognized on automotive devices"); + } + + int userId = UserHandle.USER_CURRENT_OR_SELF; + + do { + String option = getNextOption(); + if (option == null) { + break; + } + if ("--user".equals(option)) { + userId = UserHandle.parseUserArg(getNextArgRequired()); + } else { + throw new IllegalArgumentException("Unknown option: " + option); + } + } while (true); + + getOutPrintWriter().println(mService.isAdasGnssLocationEnabledForUser(userId)); + } + + private void handleSetAdasGnssLocationEnabled() { + if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { + throw new IllegalStateException("command only recognized on automotive devices"); + } + + boolean enabled = Boolean.parseBoolean(getNextArgRequired()); + + int userId = UserHandle.USER_CURRENT_OR_SELF; + + do { + String option = getNextOption(); + if (option == null) { + break; + } + if ("--user".equals(option)) { + userId = UserHandle.parseUserArg(getNextArgRequired()); + } else { + throw new IllegalArgumentException("Unknown option: " + option); + } + } while (true); + + mService.setAdasGnssLocationEnabledForUser(enabled, userId); + } + private void handleAddTestProvider() { String provider = getNextArgRequired(); @@ -297,6 +352,14 @@ class LocationShellCommand extends BasicShellCommandHandler { pw.println(" set-location-enabled true|false [--user <USER_ID>]"); pw.println(" Sets the master location switch enabled state. If no user is specified,"); pw.println(" the current user is assumed."); + if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { + pw.println(" is-adas-gnss-location-enabled [--user <USER_ID>]"); + pw.println(" Gets the ADAS GNSS location enabled state. If no user is specified,"); + pw.println(" the current user is assumed."); + pw.println(" set-adas-gnss-location-enabled true|false [--user <USER_ID>]"); + pw.println(" Sets the ADAS GNSS location enabled state. If no user is specified,"); + pw.println(" the current user is assumed."); + } pw.println(" providers"); pw.println(" The providers command is followed by a subcommand, as listed below:"); pw.println(); @@ -323,9 +386,8 @@ class LocationShellCommand extends BasicShellCommandHandler { pw.println(" Common commands that may be supported by the gps provider, depending on"); pw.println(" hardware and software configurations:"); pw.println(" delete_aiding_data - requests deletion of any predictive aiding data"); - pw.println(" force_time_injection - requests NTP time injection to chipset"); - pw.println(" force_psds_injection - " - + "requests predictive aiding data injection to chipset"); - pw.println(" request_power_stats - requests GNSS power stats update from chipset"); + pw.println(" force_time_injection - requests NTP time injection"); + pw.println(" force_psds_injection - requests predictive aiding data injection"); + pw.println(" request_power_stats - requests GNSS power stats update"); } } diff --git a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java index e6d25ece93ef..db2a43f7a00d 100644 --- a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java +++ b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java @@ -55,19 +55,20 @@ public class LocationEventLog extends LocalEventLog { private static final int EVENT_USER_SWITCHED = 1; private static final int EVENT_LOCATION_ENABLED = 2; - private static final int EVENT_PROVIDER_ENABLED = 3; - private static final int EVENT_PROVIDER_MOCKED = 4; - private static final int EVENT_PROVIDER_CLIENT_REGISTER = 5; - private static final int EVENT_PROVIDER_CLIENT_UNREGISTER = 6; - private static final int EVENT_PROVIDER_CLIENT_FOREGROUND = 7; - private static final int EVENT_PROVIDER_CLIENT_BACKGROUND = 8; - private static final int EVENT_PROVIDER_CLIENT_PERMITTED = 9; - private static final int EVENT_PROVIDER_CLIENT_UNPERMITTED = 10; - private static final int EVENT_PROVIDER_UPDATE_REQUEST = 11; - private static final int EVENT_PROVIDER_RECEIVE_LOCATION = 12; - private static final int EVENT_PROVIDER_DELIVER_LOCATION = 13; - private static final int EVENT_PROVIDER_STATIONARY_THROTTLED = 14; - private static final int EVENT_LOCATION_POWER_SAVE_MODE_CHANGE = 15; + private static final int EVENT_ADAS_LOCATION_ENABLED = 3; + private static final int EVENT_PROVIDER_ENABLED = 4; + private static final int EVENT_PROVIDER_MOCKED = 5; + private static final int EVENT_PROVIDER_CLIENT_REGISTER = 6; + private static final int EVENT_PROVIDER_CLIENT_UNREGISTER = 7; + private static final int EVENT_PROVIDER_CLIENT_FOREGROUND = 8; + private static final int EVENT_PROVIDER_CLIENT_BACKGROUND = 9; + private static final int EVENT_PROVIDER_CLIENT_PERMITTED = 10; + private static final int EVENT_PROVIDER_CLIENT_UNPERMITTED = 11; + private static final int EVENT_PROVIDER_UPDATE_REQUEST = 12; + private static final int EVENT_PROVIDER_RECEIVE_LOCATION = 13; + private static final int EVENT_PROVIDER_DELIVER_LOCATION = 14; + private static final int EVENT_PROVIDER_STATIONARY_THROTTLED = 15; + private static final int EVENT_LOCATION_POWER_SAVE_MODE_CHANGE = 16; @GuardedBy("mAggregateStats") private final ArrayMap<String, ArrayMap<CallerIdentity, AggregateStats>> mAggregateStats; @@ -116,6 +117,11 @@ public class LocationEventLog extends LocalEventLog { addLogEvent(EVENT_LOCATION_ENABLED, userId, enabled); } + /** Logs a location enabled/disabled event. */ + public void logAdasLocationEnabled(int userId, boolean enabled) { + addLogEvent(EVENT_ADAS_LOCATION_ENABLED, userId, enabled); + } + /** Logs a location provider enabled/disabled event. */ public void logProviderEnabled(String provider, int userId, boolean enabled) { addLogEvent(EVENT_PROVIDER_ENABLED, provider, userId, enabled); @@ -219,6 +225,9 @@ public class LocationEventLog extends LocalEventLog { return new UserSwitchedEvent(timeDelta, (Integer) args[0], (Integer) args[1]); case EVENT_LOCATION_ENABLED: return new LocationEnabledEvent(timeDelta, (Integer) args[0], (Boolean) args[1]); + case EVENT_ADAS_LOCATION_ENABLED: + return new LocationAdasEnabledEvent(timeDelta, (Integer) args[0], + (Boolean) args[1]); case EVENT_PROVIDER_ENABLED: return new ProviderEnabledEvent(timeDelta, (String) args[0], (Integer) args[1], (Boolean) args[2]); @@ -517,6 +526,23 @@ public class LocationEventLog extends LocalEventLog { } } + private static final class LocationAdasEnabledEvent extends LogEvent { + + private final int mUserId; + private final boolean mEnabled; + + LocationAdasEnabledEvent(long timeDelta, int userId, boolean enabled) { + super(timeDelta); + mUserId = userId; + mEnabled = enabled; + } + + @Override + public String getLogString() { + return "adas location [u" + mUserId + "] " + (mEnabled ? "enabled" : "disabled"); + } + } + /** * Aggregate statistics for a single package under a single provider. */ diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java index 1cccf08b0367..f3dcfbbf2c0a 100644 --- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java @@ -771,10 +771,10 @@ public class GnssLocationProvider extends AbstractLocationProvider implements boolean enabled = mContext.getSystemService(LocationManager.class) .isLocationEnabledForUser(UserHandle.CURRENT); - // .. but enable anyway, if there's an active settings-ignored request (e.g. ELS) + // .. but enable anyway, if there's an active bypass request (e.g. ELS or ADAS) enabled |= (mProviderRequest != null && mProviderRequest.isActive() - && mProviderRequest.isLocationSettingsIgnored()); + && mProviderRequest.isBypass()); // ... and, finally, disable anyway, if device is being shut down enabled &= !mShutdown; diff --git a/services/core/java/com/android/server/location/injector/Injector.java b/services/core/java/com/android/server/location/injector/Injector.java index b0351184ffe5..173fd13c11a1 100644 --- a/services/core/java/com/android/server/location/injector/Injector.java +++ b/services/core/java/com/android/server/location/injector/Injector.java @@ -17,6 +17,7 @@ package com.android.server.location.injector; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.location.settings.LocationSettings; /** * Injects various location dependencies so that they may be controlled by tests. @@ -27,6 +28,9 @@ public interface Injector { /** Returns a UserInfoHelper. */ UserInfoHelper getUserInfoHelper(); + /** Returns a LocationSettings. */ + LocationSettings getLocationSettings(); + /** Returns an AlarmHelper. */ AlarmHelper getAlarmHelper(); diff --git a/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java b/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java index c315da476d99..3e8da7d7478a 100644 --- a/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java +++ b/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java @@ -670,8 +670,6 @@ public class SystemSettingsHelper extends SettingsHelper { } } - - private static class PackageTagsListSetting extends DeviceConfigSetting { private final Supplier<ArrayMap<String, ArraySet<String>>> mBaseValuesSupplier; 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 8d335b83d99c..43886f7cb87b 100644 --- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java +++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java @@ -113,6 +113,8 @@ import com.android.server.location.injector.UserInfoHelper; import com.android.server.location.injector.UserInfoHelper.UserListener; import com.android.server.location.listeners.ListenerMultiplexer; import com.android.server.location.listeners.RemoteListenerRegistration; +import com.android.server.location.settings.LocationSettings; +import com.android.server.location.settings.LocationUserSettings; import java.io.FileDescriptor; import java.lang.annotation.Retention; @@ -549,6 +551,19 @@ public class LocationProviderManager extends } @GuardedBy("mLock") + final boolean onAdasGnssLocationEnabledChanged(int userId) { + if (Build.IS_DEBUGGABLE) { + Preconditions.checkState(Thread.holdsLock(mLock)); + } + + if (getIdentity().getUserId() == userId) { + return onProviderLocationRequestChanged(); + } + + return false; + } + + @GuardedBy("mLock") final boolean onForegroundChanged(int uid, boolean foreground) { if (Build.IS_DEBUGGABLE) { Preconditions.checkState(Thread.holdsLock(mLock)); @@ -592,8 +607,8 @@ public class LocationProviderManager extends onHighPowerUsageChanged(); updateService(); - // if location settings ignored has changed then the active state may have changed - return oldRequest.isLocationSettingsIgnored() != newRequest.isLocationSettingsIgnored(); + // if bypass state has changed then the active state may have changed + return oldRequest.isBypass() != newRequest.isBypass(); } private LocationRequest calculateProviderLocationRequest() { @@ -616,9 +631,24 @@ public class LocationProviderManager extends if (!mSettingsHelper.getIgnoreSettingsAllowlist().contains( getIdentity().getPackageName(), getIdentity().getAttributionTag()) && !mLocationManagerInternal.isProvider(null, getIdentity())) { - builder.setLocationSettingsIgnored(false); locationSettingsIgnored = false; } + + builder.setLocationSettingsIgnored(locationSettingsIgnored); + } + + boolean adasGnssBypass = baseRequest.isAdasGnssBypass(); + if (adasGnssBypass) { + // if we are not currently allowed use adas gnss bypass, disable it + if (!GPS_PROVIDER.equals(mName)) { + Log.e(TAG, "adas gnss bypass request received in non-gps provider"); + adasGnssBypass = false; + } else if (!mLocationSettings.getUserSettings( + getIdentity().getUserId()).isAdasGnssLocationEnabled()) { + adasGnssBypass = false; + } + + builder.setAdasGnssBypass(adasGnssBypass); } if (!locationSettingsIgnored && !isThrottlingExempt()) { @@ -769,7 +799,7 @@ public class LocationProviderManager extends Location lastLocation = getLastLocationUnsafe( getIdentity().getUserId(), getPermissionLevel(), - getRequest().isLocationSettingsIgnored(), + getRequest().isBypass(), maxLocationAgeMs); if (lastLocation != null) { executeOperation(acceptLocationChange(LocationResult.wrap(lastLocation))); @@ -1114,7 +1144,7 @@ public class LocationProviderManager extends Location lastLocation = getLastLocationUnsafe( getIdentity().getUserId(), getPermissionLevel(), - getRequest().isLocationSettingsIgnored(), + getRequest().isBypass(), MAX_CURRENT_LOCATION_AGE_MS); if (lastLocation != null) { executeOperation(acceptLocationChange(LocationResult.wrap(lastLocation))); @@ -1267,6 +1297,7 @@ public class LocationProviderManager extends private final CopyOnWriteArrayList<IProviderRequestListener> mProviderRequestListeners; protected final LocationManagerInternal mLocationManagerInternal; + protected final LocationSettings mLocationSettings; protected final SettingsHelper mSettingsHelper; protected final UserInfoHelper mUserHelper; protected final AlarmHelper mAlarmHelper; @@ -1280,6 +1311,8 @@ public class LocationProviderManager extends protected final LocationFudger mLocationFudger; private final UserListener mUserChangedListener = this::onUserChanged; + private final LocationSettings.LocationUserSettingsListener mLocationUserSettingsListener = + this::onLocationUserSettingsChanged; private final UserSettingChangedListener mLocationEnabledChangedListener = this::onLocationEnabledChanged; private final GlobalSettingChangedListener mBackgroundThrottlePackageWhitelistChangedListener = @@ -1332,6 +1365,7 @@ public class LocationProviderManager extends mLocationManagerInternal = Objects.requireNonNull( LocalServices.getService(LocationManagerInternal.class)); + mLocationSettings = injector.getLocationSettings(); mSettingsHelper = injector.getSettingsHelper(); mUserHelper = injector.getUserInfoHelper(); mAlarmHelper = injector.getAlarmHelper(); @@ -1362,6 +1396,7 @@ public class LocationProviderManager extends mStateChangedListener = listener; mUserHelper.addListener(mUserChangedListener); + mLocationSettings.registerLocationUserSettingsListener(mLocationUserSettingsListener); mSettingsHelper.addOnLocationEnabledChangedListener(mLocationEnabledChangedListener); final long identity = Binder.clearCallingIdentity(); @@ -1389,6 +1424,7 @@ public class LocationProviderManager extends } mUserHelper.removeListener(mUserChangedListener); + mLocationSettings.unregisterLocationUserSettingsListener(mLocationUserSettingsListener); mSettingsHelper.removeOnLocationEnabledChangedListener(mLocationEnabledChangedListener); // if external entities are registering listeners it's their responsibility to @@ -1550,7 +1586,7 @@ public class LocationProviderManager extends public @Nullable Location getLastLocation(LastLocationRequest request, CallerIdentity identity, @PermissionLevel int permissionLevel) { - if (!isActive(request.isLocationSettingsIgnored(), identity)) { + if (!isActive(request.isBypass(), identity)) { return null; } @@ -1564,7 +1600,7 @@ public class LocationProviderManager extends getLastLocationUnsafe( identity.getUserId(), permissionLevel, - request.isLocationSettingsIgnored(), + request.isBypass(), Long.MAX_VALUE), permissionLevel); @@ -1584,7 +1620,7 @@ public class LocationProviderManager extends * location if necessary. */ public @Nullable Location getLastLocationUnsafe(int userId, - @PermissionLevel int permissionLevel, boolean ignoreLocationSettings, + @PermissionLevel int permissionLevel, boolean isBypass, long maximumAgeMs) { if (userId == UserHandle.USER_ALL) { // find the most recent location across all users @@ -1592,7 +1628,7 @@ public class LocationProviderManager extends final int[] runningUserIds = mUserHelper.getRunningUserIds(); for (int i = 0; i < runningUserIds.length; i++) { Location next = getLastLocationUnsafe(runningUserIds[i], permissionLevel, - ignoreLocationSettings, maximumAgeMs); + isBypass, maximumAgeMs); if (lastLocation == null || (next != null && next.getElapsedRealtimeNanos() > lastLocation.getElapsedRealtimeNanos())) { lastLocation = next; @@ -1601,7 +1637,7 @@ public class LocationProviderManager extends return lastLocation; } else if (userId == UserHandle.USER_CURRENT) { return getLastLocationUnsafe(mUserHelper.getCurrentUserId(), permissionLevel, - ignoreLocationSettings, maximumAgeMs); + isBypass, maximumAgeMs); } Preconditions.checkArgument(userId >= 0); @@ -1613,7 +1649,7 @@ public class LocationProviderManager extends if (lastLocation == null) { location = null; } else { - location = lastLocation.get(permissionLevel, ignoreLocationSettings); + location = lastLocation.get(permissionLevel, isBypass); } } @@ -1925,7 +1961,7 @@ public class LocationProviderManager extends // provider, under the assumption that once we send the request off, the provider will // immediately attempt to deliver a new location satisfying that request. long delayMs; - if (!oldRequest.isLocationSettingsIgnored() && newRequest.isLocationSettingsIgnored()) { + if (!oldRequest.isBypass() && newRequest.isBypass()) { delayMs = 0; } else if (newRequest.getIntervalMillis() > oldRequest.getIntervalMillis()) { // if the interval has increased, tell the provider immediately, so it can save power @@ -2002,12 +2038,12 @@ public class LocationProviderManager extends return false; } - boolean locationSettingsIgnored = registration.getRequest().isLocationSettingsIgnored(); - if (!isActive(locationSettingsIgnored, registration.getIdentity())) { + boolean isBypass = registration.getRequest().isBypass(); + if (!isActive(isBypass, registration.getIdentity())) { return false; } - if (!locationSettingsIgnored) { + if (!isBypass) { switch (mLocationPowerSaveModeHelper.getLocationPowerSaveMode()) { case LOCATION_MODE_FOREGROUND_ONLY: if (!registration.isForeground()) { @@ -2036,15 +2072,15 @@ public class LocationProviderManager extends return true; } - private boolean isActive(boolean locationSettingsIgnored, CallerIdentity identity) { + private boolean isActive(boolean isBypass, CallerIdentity identity) { if (identity.isSystemServer()) { - if (!locationSettingsIgnored) { + if (!isBypass) { if (!isEnabled(mUserHelper.getCurrentUserId())) { return false; } } } else { - if (!locationSettingsIgnored) { + if (!isBypass) { if (!isEnabled(identity.getUserId())) { return false; } @@ -2071,6 +2107,7 @@ public class LocationProviderManager extends long intervalMs = ProviderRequest.INTERVAL_DISABLED; int quality = LocationRequest.QUALITY_LOW_POWER; long maxUpdateDelayMs = Long.MAX_VALUE; + boolean adasGnssBypass = false; boolean locationSettingsIgnored = false; boolean lowPower = true; @@ -2086,6 +2123,7 @@ public class LocationProviderManager extends intervalMs = min(request.getIntervalMillis(), intervalMs); quality = min(request.getQuality(), quality); maxUpdateDelayMs = min(request.getMaxUpdateDelayMillis(), maxUpdateDelayMs); + adasGnssBypass |= request.isAdasGnssBypass(); locationSettingsIgnored |= request.isLocationSettingsIgnored(); lowPower &= request.isLowPower(); } @@ -2123,6 +2161,7 @@ public class LocationProviderManager extends .setIntervalMillis(intervalMs) .setQuality(quality) .setMaxUpdateDelayMillis(maxUpdateDelayMs) + .setAdasGnssBypass(adasGnssBypass) .setLocationSettingsIgnored(locationSettingsIgnored) .setLowPower(lowPower) .setWorkSource(workSource) @@ -2191,6 +2230,16 @@ public class LocationProviderManager extends } } + private void onLocationUserSettingsChanged(int userId, LocationUserSettings oldSettings, + LocationUserSettings newSettings) { + if (oldSettings.isAdasGnssLocationEnabled() != newSettings.isAdasGnssLocationEnabled()) { + synchronized (mLock) { + updateRegistrations( + registration -> registration.onAdasGnssLocationEnabledChanged(userId)); + } + } + } + private void onLocationEnabledChanged(int userId) { synchronized (mLock) { if (mState == STATE_STOPPED) { @@ -2560,16 +2609,16 @@ public class LocationProviderManager extends } public @Nullable Location get(@PermissionLevel int permissionLevel, - boolean ignoreLocationSettings) { + boolean isBypass) { switch (permissionLevel) { case PERMISSION_FINE: - if (ignoreLocationSettings) { + if (isBypass) { return mFineBypassLocation; } else { return mFineLocation; } case PERMISSION_COARSE: - if (ignoreLocationSettings) { + if (isBypass) { return mCoarseBypassLocation; } else { return mCoarseLocation; diff --git a/services/core/java/com/android/server/location/settings/LocationSettings.java b/services/core/java/com/android/server/location/settings/LocationSettings.java new file mode 100644 index 000000000000..d52153893970 --- /dev/null +++ b/services/core/java/com/android/server/location/settings/LocationSettings.java @@ -0,0 +1,173 @@ +/* + * 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.location.settings; + +import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE; + +import android.content.Context; +import android.os.Environment; +import android.util.SparseArray; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; +import com.android.server.FgThread; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.File; +import java.io.IOException; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Function; + +/** + * Accessor for location user settings. Ensure there is only ever one instance as multiple instances + * don't play nicely with each other. + */ +public class LocationSettings { + + /** Listens for changes to location user settings. */ + public interface LocationUserSettingsListener { + /** Invoked when location user settings have changed for the given user. */ + void onLocationUserSettingsChanged(int userId, LocationUserSettings oldSettings, + LocationUserSettings newSettings); + } + + private static final String LOCATION_DIRNAME = "location"; + private static final String LOCATION_SETTINGS_FILENAME = "settings"; + + final Context mContext; + + @GuardedBy("mUserSettings") + private final SparseArray<LocationUserSettingsStore> mUserSettings; + private final CopyOnWriteArrayList<LocationUserSettingsListener> mUserSettingsListeners; + + public LocationSettings(Context context) { + mContext = context; + mUserSettings = new SparseArray<>(1); + mUserSettingsListeners = new CopyOnWriteArrayList<>(); + } + + /** Registers a listener for changes to location user settings. */ + public final void registerLocationUserSettingsListener(LocationUserSettingsListener listener) { + mUserSettingsListeners.add(listener); + } + + /** Unregisters a listener for changes to location user settings. */ + public final void unregisterLocationUserSettingsListener( + LocationUserSettingsListener listener) { + mUserSettingsListeners.remove(listener); + } + + protected File getUserSettingsDir(int userId) { + return Environment.getDataSystemDeDirectory(userId); + } + + protected LocationUserSettingsStore createUserSettingsStore(int userId, File file) { + return new LocationUserSettingsStore(userId, file); + } + + private LocationUserSettingsStore getUserSettingsStore(int userId) { + synchronized (mUserSettings) { + LocationUserSettingsStore settingsStore = mUserSettings.get(userId); + if (settingsStore == null) { + File file = new File(new File(getUserSettingsDir(userId), LOCATION_DIRNAME), + LOCATION_SETTINGS_FILENAME); + settingsStore = createUserSettingsStore(userId, file); + mUserSettings.put(userId, settingsStore); + } + return settingsStore; + } + } + + /** Retrieves the current state of location user settings. */ + public final LocationUserSettings getUserSettings(int userId) { + return getUserSettingsStore(userId).get(); + } + + /** Updates the current state of location user settings for the given user. */ + public final void updateUserSettings(int userId, + Function<LocationUserSettings, LocationUserSettings> updater) { + getUserSettingsStore(userId).update(updater); + } + + @VisibleForTesting + final void flushFiles() throws InterruptedException { + synchronized (mUserSettings) { + int size = mUserSettings.size(); + for (int i = 0; i < size; i++) { + mUserSettings.valueAt(i).flushFile(); + } + } + } + + @VisibleForTesting + final void deleteFiles() throws InterruptedException { + synchronized (mUserSettings) { + int size = mUserSettings.size(); + for (int i = 0; i < size; i++) { + mUserSettings.valueAt(i).deleteFile(); + } + } + } + + protected final void fireListeners(int userId, LocationUserSettings oldSettings, + LocationUserSettings newSettings) { + for (LocationUserSettingsListener listener : mUserSettingsListeners) { + listener.onLocationUserSettingsChanged(userId, oldSettings, newSettings); + } + } + + class LocationUserSettingsStore extends SettingsStore<LocationUserSettings> { + + protected final int mUserId; + + LocationUserSettingsStore(int userId, File file) { + super(file); + mUserId = userId; + } + + @Override + protected LocationUserSettings read(int version, DataInput in) throws IOException { + return filterSettings(LocationUserSettings.read(mContext.getResources(), version, in)); + } + + @Override + protected void write(DataOutput out, LocationUserSettings settings) throws IOException { + settings.write(out); + } + + @Override + public void update(Function<LocationUserSettings, LocationUserSettings> updater) { + super.update(settings -> filterSettings(updater.apply(settings))); + } + + @Override + protected void onChange(LocationUserSettings oldSettings, + LocationUserSettings newSettings) { + FgThread.getExecutor().execute(() -> fireListeners(mUserId, oldSettings, newSettings)); + } + + private LocationUserSettings filterSettings(LocationUserSettings settings) { + if (settings.isAdasGnssLocationEnabled() + && !mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE)) { + // prevent non-automotive devices from ever enabling this + settings = settings.withAdasGnssLocationEnabled(false); + } + return settings; + } + } +} diff --git a/services/core/java/com/android/server/location/settings/LocationUserSettings.java b/services/core/java/com/android/server/location/settings/LocationUserSettings.java new file mode 100644 index 000000000000..283255ef4b22 --- /dev/null +++ b/services/core/java/com/android/server/location/settings/LocationUserSettings.java @@ -0,0 +1,98 @@ +/* + * 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.location.settings; + +import android.content.res.Resources; + +import com.android.internal.R; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Objects; + +/** Holds the state of location user settings. */ +public final class LocationUserSettings implements SettingsStore.VersionedSettings { + + // remember to bump this version code and add the appropriate upgrade logic whenever the format + // is changed. + private static final int VERSION = 1; + + private final boolean mAdasGnssLocationEnabled; + + private LocationUserSettings(boolean adasGnssLocationEnabled) { + mAdasGnssLocationEnabled = adasGnssLocationEnabled; + } + + @Override + public int getVersion() { + return VERSION; + } + + public boolean isAdasGnssLocationEnabled() { + return mAdasGnssLocationEnabled; + } + + /** Returns an instance with ADAS GNSS location enabled state set as given. */ + public LocationUserSettings withAdasGnssLocationEnabled(boolean adasEnabled) { + if (adasEnabled == mAdasGnssLocationEnabled) { + return this; + } + + return new LocationUserSettings(adasEnabled); + } + + void write(DataOutput out) throws IOException { + out.writeBoolean(mAdasGnssLocationEnabled); + } + + static LocationUserSettings read(Resources resources, int version, DataInput in) + throws IOException { + boolean adasGnssLocationEnabled; + + // upgrade code goes here. remember to bump the version field when changing the format + switch (version) { + default: + // set all fields to defaults + adasGnssLocationEnabled = resources.getBoolean( + R.bool.config_defaultAdasGnssLocationEnabled); + break; + case 1: + adasGnssLocationEnabled = in.readBoolean(); + // fall through + } + + return new LocationUserSettings(adasGnssLocationEnabled); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof LocationUserSettings)) { + return false; + } + LocationUserSettings that = (LocationUserSettings) o; + return mAdasGnssLocationEnabled == that.mAdasGnssLocationEnabled; + } + + @Override + public int hashCode() { + return Objects.hash(mAdasGnssLocationEnabled); + } +} diff --git a/services/core/java/com/android/server/location/settings/SettingsStore.java b/services/core/java/com/android/server/location/settings/SettingsStore.java new file mode 100644 index 000000000000..01338a3129da --- /dev/null +++ b/services/core/java/com/android/server/location/settings/SettingsStore.java @@ -0,0 +1,166 @@ +/* + * 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.location.settings; + +import static com.android.server.location.LocationManagerService.TAG; +import static com.android.server.location.settings.SettingsStore.VersionedSettings.VERSION_DOES_NOT_EXIST; + +import android.util.AtomicFile; +import android.util.Log; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.os.BackgroundThread; +import com.android.internal.util.Preconditions; + +import java.io.ByteArrayInputStream; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Objects; +import java.util.concurrent.CountDownLatch; +import java.util.function.Function; + +/** Base class for read/write/versioning functionality for storing persistent settings to a file. */ +abstract class SettingsStore<T extends SettingsStore.VersionedSettings> { + + interface VersionedSettings { + /** Represents that the settings do not exist. */ + int VERSION_DOES_NOT_EXIST = Integer.MAX_VALUE; + + /** Must always return a version number less than {@link #VERSION_DOES_NOT_EXIST}. */ + int getVersion(); + } + + private final AtomicFile mFile; + + @GuardedBy("this") + private boolean mInitialized; + @GuardedBy("this") + private T mCache; + + protected SettingsStore(File file) { + mFile = new AtomicFile(file); + } + + /** + * Must be implemented to read in a settings instance, and upgrade to the appropriate version + * where necessary. If the provided version is {@link VersionedSettings#VERSION_DOES_NOT_EXIST} + * then the DataInput will be empty, and the method should return a settings instance with all + * settings set to the default value. + */ + protected abstract T read(int version, DataInput in) throws IOException; + + /** + * Must be implemented to write the given settings to the given DataOutput. + */ + protected abstract void write(DataOutput out, T settings) throws IOException; + + /** + * Invoked when settings change, and while holding the internal lock. If used to invoke + * listeners, ensure they are not invoked while holding the lock (ie, asynchronously). + */ + protected abstract void onChange(T oldSettings, T newSettings); + + public final synchronized void initializeCache() { + if (!mInitialized) { + if (mFile.exists()) { + try (DataInputStream is = new DataInputStream(mFile.openRead())) { + mCache = read(is.readInt(), is); + Preconditions.checkState(mCache.getVersion() < VERSION_DOES_NOT_EXIST); + } catch (IOException e) { + Log.e(TAG, "error reading location settings (" + mFile + + "), falling back to defaults", e); + } + } + + if (mCache == null) { + try { + mCache = read(VERSION_DOES_NOT_EXIST, + new DataInputStream(new ByteArrayInputStream(new byte[0]))); + Preconditions.checkState(mCache.getVersion() < VERSION_DOES_NOT_EXIST); + } catch (IOException e) { + throw new AssertionError(e); + } + } + + mInitialized = true; + } + } + + public final synchronized T get() { + initializeCache(); + return mCache; + } + + public synchronized void update(Function<T, T> updater) { + initializeCache(); + + T oldSettings = mCache; + T newSettings = Objects.requireNonNull(updater.apply(oldSettings)); + if (oldSettings.equals(newSettings)) { + return; + } + + mCache = newSettings; + Preconditions.checkState(mCache.getVersion() < VERSION_DOES_NOT_EXIST); + + writeLazily(newSettings); + + onChange(oldSettings, newSettings); + } + + @VisibleForTesting + synchronized void flushFile() throws InterruptedException { + CountDownLatch latch = new CountDownLatch(1); + BackgroundThread.getExecutor().execute(latch::countDown); + latch.await(); + } + + @VisibleForTesting + synchronized void deleteFile() throws InterruptedException { + CountDownLatch latch = new CountDownLatch(1); + BackgroundThread.getExecutor().execute(() -> { + mFile.delete(); + latch.countDown(); + }); + latch.await(); + } + + private void writeLazily(T settings) { + BackgroundThread.getExecutor().execute(() -> { + FileOutputStream os = null; + try { + os = mFile.startWrite(); + DataOutputStream out = new DataOutputStream(os); + out.writeInt(settings.getVersion()); + write(out, settings); + mFile.finishWrite(os); + } catch (IOException e) { + mFile.failWrite(os); + Log.e(TAG, "failure serializing location settings", e); + } catch (Throwable e) { + mFile.failWrite(os); + throw e; + } + }); + } +} diff --git a/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java b/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java index 2cc2ebf616c5..981e75988d56 100644 --- a/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java +++ b/services/core/java/com/android/server/media/metrics/MediaMetricsManagerService.java @@ -17,6 +17,7 @@ package com.android.server.media.metrics; import android.content.Context; +import android.content.pm.PackageManager; import android.media.metrics.IMediaMetricsManager; import android.media.metrics.NetworkEvent; import android.media.metrics.PlaybackErrorEvent; @@ -24,19 +25,60 @@ import android.media.metrics.PlaybackMetrics; import android.media.metrics.PlaybackStateEvent; import android.media.metrics.TrackChangeEvent; import android.os.Binder; +import android.provider.DeviceConfig; +import android.provider.DeviceConfig.Properties; import android.util.Base64; +import android.util.Slog; import android.util.StatsEvent; import android.util.StatsLog; +import com.android.internal.annotations.GuardedBy; import com.android.server.SystemService; import java.security.SecureRandom; +import java.util.Arrays; +import java.util.List; /** * System service manages media metrics. */ public final class MediaMetricsManagerService extends SystemService { + private static final String TAG = "MediaMetricsManagerService"; + + private static final String MEDIA_METRICS_MODE = "media_metrics_mode"; + private static final String PLAYER_METRICS_PER_APP_ATTRIBUTION_ALLOWLIST = + "player_metrics_per_app_attribution_allowlist"; + private static final String PLAYER_METRICS_APP_ALLOWLIST = "player_metrics_app_allowlist"; + + private static final String PLAYER_METRICS_PER_APP_ATTRIBUTION_BLOCKLIST = + "player_metrics_per_app_attribution_blocklist"; + private static final String PLAYER_METRICS_APP_BLOCKLIST = "player_metrics_app_blocklist"; + + private static final int MEDIA_METRICS_MODE_OFF = 0; + private static final int MEDIA_METRICS_MODE_ON = 1; + private static final int MEDIA_METRICS_MODE_BLOCKLIST = 2; + private static final int MEDIA_METRICS_MODE_ALLOWLIST = 3; + + // Cascading logging levels. The higher value, the more constrains (less logging data). + // The unused values between 2 consecutive levels are reserved for potential extra levels. + private static final int LOGGING_LEVEL_EVERYTHING = 0; + private static final int LOGGING_LEVEL_NO_UID = 1000; + private static final int LOGGING_LEVEL_BLOCKED = 99999; + + private static final String FAILED_TO_GET = "failed_to_get"; private final SecureRandom mSecureRandom; + @GuardedBy("mLock") + private Integer mMode = null; + @GuardedBy("mLock") + private List<String> mAllowlist = null; + @GuardedBy("mLock") + private List<String> mNoUidAllowlist = null; + @GuardedBy("mLock") + private List<String> mBlockList = null; + @GuardedBy("mLock") + private List<String> mNoUidBlocklist = null; + private final Object mLock = new Object(); + private final Context mContext; /** * Initializes the playback metrics manager service. @@ -45,20 +87,73 @@ public final class MediaMetricsManagerService extends SystemService { */ public MediaMetricsManagerService(Context context) { super(context); + mContext = context; mSecureRandom = new SecureRandom(); } @Override public void onStart() { publishBinderService(Context.MEDIA_METRICS_SERVICE, new BinderService()); + DeviceConfig.addOnPropertiesChangedListener( + DeviceConfig.NAMESPACE_MEDIA, + mContext.getMainExecutor(), + this::updateConfigs); + } + + private void updateConfigs(Properties properties) { + synchronized (mLock) { + mMode = properties.getInt( + MEDIA_METRICS_MODE, + MEDIA_METRICS_MODE_BLOCKLIST); + List<String> newList = getListLocked(PLAYER_METRICS_APP_ALLOWLIST); + if (newList != null || mMode != MEDIA_METRICS_MODE_ALLOWLIST) { + // don't overwrite the list if the mode IS MEDIA_METRICS_MODE_ALLOWLIST + // but failed to get + mAllowlist = newList; + } + newList = getListLocked(PLAYER_METRICS_PER_APP_ATTRIBUTION_ALLOWLIST); + if (newList != null || mMode != MEDIA_METRICS_MODE_ALLOWLIST) { + mNoUidAllowlist = newList; + } + newList = getListLocked(PLAYER_METRICS_APP_BLOCKLIST); + if (newList != null || mMode != MEDIA_METRICS_MODE_BLOCKLIST) { + mBlockList = newList; + } + newList = getListLocked(PLAYER_METRICS_PER_APP_ATTRIBUTION_BLOCKLIST); + if (newList != null || mMode != MEDIA_METRICS_MODE_BLOCKLIST) { + mNoUidBlocklist = newList; + } + } + } + + @GuardedBy("mLock") + private List<String> getListLocked(String listName) { + final long identity = Binder.clearCallingIdentity(); + String listString = FAILED_TO_GET; + try { + listString = DeviceConfig.getString( + DeviceConfig.NAMESPACE_MEDIA, listName, FAILED_TO_GET); + } finally { + Binder.restoreCallingIdentity(identity); + } + if (listString.equals(FAILED_TO_GET)) { + Slog.d(TAG, "failed to get " + listName + " from DeviceConfig"); + return null; + } + String[] pkgArr = listString.split(","); + return Arrays.asList(pkgArr); } private final class BinderService extends IMediaMetricsManager.Stub { @Override public void reportPlaybackMetrics(String sessionId, PlaybackMetrics metrics, int userId) { + int level = loggingLevel(); + if (level == LOGGING_LEVEL_BLOCKED) { + return; + } StatsEvent statsEvent = StatsEvent.newBuilder() .setAtomId(320) - .writeInt(Binder.getCallingUid()) + .writeInt(level == LOGGING_LEVEL_EVERYTHING ? Binder.getCallingUid() : 0) .writeString(sessionId) .writeLong(metrics.getMediaDurationMillis()) .writeInt(metrics.getStreamSource()) @@ -85,6 +180,10 @@ public final class MediaMetricsManagerService extends SystemService { @Override public void reportPlaybackStateEvent( String sessionId, PlaybackStateEvent event, int userId) { + int level = loggingLevel(); + if (level == LOGGING_LEVEL_BLOCKED) { + return; + } StatsEvent statsEvent = StatsEvent.newBuilder() .setAtomId(322) .writeString(sessionId) @@ -116,6 +215,10 @@ public final class MediaMetricsManagerService extends SystemService { @Override public void reportPlaybackErrorEvent( String sessionId, PlaybackErrorEvent event, int userId) { + int level = loggingLevel(); + if (level == LOGGING_LEVEL_BLOCKED) { + return; + } StatsEvent statsEvent = StatsEvent.newBuilder() .setAtomId(323) .writeString(sessionId) @@ -130,6 +233,10 @@ public final class MediaMetricsManagerService extends SystemService { public void reportNetworkEvent( String sessionId, NetworkEvent event, int userId) { + int level = loggingLevel(); + if (level == LOGGING_LEVEL_BLOCKED) { + return; + } StatsEvent statsEvent = StatsEvent.newBuilder() .setAtomId(321) .writeString(sessionId) @@ -143,6 +250,10 @@ public final class MediaMetricsManagerService extends SystemService { @Override public void reportTrackChangeEvent( String sessionId, TrackChangeEvent event, int userId) { + int level = loggingLevel(); + if (level == LOGGING_LEVEL_BLOCKED) { + return; + } StatsEvent statsEvent = StatsEvent.newBuilder() .setAtomId(324) .writeString(sessionId) @@ -165,5 +276,140 @@ public final class MediaMetricsManagerService extends SystemService { .build(); StatsLog.write(statsEvent); } + + private int loggingLevel() { + synchronized (mLock) { + int uid = Binder.getCallingUid(); + + if (mMode == null) { + final long identity = Binder.clearCallingIdentity(); + try { + mMode = DeviceConfig.getInt( + DeviceConfig.NAMESPACE_MEDIA, + MEDIA_METRICS_MODE, + MEDIA_METRICS_MODE_BLOCKLIST); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + if (mMode == MEDIA_METRICS_MODE_ON) { + return LOGGING_LEVEL_EVERYTHING; + } + if (mMode == MEDIA_METRICS_MODE_OFF) { + return LOGGING_LEVEL_BLOCKED; + } + + PackageManager pm = getContext().getPackageManager(); + String[] packages = pm.getPackagesForUid(uid); + if (packages == null || packages.length == 0) { + // The valid application UID range is from + // android.os.Process.FIRST_APPLICATION_UID to + // android.os.Process.LAST_APPLICATION_UID. + // UIDs outside this range will not have a package. + Slog.d(TAG, "empty package from uid " + uid); + // block the data if the mode is MEDIA_METRICS_MODE_ALLOWLIST + return mMode == MEDIA_METRICS_MODE_BLOCKLIST + ? LOGGING_LEVEL_NO_UID : LOGGING_LEVEL_BLOCKED; + } + if (mMode == MEDIA_METRICS_MODE_BLOCKLIST) { + if (mBlockList == null) { + mBlockList = getListLocked(PLAYER_METRICS_APP_BLOCKLIST); + if (mBlockList == null) { + // failed to get the blocklist. Block it. + return LOGGING_LEVEL_BLOCKED; + } + } + Integer level = loggingLevelInternal( + packages, mBlockList, PLAYER_METRICS_APP_BLOCKLIST); + if (level != null) { + return level; + } + if (mNoUidBlocklist == null) { + mNoUidBlocklist = + getListLocked(PLAYER_METRICS_PER_APP_ATTRIBUTION_BLOCKLIST); + if (mNoUidBlocklist == null) { + // failed to get the blocklist. Block it. + return LOGGING_LEVEL_BLOCKED; + } + } + level = loggingLevelInternal( + packages, + mNoUidBlocklist, + PLAYER_METRICS_PER_APP_ATTRIBUTION_BLOCKLIST); + if (level != null) { + return level; + } + // Not detected in any blocklist. Log everything. + return LOGGING_LEVEL_EVERYTHING; + } + if (mMode == MEDIA_METRICS_MODE_ALLOWLIST) { + if (mNoUidAllowlist == null) { + mNoUidAllowlist = + getListLocked(PLAYER_METRICS_PER_APP_ATTRIBUTION_ALLOWLIST); + if (mNoUidAllowlist == null) { + // failed to get the allowlist. Block it. + return LOGGING_LEVEL_BLOCKED; + } + } + Integer level = loggingLevelInternal( + packages, + mNoUidAllowlist, + PLAYER_METRICS_PER_APP_ATTRIBUTION_ALLOWLIST); + if (level != null) { + return level; + } + if (mAllowlist == null) { + mAllowlist = getListLocked(PLAYER_METRICS_APP_ALLOWLIST); + if (mAllowlist == null) { + // failed to get the allowlist. Block it. + return LOGGING_LEVEL_BLOCKED; + } + } + level = loggingLevelInternal( + packages, mAllowlist, PLAYER_METRICS_APP_ALLOWLIST); + if (level != null) { + return level; + } + // Not detected in any allowlist. Block. + return LOGGING_LEVEL_BLOCKED; + } + } + // Blocked by default. + return LOGGING_LEVEL_BLOCKED; + } + + private Integer loggingLevelInternal( + String[] packages, List<String> cached, String listName) { + if (inList(packages, cached)) { + return listNameToLoggingLevel(listName); + } + return null; + } + + private boolean inList(String[] packages, List<String> arr) { + for (String p : packages) { + for (String element : arr) { + if (p.equals(element)) { + return true; + } + } + } + return false; + } + + private int listNameToLoggingLevel(String listName) { + switch (listName) { + case PLAYER_METRICS_APP_BLOCKLIST: + return LOGGING_LEVEL_BLOCKED; + case PLAYER_METRICS_APP_ALLOWLIST: + return LOGGING_LEVEL_EVERYTHING; + case PLAYER_METRICS_PER_APP_ATTRIBUTION_ALLOWLIST: + case PLAYER_METRICS_PER_APP_ATTRIBUTION_BLOCKLIST: + return LOGGING_LEVEL_NO_UID; + default: + return LOGGING_LEVEL_BLOCKED; + } + } } } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 21f68aecd25b..d791bd69236c 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -1235,11 +1235,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final private BroadcastReceiver mWifiReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - synchronized (mUidRulesFirstLock) { - synchronized (mNetworkPoliciesSecondLock) { - upgradeWifiMeteredOverrideAL(); - } - } + upgradeWifiMeteredOverride(); // Only need to perform upgrade logic once mContext.unregisterReceiver(this); } @@ -2617,34 +2613,43 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { * Perform upgrade step of moving any user-defined meterness overrides over * into {@link WifiConfiguration}. */ - @GuardedBy({"mNetworkPoliciesSecondLock", "mUidRulesFirstLock"}) - private void upgradeWifiMeteredOverrideAL() { - boolean modified = false; + private void upgradeWifiMeteredOverride() { + final ArrayMap<String, Boolean> wifiNetworkIds = new ArrayMap<>(); + synchronized (mNetworkPoliciesSecondLock) { + for (int i = 0; i < mNetworkPolicy.size();) { + final NetworkPolicy policy = mNetworkPolicy.valueAt(i); + if (policy.template.getMatchRule() == NetworkTemplate.MATCH_WIFI + && !policy.inferred) { + mNetworkPolicy.removeAt(i); + wifiNetworkIds.put(policy.template.getNetworkId(), policy.metered); + } else { + i++; + } + } + } + + if (wifiNetworkIds.isEmpty()) { + return; + } final WifiManager wm = mContext.getSystemService(WifiManager.class); final List<WifiConfiguration> configs = wm.getConfiguredNetworks(); - for (int i = 0; i < mNetworkPolicy.size(); ) { - final NetworkPolicy policy = mNetworkPolicy.valueAt(i); - if (policy.template.getMatchRule() == NetworkTemplate.MATCH_WIFI - && !policy.inferred) { - mNetworkPolicy.removeAt(i); - modified = true; - - final String networkId = resolveNetworkId(policy.template.getNetworkId()); - for (WifiConfiguration config : configs) { - if (Objects.equals(resolveNetworkId(config), networkId)) { - Slog.d(TAG, "Found network " + networkId + "; upgrading metered hint"); - config.meteredOverride = policy.metered - ? WifiConfiguration.METERED_OVERRIDE_METERED - : WifiConfiguration.METERED_OVERRIDE_NOT_METERED; - wm.updateNetwork(config); - } - } - } else { - i++; + for (int i = 0; i < configs.size(); ++i) { + final WifiConfiguration config = configs.get(i); + final String networkId = resolveNetworkId(config); + final Boolean metered = wifiNetworkIds.get(networkId); + if (metered != null) { + Slog.d(TAG, "Found network " + networkId + "; upgrading metered hint"); + config.meteredOverride = metered + ? WifiConfiguration.METERED_OVERRIDE_METERED + : WifiConfiguration.METERED_OVERRIDE_NOT_METERED; + wm.updateNetwork(config); } } - if (modified) { - writePolicyAL(); + + synchronized (mUidRulesFirstLock) { + synchronized (mNetworkPoliciesSecondLock) { + writePolicyAL(); + } } } diff --git a/services/core/java/com/android/server/notification/InlineReplyUriRecord.java b/services/core/java/com/android/server/notification/InlineReplyUriRecord.java index 76cfb032aaf4..fa5c09ba0e34 100644 --- a/services/core/java/com/android/server/notification/InlineReplyUriRecord.java +++ b/services/core/java/com/android/server/notification/InlineReplyUriRecord.java @@ -16,9 +16,11 @@ package com.android.server.notification; +import android.app.ActivityManager; import android.net.Uri; import android.os.IBinder; import android.os.UserHandle; +import android.os.UserManager; import android.util.ArraySet; /** @@ -74,7 +76,9 @@ public final class InlineReplyUriRecord { */ public int getUserId() { int userId = mUser.getIdentifier(); - if (userId == UserHandle.USER_ALL) { + if (UserManager.isHeadlessSystemUserMode() && userId == UserHandle.USER_ALL) { + return ActivityManager.getCurrentUser(); + } else if (userId == UserHandle.USER_ALL) { return UserHandle.USER_SYSTEM; } else { return userId; diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 9151e4e1779a..d78fbdb53d8d 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -3815,15 +3815,18 @@ public class NotificationManagerService extends SystemService { enforceDeletingChannelHasNoFgService(pkg, callingUser, channelId); cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channelId, 0, 0, true, callingUser, REASON_CHANNEL_REMOVED, null); - mPreferencesHelper.deleteNotificationChannel(pkg, callingUid, channelId); - // Remove from both recent notification archive and notification history - mArchive.removeChannelNotifications(pkg, callingUser, channelId); - mHistoryManager.deleteNotificationChannel(pkg, callingUid, channelId); - mListeners.notifyNotificationChannelChanged(pkg, - UserHandle.getUserHandleForUid(callingUid), - mPreferencesHelper.getNotificationChannel(pkg, callingUid, channelId, true), - NOTIFICATION_CHANNEL_OR_GROUP_DELETED); - handleSavePolicyFile(); + boolean previouslyExisted = mPreferencesHelper.deleteNotificationChannel( + pkg, callingUid, channelId); + if (previouslyExisted) { + // Remove from both recent notification archive and notification history + mArchive.removeChannelNotifications(pkg, callingUser, channelId); + mHistoryManager.deleteNotificationChannel(pkg, callingUid, channelId); + mListeners.notifyNotificationChannelChanged(pkg, + UserHandle.getUserHandleForUid(callingUid), + mPreferencesHelper.getNotificationChannel(pkg, callingUid, channelId, true), + NOTIFICATION_CHANNEL_OR_GROUP_DELETED); + handleSavePolicyFile(); + } } @Override diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index 03676b5556d9..96bde3df1e68 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -1126,20 +1126,21 @@ public class PreferencesHelper implements RankingConfig { } @Override - public void deleteNotificationChannel(String pkg, int uid, String channelId) { + public boolean deleteNotificationChannel(String pkg, int uid, String channelId) { synchronized (mPackagePreferences) { PackagePreferences r = getPackagePreferencesLocked(pkg, uid); if (r == null) { - return; + return false; } NotificationChannel channel = r.channels.get(channelId); if (channel != null) { - deleteNotificationChannelLocked(channel, pkg, uid); + return deleteNotificationChannelLocked(channel, pkg, uid); } + return false; } } - private void deleteNotificationChannelLocked(NotificationChannel channel, String pkg, int uid) { + private boolean deleteNotificationChannelLocked(NotificationChannel channel, String pkg, int uid) { if (!channel.isDeleted()) { channel.setDeleted(true); channel.setDeletedTimeMs(System.currentTimeMillis()); @@ -1151,7 +1152,9 @@ public class PreferencesHelper implements RankingConfig { if (mAreChannelsBypassingDnd && channel.canBypassDnd()) { updateChannelsBypassingDnd(); } + return true; } + return false; } @Override diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java index b1d654671c2d..398259333e16 100644 --- a/services/core/java/com/android/server/notification/RankingConfig.java +++ b/services/core/java/com/android/server/notification/RankingConfig.java @@ -53,7 +53,7 @@ public interface RankingConfig { NotificationChannel getConversationNotificationChannel(String pkg, int uid, String channelId, String conversationId, boolean returnParentIfNoConversationChannel, boolean includeDeleted); - void deleteNotificationChannel(String pkg, int uid, String channelId); + boolean deleteNotificationChannel(String pkg, int uid, String channelId); void permanentlyDeleteNotificationChannel(String pkg, int uid, String channelId); void permanentlyDeleteNotificationChannels(String pkg, int uid); ParceledListSlice<NotificationChannel> getNotificationChannels(String pkg, int uid, diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index a98f113a9d57..b144ff27c993 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -417,7 +417,14 @@ public class ZenModeHelper { newConfig = mConfig.copy(); for (int i = newConfig.automaticRules.size() - 1; i >= 0; i--) { ZenRule rule = newConfig.automaticRules.get(newConfig.automaticRules.keyAt(i)); - if (rule.pkg.equals(packageName) && canManageAutomaticZenRule(rule)) { + String pkg = rule.pkg != null + ? rule.pkg + : (rule.component != null) + ? rule.component.getPackageName() + : (rule.configurationActivity != null) + ? rule.configurationActivity.getPackageName() + : null; + if (Objects.equals(pkg, packageName) && canManageAutomaticZenRule(rule)) { newConfig.automaticRules.removeAt(i); } } diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java index d1d1eb00b114..1401fa9b5e58 100644 --- a/services/core/java/com/android/server/pm/AppsFilter.java +++ b/services/core/java/com/android/server/pm/AppsFilter.java @@ -18,6 +18,7 @@ package com.android.server.pm; import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; import static android.os.UserHandle.USER_ALL; +import static android.os.UserHandle.USER_NULL; import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE; import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; @@ -838,8 +839,14 @@ public class AppsFilter implements Watchable, Snappable { private void updateEntireShouldFilterCache(int subjectUserId) { mStateProvider.runWithState((settings, users) -> { - int userId = subjectUserId; - if (!ArrayUtils.contains(users, subjectUserId)) { + int userId = USER_NULL; + for (int u = 0; u < users.length; u++) { + if (subjectUserId == users[u].id) { + userId = subjectUserId; + break; + } + } + if (userId == USER_NULL) { Slog.e(TAG, "We encountered a new user that isn't a member of known users, " + "updating the whole cache"); userId = USER_ALL; @@ -861,7 +868,7 @@ public class AppsFilter implements Watchable, Snappable { if (UserHandle.getUserId(uid2) == userId) { continue; } - cache.setValueAt(uid1, uid2, mShouldFilterCache.valueAt(uid1, uid2)); + cache.put(uid1, uid2, mShouldFilterCache.get(uid1, uid2)); } } } diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index c33130037027..acc83cfd05b6 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -2799,7 +2799,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { private boolean isApexUpdateAllowed(String apexPackageName) { return mPm.getModuleInfo(apexPackageName, 0) != null - || SystemConfig.getInstance().getAllowedPartnerApexes().contains(apexPackageName); + || SystemConfig.getInstance().getAllowedVendorApexes().contains(apexPackageName); } /** diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index b0a662b3514d..889785d5f766 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -245,7 +245,6 @@ import android.content.pm.parsing.ParsingPackageUtils; import android.content.pm.parsing.ParsingPackageUtils.ParseFlags; import android.content.pm.parsing.component.ParsedActivity; import android.content.pm.parsing.component.ParsedInstrumentation; -import android.content.pm.parsing.component.ParsedIntentInfo; import android.content.pm.parsing.component.ParsedMainComponent; import android.content.pm.parsing.component.ParsedPermission; import android.content.pm.parsing.component.ParsedPermissionGroup; @@ -17102,9 +17101,15 @@ public class PackageManagerService extends IPackageManager.Stub return new ParceledListSlice<IntentFilter>(result) { @Override protected void writeElement(IntentFilter parcelable, Parcel dest, int callFlags) { - // WatchedIntentFilter has final Parcelable methods, so redirect to the subclass - ((ParsedIntentInfo) parcelable).writeIntentInfoToParcel(dest, - callFlags); + parcelable.writeToParcel(dest, callFlags); + } + + @Override + protected void writeParcelableCreator(IntentFilter parcelable, Parcel dest) { + // All Parcel#writeParcelableCreator does is serialize the class name to + // access via reflection to grab its CREATOR. This does that manually, pointing + // to the parent IntentFilter so that all of the subclass fields are ignored. + dest.writeString(IntentFilter.class.getName()); } }; } @@ -21481,7 +21486,7 @@ public class PackageManagerService extends IPackageManager.Stub // user handle installed state int[] allUsers; final int freezeUser; - final SparseArray<Pair<Integer, String>> enabledStateAndCallerPerUser; + final SparseArray<TempUserState> priorUserStates; /** enabled state of the uninstalled application */ synchronized (mLock) { uninstalledPs = mSettings.getPackageLPr(packageName); @@ -21532,16 +21537,16 @@ public class PackageManagerService extends IPackageManager.Stub // We're downgrading a system app, which will apply to all users, so // freeze them all during the downgrade freezeUser = UserHandle.USER_ALL; - enabledStateAndCallerPerUser = new SparseArray<>(); + priorUserStates = new SparseArray<>(); for (int i = 0; i < allUsers.length; i++) { PackageUserState userState = uninstalledPs.readUserState(allUsers[i]); - Pair<Integer, String> enabledStateAndCaller = - new Pair<>(userState.enabled, userState.lastDisableAppCaller); - enabledStateAndCallerPerUser.put(allUsers[i], enabledStateAndCaller); + priorUserStates.put(allUsers[i], + new TempUserState(userState.enabled, userState.lastDisableAppCaller, + userState.installed)); } } else { freezeUser = removeUser; - enabledStateAndCallerPerUser = null; + priorUserStates = null; } } @@ -21578,6 +21583,30 @@ public class PackageManagerService extends IPackageManager.Stub if (info.args != null) { info.args.doPostDeleteLI(true); } + + boolean reEnableStub = false; + + if (priorUserStates != null) { + synchronized (mLock) { + for (int i = 0; i < allUsers.length; i++) { + TempUserState priorUserState = priorUserStates.get(allUsers[i]); + int enabledState = priorUserState.enabledState; + PackageSetting pkgSetting = getPackageSetting(packageName); + pkgSetting.setEnabled(enabledState, allUsers[i], + priorUserState.lastDisableAppCaller); + + AndroidPackage aPkg = pkgSetting.getPkg(); + boolean pkgEnabled = aPkg != null && aPkg.isEnabled(); + if (!reEnableStub && priorUserState.installed + && ((enabledState == COMPONENT_ENABLED_STATE_DEFAULT && pkgEnabled) + || enabledState == COMPONENT_ENABLED_STATE_ENABLED)) { + reEnableStub = true; + } + } + mSettings.writeAllUsersPackageRestrictionsLPr(); + } + } + final AndroidPackage stubPkg = (disabledSystemPs == null) ? null : disabledSystemPs.pkg; if (stubPkg != null && stubPkg.isStub()) { @@ -21587,19 +21616,7 @@ public class PackageManagerService extends IPackageManager.Stub } if (stubPs != null) { - boolean enable = false; - for (int aUserId : allUsers) { - if (stubPs.getInstalled(aUserId)) { - int enabled = stubPs.getEnabled(aUserId); - if (enabled == COMPONENT_ENABLED_STATE_DEFAULT - || enabled == COMPONENT_ENABLED_STATE_ENABLED) { - enable = true; - break; - } - } - } - - if (enable) { + if (reEnableStub) { if (DEBUG_COMPRESSION) { Slog.i(TAG, "Enabling system stub after removal; pkg: " + stubPkg.getPackageName()); @@ -21611,19 +21628,6 @@ public class PackageManagerService extends IPackageManager.Stub } } } - if (enabledStateAndCallerPerUser != null) { - synchronized (mLock) { - for (int i = 0; i < allUsers.length; i++) { - Pair<Integer, String> enabledStateAndCaller = - enabledStateAndCallerPerUser.get(allUsers[i]); - getPackageSetting(packageName) - .setEnabled(enabledStateAndCaller.first, - allUsers[i], - enabledStateAndCaller.second); - } - mSettings.writeAllUsersPackageRestrictionsLPr(); - } - } } return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; @@ -28148,8 +28152,8 @@ public class PackageManagerService extends IPackageManager.Stub } @Override - public void deleteOatArtifactsOfPackage(String packageName) { - PackageManagerService.this.deleteOatArtifactsOfPackage(packageName); + public long deleteOatArtifactsOfPackage(String packageName) { + return PackageManagerService.this.deleteOatArtifactsOfPackage(packageName); } @Override @@ -28928,6 +28932,20 @@ public class PackageManagerService extends IPackageManager.Stub } } } + + private static class TempUserState { + public final int enabledState; + @Nullable + public final String lastDisableAppCaller; + public final boolean installed; + + private TempUserState(int enabledState, @Nullable String lastDisableAppCaller, + boolean installed) { + this.enabledState = enabledState; + this.lastDisableAppCaller = lastDisableAppCaller; + this.installed = installed; + } + } } interface PackageSender { diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 4a68b7606c60..c842ff1b11a5 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -955,8 +955,7 @@ public class StagingManager { continue; } else if (isApexSessionFailed(apexSession)) { hasFailedApexSession = true; - String errorMsg = "APEX activation failed. Check logcat messages from apexd " - + "for more information."; + String errorMsg = "APEX activation failed. " + apexSession.errorMessage; if (!TextUtils.isEmpty(apexSession.crashingNativeProcess)) { prepareForLoggingApexdRevert(session, apexSession.crashingNativeProcess); errorMsg = "Session reverted due to crashing native process: " diff --git a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java index 83d4ce7ff057..b26b6940a1af 100644 --- a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java +++ b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java @@ -22,6 +22,7 @@ import static com.android.internal.art.ArtStatsLog.ART_DATUM_REPORTED__COMPILATI import static com.android.internal.art.ArtStatsLog.ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_APK_FALLBACK; import static com.android.internal.art.ArtStatsLog.ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_FAKE_RUN_FROM_VDEX_FALLBACK; +import android.os.SystemClock; import android.util.Slog; import android.util.jar.StrictJarFile; @@ -288,7 +289,7 @@ public class ArtStatsLogUtils { ART_DATUM_REPORTED__COMPILE_FILTER__ART_COMPILATION_FILTER_UNKNOWN), COMPILATION_REASON_MAP.getOrDefault(compilationReason, ArtStatsLog. ART_DATUM_REPORTED__COMPILATION_REASON__ART_COMPILATION_REASON_UNKNOWN), - /*timestamp_millis=*/ 0L, + /*timestamp_millis=*/ SystemClock.uptimeMillis(), ArtStatsLog.ART_DATUM_REPORTED__THREAD_TYPE__ART_THREAD_MAIN, kind, value, diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java index bad7e5c27b7b..dab980a9e4b2 100644 --- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java @@ -641,7 +641,7 @@ final class DefaultPermissionGrantPolicy { // Cell Broadcast Receiver grantSystemFixedPermissionsToSystemPackage(pm, getDefaultSystemHandlerActivityPackage(pm, Intents.SMS_CB_RECEIVED_ACTION, userId), - userId, SMS_PERMISSIONS); + userId, SMS_PERMISSIONS, NEARBY_DEVICES_PERMISSIONS); // Carrier Provisioning Service grantPermissionsToSystemPackage(pm, diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index a391dbc1fa47..38e9d3ec34e3 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -5720,10 +5720,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { boolean fromDatasource, int attributedOp) { // Now let's check the identity chain... final int op = AppOpsManager.permissionToOpCode(permission); - final int attributionChainId = (startDataDelivery) - ? sAttributionChainIds.incrementAndGet() - : AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE; - + final int attributionChainId = + getAttributionChainId(startDataDelivery, attributionSource); AttributionSource current = attributionSource; AttributionSource next = null; @@ -5879,9 +5877,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { return PermissionChecker.PERMISSION_HARD_DENIED; } - final int attributionChainId = (startDataDelivery) - ? sAttributionChainIds.incrementAndGet() - : AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE; + final int attributionChainId = + getAttributionChainId(startDataDelivery, attributionSource); AttributionSource current = attributionSource; AttributionSource next = null; @@ -6064,6 +6061,21 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } + private static int getAttributionChainId(boolean startDataDelivery, + AttributionSource source) { + if (source == null || source.getNext() == null || !startDataDelivery) { + return AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE; + } + int attributionChainId = sAttributionChainIds.incrementAndGet(); + + // handle overflow + if (attributionChainId < 0) { + attributionChainId = 0; + sAttributionChainIds.set(0); + } + return attributionChainId; + } + private static @Nullable String resolvePackageName(@NonNull Context context, @NonNull AttributionSource attributionSource) { if (attributionSource.getPackageName() != null) { diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java index 22c370ef4dbe..a389f40e772b 100644 --- a/services/core/java/com/android/server/policy/AppOpsPolicy.java +++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java @@ -39,7 +39,6 @@ import android.os.UserHandle; import android.service.voice.VoiceInteractionManagerInternal; import android.service.voice.VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity; import android.text.TextUtils; -import android.util.ArraySet; import android.util.Log; import android.util.SparseArray; @@ -48,6 +47,7 @@ import com.android.internal.util.function.DecFunction; import com.android.internal.util.function.HeptFunction; import com.android.internal.util.function.HexFunction; import com.android.internal.util.function.QuadFunction; +import com.android.internal.util.function.QuintConsumer; import com.android.internal.util.function.QuintFunction; import com.android.internal.util.function.TriFunction; import com.android.internal.util.function.UndecFunction; @@ -68,10 +68,6 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat "android:activity_recognition_allow_listed_tags"; private static final String ACTIVITY_RECOGNITION_TAGS_SEPARATOR = ";"; - private static final ArraySet<String> sExpectedTags = new ArraySet<>(new String[] { - "awareness_provider", "activity_recognition_provider", "network_location_provider", - "network_location_calibration", "fused_location_provider", "geofencer_provider"}); - @NonNull private final Object mLock = new Object(); @@ -243,6 +239,14 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat } @Override + public void finishOperation(IBinder clientId, int code, int uid, String packageName, + String attributionTag, + @NonNull QuintConsumer<IBinder, Integer, Integer, String, String> superImpl) { + superImpl.accept(clientId, resolveDatasourceOp(code, uid, packageName, attributionTag), + resolveUid(code, uid), packageName, attributionTag); + } + + @Override public void finishProxyOperation(int code, @NonNull AttributionSource attributionSource, boolean skipProxyOperation, @NonNull TriFunction<Integer, AttributionSource, Boolean, Void> superImpl) { @@ -260,32 +264,14 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat if (resolvedCode != code) { if (isDatasourceAttributionTag(uid, packageName, attributionTag, mLocationTags)) { - if (packageName.equals("com.google.android.gms") - && !sExpectedTags.contains(attributionTag)) { - Log.i("AppOpsDebugRemapping", "remapping " + packageName + " location " - + "for tag " + attributionTag); - } return resolvedCode; - } else if (packageName.equals("com.google.android.gms") - && sExpectedTags.contains(attributionTag)) { - Log.i("AppOpsDebugRemapping", "NOT remapping " + packageName + " code " - + code + " for tag " + attributionTag); } } else { resolvedCode = resolveArOp(code); if (resolvedCode != code) { if (isDatasourceAttributionTag(uid, packageName, attributionTag, mActivityRecognitionTags)) { - if (packageName.equals("com.google.android.gms") - && !sExpectedTags.contains(attributionTag)) { - Log.i("AppOpsDebugRemapping", "remapping " + packageName + " " - + "activity recognition for tag " + attributionTag); - } return resolvedCode; - } else if (packageName.equals("com.google.android.gms") - && sExpectedTags.contains(attributionTag)) { - Log.i("AppOpsDebugRemapping", "NOT remapping " + packageName - + " code " + code + " for tag " + attributionTag); } } } diff --git a/services/core/java/com/android/server/tracing/TracingServiceProxy.java b/services/core/java/com/android/server/tracing/TracingServiceProxy.java index 8f227489740f..ff2f08bc4a50 100644 --- a/services/core/java/com/android/server/tracing/TracingServiceProxy.java +++ b/services/core/java/com/android/server/tracing/TracingServiceProxy.java @@ -20,6 +20,7 @@ import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.os.Binder; import android.os.UserHandle; import android.tracing.ITracingServiceProxy; import android.util.Log; @@ -30,6 +31,8 @@ import com.android.server.SystemService; * TracingServiceProxy is the system_server intermediary between the Perfetto tracing daemon and the * system tracing app Traceur. * + * Access to this service is restricted via SELinux. Normal apps do not have access. + * * @hide */ public class TracingServiceProxy extends SystemService { @@ -87,11 +90,15 @@ public class TracingServiceProxy extends SystemService { intent.setAction(INTENT_ACTION_NOTIFY_SESSION_STOPPED); } + final long identity = Binder.clearCallingIdentity(); try { mContext.startForegroundServiceAsUser(intent, UserHandle.SYSTEM); } catch (RuntimeException e) { Log.e(TAG, "Failed to notifyTraceSessionEnded", e); + } finally { + Binder.restoreCallingIdentity(identity); } + } catch (NameNotFoundException e) { Log.e(TAG, "Failed to locate Traceur", e); } diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java index 95a06fcff734..44a6d13153fd 100644 --- a/services/core/java/com/android/server/vcn/Vcn.java +++ b/services/core/java/com/android/server/vcn/Vcn.java @@ -518,7 +518,11 @@ public class Vcn extends Handler { } private String getLogPrefix() { - return "[" + LogUtils.getHashedSubscriptionGroup(mSubscriptionGroup) + "] "; + return "[" + + LogUtils.getHashedSubscriptionGroup(mSubscriptionGroup) + + "-" + + System.identityHashCode(this) + + "] "; } private void logVdbg(String msg) { diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java index 493697049f34..c6f3f73d0c61 100644 --- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java +++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java @@ -714,6 +714,18 @@ public class VcnGatewayConnection extends StateMachine { protected void onQuitting() { logDbg("Quitting VcnGatewayConnection"); + if (mNetworkAgent != null) { + logWtf("NetworkAgent was non-null in onQuitting"); + mNetworkAgent.unregister(); + mNetworkAgent = null; + } + + if (mIkeSession != null) { + logWtf("IkeSession was non-null in onQuitting"); + mIkeSession.kill(); + mIkeSession = null; + } + // No need to call setInterfaceDown(); the IpSecInterface is being fully torn down. if (mTunnelIface != null) { mTunnelIface.close(); @@ -1863,6 +1875,7 @@ public class VcnGatewayConnection extends StateMachine { if (mUnderlying == null) { logWtf("Underlying network was null in retry state"); + teardownNetwork(); transitionTo(mDisconnectedState); } else { // Safe to blindly set up, as it is cancelled and cleared on exiting this state @@ -1879,6 +1892,7 @@ public class VcnGatewayConnection extends StateMachine { // If new underlying is null, all networks were lost; go back to disconnected. if (mUnderlying == null) { + teardownNetwork(); transitionTo(mDisconnectedState); return; } else if (oldUnderlying != null @@ -2134,6 +2148,8 @@ public class VcnGatewayConnection extends StateMachine { + LogUtils.getHashedSubscriptionGroup(mSubscriptionGroup) + "-" + mConnectionConfig.getGatewayConnectionName() + + "-" + + System.identityHashCode(this) + "] "; } diff --git a/services/core/java/com/android/server/vibrator/StepToRampAdapter.java b/services/core/java/com/android/server/vibrator/StepToRampAdapter.java index d439b94ec2fc..1d8c64bddd49 100644 --- a/services/core/java/com/android/server/vibrator/StepToRampAdapter.java +++ b/services/core/java/com/android/server/vibrator/StepToRampAdapter.java @@ -22,6 +22,7 @@ import android.os.vibrator.RampSegment; import android.os.vibrator.StepSegment; import android.os.vibrator.VibrationEffectSegment; +import java.util.ArrayList; import java.util.List; /** @@ -59,6 +60,7 @@ final class StepToRampAdapter implements VibrationEffectAdapters.SegmentsAdapter convertStepsToRamps(segments); int newRepeatIndex = addRampDownToZeroAmplitudeSegments(segments, repeatIndex); newRepeatIndex = addRampDownToLoop(segments, newRepeatIndex); + newRepeatIndex = splitLongRampSegments(info, segments, newRepeatIndex); return newRepeatIndex; } @@ -210,11 +212,70 @@ final class StepToRampAdapter implements VibrationEffectAdapters.SegmentsAdapter return repeatIndex; } + /** + * Split {@link RampSegment} entries that have duration longer than {@link + * VibratorInfo#getPwlePrimitiveDurationMax()}. + */ + private int splitLongRampSegments(VibratorInfo info, List<VibrationEffectSegment> segments, + int repeatIndex) { + int maxDuration = info.getPwlePrimitiveDurationMax(); + if (maxDuration <= 0) { + // No limit set to PWLE primitive duration. + return repeatIndex; + } + + int segmentCount = segments.size(); + for (int i = 0; i < segmentCount; i++) { + if (!(segments.get(i) instanceof RampSegment)) { + continue; + } + RampSegment ramp = (RampSegment) segments.get(i); + int splits = ((int) ramp.getDuration() + maxDuration - 1) / maxDuration; + if (splits <= 1) { + continue; + } + segments.remove(i); + segments.addAll(i, splitRampSegment(ramp, splits)); + int addedSegments = splits - 1; + if (repeatIndex > i) { + repeatIndex += addedSegments; + } + i += addedSegments; + segmentCount += addedSegments; + } + + return repeatIndex; + } + private static RampSegment apply(StepSegment segment) { return new RampSegment(segment.getAmplitude(), segment.getAmplitude(), segment.getFrequency(), segment.getFrequency(), (int) segment.getDuration()); } + private static List<RampSegment> splitRampSegment(RampSegment ramp, int splits) { + List<RampSegment> ramps = new ArrayList<>(splits); + long splitDuration = ramp.getDuration() / splits; + float previousAmplitude = ramp.getStartAmplitude(); + float previousFrequency = ramp.getStartFrequency(); + long accumulatedDuration = 0; + + for (int i = 1; i < splits; i++) { + accumulatedDuration += splitDuration; + RampSegment rampSplit = new RampSegment( + previousAmplitude, interpolateAmplitude(ramp, accumulatedDuration), + previousFrequency, interpolateFrequency(ramp, accumulatedDuration), + (int) splitDuration); + ramps.add(rampSplit); + previousAmplitude = rampSplit.getEndAmplitude(); + previousFrequency = rampSplit.getEndFrequency(); + } + + ramps.add(new RampSegment(previousAmplitude, ramp.getEndAmplitude(), previousFrequency, + ramp.getEndFrequency(), (int) (ramp.getDuration() - accumulatedDuration))); + + return ramps; + } + private static RampSegment createRampDown(float amplitude, float frequency, long duration) { return new RampSegment(amplitude, /* endAmplitude= */ 0, frequency, frequency, (int) duration); @@ -244,4 +305,19 @@ final class StepToRampAdapter implements VibrationEffectAdapters.SegmentsAdapter } return false; } + + private static float interpolateAmplitude(RampSegment ramp, long duration) { + return interpolate(ramp.getStartAmplitude(), ramp.getEndAmplitude(), duration, + ramp.getDuration()); + } + + private static float interpolateFrequency(RampSegment ramp, long duration) { + return interpolate(ramp.getStartFrequency(), ramp.getEndFrequency(), duration, + ramp.getDuration()); + } + + private static float interpolate(float start, float end, long duration, long totalDuration) { + float position = (float) duration / totalDuration; + return start + position * (end - start); + } } diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index 782e18b0250c..771332071756 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -405,20 +405,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub needsExtraction = wallpaper.primaryColors == null; } - // Let's notify the current values, it's fine if it's null, it just means - // that we don't know yet. - notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId, displayId); - if (needsExtraction) { extractColors(wallpaper); - synchronized (mLock) { - // Don't need to notify if nothing changed. - if (wallpaper.primaryColors == null) { - return; - } - } - notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId, displayId); } + notifyColorListeners(wallpaper.primaryColors, which, wallpaper.userId, displayId); } private static <T extends IInterface> boolean emptyCallbackList(RemoteCallbackList<T> list) { diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java index f6217bc2ffd2..0f6a71823334 100644 --- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java @@ -609,13 +609,27 @@ class ActivityMetricsLogger { return; } + // If the launched activity is started from an existing active transition, it will be put + // into the transition info. if (info != null && info.canCoalesce(launchedActivity)) { - // If we are already in an existing transition on the same display, only update the - // activity name, but not the other attributes. + if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched consecutive launch"); - if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched update launched activity"); + final boolean crossPackage = + !info.mLastLaunchedActivity.packageName.equals(launchedActivity.packageName); + // The trace name uses package name so different packages should be separated. + if (crossPackage) { + stopLaunchTrace(info); + } + + mLastTransitionInfo.remove(info.mLastLaunchedActivity); // Coalesce multiple (trampoline) activities from a single sequence together. info.setLatestLaunchedActivity(launchedActivity); + // Update the latest one so it can be found when reporting fully-drawn. + mLastTransitionInfo.put(launchedActivity, info); + + if (crossPackage) { + startLaunchTrace(info); + } return; } @@ -638,12 +652,24 @@ class ActivityMetricsLogger { launchObserverNotifyIntentFailed(); } if (launchedActivity.mDisplayContent.isSleeping()) { - // It is unknown whether the activity can be drawn or not, e.g. ut depends on the + // It is unknown whether the activity can be drawn or not, e.g. it depends on the // keyguard states and the attributes or flags set by the activity. If the activity // keeps invisible in the grace period, the tracker will be cancelled so it won't get // a very long launch time that takes unlocking as the end of launch. scheduleCheckActivityToBeDrawn(launchedActivity, UNKNOWN_VISIBILITY_CHECK_DELAY_MS); } + + // If the previous transitions are no longer visible, abort them to avoid counting the + // launch time when resuming from back stack. E.g. launch 2 independent tasks in a short + // time, the transition info of the first task should not keep active until it becomes + // visible such as after the top task is finished. + for (int i = mTransitionInfoList.size() - 2; i >= 0; i--) { + final TransitionInfo prevInfo = mTransitionInfoList.get(i); + prevInfo.updatePendingDraw(); + if (prevInfo.allDrawn()) { + abort(prevInfo, "nothing will be drawn"); + } + } } /** @@ -864,6 +890,7 @@ class ActivityMetricsLogger { final Boolean isHibernating = mLastHibernationStates.remove(info.mLastLaunchedActivity.packageName); if (abort) { + mLastTransitionInfo.remove(info.mLastLaunchedActivity); mSupervisor.stopWaitingForActivityVisible(info.mLastLaunchedActivity); launchObserverNotifyActivityLaunchCancelled(info); } else { diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index b156e12a1ce8..0ad8782cea4f 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -38,6 +38,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.ROTATION_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; @@ -277,6 +278,7 @@ import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; import android.os.storage.StorageManager; +import android.service.contentcapture.ActivityEvent; import android.service.dreams.DreamActivity; import android.service.dreams.DreamManagerInternal; import android.service.voice.IVoiceInteractionSession; @@ -327,6 +329,7 @@ import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.LocalServices; import com.android.server.am.AppTimeTracker; import com.android.server.am.PendingIntentRecord; +import com.android.server.contentcapture.ContentCaptureManagerInternal; import com.android.server.display.color.ColorDisplayService; import com.android.server.policy.WindowManagerPolicy; import com.android.server.uri.NeededUriGrants; @@ -1786,17 +1789,19 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** * Evaluate the theme for a starting window. + * @param prev Previous activity which may have a starting window. * @param originalTheme The original theme which read from activity or application. * @param replaceTheme The replace theme which requested from starter. * @return Resolved theme. */ - private int evaluateStartingWindowTheme(String pkg, int originalTheme, int replaceTheme) { + private int evaluateStartingWindowTheme(ActivityRecord prev, String pkg, int originalTheme, + int replaceTheme) { // Skip if the package doesn't want a starting window. - if (!validateStartingWindowTheme(pkg, originalTheme)) { + if (!validateStartingWindowTheme(prev, pkg, originalTheme)) { return 0; } int selectedTheme = originalTheme; - if (replaceTheme != 0 && validateStartingWindowTheme(pkg, replaceTheme)) { + if (replaceTheme != 0 && validateStartingWindowTheme(prev, pkg, replaceTheme)) { // allow to replace theme selectedTheme = replaceTheme; } @@ -1833,7 +1838,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return LAUNCH_SOURCE_TYPE_APPLICATION; } - private boolean validateStartingWindowTheme(String pkg, int theme) { + private boolean validateStartingWindowTheme(ActivityRecord prev, String pkg, int theme) { // If this is a translucent window, then don't show a starting window -- the current // effect (a full-screen opaque starting window that fades away to the real contents // when it is ready) does not work for this. @@ -1870,7 +1875,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } if (windowDisableStarting && !launchedFromSystemSurface()) { - return false; + // Check if previous activity can transfer the starting window to this activity. + return prev != null && prev.getActivityType() == ACTIVITY_TYPE_STANDARD + && prev.mTransferringSplashScreenState == TRANSFER_SPLASH_SCREEN_IDLE + && (prev.mStartingData != null + || (prev.mStartingWindow != null && prev.mStartingSurface != null)); } return true; } @@ -4871,6 +4880,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A true /* activityChange */, true /* updateOomAdj */, true /* addPendingTopUid */); } + final ContentCaptureManagerInternal contentCaptureService = + LocalServices.getService(ContentCaptureManagerInternal.class); + if (contentCaptureService != null) { + contentCaptureService.notifyActivityEvent(mUserId, mActivityComponent, + ActivityEvent.TYPE_ACTIVITY_STARTED); + } break; case PAUSED: mAtmService.updateBatteryStats(this, false); @@ -6276,15 +6291,21 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mSplashScreenStyleEmpty = shouldUseEmptySplashScreen(sourceRecord); - final int resolvedTheme = evaluateStartingWindowTheme(packageName, theme, + final int resolvedTheme = evaluateStartingWindowTheme(prev, packageName, theme, splashScreenTheme); + final boolean activityCreated = + mState.ordinal() >= STARTED.ordinal() && mState.ordinal() <= STOPPED.ordinal(); + // If this activity is just created and all activities below are finish, treat this + // scenario as warm launch. + final boolean newSingleActivity = !newTask && !activityCreated + && task.getActivity((r) -> !r.finishing && r != this) == null; + final boolean shown = addStartingWindow(packageName, resolvedTheme, compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags, - prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(), - allowTaskSnapshot(), - mState.ordinal() >= STARTED.ordinal() && mState.ordinal() <= STOPPED.ordinal(), - mSplashScreenStyleEmpty); + prev != null ? prev.appToken : null, + newTask || newSingleActivity, taskSwitch, isProcessRunning(), + allowTaskSnapshot(), activityCreated, mSplashScreenStyleEmpty); if (shown) { mStartingWindowState = STARTING_WINDOW_SHOWN; } diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java index 72574786c46b..b6f2f243040e 100644 --- a/services/core/java/com/android/server/wm/ActivityStartController.java +++ b/services/core/java/com/android/server/wm/ActivityStartController.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static android.app.ActivityManager.START_CANCELED; import static android.app.ActivityManager.START_SUCCESS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; @@ -390,15 +391,18 @@ public class ActivityStartController { 0 /* startFlags */, null /* profilerInfo */, userId, filterCallingUid); aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId); - // Carefully collect grants without holding lock if (aInfo != null) { - intentGrants = mSupervisor.mService.mUgmInternal - .checkGrantUriPermissionFromIntent(intent, filterCallingUid, - aInfo.applicationInfo.packageName, - UserHandle.getUserId(aInfo.applicationInfo.uid)); - } + try { + // Carefully collect grants without holding lock + intentGrants = mSupervisor.mService.mUgmInternal + .checkGrantUriPermissionFromIntent(intent, filterCallingUid, + aInfo.applicationInfo.packageName, + UserHandle.getUserId(aInfo.applicationInfo.uid)); + } catch (SecurityException e) { + Slog.d(TAG, "Not allowed to start activity since no uri permission."); + return START_CANCELED; + } - if (aInfo != null) { if ((aInfo.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) { throw new IllegalArgumentException( diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java index 01ee3be08f5f..1759cdeb60d7 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java @@ -280,11 +280,6 @@ public abstract class ActivityTaskManagerInternal { public abstract boolean isRecentsComponentHomeActivity(int userId); /** - * Cancels any currently running recents animation. - */ - public abstract void cancelRecentsAnimation(boolean restoreHomeRootTaskPosition); - - /** * Returns true if the app can close system dialogs. Otherwise it either throws a {@link * SecurityException} or returns false with a logcat message depending on whether the app * targets SDK level {@link android.os.Build.VERSION_CODES#S} or not. diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 5e75cebc322d..569c11be01e7 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -580,19 +580,28 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { * windowing modes. * 0: If it is a small screen (smallest width < {@link #mLargeScreenSmallestScreenWidthDp}), * the device compares the activity min width/height with the min multi windowing modes - * dimensions {@link #mMinPercentageMultiWindowSupportWidth} the device supports to + * dimensions {@link #mMinPercentageMultiWindowSupportHeight} the device supports to * determine whether the activity can be shown in multi windowing modes * 1: The device always compare the activity min width/height with the min multi windowing - * modes dimensions {@link #mMinPercentageMultiWindowSupportWidth} the device supports to + * modes dimensions {@link #mMinPercentageMultiWindowSupportHeight} the device supports to * determine whether it can be shown in multi windowing modes. */ int mRespectsActivityMinWidthHeightMultiWindow; /** - * This value is only used when the device checks activity min width/height to determine if it + * This value is only used when the device checks activity min height to determine if it * can be shown in multi windowing modes. - * If the activity min width/height is greater than this percentage of the display smallest - * width, it will not be allowed to be shown in multi windowing modes. + * If the activity min height is greater than this percentage of the display height in portrait, + * it will not be allowed to be shown in multi windowing modes. + * The value should be between [0 - 1]. + */ + float mMinPercentageMultiWindowSupportHeight; + + /** + * This value is only used when the device checks activity min width to determine if it + * can be shown in multi windowing modes. + * If the activity min width is greater than this percentage of the display width in landscape, + * it will not be allowed to be shown in multi windowing modes. * The value should be between [0 - 1]. */ float mMinPercentageMultiWindowSupportWidth; @@ -840,6 +849,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { com.android.internal.R.integer.config_supportsNonResizableMultiWindow); final int respectsActivityMinWidthHeightMultiWindow = mContext.getResources().getInteger( com.android.internal.R.integer.config_respectsActivityMinWidthHeightMultiWindow); + final float minPercentageMultiWindowSupportHeight = mContext.getResources().getFloat( + com.android.internal.R.dimen.config_minPercentageMultiWindowSupportHeight); final float minPercentageMultiWindowSupportWidth = mContext.getResources().getFloat( com.android.internal.R.dimen.config_minPercentageMultiWindowSupportWidth); final int largeScreenSmallestScreenWidthDp = mContext.getResources().getInteger( @@ -860,6 +871,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mDevEnableNonResizableMultiWindow = devEnableNonResizableMultiWindow; mSupportsNonResizableMultiWindow = supportsNonResizableMultiWindow; mRespectsActivityMinWidthHeightMultiWindow = respectsActivityMinWidthHeightMultiWindow; + mMinPercentageMultiWindowSupportHeight = minPercentageMultiWindowSupportHeight; mMinPercentageMultiWindowSupportWidth = minPercentageMultiWindowSupportWidth; mLargeScreenSmallestScreenWidthDp = largeScreenSmallestScreenWidthDp; final boolean multiWindowFormEnabled = freeformWindowManagement @@ -4146,21 +4158,21 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** * Update the asset configuration and increase the assets sequence number. - * @param processes the processes that needs to update the asset configuration, if none - * updates the global configuration for all processes. + * @param processes the processes that needs to update the asset configuration */ - public void updateAssetConfiguration(List<WindowProcessController> processes) { + public void updateAssetConfiguration(List<WindowProcessController> processes, + boolean updateFrameworkRes) { synchronized (mGlobalLock) { final int assetSeq = increaseAssetConfigurationSeq(); - // Update the global configuration if the no target processes - if (processes == null) { + if (updateFrameworkRes) { Configuration newConfig = new Configuration(); newConfig.assetsSeq = assetSeq; updateConfiguration(newConfig); - return; } + // Always update the override of every process so the asset sequence of the process is + // always greater than or equal to the global configuration. for (int i = processes.size() - 1; i >= 0; i--) { final WindowProcessController wpc = processes.get(i); wpc.updateAssetConfiguration(assetSeq); @@ -5256,11 +5268,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public void cancelRecentsAnimation(boolean restoreHomeRootTaskPosition) { - ActivityTaskManagerService.this.cancelRecentsAnimation(restoreHomeRootTaskPosition); - } - - @Override public boolean checkCanCloseSystemDialogs(int pid, int uid, @Nullable String packageName) { return ActivityTaskManagerService.this.checkCanCloseSystemDialogs(pid, uid, packageName); diff --git a/services/core/java/com/android/server/wm/CompatModePackages.java b/services/core/java/com/android/server/wm/CompatModePackages.java index 0ec01422474a..2ea043a5c623 100644 --- a/services/core/java/com/android/server/wm/CompatModePackages.java +++ b/services/core/java/com/android/server/wm/CompatModePackages.java @@ -75,10 +75,18 @@ public final class CompatModePackages { * CompatModePackages#DOWNSCALED is the gatekeeper of all per-app buffer downscaling * changes. Disabling this change will prevent the following scaling factors from working: * CompatModePackages#DOWNSCALE_90 + * CompatModePackages#DOWNSCALE_85 * CompatModePackages#DOWNSCALE_80 + * CompatModePackages#DOWNSCALE_75 * CompatModePackages#DOWNSCALE_70 + * CompatModePackages#DOWNSCALE_65 * CompatModePackages#DOWNSCALE_60 + * CompatModePackages#DOWNSCALE_55 * CompatModePackages#DOWNSCALE_50 + * CompatModePackages#DOWNSCALE_45 + * CompatModePackages#DOWNSCALE_40 + * CompatModePackages#DOWNSCALE_35 + * CompatModePackages#DOWNSCALE_30 * * If CompatModePackages#DOWNSCALED is enabled for an app package, then the app will be forcibly * resized to the highest enabled scaling factor e.g. 80% if both 80% and 70% were enabled. @@ -100,6 +108,16 @@ public final class CompatModePackages { /** * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id + * CompatModePackages#DOWNSCALE_85 for a package will force the app to assume it's + * running on a display with 85% the vertical and horizontal resolution of the real display. + */ + @ChangeId + @Disabled + @Overridable + public static final long DOWNSCALE_85 = 189969734L; + + /** + * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id * CompatModePackages#DOWNSCALE_80 for a package will force the app to assume it's * running on a display with 80% the vertical and horizontal resolution of the real display. */ @@ -110,6 +128,16 @@ public final class CompatModePackages { /** * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id + * CompatModePackages#DOWNSCALE_75 for a package will force the app to assume it's + * running on a display with 75% the vertical and horizontal resolution of the real display. + */ + @ChangeId + @Disabled + @Overridable + public static final long DOWNSCALE_75 = 189969779L; + + /** + * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id * CompatModePackages#DOWNSCALE_70 for a package will force the app to assume it's * running on a display with 70% the vertical and horizontal resolution of the real display. */ @@ -120,6 +148,16 @@ public final class CompatModePackages { /** * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id + * CompatModePackages#DOWNSCALE_65 for a package will force the app to assume it's + * running on a display with 65% the vertical and horizontal resolution of the real display. + */ + @ChangeId + @Disabled + @Overridable + public static final long DOWNSCALE_65 = 189969744L; + + /** + * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id * CompatModePackages#DOWNSCALE_60 for a package will force the app to assume it's * running on a display with 60% the vertical and horizontal resolution of the real display. */ @@ -130,6 +168,16 @@ public final class CompatModePackages { /** * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id + * CompatModePackages#DOWNSCALE_55 for a package will force the app to assume it's + * running on a display with 55% the vertical and horizontal resolution of the real display. + */ + @ChangeId + @Disabled + @Overridable + public static final long DOWNSCALE_55 = 189970036L; + + /** + * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id * CompatModePackages#DOWNSCALE_50 for a package will force the app to assume it's * running on a display with 50% vertical and horizontal resolution of the real display. */ @@ -139,6 +187,46 @@ public final class CompatModePackages { public static final long DOWNSCALE_50 = 176926741L; /** + * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id + * CompatModePackages#DOWNSCALE_45 for a package will force the app to assume it's + * running on a display with 45% the vertical and horizontal resolution of the real display. + */ + @ChangeId + @Disabled + @Overridable + public static final long DOWNSCALE_45 = 189969782L; + + /** + * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id + * CompatModePackages#DOWNSCALE_40 for a package will force the app to assume it's + * running on a display with 40% the vertical and horizontal resolution of the real display. + */ + @ChangeId + @Disabled + @Overridable + public static final long DOWNSCALE_40 = 189970038L; + + /** + * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id + * CompatModePackages#DOWNSCALE_35 for a package will force the app to assume it's + * running on a display with 35% the vertical and horizontal resolution of the real display. + */ + @ChangeId + @Disabled + @Overridable + public static final long DOWNSCALE_35 = 189969749L; + + /** + * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id + * CompatModePackages#DOWNSCALE_30 for a package will force the app to assume it's + * running on a display with 30% the vertical and horizontal resolution of the real display. + */ + @ChangeId + @Disabled + @Overridable + public static final long DOWNSCALE_30 = 189970040L; + + /** * On Android TV applications that target pre-S are not expecting to receive a Window larger * than 1080p, so if needed we are downscaling their Windows to 1080p. * However, applications that target S and greater release version are expected to be able to @@ -291,18 +379,42 @@ public final class CompatModePackages { if (CompatChanges.isChangeEnabled(DOWNSCALE_90, packageName, userHandle)) { return 1f / 0.9f; } + if (CompatChanges.isChangeEnabled(DOWNSCALE_85, packageName, userHandle)) { + return 1f / 0.85f; + } if (CompatChanges.isChangeEnabled(DOWNSCALE_80, packageName, userHandle)) { return 1f / 0.8f; } + if (CompatChanges.isChangeEnabled(DOWNSCALE_75, packageName, userHandle)) { + return 1f / 0.75f; + } if (CompatChanges.isChangeEnabled(DOWNSCALE_70, packageName, userHandle)) { return 1f / 0.7f; } + if (CompatChanges.isChangeEnabled(DOWNSCALE_65, packageName, userHandle)) { + return 1f / 0.65f; + } if (CompatChanges.isChangeEnabled(DOWNSCALE_60, packageName, userHandle)) { return 1f / 0.6f; } + if (CompatChanges.isChangeEnabled(DOWNSCALE_55, packageName, userHandle)) { + return 1f / 0.55f; + } if (CompatChanges.isChangeEnabled(DOWNSCALE_50, packageName, userHandle)) { return 1f / 0.5f; } + if (CompatChanges.isChangeEnabled(DOWNSCALE_45, packageName, userHandle)) { + return 1f / 0.45f; + } + if (CompatChanges.isChangeEnabled(DOWNSCALE_40, packageName, userHandle)) { + return 1f / 0.4f; + } + if (CompatChanges.isChangeEnabled(DOWNSCALE_35, packageName, userHandle)) { + return 1f / 0.35f; + } + if (CompatChanges.isChangeEnabled(DOWNSCALE_30, packageName, userHandle)) { + return 1f / 0.3f; + } } if (mService.mHasLeanbackFeature) { diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index c7cf4b05564f..3dbc517af45c 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5492,6 +5492,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } boolean updateDisplayOverrideConfigurationLocked() { + // Preemptively cancel the running recents animation -- SysUI can't currently handle this + // case properly since the signals it receives all happen post-change + final RecentsAnimationController recentsAnimationController = + mWmService.getRecentsAnimationController(); + if (recentsAnimationController != null) { + recentsAnimationController.cancelAnimationForDisplayChange(); + } + Configuration values = new Configuration(); computeScreenConfiguration(values); diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index c8f2777cc172..73d6cecd9155 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -480,6 +480,16 @@ public class DisplayRotation { return false; } + // Preemptively cancel the running recents animation -- SysUI can't currently handle this + // case properly since the signals it receives all happen post-change. We do this earlier + // in the rotation flow, since DisplayContent.updateDisplayOverrideConfigurationLocked seems + // to happen too late. + final RecentsAnimationController recentsAnimationController = + mService.getRecentsAnimationController(); + if (recentsAnimationController != null) { + recentsAnimationController.cancelAnimationForDisplayChange(); + } + final Transition t = (useShellTransitions && !mService.mAtmService.getTransitionController().isCollecting()) ? mService.mAtmService.getTransitionController().createTransition(TRANSIT_CHANGE) diff --git a/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java b/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java index b1e12b685fb4..d230936b5d51 100644 --- a/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java +++ b/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java @@ -99,8 +99,10 @@ class NonAppWindowAnimationAdapter implements AnimationAdapter { final WindowManagerPolicy policy = service.mPolicy; service.mRoot.forAllWindows(nonAppWindow -> { + // Animation on the IME window is controlled via Insets. if (nonAppWindow.mActivityRecord == null && policy.canBeHiddenByKeyguardLw(nonAppWindow) - && nonAppWindow.wouldBeVisibleIfPolicyIgnored() && !nonAppWindow.isVisible()) { + && nonAppWindow.wouldBeVisibleIfPolicyIgnored() && !nonAppWindow.isVisible() + && nonAppWindow != service.mRoot.getCurrentInputMethodWindow()) { final NonAppWindowAnimationAdapter nonAppAdapter = new NonAppWindowAnimationAdapter( nonAppWindow, durationHint, statusBarTransitionDelay); adaptersOut.add(nonAppAdapter); diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 5362771ed286..710dd552f72d 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -36,8 +36,10 @@ import static com.android.server.wm.WindowManagerInternal.AppTransitionListener; import android.annotation.IntDef; import android.annotation.NonNull; import android.app.WindowConfiguration; +import android.graphics.GraphicBuffer; import android.graphics.Point; import android.graphics.Rect; +import android.hardware.HardwareBuffer; import android.os.Binder; import android.os.IBinder.DeathRecipient; import android.os.RemoteException; @@ -54,6 +56,7 @@ import android.view.InputWindowHandle; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; +import android.view.SurfaceSession; import android.view.WindowInsets.Type; import android.window.PictureInPictureSurfaceTransaction; import android.window.TaskSnapshot; @@ -150,6 +153,8 @@ public class RecentsAnimationController implements DeathRecipient { private boolean mCancelOnNextTransitionStart; // Whether to take a screenshot when handling a deferred cancel private boolean mCancelDeferredWithScreenshot; + // The reorder mode to apply after the cleanupScreenshot() callback + private int mPendingCancelWithScreenshotReorderMode = REORDER_MOVE_TO_ORIGINAL_POSITION; @VisibleForTesting boolean mIsAddingTaskToTargets; @@ -159,12 +164,6 @@ public class RecentsAnimationController implements DeathRecipient { private ActivityRecord mNavBarAttachedApp; /** - * Animates the screenshot of task that used to be controlled by RecentsAnimation. - * @see {@link #setCancelOnNextTransitionStart} - */ - SurfaceAnimator mRecentScreenshotAnimator; - - /** * An app transition listener to cancel the recents animation only after the app transition * starts or is canceled. */ @@ -221,7 +220,7 @@ public class RecentsAnimationController implements DeathRecipient { final ArraySet<Task> tasks = Sets.newArraySet(task); snapshotController.snapshotTasks(tasks); snapshotController.addSkipClosingAppSnapshotTasks(tasks); - return snapshotController.getSnapshot(taskId, 0 /* userId */, + return snapshotController.getSnapshot(taskId, task.mUserId, false /* restoreFromDisk */, false /* isLowResolution */); } } @@ -353,18 +352,20 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void cleanupScreenshot() { - synchronized (mService.mGlobalLock) { - if (mRecentScreenshotAnimator != null) { - mRecentScreenshotAnimator.cancelAnimation(); - mRecentScreenshotAnimator = null; - } + final long token = Binder.clearCallingIdentity(); + try { + // Note, the callback will handle its own synchronization, do not lock on WM lock + // prior to calling the callback + continueDeferredCancelAnimation(); + } finally { + Binder.restoreCallingIdentity(token); } } @Override public void setWillFinishToHome(boolean willFinishToHome) { synchronized (mService.getWindowManagerLock()) { - mWillFinishToHome = willFinishToHome; + RecentsAnimationController.this.setWillFinishToHome(willFinishToHome); } } @@ -513,15 +514,14 @@ public class RecentsAnimationController implements DeathRecipient { || config.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; } - @VisibleForTesting - AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) { + TaskAnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) { return addAnimation(task, isRecentTaskInvisible, false /* hidden */, null /* finishedCallback */); } @VisibleForTesting - AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible, boolean hidden, + TaskAnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible, boolean hidden, OnAnimationFinishedCallback finishedCallback) { ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "addAnimation(%s)", task.getName()); final TaskAnimationAdapter taskAdapter = new TaskAnimationAdapter(task, @@ -537,9 +537,7 @@ public class RecentsAnimationController implements DeathRecipient { void removeAnimation(TaskAnimationAdapter taskAdapter) { ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "removeAnimation(%d)", taskAdapter.mTask.mTaskId); - taskAdapter.mTask.setCanAffectSystemUiFlags(true); - taskAdapter.mCapturedFinishCallback.onAnimationFinished(taskAdapter.mLastAnimationType, - taskAdapter); + taskAdapter.onRemove(); mPendingAnimations.remove(taskAdapter); } @@ -816,6 +814,32 @@ public class RecentsAnimationController implements DeathRecipient { cancelAnimation(REORDER_KEEP_IN_PLACE, screenshot, "rootTaskOrderChanged"); } + /** + * Cancels the running animation when starting home, providing a snapshot for the runner to + * properly handle the cancellation. This call uses the provided hint to determine how to + * finish the animation. + */ + public void cancelAnimationForHomeStart() { + if (mCanceled) { + return; + } + cancelAnimation(mWillFinishToHome ? REORDER_MOVE_TO_TOP : REORDER_KEEP_IN_PLACE, + true /* screenshot */, "cancelAnimationForHomeStart"); + } + + /** + * Cancels the running animation when there is a display change, providing a snapshot for the + * runner to properly handle the cancellation. This call uses the provided hint to determine + * how to finish the animation. + */ + public void cancelAnimationForDisplayChange() { + if (mCanceled) { + return; + } + cancelAnimation(mWillFinishToHome ? REORDER_MOVE_TO_TOP : REORDER_MOVE_TO_ORIGINAL_POSITION, + true /* screenshot */, "cancelAnimationForDisplayChange"); + } + private void cancelAnimation(@ReorderMode int reorderMode, boolean screenshot, String reason) { ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "cancelAnimation(): reason=%s", reason); synchronized (mService.getWindowManagerLock()) { @@ -826,17 +850,23 @@ public class RecentsAnimationController implements DeathRecipient { mService.mH.removeCallbacks(mFailsafeRunnable); mCanceled = true; - if (screenshot) { + if (screenshot && !mPendingAnimations.isEmpty()) { + final TaskAnimationAdapter adapter = mPendingAnimations.get(0); + final Task task = adapter.mTask; // Screen shot previous task when next task starts transition and notify the runner. // We will actually finish the animation once the runner calls cleanUpScreenshot(). - final Task task = mPendingAnimations.get(0).mTask; - final TaskSnapshot taskSnapshot = screenshotRecentTask(task, reorderMode); + final TaskSnapshot taskSnapshot = screenshotRecentTask(task); + mPendingCancelWithScreenshotReorderMode = reorderMode; try { mRunner.onAnimationCanceled(taskSnapshot); } catch (RemoteException e) { Slog.e(TAG, "Failed to cancel recents animation", e); } - if (taskSnapshot == null) { + if (taskSnapshot != null) { + // Defer until the runner calls back to cleanupScreenshot() + adapter.setSnapshotOverlay(taskSnapshot); + } else { + // Do a normal cancel since we couldn't screenshot mCallbacks.onAnimationFinished(reorderMode, false /* sendUserLeaveHint */); } } else { @@ -853,6 +883,17 @@ public class RecentsAnimationController implements DeathRecipient { } } + @VisibleForTesting + void continueDeferredCancelAnimation() { + mCallbacks.onAnimationFinished(mPendingCancelWithScreenshotReorderMode, + false /* sendUserLeaveHint */); + } + + @VisibleForTesting + void setWillFinishToHome(boolean willFinishToHome) { + mWillFinishToHome = willFinishToHome; + } + /** * Cancel recents animation when the next app transition starts. * <p> @@ -894,28 +935,13 @@ public class RecentsAnimationController implements DeathRecipient { return mRequestDeferCancelUntilNextTransition && mCancelDeferredWithScreenshot; } - TaskSnapshot screenshotRecentTask(Task task, @ReorderMode int reorderMode) { + TaskSnapshot screenshotRecentTask(Task task) { final TaskSnapshotController snapshotController = mService.mTaskSnapshotController; final ArraySet<Task> tasks = Sets.newArraySet(task); snapshotController.snapshotTasks(tasks); snapshotController.addSkipClosingAppSnapshotTasks(tasks); - final TaskSnapshot taskSnapshot = snapshotController.getSnapshot(task.mTaskId, - task.mUserId, false /* restoreFromDisk */, false /* isLowResolution */); - if (taskSnapshot == null) { - return null; - } - - final TaskScreenshotAnimatable animatable = new TaskScreenshotAnimatable(mService.mSurfaceControlFactory, task, - new SurfaceControl.ScreenshotHardwareBuffer(taskSnapshot.getHardwareBuffer(), - taskSnapshot.getColorSpace(), false /* containsSecureLayers */)); - mRecentScreenshotAnimator = new SurfaceAnimator( - animatable, - (type, anim) -> { - ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "mRecentScreenshotAnimator finish"); - mCallbacks.onAnimationFinished(reorderMode, false /* sendUserLeaveHint */); - }, mService); - mRecentScreenshotAnimator.transferAnimation(task.mSurfaceAnimator); - return taskSnapshot; + return snapshotController.getSnapshot(task.mTaskId, task.mUserId, + false /* restoreFromDisk */, false /* isLowResolution */); } void cleanupAnimation(@ReorderMode int reorderMode) { @@ -954,12 +980,6 @@ public class RecentsAnimationController implements DeathRecipient { mRunner = null; mCanceled = true; - // Make sure previous animator has cleaned-up. - if (mRecentScreenshotAnimator != null) { - mRecentScreenshotAnimator.cancelAnimation(); - mRecentScreenshotAnimator = null; - } - // Restore IME icon only when moving the original app task to front from recents, in case // IME icon may missing if the moving task has already been the current focused task. if (reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION && !mIsAddingTaskToTargets) { @@ -1140,6 +1160,8 @@ public class RecentsAnimationController implements DeathRecipient { private PictureInPictureSurfaceTransaction mFinishTransaction; // An overlay used to mask the content as an app goes into PIP private SurfaceControl mFinishOverlay; + // An overlay used for canceling the animation with a screenshot + private SurfaceControl mSnapshotOverlay; TaskAnimationAdapter(Task task, boolean isRecentTaskInvisible) { mTask = task; @@ -1174,10 +1196,47 @@ public class RecentsAnimationController implements DeathRecipient { return mTarget; } + void setSnapshotOverlay(TaskSnapshot snapshot) { + // Create a surface control for the snapshot and reparent it to the leash + final HardwareBuffer buffer = snapshot.getHardwareBuffer(); + if (buffer == null) { + return; + } + + final SurfaceSession session = new SurfaceSession(); + mSnapshotOverlay = mService.mSurfaceControlFactory.apply(session) + .setName("RecentTaskScreenshotSurface") + .setCallsite("TaskAnimationAdapter.setSnapshotOverlay") + .setFormat(buffer.getFormat()) + .setParent(mCapturedLeash) + .setBLASTLayer() + .build(); + + final float scale = 1.0f * mTask.getBounds().width() / buffer.getWidth(); + mTask.getPendingTransaction() + .setBuffer(mSnapshotOverlay, GraphicBuffer.createFromHardwareBuffer(buffer)) + .setColorSpace(mSnapshotOverlay, snapshot.getColorSpace()) + .setLayer(mSnapshotOverlay, Integer.MAX_VALUE) + .setMatrix(mSnapshotOverlay, scale, 0, 0, scale) + .show(mSnapshotOverlay) + .apply(); + } + + void onRemove() { + if (mSnapshotOverlay != null) { + // Clean up the snapshot overlay if necessary + mTask.getPendingTransaction() + .remove(mSnapshotOverlay) + .apply(); + mSnapshotOverlay = null; + } + mTask.setCanAffectSystemUiFlags(true); + mCapturedFinishCallback.onAnimationFinished(mLastAnimationType, this); + } + void onCleanup() { + final Transaction pendingTransaction = mTask.getPendingTransaction(); if (mFinishTransaction != null) { - final Transaction pendingTransaction = mTask.getPendingTransaction(); - // Reparent the overlay if (mFinishOverlay != null) { pendingTransaction.reparent(mFinishOverlay, mTask.mSurfaceControl); @@ -1205,10 +1264,15 @@ public class RecentsAnimationController implements DeathRecipient { } else if (!mTask.isAttached()) { // Apply the task's pending transaction in case it is detached and its transaction // is not reachable. - mTask.getPendingTransaction().apply(); + pendingTransaction.apply(); } } + @VisibleForTesting + public SurfaceControl getSnapshotOverlay() { + return mSnapshotOverlay; + } + @Override public boolean getShowWallpaper() { return false; diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index c510603d1d7d..6242b9791464 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -221,6 +221,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // transaction from the global transaction. private final SurfaceControl.Transaction mDisplayTransaction; + // The tag for the token to put root tasks on the displays to sleep. + private static final String DISPLAY_OFF_SLEEP_TOKEN_TAG = "Display-off"; + /** The token acquirer to put root tasks on the displays to sleep */ final ActivityTaskManagerInternal.SleepTokenAcquirer mDisplayOffTokenAcquirer; @@ -450,7 +453,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> mService = service.mAtmService; mTaskSupervisor = mService.mTaskSupervisor; mTaskSupervisor.mRootWindowContainer = this; - mDisplayOffTokenAcquirer = mService.new SleepTokenAcquirerImpl("Display-off"); + mDisplayOffTokenAcquirer = mService.new SleepTokenAcquirerImpl(DISPLAY_OFF_SLEEP_TOKEN_TAG); } boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) { @@ -1526,7 +1529,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // Updates the extra information of the intent. if (fromHomeKey) { homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true); - mWindowManager.cancelRecentsAnimation(REORDER_KEEP_IN_PLACE, "startHomeActivity"); + if (mWindowManager.getRecentsAnimationController() != null) { + mWindowManager.getRecentsAnimationController().cancelAnimationForHomeStart(); + } } homeIntent.putExtra(WindowManagerPolicy.EXTRA_START_REASON, reason); @@ -2654,12 +2659,14 @@ class RootWindowContainer extends WindowContainer<DisplayContent> Slog.d(TAG, "Remove non-exist sleep token: " + token + " from " + Debug.getCallers(6)); } mSleepTokens.remove(token.mHashKey); - final DisplayContent display = getDisplayContent(token.mDisplayId); if (display != null) { display.mAllSleepTokens.remove(token); if (display.mAllSleepTokens.isEmpty()) { mService.updateSleepIfNeededLocked(); + if (token.mTag.equals(DISPLAY_OFF_SLEEP_TOKEN_TAG)) { + display.mSkipAppTransitionAnimation = true; + } } } } diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 90d40f3b13c2..d450dbffe4a1 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -31,6 +31,7 @@ import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; +import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES; @@ -44,6 +45,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.Nullable; import android.app.ActivityOptions; import android.app.WindowConfiguration; +import android.content.res.Configuration; import android.os.UserHandle; import android.util.IntArray; import android.util.Slog; @@ -1705,10 +1707,18 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { return true; } // Check if the request min width/height is supported in multi window. - final int maxSupportMinDimensions = (int) (mAtmService.mMinPercentageMultiWindowSupportWidth - * getConfiguration().smallestScreenWidthDp - * mDisplayContent.getDisplayMetrics().density); - return minWidth <= maxSupportMinDimensions && minHeight <= maxSupportMinDimensions; + final Configuration config = getConfiguration(); + final int orientation = config.orientation; + if (orientation == ORIENTATION_LANDSCAPE) { + final int maxSupportMinWidth = (int) (mAtmService.mMinPercentageMultiWindowSupportWidth + * config.screenWidthDp * mDisplayContent.getDisplayMetrics().density); + return minWidth <= maxSupportMinWidth; + } else { + final int maxSupportMinHeight = + (int) (mAtmService.mMinPercentageMultiWindowSupportHeight + * config.screenHeightDp * mDisplayContent.getDisplayMetrics().density); + return minHeight <= maxSupportMinHeight; + } } /** diff --git a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java deleted file mode 100644 index 7e992ac263bc..000000000000 --- a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.server.wm; - -import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS; - -import android.graphics.GraphicBuffer; -import android.hardware.HardwareBuffer; -import android.view.SurfaceControl; -import android.view.SurfaceSession; - -import com.android.internal.protolog.common.ProtoLog; - -import java.util.function.Function; - -/** - * Class used by {@link RecentsAnimationController} to create a surface control with taking - * screenshot of task when canceling recents animation. - * - * @see {@link RecentsAnimationController#setCancelOnNextTransitionStart} - */ -class TaskScreenshotAnimatable implements SurfaceAnimator.Animatable { - private static final String TAG = "TaskScreenshotAnim"; - private Task mTask; - private SurfaceControl mSurfaceControl; - private int mWidth; - private int mHeight; - - TaskScreenshotAnimatable(Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory, - Task task, SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer) { - HardwareBuffer buffer = screenshotBuffer == null - ? null : screenshotBuffer.getHardwareBuffer(); - mTask = task; - mWidth = (buffer != null) ? buffer.getWidth() : 1; - mHeight = (buffer != null) ? buffer.getHeight() : 1; - ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, - "Creating TaskScreenshotAnimatable: task: %s width: %d height: %d", - task, mWidth, mHeight); - mSurfaceControl = surfaceControlFactory.apply(new SurfaceSession()) - .setName("RecentTaskScreenshotSurface") - .setBLASTLayer() - .setCallsite("TaskScreenshotAnimatable") - .build(); - if (buffer != null) { - GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer(buffer); - getPendingTransaction().setBuffer(mSurfaceControl, graphicBuffer); - getPendingTransaction().setColorSpace(mSurfaceControl, - screenshotBuffer.getColorSpace()); - final float scale = 1.0f * mTask.getBounds().width() / mWidth; - getPendingTransaction().setMatrix(mSurfaceControl, scale, 0, 0, scale); - } - getPendingTransaction().show(mSurfaceControl); - } - - @Override - public SurfaceControl.Transaction getPendingTransaction() { - return mTask.getPendingTransaction(); - } - - @Override - public void commitPendingTransaction() { - mTask.commitPendingTransaction(); - } - - @Override - public void onAnimationLeashCreated(SurfaceControl.Transaction t, SurfaceControl leash) { - t.setLayer(leash, 1); - } - - @Override - public void onAnimationLeashLost(SurfaceControl.Transaction t) { - if (mSurfaceControl != null) { - t.remove(mSurfaceControl); - mSurfaceControl = null; - } - } - - @Override - public SurfaceControl.Builder makeAnimationLeash() { - return mTask.makeAnimationLeash(); - } - - @Override - public SurfaceControl getAnimationLeashParent() { - return mTask.getAnimationLeashParent(); - } - - @Override - public SurfaceControl getSurfaceControl() { - return mSurfaceControl; - } - - @Override - public SurfaceControl getParentSurfaceControl() { - return mTask.mSurfaceControl; - } - - @Override - public int getSurfaceWidth() { - return mWidth; - } - - @Override - public int getSurfaceHeight() { - return mHeight; - } -} diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 2c8fcebdd50f..147260b9e912 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -34,6 +34,7 @@ import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEME import static android.content.pm.PackageManager.FEATURE_PC; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS; +import static android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE; import static android.os.Process.SYSTEM_UID; import static android.os.Process.myPid; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; @@ -2545,12 +2546,13 @@ public class WindowManagerService extends IWindowManager.Stub // We will leave the critical section before returning the leash to the client, // so we need to copy the leash to prevent others release the one that we are // about to return. - // TODO: We will have an extra copy if the client is not local. - // For now, we rely on GC to release it. - // Maybe we can modify InsetsSourceControl.writeToParcel so it can release - // the extra leash as soon as possible. - outControls[i] = controls[i] != null - ? new InsetsSourceControl(controls[i]) : null; + if (controls[i] != null) { + // This source control is an extra copy if the client is not local. By setting + // PARCELABLE_WRITE_RETURN_VALUE, the leash will be released at the end of + // SurfaceControl.writeToParcel. + outControls[i] = new InsetsSourceControl(controls[i]); + outControls[i].setParcelableFlags(PARCELABLE_WRITE_RETURN_VALUE); + } } } } diff --git a/services/core/java/com/android/server/wm/WindowOrientationListener.java b/services/core/java/com/android/server/wm/WindowOrientationListener.java index 6a4767a21dc9..0ded8fb313cd 100644 --- a/services/core/java/com/android/server/wm/WindowOrientationListener.java +++ b/services/core/java/com/android/server/wm/WindowOrientationListener.java @@ -68,7 +68,7 @@ public abstract class WindowOrientationListener { private static final String KEY_ROTATION_MEMORIZATION_TIMEOUT = "rotation_memorization_timeout_millis"; private static final long DEFAULT_ROTATION_RESOLVER_TIMEOUT_MILLIS = 700L; - private static final long DEFAULT_ROTATION_MEMORIZATION_TIMEOUT_MILLIS = 300_000L; // 5 minutes + private static final long DEFAULT_ROTATION_MEMORIZATION_TIMEOUT_MILLIS = 10_000L; // 10 seconds private Handler mHandler; private SensorManager mSensorManager; diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index bba50a75a3b9..c3fc99554bcc 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -5477,8 +5477,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP getPendingTransaction().setMatrix(getSurfaceControl(), newHScale, 0, 0, newVScale); mLastGlobalScale = mGlobalScale; - mLastHScale = mHScale; - mLastVScale = mVScale; + mLastHScale = newHScale; + mLastVScale = newVScale; } } diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 9a6e4448966d..80941961cc5a 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -16,12 +16,6 @@ package com.android.server.wm; -import static android.graphics.Matrix.MSCALE_X; -import static android.graphics.Matrix.MSCALE_Y; -import static android.graphics.Matrix.MSKEW_X; -import static android.graphics.Matrix.MSKEW_Y; -import static android.graphics.Matrix.MTRANS_X; -import static android.graphics.Matrix.MTRANS_Y; import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; @@ -54,14 +48,12 @@ import static com.android.server.wm.WindowStateAnimatorProto.SURFACE; import static com.android.server.wm.WindowStateAnimatorProto.SYSTEM_DECOR_RECT; import android.content.Context; -import android.graphics.Matrix; import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.Debug; import android.os.Trace; import android.util.Slog; import android.util.proto.ProtoOutputStream; -import android.view.DisplayInfo; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; import android.view.WindowManager; @@ -260,7 +252,10 @@ class WindowStateAnimator { } if (postDrawTransaction != null) { - if (mLastHidden) { + // If there is no surface, the last draw was for the previous surface. We don't want to + // wait until the new surface is shown and instead just apply the transaction right + // away. + if (mLastHidden && mDrawState != NO_SURFACE) { mPostDrawTransaction.merge(postDrawTransaction); layoutNeeded = true; } else { @@ -683,8 +678,9 @@ class WindowStateAnimator { } // We don't apply animation for application main window here since this window type - // should be controlled by AppWindowToken in general. - if (mAttrType != TYPE_BASE_APPLICATION) { + // should be controlled by ActivityRecord in general. Wallpaper is also excluded because + // WallpaperController should handle it. + if (mAttrType != TYPE_BASE_APPLICATION && !mIsWallpaper) { applyAnimationLocked(transit, true); } @@ -829,6 +825,10 @@ class WindowStateAnimator { } void destroySurface(SurfaceControl.Transaction t) { + // Since the SurfaceControl is getting torn down, it's safe to just clean up any + // pending transactions that were in mPostDrawTransaction, as well. + t.merge(mPostDrawTransaction); + try { if (mSurfaceController != null) { mSurfaceController.destroy(t); diff --git a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp index f439777e0c7a..7513512406e8 100644 --- a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp +++ b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp @@ -133,8 +133,12 @@ static bool sendRequest(int fd, RequestType requestType, FileIdx fileIdx = -1, static int waitForDataOrSignal(int fd, int event_fd) { struct pollfd pfds[2] = {{fd, POLLIN, 0}, {event_fd, POLLIN, 0}}; - // Wait indefinitely until either data is ready or stop signal is received + // Wait until either data is ready or stop signal is received int res = poll(pfds, 2, PollTimeoutMs); + if (res == -1 && errno == EINTR) { + // Treat it the same as timeout and allow the caller to retry. + return 0; + } if (res <= 0) { return res; } diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp index 757c9dec06ed..0e96567dbfad 100644 --- a/services/incremental/IncrementalService.cpp +++ b/services/incremental/IncrementalService.cpp @@ -91,7 +91,7 @@ struct Constants { static constexpr auto readLogsMaxInterval = 2h; // How long should we wait till dataLoader reports destroyed. - static constexpr auto destroyTimeout = 60s; + static constexpr auto destroyTimeout = 10s; static constexpr auto anyStatus = INT_MIN; }; diff --git a/services/net/Android.bp b/services/net/Android.bp index dd864aed4e8e..a822257e1a74 100644 --- a/services/net/Android.bp +++ b/services/net/Android.bp @@ -51,7 +51,6 @@ java_library { // All the classes in netd_aidl_interface must be jarjar so they do not conflict with the // classes generated by netd_aidl_interfaces-platform-java above. "netd_aidl_interface-V3-java", - "netlink-client", "networkstack-client", "modules-utils-build_system", ], diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java index 9706d7f5f78d..e3e2708eb788 100644 --- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java +++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java @@ -37,6 +37,7 @@ import android.os.UserManager; import android.provider.DeviceConfig; import android.util.Log; +import com.android.internal.R; import com.android.server.IoThread; import com.android.server.LocalServices; import com.android.server.SystemService; @@ -302,8 +303,15 @@ public final class ProfcollectForwardingService extends SystemService { return; } + if (!getUploaderEnabledConfig(getContext())) { + return; + } + new Thread(() -> { try { + Context context = getContext(); + final String uploaderPkg = getUploaderPackageName(context); + final String uploaderAction = getUploaderActionName(context); String reportUuid = mIProfcollect.report(); final int profileId = getBBProfileId(); @@ -317,13 +325,12 @@ public final class ProfcollectForwardingService extends SystemService { } Intent uploadIntent = - new Intent("com.google.android.apps.betterbug.intent.action.UPLOAD_PROFILE") - .setPackage("com.google.android.apps.internal.betterbug") + new Intent(uploaderAction) + .setPackage(uploaderPkg) .putExtra("EXTRA_DESTINATION", "PROFCOLLECT") .putExtra("EXTRA_PACKAGE_NAME", getContext().getPackageName()) .putExtra("EXTRA_PROFILE_PATH", reportPath) .addFlags(Intent.FLAG_RECEIVER_FOREGROUND); - Context context = getContext(); List<ResolveInfo> receivers = context.getPackageManager().queryBroadcastReceivers(uploadIntent, 0); @@ -356,4 +363,19 @@ public final class ProfcollectForwardingService extends SystemService { } return UserHandle.USER_SYSTEM; } + + private boolean getUploaderEnabledConfig(Context context) { + return context.getResources().getBoolean( + R.bool.config_profcollectReportUploaderEnabled); + } + + private String getUploaderPackageName(Context context) { + return context.getResources().getString( + R.string.config_defaultProfcollectReportUploaderApp); + } + + private String getUploaderActionName(Context context) { + return context.getResources().getString( + R.string.config_defaultProfcollectReportUploaderAction); + } } diff --git a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SystemStubMultiUserDisableUninstallTest.kt b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SystemStubMultiUserDisableUninstallTest.kt index 46120af06550..45e0d09a1753 100644 --- a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SystemStubMultiUserDisableUninstallTest.kt +++ b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SystemStubMultiUserDisableUninstallTest.kt @@ -281,7 +281,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { assertState( primaryInstalled = false, primaryEnabled = true, secondaryInstalled = true, secondaryEnabled = true, - codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) + codePaths = listOf(CodePath.SAME, CodePath.SYSTEM) ) uninstall(User.SECONDARY) @@ -289,7 +289,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { assertState( primaryInstalled = false, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, - codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) + codePaths = listOf(CodePath.SAME, CodePath.SYSTEM) ) installExisting(User.PRIMARY) @@ -311,20 +311,20 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { @Test fun uninstallSecondaryFirstByUserAndInstallExistingSecondaryFirst() { - uninstall(User.PRIMARY) + uninstall(User.SECONDARY) assertState( - primaryInstalled = false, primaryEnabled = true, - secondaryInstalled = true, secondaryEnabled = true, - codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) + primaryInstalled = true, primaryEnabled = true, + secondaryInstalled = false, secondaryEnabled = true, + codePaths = listOf(CodePath.SAME, CodePath.SYSTEM) ) - uninstall(User.SECONDARY) + uninstall(User.PRIMARY) assertState( primaryInstalled = false, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, - codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) + codePaths = listOf(CodePath.SAME, CodePath.SYSTEM) ) installExisting(User.SECONDARY) @@ -348,15 +348,14 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { fun uninstallUpdatesAndEnablePrimaryFirst() { device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") - // Uninstall-system-updates always disables system user 0 - // TODO: Is this intentional? There is no user argument for this command. assertState( - primaryInstalled = true, primaryEnabled = false, + primaryInstalled = true, primaryEnabled = true, secondaryInstalled = true, secondaryEnabled = true, // If any user is enabled when uninstalling updates, /data is re-uncompressed codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) ) + toggleEnabled(false, User.PRIMARY) toggleEnabled(true, User.PRIMARY) assertState( @@ -379,14 +378,15 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { fun uninstallUpdatesAndEnableSecondaryFirst() { device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") - // Uninstall-system-updates always disables system user 0 assertState( - primaryInstalled = true, primaryEnabled = false, + primaryInstalled = true, primaryEnabled = true, secondaryInstalled = true, secondaryEnabled = true, // If any user is enabled when uninstalling updates, /data is re-uncompressed codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) ) + toggleEnabled(false, User.PRIMARY) + toggleEnabled(true, User.SECONDARY) assertState( @@ -417,6 +417,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { codePaths = listOf(CodePath.SYSTEM) ) + toggleEnabled(false, User.PRIMARY) toggleEnabled(true, User.PRIMARY) assertState( @@ -447,6 +448,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { codePaths = listOf(CodePath.SYSTEM) ) + toggleEnabled(false, User.PRIMARY) toggleEnabled(true, User.SECONDARY) assertState( @@ -471,13 +473,13 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") - // Uninstall-system-updates always disables system user 0 assertState( - primaryInstalled = false, primaryEnabled = false, + primaryInstalled = false, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, codePaths = listOf(CodePath.SYSTEM) ) + toggleEnabled(false, User.PRIMARY) toggleEnabled(true, User.PRIMARY) assertState( @@ -502,9 +504,8 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { device.executeShellCommand("pm uninstall-system-updates $TEST_PKG_NAME") - // Uninstall-system-updates always disables system user 0 assertState( - primaryInstalled = false, primaryEnabled = false, + primaryInstalled = false, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, codePaths = listOf(CodePath.SYSTEM) ) @@ -512,7 +513,7 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { toggleEnabled(true, User.SECONDARY) assertState( - primaryInstalled = false, primaryEnabled = false, + primaryInstalled = false, primaryEnabled = true, secondaryInstalled = false, secondaryEnabled = true, codePaths = listOf(CodePath.DIFFERENT, CodePath.SYSTEM) ) @@ -582,22 +583,24 @@ class SystemStubMultiUserDisableUninstallTest : BaseHostJUnit4Test() { codePaths: List<CodePath> ) { HostUtils.getUserIdToPkgInstalledState(device, TEST_PKG_NAME) - .forEach { (userId, installed) -> - if (userId == 0) { - assertThat(installed).isEqualTo(primaryInstalled) - } else { - assertThat(installed).isEqualTo(secondaryInstalled) - } + .also { assertThat(it.size).isAtLeast(USER_COUNT) } + .forEach { (userId, installed) -> + if (userId == 0) { + assertThat(installed).isEqualTo(primaryInstalled) + } else { + assertThat(installed).isEqualTo(secondaryInstalled) } + } HostUtils.getUserIdToPkgEnabledState(device, TEST_PKG_NAME) - .forEach { (userId, enabled) -> - if (userId == 0) { - assertThat(enabled).isEqualTo(primaryEnabled) - } else { - assertThat(enabled).isEqualTo(secondaryEnabled) - } + .also { assertThat(it.size).isAtLeast(USER_COUNT) } + .forEach { (userId, enabled) -> + if (userId == 0) { + assertThat(enabled).isEqualTo(primaryEnabled) + } else { + assertThat(enabled).isEqualTo(secondaryEnabled) } + } assertCodePaths(codePaths.first(), codePaths.getOrNull(1)) } diff --git a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java index 624e7dd3be4f..607fb4760236 100644 --- a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java @@ -1003,8 +1003,6 @@ public class AppStateTrackerTest { verify(l, times(0)).updateAllJobs(); verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean()); - verify(l, times(1)).updateForceAppStandbyForUidPackage(eq(UID_10_2), eq(PACKAGE_2), - eq(true)); verify(l, times(0)).updateAllAlarms(); verify(l, times(0)).updateAlarmsForUid(anyInt()); @@ -1019,8 +1017,6 @@ public class AppStateTrackerTest { verify(l, times(0)).updateAllJobs(); verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean()); - verify(l, times(1)).updateForceAppStandbyForUidPackage(eq(UID_10_2), eq(PACKAGE_2), - eq(false)); verify(l, times(0)).updateAllAlarms(); verify(l, times(0)).updateAlarmsForUid(anyInt()); @@ -1034,7 +1030,6 @@ public class AppStateTrackerTest { verify(l, times(0)).updateAllJobs(); verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(0)).updateAllAlarms(); verify(l, times(0)).updateAlarmsForUid(anyInt()); @@ -1052,8 +1047,6 @@ public class AppStateTrackerTest { verify(l, times(1)).updateAllJobs(); verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean()); - verify(l, times(1)).updateForceAppStandbyForUidPackage(eq(UID_10_2), eq(PACKAGE_2), - eq(true)); verify(l, times(1)).updateAllAlarms(); verify(l, times(0)).updateAlarmsForUid(anyInt()); @@ -1070,7 +1063,6 @@ public class AppStateTrackerTest { verify(l, times(1)).updateAllJobs(); verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(1)).updateAllAlarms(); verify(l, times(0)).updateAlarmsForUid(anyInt()); @@ -1089,7 +1081,6 @@ public class AppStateTrackerTest { verify(l, times(1)).updateAllJobs(); verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(1)).updateAllAlarms(); verify(l, times(0)).updateAlarmsForUid(anyInt()); @@ -1104,7 +1095,6 @@ public class AppStateTrackerTest { verify(l, times(1)).updateAllJobs(); verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(1)).updateAllAlarms(); verify(l, times(0)).updateAlarmsForUid(anyInt()); @@ -1121,7 +1111,6 @@ public class AppStateTrackerTest { verify(l, times(1)).updateAllJobs(); verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(0)).updateAllAlarms(); verify(l, times(0)).updateAlarmsForUid(anyInt()); @@ -1137,7 +1126,6 @@ public class AppStateTrackerTest { verify(l, times(1)).updateAllJobs(); verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(0)).updateAllAlarms(); verify(l, times(0)).updateAlarmsForUid(anyInt()); @@ -1154,7 +1142,6 @@ public class AppStateTrackerTest { verify(l, times(1)).updateAllJobs(); verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(1)).updateAllAlarms(); verify(l, times(0)).updateAlarmsForUid(anyInt()); @@ -1171,7 +1158,6 @@ public class AppStateTrackerTest { verify(l, times(2)).updateAllJobs(); verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(1)).updateAllAlarms(); verify(l, times(0)).updateAlarmsForUid(anyInt()); @@ -1186,7 +1172,6 @@ public class AppStateTrackerTest { verify(l, times(1)).updateAllJobs(); verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(1)).updateAllAlarms(); verify(l, times(0)).updateAlarmsForUid(anyInt()); @@ -1203,7 +1188,6 @@ public class AppStateTrackerTest { verify(l, times(1)).updateAllJobs(); verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(0)).updateAllAlarms(); verify(l, times(0)).updateAlarmsForUid(anyInt()); @@ -1219,7 +1203,6 @@ public class AppStateTrackerTest { verify(l, times(1)).updateAllJobs(); verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(0)).updateAllAlarms(); verify(l, times(0)).updateAlarmsForUid(anyInt()); @@ -1242,7 +1225,6 @@ public class AppStateTrackerTest { verify(l, times(0)).updateAllJobs(); verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(0)).updateAllAlarms(); verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1)); @@ -1258,7 +1240,6 @@ public class AppStateTrackerTest { verify(l, times(0)).updateAllJobs(); verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(0)).updateAllAlarms(); verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1)); @@ -1274,7 +1255,6 @@ public class AppStateTrackerTest { verify(l, times(0)).updateAllJobs(); verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(0)).updateAllAlarms(); verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1)); @@ -1290,7 +1270,6 @@ public class AppStateTrackerTest { verify(l, times(0)).updateAllJobs(); verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(0)).updateAllAlarms(); verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1)); @@ -1307,7 +1286,6 @@ public class AppStateTrackerTest { verify(l, times(1)).updateAllJobs(); verify(l, times(0)).updateJobsForUid(eq(UID_10_1), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(1)).updateAllAlarms(); verify(l, times(0)).updateAlarmsForUid(eq(UID_10_1)); @@ -1323,7 +1301,6 @@ public class AppStateTrackerTest { verify(l, times(0)).updateAllJobs(); verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(0)).updateAllAlarms(); verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1)); @@ -1339,7 +1316,6 @@ public class AppStateTrackerTest { verify(l, times(0)).updateAllJobs(); verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(0)).updateAllAlarms(); verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1)); @@ -1355,7 +1331,6 @@ public class AppStateTrackerTest { verify(l, times(0)).updateAllJobs(); verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(0)).updateAllAlarms(); verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1)); @@ -1371,7 +1346,6 @@ public class AppStateTrackerTest { verify(l, times(0)).updateAllJobs(); verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean()); verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean()); - verify(l, times(0)).updateForceAppStandbyForUidPackage(anyInt(), anyString(), anyBoolean()); verify(l, times(0)).updateAllAlarms(); verify(l, times(1)).updateAlarmsForUid(eq(UID_10_1)); diff --git a/services/tests/mockingservicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java b/services/tests/mockingservicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java index da0b83ec819c..28fcaee79572 100644 --- a/services/tests/mockingservicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java @@ -21,7 +21,6 @@ import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import static com.google.common.truth.Truth.assertThat; import android.os.SystemClock; -import android.os.UserHandle; import android.provider.DeviceConfig; import androidx.test.core.app.ApplicationProvider; @@ -63,7 +62,6 @@ public class PlatformLoggerTest { public void testCreateExtraStatsLocked_samplingIntervalNotSet_returnsDefault() { PlatformLogger logger = new PlatformLogger( ApplicationProvider.getApplicationContext(), - UserHandle.of(UserHandle.USER_NULL), mAppSearchConfig); DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH, @@ -96,8 +94,7 @@ public class PlatformLoggerTest { int putDocumentSamplingInterval = 1; int batchCallSamplingInterval = 2; PlatformLogger logger = new PlatformLogger( - ApplicationProvider.getApplicationContext(), - UserHandle.of(UserHandle.USER_NULL), mAppSearchConfig); + ApplicationProvider.getApplicationContext(), mAppSearchConfig); DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH, AppSearchConfig.KEY_MIN_TIME_INTERVAL_BETWEEN_SAMPLES_MILLIS, @@ -143,7 +140,6 @@ public class PlatformLoggerTest { final String testPackageName = "packageName"; PlatformLogger logger = new PlatformLogger( ApplicationProvider.getApplicationContext(), - UserHandle.of(UserHandle.USER_NULL), mAppSearchConfig); DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH, @@ -162,7 +158,6 @@ public class PlatformLoggerTest { final String testPackageName = "packageName"; PlatformLogger logger = new PlatformLogger( ApplicationProvider.getApplicationContext(), - UserHandle.of(UserHandle.USER_NULL), mAppSearchConfig); DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH, @@ -186,7 +181,6 @@ public class PlatformLoggerTest { final String testPackageName = "packageName"; PlatformLogger logger = new PlatformLogger( ApplicationProvider.getApplicationContext(), - UserHandle.of(UserHandle.USER_NULL), mAppSearchConfig); DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH, @@ -214,7 +208,6 @@ public class PlatformLoggerTest { final String testPackageName = "packageName"; PlatformLogger logger = new PlatformLogger( ApplicationProvider.getApplicationContext(), - UserHandle.of(UserHandle.USER_NULL), mAppSearchConfig); DeviceConfig.setProperty(DeviceConfig.NAMESPACE_APPSEARCH, diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java index f2bb47bfb8ad..b2471fac8b45 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java @@ -30,6 +30,7 @@ import static com.android.server.job.JobSchedulerService.RARE_INDEX; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -54,6 +55,9 @@ import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; +import android.util.Log; +import android.util.SparseBooleanArray; +import android.util.SparseLongArray; import com.android.server.AppStateTracker; import com.android.server.AppStateTrackerImpl; @@ -75,8 +79,11 @@ import org.mockito.quality.Strictness; import java.time.Clock; import java.time.Duration; import java.time.ZoneOffset; +import java.util.Random; public class JobSchedulerServiceTest { + private static final String TAG = JobSchedulerServiceTest.class.getSimpleName(); + private JobSchedulerService mService; private MockitoSession mMockingSession; @@ -178,12 +185,21 @@ public class JobSchedulerServiceTest { } private static JobInfo.Builder createJobInfo() { - return new JobInfo.Builder(351, new ComponentName("foo", "bar")); + return createJobInfo(351); + } + + private static JobInfo.Builder createJobInfo(int jobId) { + return new JobInfo.Builder(jobId, new ComponentName("foo", "bar")); } private JobStatus createJobStatus(String testTag, JobInfo.Builder jobInfoBuilder) { + return createJobStatus(testTag, jobInfoBuilder, 1234); + } + + private JobStatus createJobStatus(String testTag, JobInfo.Builder jobInfoBuilder, + int callingUid) { return JobStatus.createFromJobInfo( - jobInfoBuilder.build(), 1234, "com.android.test", 0, testTag); + jobInfoBuilder.build(), callingUid, "com.android.test", 0, testTag); } /** @@ -716,7 +732,7 @@ public class JobSchedulerServiceTest { assertEquals(i + 1, maybeQueueFunctor.runnableJobs.size()); assertEquals(sElapsedRealtimeClock.millis(), job.getFirstForceBatchedTimeElapsed()); } - maybeQueueFunctor.postProcess(); + maybeQueueFunctor.postProcessLocked(); assertEquals(0, mService.mPendingJobs.size()); // Enough RARE jobs to run. @@ -728,7 +744,7 @@ public class JobSchedulerServiceTest { assertEquals(i + 1, maybeQueueFunctor.runnableJobs.size()); assertEquals(sElapsedRealtimeClock.millis(), job.getFirstForceBatchedTimeElapsed()); } - maybeQueueFunctor.postProcess(); + maybeQueueFunctor.postProcessLocked(); assertEquals(5, mService.mPendingJobs.size()); // Not enough RARE jobs to run, but a non-batched job saves the day. @@ -745,7 +761,7 @@ public class JobSchedulerServiceTest { assertEquals(sElapsedRealtimeClock.millis(), job.getFirstForceBatchedTimeElapsed()); } maybeQueueFunctor.accept(activeJob); - maybeQueueFunctor.postProcess(); + maybeQueueFunctor.postProcessLocked(); assertEquals(3, mService.mPendingJobs.size()); // Not enough RARE jobs to run, but an old RARE job saves the day. @@ -764,7 +780,7 @@ public class JobSchedulerServiceTest { } maybeQueueFunctor.accept(oldRareJob); assertEquals(oldBatchTime, oldRareJob.getFirstForceBatchedTimeElapsed()); - maybeQueueFunctor.postProcess(); + maybeQueueFunctor.postProcessLocked(); assertEquals(3, mService.mPendingJobs.size()); } @@ -853,4 +869,207 @@ public class JobSchedulerServiceTest { 0, "")); } } + + @Test + public void testPendingJobSorting() { + // First letter in job variable name indicate regular (r) or expedited (e). + // Capital letters in job variable name indicate the app/UID. + // Numbers in job variable name indicate the enqueue time. + // Expected sort order: + // eA7 > rA1 > eB6 > rB2 > eC3 > rD4 > eE5 > eF9 > rF8 > eC11 > rC10 > rG12 > rG13 > eE14 + // Intentions: + // * A jobs let us test skipping both regular and expedited jobs of other apps + // * B jobs let us test skipping only regular job of another app without going too far + // * C jobs test that regular jobs don't skip over other app's jobs and that EJs only + // skip up to level of the earliest regular job + // * E jobs test that expedited jobs don't skip the line when the app has no regular jobs + // * F jobs test correct expedited/regular ordering doesn't push jobs too high in list + // * G jobs test correct ordering for regular jobs + JobStatus rA1 = createJobStatus("testPendingJobSorting", createJobInfo(1), 1); + JobStatus rB2 = createJobStatus("testPendingJobSorting", createJobInfo(2), 2); + JobStatus eC3 = createJobStatus("testPendingJobSorting", + createJobInfo(3).setExpedited(true), 3); + JobStatus rD4 = createJobStatus("testPendingJobSorting", createJobInfo(4), 4); + JobStatus eE5 = createJobStatus("testPendingJobSorting", + createJobInfo(5).setExpedited(true), 5); + JobStatus eB6 = createJobStatus("testPendingJobSorting", + createJobInfo(6).setExpedited(true), 2); + JobStatus eA7 = createJobStatus("testPendingJobSorting", + createJobInfo(7).setExpedited(true), 1); + JobStatus rF8 = createJobStatus("testPendingJobSorting", createJobInfo(8), 6); + JobStatus eF9 = createJobStatus("testPendingJobSorting", + createJobInfo(9).setExpedited(true), 6); + JobStatus rC10 = createJobStatus("testPendingJobSorting", createJobInfo(10), 3); + JobStatus eC11 = createJobStatus("testPendingJobSorting", + createJobInfo(11).setExpedited(true), 3); + JobStatus rG12 = createJobStatus("testPendingJobSorting", createJobInfo(12), 7); + JobStatus rG13 = createJobStatus("testPendingJobSorting", createJobInfo(13), 7); + JobStatus eE14 = createJobStatus("testPendingJobSorting", + createJobInfo(14).setExpedited(true), 5); + + rA1.enqueueTime = 1; + rB2.enqueueTime = 2; + eC3.enqueueTime = 3; + rD4.enqueueTime = 4; + eE5.enqueueTime = 5; + eB6.enqueueTime = 6; + eA7.enqueueTime = 7; + rF8.enqueueTime = 8; + eF9.enqueueTime = 9; + rC10.enqueueTime = 10; + eC11.enqueueTime = 11; + rG12.enqueueTime = 12; + rG13.enqueueTime = 13; + eE14.enqueueTime = 14; + + mService.mPendingJobs.clear(); + // Add in random order so sorting is apparent. + mService.mPendingJobs.add(eC3); + mService.mPendingJobs.add(eE5); + mService.mPendingJobs.add(rA1); + mService.mPendingJobs.add(rG13); + mService.mPendingJobs.add(rD4); + mService.mPendingJobs.add(eA7); + mService.mPendingJobs.add(rG12); + mService.mPendingJobs.add(rF8); + mService.mPendingJobs.add(eB6); + mService.mPendingJobs.add(eE14); + mService.mPendingJobs.add(eF9); + mService.mPendingJobs.add(rB2); + mService.mPendingJobs.add(rC10); + mService.mPendingJobs.add(eC11); + + mService.mPendingJobComparator.refreshLocked(); + mService.mPendingJobs.sort(mService.mPendingJobComparator); + + final JobStatus[] expectedOrder = new JobStatus[]{ + eA7, rA1, eB6, rB2, eC3, rD4, eE5, eF9, rF8, eC11, rC10, rG12, rG13, eE14}; + for (int i = 0; i < expectedOrder.length; ++i) { + assertEquals("List wasn't correctly sorted @ index " + i, + expectedOrder[i].getJobId(), mService.mPendingJobs.get(i).getJobId()); + } + } + + private void checkPendingJobInvariants() { + long regJobEnqueueTime = 0; + final SparseBooleanArray regJobSeen = new SparseBooleanArray(); + final SparseLongArray ejEnqueueTimes = new SparseLongArray(); + + for (int i = 0; i < mService.mPendingJobs.size(); ++i) { + final JobStatus job = mService.mPendingJobs.get(i); + final int uid = job.getSourceUid(); + + if (!job.isRequestedExpeditedJob()) { + // Invariant #1: Regular jobs are sorted by enqueue time. + assertTrue("Regular job with earlier enqueue time sorted after a later time: " + + regJobEnqueueTime + " vs " + job.enqueueTime, + regJobEnqueueTime <= job.enqueueTime); + regJobEnqueueTime = job.enqueueTime; + regJobSeen.put(uid, true); + } else { + // Invariant #2: EJs should be before regular jobs for an individual app + if (regJobSeen.get(uid)) { + fail("UID " + uid + " had an EJ ordered after a regular job"); + } + final long ejEnqueueTime = ejEnqueueTimes.get(uid, 0); + // Invariant #3: EJs for an individual app should be sorted by enqueue time. + assertTrue("EJ with earlier enqueue time sorted after a later time: " + + ejEnqueueTime + " vs " + job.enqueueTime, + ejEnqueueTime <= job.enqueueTime); + ejEnqueueTimes.put(uid, job.enqueueTime); + } + } + } + + private static String sortedJobToString(JobStatus job) { + return "testJob " + job.getSourceUid() + "/" + job.getJobId() + "/" + + job.isRequestedExpeditedJob() + "@" + job.enqueueTime; + } + + @Test + public void testPendingJobSorting_Random() { + Random random = new Random(1); // Always use the same series of pseudo random values. + + mService.mPendingJobs.clear(); + + for (int i = 0; i < 2500; ++i) { + JobStatus job = createJobStatus("testPendingJobSorting_Random", + createJobInfo(i).setExpedited(random.nextBoolean()), random.nextInt(250)); + job.enqueueTime = Math.abs(random.nextInt(1_000_000)); + mService.mPendingJobs.add(job); + + mService.mPendingJobComparator.refreshLocked(); + try { + mService.mPendingJobs.sort(mService.mPendingJobComparator); + } catch (Exception e) { + for (JobStatus toDump : mService.mPendingJobs) { + Log.i(TAG, sortedJobToString(toDump)); + } + throw e; + } + checkPendingJobInvariants(); + } + } + + private int sign(int i) { + if (i > 0) { + return 1; + } + if (i < 0) { + return -1; + } + return 0; + } + + @Test + public void testPendingJobSortingTransitivity() { + Random random = new Random(1); // Always use the same series of pseudo random values. + + mService.mPendingJobs.clear(); + + for (int i = 0; i < 250; ++i) { + JobStatus job = createJobStatus("testPendingJobSortingTransitivity", + createJobInfo(i).setExpedited(random.nextBoolean()), random.nextInt(50)); + job.enqueueTime = Math.abs(random.nextInt(1_000_000)); + job.overrideState = random.nextInt(4); + mService.mPendingJobs.add(job); + } + + mService.mPendingJobComparator.refreshLocked(); + + for (int i = 0; i < mService.mPendingJobs.size(); ++i) { + final JobStatus job1 = mService.mPendingJobs.get(i); + + for (int j = 0; j < mService.mPendingJobs.size(); ++j) { + final JobStatus job2 = mService.mPendingJobs.get(j); + final int sign12 = sign(mService.mPendingJobComparator.compare(job1, job2)); + final int sign21 = sign(mService.mPendingJobComparator.compare(job2, job1)); + if (sign12 != -sign21) { + final String job1String = sortedJobToString(job1); + final String job2String = sortedJobToString(job2); + fail("compare(" + job1String + ", " + job2String + ") != " + + "-compare(" + job2String + ", " + job1String + ")"); + } + + for (int k = 0; k < mService.mPendingJobs.size(); ++k) { + final JobStatus job3 = mService.mPendingJobs.get(k); + final int sign23 = sign(mService.mPendingJobComparator.compare(job2, job3)); + final int sign13 = sign(mService.mPendingJobComparator.compare(job1, job3)); + + // Confirm 1 < 2 < 3 or 1 > 2 > 3 or 1 == 2 == 3 + if ((sign12 == sign23 && sign12 != sign13) + // Confirm that if 1 == 2, then (1 < 3 AND 2 < 3) OR (1 > 3 && 2 > 3) + || (sign12 == 0 && sign13 != sign23)) { + final String job1String = sortedJobToString(job1); + final String job2String = sortedJobToString(job2); + final String job3String = sortedJobToString(job3); + fail("Transitivity fail" + + ": compare(" + job1String + ", " + job2String + ")=" + sign12 + + ", compare(" + job2String + ", " + job3String + ")=" + sign23 + + ", compare(" + job1String + ", " + job3String + ")=" + sign13); + } + } + } + } + } } diff --git a/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssGeofenceProxyTest.java b/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssGeofenceProxyTest.java index b480f24fb371..5e219a25ed9a 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssGeofenceProxyTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssGeofenceProxyTest.java @@ -18,6 +18,7 @@ package com.android.server.location.gnss; import static com.google.common.truth.Truth.assertThat; +import android.content.Context; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; @@ -49,6 +50,7 @@ public class GnssGeofenceProxyTest { private static final int NOTIFICATION_RESPONSIVENESS = 0; private static final int UNKNOWN_TIMER = 0; + private @Mock Context mContext; private @Mock GnssConfiguration mMockConfiguration; private @Mock GnssNative.GeofenceCallbacks mGeofenceCallbacks; @@ -63,7 +65,7 @@ public class GnssGeofenceProxyTest { GnssNative.setGnssHalForTest(mFakeHal); GnssNative gnssNative = Objects.requireNonNull( - GnssNative.create(new TestInjector(), mMockConfiguration)); + GnssNative.create(new TestInjector(mContext), mMockConfiguration)); gnssNative.setGeofenceCallbacks(mGeofenceCallbacks); mTestProvider = new GnssGeofenceProxy(gnssNative); gnssNative.register(); diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeAppOpsHelper.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeAppOpsHelper.java index 3d0378170c94..d728451d92b9 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeAppOpsHelper.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeAppOpsHelper.java @@ -29,9 +29,10 @@ import java.util.HashMap; public class FakeAppOpsHelper extends AppOpsHelper { private static class AppOp { - private boolean mAllowed = true; - private boolean mStarted = false; - private int mNoteCount = 0; + AppOp() {} + boolean mAllowed = true; + boolean mStarted = false; + int mNoteCount = 0; } private final HashMap<String, SparseArray<AppOp>> mAppOps; diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeSettingsHelper.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeSettingsHelper.java index f1099f0e8184..cd70020f5c28 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeSettingsHelper.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeSettingsHelper.java @@ -29,8 +29,8 @@ import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; /** - * Version of AppOpsHelper for testing. Settings are initialized to reasonable defaults (location is - * enabled by default). + * Version of SettingsHelper for testing. Settings are initialized to reasonable defaults (location + * is enabled by default). */ public class FakeSettingsHelper extends SettingsHelper { diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java index ae70dadba041..bd24cfd78a2c 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java @@ -16,9 +16,14 @@ package com.android.server.location.injector; +import android.content.Context; + +import com.android.server.location.settings.FakeLocationSettings; + public class TestInjector implements Injector { private final FakeUserInfoHelper mUserInfoHelper; + private final FakeLocationSettings mLocationSettings; private final FakeAlarmHelper mAlarmHelper; private final FakeAppOpsHelper mAppOpsHelper; private final FakeLocationPermissionsHelper mLocationPermissionsHelper; @@ -32,8 +37,9 @@ public class TestInjector implements Injector { private final FakeEmergencyHelper mEmergencyHelper; private final LocationUsageLogger mLocationUsageLogger; - public TestInjector() { + public TestInjector(Context context) { mUserInfoHelper = new FakeUserInfoHelper(); + mLocationSettings = new FakeLocationSettings(context); mAlarmHelper = new FakeAlarmHelper(); mAppOpsHelper = new FakeAppOpsHelper(); mLocationPermissionsHelper = new FakeLocationPermissionsHelper(mAppOpsHelper); @@ -54,6 +60,11 @@ public class TestInjector implements Injector { } @Override + public FakeLocationSettings getLocationSettings() { + return mLocationSettings; + } + + @Override public FakeAlarmHelper getAlarmHelper() { return mAlarmHelper; } diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java index 6bc3b6041070..f703e2e59181 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java @@ -19,6 +19,8 @@ package com.android.server.location.provider; import static android.app.AppOpsManager.OP_FINE_LOCATION; import static android.app.AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION; import static android.app.AppOpsManager.OP_MONITOR_LOCATION; +import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE; +import static android.location.LocationManager.GPS_PROVIDER; import static android.location.LocationRequest.PASSIVE_INTERVAL; import static android.location.provider.ProviderProperties.POWER_USAGE_HIGH; import static android.os.PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF; @@ -56,6 +58,8 @@ import static org.mockito.MockitoAnnotations.initMocks; import static org.testng.Assert.assertThrows; import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.Resources; import android.location.ILocationCallback; import android.location.ILocationListener; import android.location.LastLocationRequest; @@ -82,6 +86,7 @@ import android.util.Log; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.internal.R; import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.location.injector.FakeUserInfoHelper; @@ -139,6 +144,10 @@ public class LocationProviderManagerTest { @Mock private Context mContext; @Mock + private Resources mResources; + @Mock + private PackageManager mPackageManager; + @Mock private PowerManager mPowerManager; @Mock private PowerManager.WakeLock mWakeLock; @@ -161,20 +170,28 @@ public class LocationProviderManagerTest { LocalServices.addService(LocationManagerInternal.class, mInternal); doReturn("android").when(mContext).getPackageName(); + doReturn(mResources).when(mContext).getResources(); + doReturn(mPackageManager).when(mContext).getPackageManager(); doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class); doReturn(mWakeLock).when(mPowerManager).newWakeLock(anyInt(), anyString()); - mInjector = new TestInjector(); + mInjector = new TestInjector(mContext); mInjector.getUserInfoHelper().startUser(OTHER_USER); mPassive = new PassiveLocationProviderManager(mContext, mInjector); mPassive.startManager(null); mPassive.setRealProvider(new PassiveLocationProvider(mContext)); + createManager(NAME); + } + + private void createManager(String name) { + mStateChangedListener = mock(LocationProviderManager.StateChangedListener.class); + mProvider = new TestProvider(PROPERTIES, PROVIDER_IDENTITY); mProvider.setProviderAllowed(true); - mManager = new LocationProviderManager(mContext, mInjector, NAME, mPassive); + mManager = new LocationProviderManager(mContext, mInjector, name, mPassive); mManager.startManager(mStateChangedListener); mManager.setRealProvider(mProvider); } @@ -1017,6 +1034,95 @@ public class LocationProviderManagerTest { } @Test + public void testProviderRequest_AdasGnssBypass() { + doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE); + doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled); + + createManager(GPS_PROVIDER); + + ILocationListener listener1 = createMockLocationListener(); + LocationRequest request1 = new LocationRequest.Builder(5) + .setWorkSource(WORK_SOURCE) + .build(); + mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); + + assertThat(mProvider.getRequest().isActive()).isTrue(); + assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5); + assertThat(mProvider.getRequest().isAdasGnssBypass()).isFalse(); + + ILocationListener listener2 = createMockLocationListener(); + LocationRequest request2 = new LocationRequest.Builder(1) + .setAdasGnssBypass(true) + .setWorkSource(WORK_SOURCE) + .build(); + mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2); + + assertThat(mProvider.getRequest().isActive()).isTrue(); + assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1); + assertThat(mProvider.getRequest().isAdasGnssBypass()).isTrue(); + } + + @Test + public void testProviderRequest_AdasGnssBypass_ProviderDisabled() { + doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE); + doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled); + + createManager(GPS_PROVIDER); + + ILocationListener listener1 = createMockLocationListener(); + LocationRequest request1 = new LocationRequest.Builder(1) + .setWorkSource(WORK_SOURCE) + .build(); + mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); + + ILocationListener listener2 = createMockLocationListener(); + LocationRequest request2 = new LocationRequest.Builder(5) + .setAdasGnssBypass(true) + .setWorkSource(WORK_SOURCE) + .build(); + mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2); + + mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId()); + + assertThat(mProvider.getRequest().isActive()).isTrue(); + assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5); + assertThat(mProvider.getRequest().isAdasGnssBypass()).isTrue(); + } + + @Test + public void testProviderRequest_AdasGnssBypass_ProviderDisabled_AdasDisabled() { + mInjector.getSettingsHelper().setIgnoreSettingsAllowlist( + new PackageTagsList.Builder().add( + IDENTITY.getPackageName()).build()); + doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE); + doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled); + + createManager(GPS_PROVIDER); + + ILocationListener listener1 = createMockLocationListener(); + LocationRequest request1 = new LocationRequest.Builder(5) + .setLocationSettingsIgnored(true) + .setWorkSource(WORK_SOURCE) + .build(); + mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); + + ILocationListener listener2 = createMockLocationListener(); + LocationRequest request2 = new LocationRequest.Builder(1) + .setAdasGnssBypass(true) + .setWorkSource(WORK_SOURCE) + .build(); + mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2); + + mInjector.getLocationSettings().updateUserSettings(IDENTITY.getUserId(), + settings -> settings.withAdasGnssLocationEnabled(false)); + mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId()); + + assertThat(mProvider.getRequest().isActive()).isTrue(); + assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5); + assertThat(mProvider.getRequest().isAdasGnssBypass()).isFalse(); + } + + @Test public void testProviderRequest_BatterySaver_ScreenOnOff() { mInjector.getLocationPowerSaveModeHelper().setLocationPowerSaveMode( LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF); diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java index 04e0151e619a..63996f0e021c 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.MockitoAnnotations.initMocks; +import android.content.Context; import android.location.Location; import android.location.LocationResult; import android.location.provider.ProviderRequest; @@ -58,6 +59,7 @@ public class StationaryThrottlingLocationProviderTest { private TestInjector mInjector; private FakeProvider mDelegateProvider; + private @Mock Context mContext; private @Mock AbstractLocationProvider.Listener mListener; private @Mock FakeProvider.FakeProviderInterface mDelegate; @@ -72,7 +74,7 @@ public class StationaryThrottlingLocationProviderTest { mRandom = new Random(seed); - mInjector = new TestInjector(); + mInjector = new TestInjector(mContext); mDelegateProvider = new FakeProvider(mDelegate); mProvider = new StationaryThrottlingLocationProvider("test_provider", mInjector, diff --git a/services/tests/mockingservicestests/src/com/android/server/location/settings/FakeLocationSettings.java b/services/tests/mockingservicestests/src/com/android/server/location/settings/FakeLocationSettings.java new file mode 100644 index 000000000000..4d46abaa6733 --- /dev/null +++ b/services/tests/mockingservicestests/src/com/android/server/location/settings/FakeLocationSettings.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.location.settings; + +import android.content.Context; + +import androidx.test.core.app.ApplicationProvider; + +import java.io.File; + +public class FakeLocationSettings extends LocationSettings { + + public FakeLocationSettings(Context context) { + super(context); + } + + @Override + protected File getUserSettingsDir(int userId) { + return ApplicationProvider.getApplicationContext().getCacheDir(); + } + + @Override + protected LocationUserSettingsStore createUserSettingsStore(int userId, File file) { + return new FakeLocationUserSettingsStore(userId, file); + } + + private class FakeLocationUserSettingsStore extends LocationUserSettingsStore { + + FakeLocationUserSettingsStore(int userId, File file) { + super(userId, file); + } + + @Override + protected void onChange(LocationUserSettings oldSettings, + LocationUserSettings newSettings) { + fireListeners(mUserId, oldSettings, newSettings); + } + } +} + diff --git a/services/tests/mockingservicestests/src/com/android/server/location/settings/LocationSettingsTest.java b/services/tests/mockingservicestests/src/com/android/server/location/settings/LocationSettingsTest.java new file mode 100644 index 000000000000..4b6c79b954cd --- /dev/null +++ b/services/tests/mockingservicestests/src/com/android/server/location/settings/LocationSettingsTest.java @@ -0,0 +1,171 @@ +/* + * 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.location.settings; + +import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.after; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.platform.test.annotations.Presubmit; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.internal.R; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; + +import java.io.File; + +@Presubmit +@SmallTest +@RunWith(AndroidJUnit4.class) +public class LocationSettingsTest { + + private @Mock Context mContext; + private @Mock Resources mResources; + private @Mock PackageManager mPackageManager; + + private LocationSettings mLocationSettings; + + @Before + public void setUp() { + initMocks(this); + + doReturn(mResources).when(mContext).getResources(); + doReturn(mPackageManager).when(mContext).getPackageManager(); + doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE); + + resetLocationSettings(); + } + + @After + public void tearDown() throws Exception { + mLocationSettings.deleteFiles(); + } + + private void resetLocationSettings() { + mLocationSettings = new LocationSettings(mContext) { + @Override + protected File getUserSettingsDir(int userId) { + return ApplicationProvider.getApplicationContext().getCacheDir(); + } + }; + } + + @Test + public void testLoadDefaults() { + doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled); + assertThat(mLocationSettings.getUserSettings(1).isAdasGnssLocationEnabled()).isTrue(); + + doReturn(false).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled); + assertThat(mLocationSettings.getUserSettings(2).isAdasGnssLocationEnabled()).isFalse(); + } + + @Test + public void testUpdate() { + doReturn(false).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled); + mLocationSettings.updateUserSettings(1, + settings -> settings.withAdasGnssLocationEnabled(true)); + assertThat(mLocationSettings.getUserSettings(1).isAdasGnssLocationEnabled()).isTrue(); + + mLocationSettings.updateUserSettings(1, + settings -> settings.withAdasGnssLocationEnabled(false)); + assertThat(mLocationSettings.getUserSettings(1).isAdasGnssLocationEnabled()).isFalse(); + } + + @Test + public void testSerialization() throws Exception { + doReturn(false).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled); + mLocationSettings.updateUserSettings(1, + settings -> settings.withAdasGnssLocationEnabled(true)); + assertThat(mLocationSettings.getUserSettings(1).isAdasGnssLocationEnabled()).isTrue(); + + mLocationSettings.flushFiles(); + resetLocationSettings(); + assertThat(mLocationSettings.getUserSettings(1).isAdasGnssLocationEnabled()).isTrue(); + } + + @Test + public void testListeners() { + doReturn(false).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled); + LocationSettings.LocationUserSettingsListener listener = mock( + LocationSettings.LocationUserSettingsListener.class); + + mLocationSettings.registerLocationUserSettingsListener(listener); + + ArgumentCaptor<LocationUserSettings> oldCaptor = ArgumentCaptor.forClass( + LocationUserSettings.class); + ArgumentCaptor<LocationUserSettings> newCaptor = ArgumentCaptor.forClass( + LocationUserSettings.class); + mLocationSettings.updateUserSettings(1, + settings -> settings.withAdasGnssLocationEnabled(true)); + verify(listener, timeout(500).times(1)).onLocationUserSettingsChanged(eq(1), + oldCaptor.capture(), newCaptor.capture()); + assertThat(oldCaptor.getValue().isAdasGnssLocationEnabled()).isFalse(); + assertThat(newCaptor.getValue().isAdasGnssLocationEnabled()).isTrue(); + + oldCaptor = ArgumentCaptor.forClass(LocationUserSettings.class); + newCaptor = ArgumentCaptor.forClass(LocationUserSettings.class); + mLocationSettings.updateUserSettings(1, + settings -> settings.withAdasGnssLocationEnabled(false)); + verify(listener, timeout(500).times(2)).onLocationUserSettingsChanged(eq(1), + oldCaptor.capture(), newCaptor.capture()); + assertThat(oldCaptor.getValue().isAdasGnssLocationEnabled()).isTrue(); + assertThat(newCaptor.getValue().isAdasGnssLocationEnabled()).isFalse(); + + mLocationSettings.unregisterLocationUserSettingsListener(listener); + mLocationSettings.updateUserSettings(1, + settings -> settings.withAdasGnssLocationEnabled(true)); + verify(listener, after(500).times(2)).onLocationUserSettingsChanged(anyInt(), any(), any()); + } + + @Test + public void testNonAutomotive() { + doReturn(false).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE); + doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled); + + LocationSettings.LocationUserSettingsListener listener = mock( + LocationSettings.LocationUserSettingsListener.class); + mLocationSettings.registerLocationUserSettingsListener(listener); + + assertThat(mLocationSettings.getUserSettings(1).isAdasGnssLocationEnabled()).isFalse(); + mLocationSettings.updateUserSettings(1, + settings -> settings.withAdasGnssLocationEnabled(true)); + assertThat(mLocationSettings.getUserSettings(1).isAdasGnssLocationEnabled()).isFalse(); + verify(listener, after(500).never()).onLocationUserSettingsChanged(anyInt(), any(), any()); + } +} diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java index 7d628be571a9..68570ffc6fce 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/StagingManagerTest.java @@ -286,6 +286,7 @@ public class StagingManagerTest { ApexSessionInfo activationFailed = new ApexSessionInfo(); activationFailed.sessionId = 1543; activationFailed.isActivationFailed = true; + activationFailed.errorMessage = "Failed for test"; ApexSessionInfo staged = new ApexSessionInfo(); staged.sessionId = 101; @@ -309,8 +310,8 @@ public class StagingManagerTest { assertThat(apexSession1.getErrorCode()) .isEqualTo(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED); - assertThat(apexSession1.getErrorMessage()).isEqualTo("APEX activation failed. Check logcat " - + "messages from apexd for more information."); + assertThat(apexSession1.getErrorMessage()).isEqualTo("APEX activation failed. " + + "Failed for test"); assertThat(apexSession2.getErrorCode()) .isEqualTo(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED); diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java index e19aa727b735..4b030d18f7c3 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java @@ -52,7 +52,6 @@ import android.server.wm.settings.SettingsSession; import android.support.test.uiautomator.UiDevice; import android.test.suitebuilder.annotation.LargeTest; import android.text.TextUtils; -import android.util.KeyValueListParser; import android.util.Log; import androidx.test.InstrumentationRegistry; @@ -421,142 +420,6 @@ public class ActivityManagerTest { return false; } - @LargeTest - @Test - public void testKillAppIfFasCachedIdle() throws Exception { - final long shortTimeoutMs = 5_000; - final long backgroundSettleMs = 10_000; - final PackageManager pm = mContext.getPackageManager(); - final int uid = pm.getPackageUid(TEST_APP1, 0); - final MyUidImportanceListener uidListener1 = new MyUidImportanceListener(uid); - final MyUidImportanceListener uidListener2 = new MyUidImportanceListener(uid); - SettingsSession<String> amConstantsSettings = null; - DeviceConfigSession<Boolean> killForceAppStandByAndCachedIdle = null; - final ActivityManager am = mContext.getSystemService(ActivityManager.class); - final CountDownLatch[] latchHolder = new CountDownLatch[1]; - final H handler = new H(Looper.getMainLooper(), latchHolder); - final Messenger messenger = new Messenger(handler); - try { - am.addOnUidImportanceListener(uidListener1, - RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE); - am.addOnUidImportanceListener(uidListener2, RunningAppProcessInfo.IMPORTANCE_GONE); - toggleScreenOn(true); - - killForceAppStandByAndCachedIdle = new DeviceConfigSession<>( - DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - ActivityManagerConstants.KEY_KILL_FAS_CACHED_IDLE, - DeviceConfig::getBoolean, - ActivityManagerConstants.DEFAULT_KILL_FAS_CACHED_IDLE); - killForceAppStandByAndCachedIdle.set(true); - amConstantsSettings = new SettingsSession<>( - Settings.Global.getUriFor(Settings.Global.ACTIVITY_MANAGER_CONSTANTS), - Settings.Global::getString, Settings.Global::putString); - final KeyValueListParser parser = new KeyValueListParser(','); - long currentBackgroundSettleMs = - ActivityManagerConstants.DEFAULT_BACKGROUND_SETTLE_TIME; - try { - parser.setString(amConstantsSettings.get()); - currentBackgroundSettleMs = parser.getLong( - ActivityManagerConstants.KEY_BACKGROUND_SETTLE_TIME, - ActivityManagerConstants.DEFAULT_BACKGROUND_SETTLE_TIME); - } catch (IllegalArgumentException e) { - } - // Drain queue to make sure the existing UID_IDLE_MSG has been processed. - Thread.sleep(currentBackgroundSettleMs); - amConstantsSettings.set( - ActivityManagerConstants.KEY_BACKGROUND_SETTLE_TIME + "=" + backgroundSettleMs); - runShellCommand("cmd appops set " + TEST_APP1 + " RUN_ANY_IN_BACKGROUND allow"); - - final Intent intent = new Intent(ACTION_FGS_STATS_TEST); - final ComponentName cn = ComponentName.unflattenFromString( - TEST_APP1 + "/" + TEST_FGS_CLASS); - final Bundle bundle = new Bundle(); - intent.setComponent(cn); - bundle.putBinder(EXTRA_MESSENGER, messenger.getBinder()); - intent.putExtras(bundle); - - // Start the FGS. - latchHolder[0] = new CountDownLatch(1); - mContext.startForegroundService(intent); - assertTrue("Timed out to start fg service", uidListener1.waitFor( - RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE, shortTimeoutMs)); - assertTrue("Timed out to get the remote messenger", latchHolder[0].await( - shortTimeoutMs, TimeUnit.MILLISECONDS)); - assertFalse("FGS shouldn't be killed", uidListener2.waitFor( - RunningAppProcessInfo.IMPORTANCE_GONE, backgroundSettleMs + shortTimeoutMs)); - - // Stop the FGS, it shouldn't be killed because it's not in FAS state. - latchHolder[0] = new CountDownLatch(1); - handler.sendRemoteMessage(H.MSG_STOP_FOREGROUND, 0, 0, null); - assertTrue("Timed out to wait for stop fg", latchHolder[0].await( - shortTimeoutMs, TimeUnit.MILLISECONDS)); - assertFalse("FGS shouldn't be killed", uidListener2.waitFor( - RunningAppProcessInfo.IMPORTANCE_GONE, backgroundSettleMs + shortTimeoutMs)); - - // Set the FAS state. - runShellCommand("cmd appops set " + TEST_APP1 + " RUN_ANY_IN_BACKGROUND deny"); - // Now it should've been killed. - assertTrue("Should have been killed", uidListener2.waitFor( - RunningAppProcessInfo.IMPORTANCE_GONE, backgroundSettleMs + shortTimeoutMs)); - - // Start the FGS. - // Temporarily allow RUN_ANY_IN_BACKGROUND to start FGS. - runShellCommand("cmd appops set " + TEST_APP1 + " RUN_ANY_IN_BACKGROUND allow"); - latchHolder[0] = new CountDownLatch(1); - mContext.startForegroundService(intent); - assertTrue("Timed out to start fg service", uidListener1.waitFor( - RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE, shortTimeoutMs)); - assertTrue("Timed out to get the remote messenger", latchHolder[0].await( - shortTimeoutMs, TimeUnit.MILLISECONDS)); - runShellCommand("cmd appops set " + TEST_APP1 + " RUN_ANY_IN_BACKGROUND deny"); - // It shouldn't be killed since it's not cached. - assertFalse("FGS shouldn't be killed", uidListener2.waitFor( - RunningAppProcessInfo.IMPORTANCE_GONE, backgroundSettleMs + shortTimeoutMs)); - - // Stop the FGS, it should get killed because it's cached & uid idle & in FAS state. - latchHolder[0] = new CountDownLatch(1); - handler.sendRemoteMessage(H.MSG_STOP_FOREGROUND, 0, 0, null); - assertTrue("Timed out to wait for stop fg", latchHolder[0].await( - shortTimeoutMs, TimeUnit.MILLISECONDS)); - assertTrue("Should have been killed", uidListener2.waitFor( - RunningAppProcessInfo.IMPORTANCE_GONE, backgroundSettleMs + shortTimeoutMs)); - - // Disable this FAS cached idle kill feature. - killForceAppStandByAndCachedIdle.set(false); - - // Start the FGS. - // Temporarily allow RUN_ANY_IN_BACKGROUND to start FGS. - runShellCommand("cmd appops set " + TEST_APP1 + " RUN_ANY_IN_BACKGROUND allow"); - latchHolder[0] = new CountDownLatch(1); - mContext.startForegroundService(intent); - assertTrue("Timed out to start fg service", uidListener1.waitFor( - RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE, shortTimeoutMs)); - assertTrue("Timed out to get the remote messenger", latchHolder[0].await( - shortTimeoutMs, TimeUnit.MILLISECONDS)); - runShellCommand("cmd appops set " + TEST_APP1 + " RUN_ANY_IN_BACKGROUND deny"); - assertFalse("FGS shouldn't be killed", uidListener2.waitFor( - RunningAppProcessInfo.IMPORTANCE_GONE, backgroundSettleMs + shortTimeoutMs)); - - // Stop the FGS, it shouldn't be killed because the feature has been turned off. - latchHolder[0] = new CountDownLatch(1); - handler.sendRemoteMessage(H.MSG_STOP_FOREGROUND, 0, 0, null); - assertTrue("Timed out to wait for stop fg", latchHolder[0].await( - shortTimeoutMs, TimeUnit.MILLISECONDS)); - assertFalse("FGS shouldn't be killed", uidListener2.waitFor( - RunningAppProcessInfo.IMPORTANCE_GONE, backgroundSettleMs + shortTimeoutMs)); - } finally { - runShellCommand("cmd appops set " + TEST_APP1 + " RUN_ANY_IN_BACKGROUND default"); - if (amConstantsSettings != null) { - amConstantsSettings.close(); - } - if (killForceAppStandByAndCachedIdle != null) { - killForceAppStandByAndCachedIdle.close(); - } - am.removeOnUidImportanceListener(uidListener1); - am.removeOnUidImportanceListener(uidListener2); - } - } - @Ignore("Need to disable calling uid check in ActivityManagerService.killPids before this test") @Test public void testKillPids() throws Exception { diff --git a/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java b/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java index f4f907355aee..3c10789bc792 100644 --- a/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java +++ b/services/tests/servicestests/src/com/android/server/appsearch/AppSearchImplPlatformTest.java @@ -42,7 +42,7 @@ import androidx.test.core.app.ApplicationProvider; import com.android.compatibility.common.util.SystemUtil; import com.android.server.appsearch.external.localstorage.util.PrefixUtil; -import com.android.server.appsearch.visibilitystore.VisibilityStore; +import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -67,7 +67,7 @@ public class AppSearchImplPlatformTest { private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>(); private Context mContext; private AppSearchImpl mAppSearchImpl; - private VisibilityStore mVisibilityStore; + private VisibilityStoreImpl mVisibilityStore; private int mGlobalQuerierUid; @Before @@ -93,7 +93,7 @@ public class AppSearchImplPlatformTest { // Give ourselves global query permissions mAppSearchImpl = AppSearchImpl.create( mTemporaryFolder.newFolder(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE); - mVisibilityStore = VisibilityStore.create(mAppSearchImpl, mContext); + mVisibilityStore = VisibilityStoreImpl.create(mAppSearchImpl, mContext); mGlobalQuerierUid = mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0); } diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java index 02bb168dbde6..330b1a74d879 100644 --- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java +++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java @@ -43,19 +43,19 @@ import androidx.test.core.app.ApplicationProvider; import com.android.server.appsearch.external.localstorage.converter.GenericDocumentToProtoConverter; import com.android.server.appsearch.external.localstorage.stats.InitializeStats; import com.android.server.appsearch.external.localstorage.util.PrefixUtil; -import com.android.server.appsearch.proto.DocumentProto; -import com.android.server.appsearch.proto.GetOptimizeInfoResultProto; -import com.android.server.appsearch.proto.PersistType; -import com.android.server.appsearch.proto.PropertyConfigProto; -import com.android.server.appsearch.proto.PropertyProto; -import com.android.server.appsearch.proto.PutResultProto; -import com.android.server.appsearch.proto.SchemaProto; -import com.android.server.appsearch.proto.SchemaTypeConfigProto; -import com.android.server.appsearch.proto.SearchResultProto; -import com.android.server.appsearch.proto.SearchSpecProto; -import com.android.server.appsearch.proto.StatusProto; -import com.android.server.appsearch.proto.StringIndexingConfig; -import com.android.server.appsearch.proto.TermMatchType; +import com.android.server.appsearch.icing.proto.DocumentProto; +import com.android.server.appsearch.icing.proto.GetOptimizeInfoResultProto; +import com.android.server.appsearch.icing.proto.PersistType; +import com.android.server.appsearch.icing.proto.PropertyConfigProto; +import com.android.server.appsearch.icing.proto.PropertyProto; +import com.android.server.appsearch.icing.proto.PutResultProto; +import com.android.server.appsearch.icing.proto.SchemaProto; +import com.android.server.appsearch.icing.proto.SchemaTypeConfigProto; +import com.android.server.appsearch.icing.proto.SearchResultProto; +import com.android.server.appsearch.icing.proto.SearchSpecProto; +import com.android.server.appsearch.icing.proto.StatusProto; +import com.android.server.appsearch.icing.proto.StringIndexingConfig; +import com.android.server.appsearch.icing.proto.TermMatchType; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java index 9b75561fd2ec..080c375ac7c6 100644 --- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java +++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchLoggerTest.java @@ -32,15 +32,15 @@ import com.android.server.appsearch.external.localstorage.stats.InitializeStats; import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats; import com.android.server.appsearch.external.localstorage.stats.RemoveStats; import com.android.server.appsearch.external.localstorage.stats.SearchStats; -import com.android.server.appsearch.proto.DeleteStatsProto; -import com.android.server.appsearch.proto.DocumentProto; -import com.android.server.appsearch.proto.InitializeStatsProto; -import com.android.server.appsearch.proto.PutDocumentStatsProto; -import com.android.server.appsearch.proto.PutResultProto; -import com.android.server.appsearch.proto.QueryStatsProto; -import com.android.server.appsearch.proto.ScoringSpecProto; -import com.android.server.appsearch.proto.StatusProto; -import com.android.server.appsearch.proto.TermMatchType; +import com.android.server.appsearch.icing.proto.DeleteStatsProto; +import com.android.server.appsearch.icing.proto.DocumentProto; +import com.android.server.appsearch.icing.proto.InitializeStatsProto; +import com.android.server.appsearch.icing.proto.PutDocumentStatsProto; +import com.android.server.appsearch.icing.proto.PutResultProto; +import com.android.server.appsearch.icing.proto.QueryStatsProto; +import com.android.server.appsearch.icing.proto.ScoringSpecProto; +import com.android.server.appsearch.icing.proto.StatusProto; +import com.android.server.appsearch.icing.proto.TermMatchType; import com.google.common.collect.ImmutableList; diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategyTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategyTest.java index f30cbb8c5158..de71d21e6eb1 100644 --- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategyTest.java +++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/FrameworkOptimizeStrategyTest.java @@ -22,8 +22,8 @@ import static com.android.server.appsearch.external.localstorage.FrameworkOptimi import static com.google.common.truth.Truth.assertThat; -import com.android.server.appsearch.proto.GetOptimizeInfoResultProto; -import com.android.server.appsearch.proto.StatusProto; +import com.android.server.appsearch.icing.proto.GetOptimizeInfoResultProto; +import com.android.server.appsearch.icing.proto.StatusProto; import org.junit.Test; diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java index ada49ff4b97a..204fc54fab5b 100644 --- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java +++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java @@ -20,10 +20,10 @@ import static com.google.common.truth.Truth.assertThat; import android.app.appsearch.GenericDocument; -import com.android.server.appsearch.proto.DocumentProto; -import com.android.server.appsearch.proto.PropertyConfigProto; -import com.android.server.appsearch.proto.PropertyProto; -import com.android.server.appsearch.proto.SchemaTypeConfigProto; +import com.android.server.appsearch.icing.proto.DocumentProto; +import com.android.server.appsearch.icing.proto.PropertyConfigProto; +import com.android.server.appsearch.icing.proto.PropertyProto; +import com.android.server.appsearch.icing.proto.SchemaTypeConfigProto; import com.android.server.appsearch.protobuf.ByteString; import com.google.common.collect.ImmutableMap; diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java index 77e01350cc4d..ebceba4ffa71 100644 --- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java +++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java @@ -20,10 +20,10 @@ import static com.google.common.truth.Truth.assertThat; import android.app.appsearch.AppSearchSchema; -import com.android.server.appsearch.proto.PropertyConfigProto; -import com.android.server.appsearch.proto.SchemaTypeConfigProto; -import com.android.server.appsearch.proto.StringIndexingConfig; -import com.android.server.appsearch.proto.TermMatchType; +import com.android.server.appsearch.icing.proto.PropertyConfigProto; +import com.android.server.appsearch.icing.proto.SchemaTypeConfigProto; +import com.android.server.appsearch.icing.proto.StringIndexingConfig; +import com.android.server.appsearch.icing.proto.TermMatchType; import org.junit.Test; diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java index 64a670dcdb38..992961c0c23a 100644 --- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java +++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java @@ -22,12 +22,12 @@ import android.app.appsearch.SearchResult; import android.app.appsearch.SearchResultPage; import com.android.server.appsearch.external.localstorage.util.PrefixUtil; -import com.android.server.appsearch.proto.DocumentProto; -import com.android.server.appsearch.proto.PropertyProto; -import com.android.server.appsearch.proto.SchemaTypeConfigProto; -import com.android.server.appsearch.proto.SearchResultProto; -import com.android.server.appsearch.proto.SnippetMatchProto; -import com.android.server.appsearch.proto.SnippetProto; +import com.android.server.appsearch.icing.proto.DocumentProto; +import com.android.server.appsearch.icing.proto.PropertyProto; +import com.android.server.appsearch.icing.proto.SchemaTypeConfigProto; +import com.android.server.appsearch.icing.proto.SearchResultProto; +import com.android.server.appsearch.icing.proto.SnippetMatchProto; +import com.android.server.appsearch.icing.proto.SnippetProto; import org.junit.Test; diff --git a/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java b/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java index 7c275e13e24a..ec96d6a71be4 100644 --- a/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java +++ b/services/tests/servicestests/src/com/android/server/appsearch/stats/PlatformLoggerTest.java @@ -65,13 +65,8 @@ public class PlatformLoggerTest { Context context = ApplicationProvider.getApplicationContext(); mContext = new ContextWrapper(context) { @Override - public Context createContextAsUser(UserHandle user, int flags) { - return new ContextWrapper(super.createContextAsUser(user, flags)) { - @Override - public PackageManager getPackageManager() { - return getMockPackageManager(user); - } - }; + public PackageManager getPackageManager() { + return getMockPackageManager(mContext.getUser()); } }; } @@ -153,7 +148,6 @@ public class PlatformLoggerTest { final int testUid = 1234; PlatformLogger logger = new PlatformLogger( mContext, - mContext.getUser(), AppSearchConfig.create(DIRECT_EXECUTOR)); PackageManager mockPackageManager = getMockPackageManager(mContext.getUser()); when(mockPackageManager.getPackageUid(testPackageName, /*flags=*/0)).thenReturn(testUid); diff --git a/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java b/services/tests/servicestests/src/com/android/server/appsearch/visibilitystore/VisibilityStoreImplTest.java index 183cb8603c33..07a728bac2a5 100644 --- a/services/tests/servicestests/src/com/android/server/appsearch/VisibilityStoreTest.java +++ b/services/tests/servicestests/src/com/android/server/appsearch/visibilitystore/VisibilityStoreImplTest.java @@ -14,10 +14,7 @@ * limitations under the License. */ -// TODO(b/169883602): This is purposely a different package from the path so that it can access -// AppSearchImpl methods without having to make methods public. This should be moved into a proper -// package once AppSearchImpl-VisibilityStore's dependencies are refactored. -package com.android.server.appsearch.external.localstorage; +package com.android.server.appsearch.visibilitystore; import static android.Manifest.permission.READ_GLOBAL_APP_SEARCH_DATA; import static android.content.pm.PackageManager.PERMISSION_DENIED; @@ -39,8 +36,10 @@ import android.util.ArrayMap; import androidx.test.core.app.ApplicationProvider; +import com.android.server.appsearch.external.localstorage.AppSearchImpl; +import com.android.server.appsearch.external.localstorage.OptimizeStrategy; import com.android.server.appsearch.external.localstorage.util.PrefixUtil; -import com.android.server.appsearch.visibilitystore.VisibilityStore; +import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -55,7 +54,7 @@ import org.mockito.Mockito; import java.util.Collections; import java.util.Map; -public class VisibilityStoreTest { +public class VisibilityStoreImplTest { /** * Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class. */ @@ -64,7 +63,7 @@ public class VisibilityStoreTest { @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder(); private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>(); private Context mContext; - private VisibilityStore mVisibilityStore; + private VisibilityStoreImpl mVisibilityStore; private int mUid; @Before @@ -90,7 +89,7 @@ public class VisibilityStoreTest { // Give ourselves global query permissions AppSearchImpl appSearchImpl = AppSearchImpl.create( mTemporaryFolder.newFolder(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE); - mVisibilityStore = VisibilityStore.create(appSearchImpl, mContext); + mVisibilityStore = VisibilityStoreImpl.create(appSearchImpl, mContext); mUid = mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0); } diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java index 9937ec13bd7d..7ff253f3936e 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java @@ -19,6 +19,7 @@ package com.android.server.biometrics.sensors; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -57,12 +58,16 @@ public class UserAwareBiometricSchedulerTest { private TestUserStartedCallback mUserStartedCallback; private TestUserStoppedCallback mUserStoppedCallback; private int mCurrentUserId = UserHandle.USER_NULL; + private boolean mStartOperationsFinish; + private int mStartUserClientCount; @Before public void setUp() { MockitoAnnotations.initMocks(this); mToken = new Binder(); + mStartOperationsFinish = true; + mStartUserClientCount = 0; mUserStartedCallback = new TestUserStartedCallback(); mUserStoppedCallback = new TestUserStoppedCallback(); @@ -81,8 +86,9 @@ public class UserAwareBiometricSchedulerTest { @NonNull @Override public StartUserClient<?, ?> getStartUserClient(int newUserId) { + mStartUserClientCount++; return new TestStartUserClient(mContext, Object::new, mToken, newUserId, - TEST_SENSOR_ID, mUserStartedCallback); + TEST_SENSOR_ID, mUserStartedCallback, mStartOperationsFinish); } }); } @@ -91,21 +97,42 @@ public class UserAwareBiometricSchedulerTest { public void testScheduleOperation_whenNoUser() { mCurrentUserId = UserHandle.USER_NULL; - final int nextUserId = 0; - - BaseClientMonitor nextClient = mock(BaseClientMonitor.class); - when(nextClient.getTargetUserId()).thenReturn(nextUserId); + final BaseClientMonitor nextClient = mock(BaseClientMonitor.class); + when(nextClient.getTargetUserId()).thenReturn(0); mScheduler.scheduleClientMonitor(nextClient); + waitForIdle(); assertEquals(0, mUserStoppedCallback.numInvocations); assertEquals(1, mUserStartedCallback.numInvocations); - - waitForIdle(); verify(nextClient).start(any()); } @Test + public void testScheduleOperation_whenNoUser_notStarted() { + mCurrentUserId = UserHandle.USER_NULL; + mStartOperationsFinish = false; + + final BaseClientMonitor[] nextClients = new BaseClientMonitor[] { + mock(BaseClientMonitor.class), + mock(BaseClientMonitor.class), + mock(BaseClientMonitor.class) + }; + for (BaseClientMonitor client : nextClients) { + when(client.getTargetUserId()).thenReturn(5); + mScheduler.scheduleClientMonitor(client); + waitForIdle(); + } + + assertEquals(0, mUserStoppedCallback.numInvocations); + assertEquals(0, mUserStartedCallback.numInvocations); + assertEquals(1, mStartUserClientCount); + for (BaseClientMonitor client : nextClients) { + verify(client, never()).start(any()); + } + } + + @Test public void testScheduleOperation_whenSameUser() { mCurrentUserId = 10; @@ -192,10 +219,13 @@ public class UserAwareBiometricSchedulerTest { } private static class TestStartUserClient extends StartUserClient<Object, Object> { + private final boolean mShouldFinish; + public TestStartUserClient(@NonNull Context context, @NonNull LazyDaemon<Object> lazyDaemon, @Nullable IBinder token, int userId, - int sensorId, @NonNull UserStartedCallback<Object> callback) { + int sensorId, @NonNull UserStartedCallback<Object> callback, boolean shouldFinish) { super(context, lazyDaemon, token, userId, sensorId, callback); + mShouldFinish = shouldFinish; } @Override @@ -206,8 +236,10 @@ public class UserAwareBiometricSchedulerTest { @Override public void start(@NonNull Callback callback) { super.start(callback); - mUserStartedCallback.onUserStarted(getTargetUserId(), new Object()); - callback.onClientFinished(this, true /* success */); + if (mShouldFinish) { + mUserStartedCallback.onUserStarted(getTargetUserId(), new Object()); + callback.onClientFinished(this, true /* success */); + } } @Override diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java index 68803023c451..6502e4813171 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java @@ -32,9 +32,15 @@ import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + import android.content.Context; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiPortInfo; +import android.media.AudioManager; import android.os.test.TestLooper; import android.platform.test.annotations.Presubmit; @@ -45,6 +51,8 @@ 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; import java.util.Arrays; @@ -123,8 +131,12 @@ public class HdmiCecLocalDeviceTest { private boolean isControlEnabled; private int mPowerStatus; + @Mock + private AudioManager mAudioManager; + @Before public void SetUp() { + MockitoAnnotations.initMocks(this); Context context = InstrumentationRegistry.getTargetContext(); @@ -161,6 +173,11 @@ public class HdmiCecLocalDeviceTest { void wakeUp() { mWakeupMessageReceived = true; } + + @Override + AudioManager getAudioManager() { + return mAudioManager; + } }; mHdmiControlService.setIoLooper(mTestLooper.getLooper()); mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context)); @@ -419,6 +436,28 @@ public class HdmiCecLocalDeviceTest { } @Test + public void handleUserControlPressed_muteFunction() { + @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed( + HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1, + HdmiCecKeycode.CEC_KEYCODE_MUTE_FUNCTION)); + + assertEquals(result, Constants.HANDLED); + verify(mAudioManager, times(1)) + .adjustStreamVolume(anyInt(), eq(AudioManager.ADJUST_MUTE), anyInt()); + } + + @Test + public void handleUserControlPressed_restoreVolumeFunction() { + @Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed( + HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1, + HdmiCecKeycode.CEC_KEYCODE_RESTORE_VOLUME_FUNCTION)); + + assertEquals(result, Constants.HANDLED); + verify(mAudioManager, times(1)) + .adjustStreamVolume(anyInt(), eq(AudioManager.ADJUST_UNMUTE), anyInt()); + } + + @Test public void handleVendorCommand_notHandled() { HdmiCecMessage vendorCommand = HdmiCecMessageBuilder.buildVendorCommand(ADDR_TV, ADDR_PLAYBACK_1, new byte[]{0}); diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java index 23517a9b0458..70641c2938a7 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java @@ -162,13 +162,13 @@ import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.internal.util.test.BroadcastInterceptingContext.FutureIntent; +import com.android.internal.util.test.FsUtil; import com.android.server.DeviceIdleInternal; import com.android.server.LocalServices; import com.android.server.usage.AppStandbyInternal; import com.google.common.util.concurrent.AbstractFuture; -import libcore.io.IoUtils; import libcore.io.Streams; import org.junit.After; @@ -2385,7 +2385,7 @@ public class NetworkPolicyManagerServiceTest { private void setNetpolicyXml(Context context) throws Exception { mPolicyDir = context.getFilesDir(); if (mPolicyDir.exists()) { - IoUtils.deleteContents(mPolicyDir); + FsUtil.deleteContents(mPolicyDir); } if (!TextUtils.isEmpty(mNetpolicyXml)) { final String assetPath = NETPOLICY_DIR + "/" + mNetpolicyXml; diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java index 019254d542b2..c572dd65245f 100644 --- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java @@ -785,7 +785,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } @Override - public void getNextPage(long nextPageToken, UserHandle userHandle, + public void getNextPage(String packageName, long nextPageToken, UserHandle userHandle, IAppSearchResultCallback callback) throws RemoteException { final Bundle page = new Bundle(); page.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, 1); @@ -795,8 +795,8 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } @Override - public void invalidateNextPageToken(long nextPageToken, UserHandle userHandle) - throws RemoteException { + public void invalidateNextPageToken(String packageName, long nextPageToken, + UserHandle userHandle) throws RemoteException { } @Override @@ -875,13 +875,13 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } @Override - public void persistToDisk(UserHandle userHandle, long binderCallStartTimeMillis) - throws RemoteException { + public void persistToDisk(String packageName, UserHandle userHandle, + long binderCallStartTimeMillis) throws RemoteException { } @Override - public void initialize(UserHandle userHandle, long binderCallStartTimeMillis, - IAppSearchResultCallback callback) + public void initialize(String packageName, UserHandle userHandle, + long binderCallStartTimeMillis, IAppSearchResultCallback callback) throws RemoteException { ignore(callback); } diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java index f880563e2880..9044b27d4994 100644 --- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java +++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java @@ -222,61 +222,61 @@ public class SystemConfigTest { } /** - * Tests that readPermissions works correctly with {@link SystemConfig#ALLOW_APP_CONFIGS} - * permission flag for the tag: {@code allowed-partner-apex}. + * Tests that readPermissions works correctly with {@link SystemConfig#ALLOW_VENDOR_APEX} + * permission flag for the tag: {@code allowed-vendor-apex}. */ @Test - public void readPermissions_allowAppConfigs_parsesPartnerApexAllowList() + public void readPermissions_allowVendorApex_parsesVendorApexAllowList() throws IOException { final String contents = "<config>\n" - + " <allowed-partner-apex package=\"com.android.apex1\" />\n" + + " <allowed-vendor-apex package=\"com.android.apex1\" />\n" + "</config>"; final File folder = createTempSubfolder("folder"); - createTempFile(folder, "partner-apex-allowlist.xml", contents); + createTempFile(folder, "vendor-apex-allowlist.xml", contents); mSysConfig.readPermissions(folder, /* Grant all permission flags */ ~0); - assertThat(mSysConfig.getAllowedPartnerApexes()).containsExactly("com.android.apex1"); + assertThat(mSysConfig.getAllowedVendorApexes()).containsExactly("com.android.apex1"); } /** - * Tests that readPermissions works correctly with {@link SystemConfig#ALLOW_APP_CONFIGS} - * permission flag for the tag: {@code allowed-partner-apex}. + * Tests that readPermissions works correctly with {@link SystemConfig#ALLOW_VENDOR_APEX} + * permission flag for the tag: {@code allowed-vendor-apex}. */ @Test - public void readPermissions_allowAppConfigs_parsesPartnerApexAllowList_noPackage() + public void readPermissions_allowVendorApex_parsesVendorApexAllowList_noPackage() throws IOException { final String contents = "<config>\n" - + " <allowed-partner-apex/>\n" + + " <allowed-vendor-apex/>\n" + "</config>"; final File folder = createTempSubfolder("folder"); - createTempFile(folder, "partner-apex-allowlist.xml", contents); + createTempFile(folder, "vendor-apex-allowlist.xml", contents); mSysConfig.readPermissions(folder, /* Grant all permission flags */ ~0); - assertThat(mSysConfig.getAllowedPartnerApexes()).isEmpty(); + assertThat(mSysConfig.getAllowedVendorApexes()).isEmpty(); } /** - * Tests that readPermissions works correctly without {@link SystemConfig#ALLOW_APP_CONFIGS} - * permission flag for the tag: {@code allowed-partner-apex}. + * Tests that readPermissions works correctly without {@link SystemConfig#ALLOW_VENDOR_APEX} + * permission flag for the tag: {@code allowed-oem-apex}. */ @Test - public void readPermissions_notAllowAppConfigs_doesNotParsePartnerApexAllowList() + public void readPermissions_notAllowVendorApex_doesNotParseVendorApexAllowList() throws IOException { final String contents = "<config>\n" - + " <allowed-partner-apex package=\"com.android.apex1\" />\n" + + " <allowed-vendor-apex package=\"com.android.apex1\" />\n" + "</config>"; final File folder = createTempSubfolder("folder"); - createTempFile(folder, "partner-apex-allowlist.xml", contents); + createTempFile(folder, "vendor-apex-allowlist.xml", contents); - mSysConfig.readPermissions(folder, /* Grant all but ALLOW_APP_CONFIGS flag */ ~0x08); + mSysConfig.readPermissions(folder, /* Grant all but ALLOW_VENDOR_APEX flag */ ~0x400); - assertThat(mSysConfig.getAllowedPartnerApexes()).isEmpty(); + assertThat(mSysConfig.getAllowedVendorApexes()).isEmpty(); } /** diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java index 4c157c0e0a73..645fa630f0db 100644 --- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java @@ -114,6 +114,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Random; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -166,6 +167,8 @@ public class AppStandbyControllerTests { /** Mock variable used in {@link MyInjector#isPackageInstalled(String, int, int)} */ private static boolean isPackageInstalled = true; + private static final Random sRandom = new Random(); + private MyInjector mInjector; private AppStandbyController mController; @@ -294,7 +297,7 @@ public class AppStandbyControllerTests { @Override File getDataSystemDirectory() { - return new File(getContext().getFilesDir(), Long.toString(Math.randomLongInternal())); + return new File(getContext().getFilesDir(), Long.toString(sRandom.nextLong())); } @Override diff --git a/services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java b/services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java index f4eb2ded5a9d..32988efbab2c 100644 --- a/services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java +++ b/services/tests/servicestests/src/com/android/server/vibrator/StepToRampAdapterTest.java @@ -68,6 +68,38 @@ public class StepToRampAdapterTest { } @Test + public void testRampSegments_withPwleDurationLimit_splitsLongRamps() { + List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( + new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f, + /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10), + new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 1, + /* startFrequency= */ 0, /* endFrequency= */ -1, /* duration= */ 25), + new RampSegment(/* startAmplitude= */ 1, /* endAmplitude*/ 1, + /* startFrequency= */ 0, /* endFrequency= */ 1, /* duration= */ 5))); + List<VibrationEffectSegment> expectedSegments = Arrays.asList( + new RampSegment(/* startAmplitude= */ 0.5f, /* endAmplitude*/ 0.5f, + /* startFrequency= */ -1, /* endFrequency= */ -1, /* duration= */ 10), + new RampSegment(/* startAmplitude= */ 0, /* endAmplitude= */ 0.32f, + /* startFrequency= */ 0, /* endFrequency= */ -0.32f, /* duration= */ 8), + new RampSegment(/* startAmplitude= */ 0.32f, /* endAmplitude= */ 0.64f, + /* startFrequency= */ -0.32f, /* endFrequency= */ -0.64f, + /* duration= */ 8), + new RampSegment(/* startAmplitude= */ 0.64f, /* endAmplitude= */ 1, + /* startFrequency= */ -0.64f, /* endFrequency= */ -1, /* duration= */ 9), + new RampSegment(/* startAmplitude= */ 1, /* endAmplitude*/ 1, + /* startFrequency= */ 0, /* endFrequency= */ 1, /* duration= */ 5)); + + VibratorInfo vibratorInfo = new VibratorInfo.Builder(0) + .setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS) + .setPwlePrimitiveDurationMax(10) + .build(); + + // Update repeat index to skip the ramp splits. + assertEquals(4, mAdapter.apply(segments, 2, vibratorInfo)); + assertEquals(expectedSegments, segments); + } + + @Test public void testStepAndRampSegments_withoutPwleCapability_keepsListUnchanged() { mAdapter = new StepToRampAdapter(50); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index a522b5c6161e..3c6f62a0a42d 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -94,6 +94,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import android.app.ActivityManager; @@ -232,6 +233,7 @@ import java.util.function.Consumer; @RunWithLooper public class NotificationManagerServiceTest extends UiServiceTestCase { private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId"; + private static final int UID_HEADLESS = 1000000; private final int mUid = Binder.getCallingUid(); private TestableNotificationManagerService mService; @@ -2425,6 +2427,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(), eq(mTestNotificationChannel.getId()), anyBoolean())) .thenReturn(mTestNotificationChannel); + when(mPreferencesHelper.deleteNotificationChannel(eq(PKG), anyInt(), + eq(mTestNotificationChannel.getId()))).thenReturn(true); reset(mListeners); mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId()); verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG), @@ -2433,6 +2437,22 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testDeleteChannelOnlyDoExtraWorkIfExisted() throws Exception { + List<String> associations = new ArrayList<>(); + associations.add("a"); + when(mCompanionMgr.getAssociations(PKG, UserHandle.getUserId(mUid))) + .thenReturn(associations); + mService.setPreferencesHelper(mPreferencesHelper); + when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(), + eq(mTestNotificationChannel.getId()), anyBoolean())) + .thenReturn(null); + reset(mListeners); + mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId()); + verifyNoMoreInteractions(mListeners); + verifyNoMoreInteractions(mHistoryManager); + } + + @Test public void testDeleteChannelGroupNotifyListener() throws Exception { List<String> associations = new ArrayList<>(); associations.add("a"); @@ -6739,7 +6759,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testGrantInlineReplyUriPermission_recordExists() throws Exception { - NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel, 0); + int userId = UserManager.isHeadlessSystemUserMode() + ? UserHandle.getUserId(UID_HEADLESS) + : USER_SYSTEM; + + NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel, userId); mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId()); waitForIdle(); @@ -6764,7 +6788,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testGrantInlineReplyUriPermission_noRecordExists() throws Exception { - NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel, 0); + int userId = UserManager.isHeadlessSystemUserMode() + ? UserHandle.getUserId(UID_HEADLESS) + : USER_SYSTEM; + + NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel, userId); waitForIdle(); // No notifications exist for the given record @@ -6808,7 +6836,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // Target user for the grant is USER_ALL instead of USER_SYSTEM verify(mUgm, times(1)).grantUriPermissionFromOwner(any(), eq(nr.getSbn().getUid()), eq(nr.getSbn().getPackageName()), eq(uri), anyInt(), - anyInt(), eq(UserHandle.USER_SYSTEM)); + anyInt(), UserManager.isHeadlessSystemUserMode() + ? eq(UserHandle.getUserId(UID_HEADLESS)) + : eq(USER_SYSTEM)); } @Test @@ -6851,7 +6881,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testClearInlineReplyUriPermission_uriRecordExists() throws Exception { - NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel, 0); + int userId = UserManager.isHeadlessSystemUserMode() + ? UserHandle.getUserId(UID_HEADLESS) + : USER_SYSTEM; + + NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel, userId); reset(mPackageManager); Uri uri1 = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 1); @@ -6913,7 +6947,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // permissionOwner destroyed for USER_SYSTEM, not USER_ALL verify(mUgmInternal, times(1)).revokeUriPermissionFromOwner( - eq(record.getPermissionOwner()), eq(null), eq(~0), eq(USER_SYSTEM)); + eq(record.getPermissionOwner()), eq(null), eq(~0), + UserManager.isHeadlessSystemUserMode() + ? eq(UserHandle.getUserId(UID_HEADLESS)) + : eq(USER_SYSTEM)); } @Test @@ -7406,6 +7443,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void createConversationNotificationChannel() throws Exception { + int userId = UserManager.isHeadlessSystemUserMode() + ? UserHandle.getUserId(UID_HEADLESS) + : USER_SYSTEM; + NotificationChannel original = new NotificationChannel("a", "a", IMPORTANCE_HIGH); original.setAllowBubbles(!original.canBubble()); original.setShowBadge(!original.canShowBadge()); @@ -7424,7 +7465,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { PKG, mUid, orig, "friend"); NotificationChannel friendChannel = mBinderService.getConversationNotificationChannel( - PKG, 0, PKG, original.getId(), false, "friend"); + PKG, userId, PKG, original.getId(), false, "friend"); assertEquals(original.getName(), friendChannel.getName()); assertEquals(original.getId(), friendChannel.getParentChannelId()); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index 3a51ff2fb5fa..bf0ed713e4c3 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -90,7 +90,7 @@ import android.os.Bundle; import android.os.RemoteCallback; import android.os.RemoteException; import android.os.UserHandle; -import android.provider.Settings; +import android.os.UserManager; import android.provider.Settings.Global; import android.provider.Settings.Secure; import android.service.notification.ConversationChannelWrapper; @@ -137,6 +137,7 @@ import java.util.concurrent.ThreadLocalRandom; @RunWith(AndroidJUnit4.class) public class PreferencesHelperTest extends UiServiceTestCase { private static final int UID_N_MR1 = 0; + private static final int UID_HEADLESS = 1000000; private static final UserHandle USER = UserHandle.of(0); private static final int UID_O = 1111; private static final int UID_P = 2222; @@ -1495,11 +1496,13 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testCreateAndDeleteCanChannelsBypassDnd() throws Exception { + int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1; + // create notification channel that can't bypass dnd // expected result: areChannelsBypassingDnd = false // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW); - mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false); + mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false); assertFalse(mHelper.areChannelsBypassingDnd()); verify(mMockZenModeHelper, never()).setNotificationPolicy(any()); resetZenModeHelper(); @@ -1508,18 +1511,18 @@ public class PreferencesHelperTest extends UiServiceTestCase { // expected result: areChannelsBypassingDnd = true NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW); channel2.setBypassDnd(true); - mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, true); + mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true); assertTrue(mHelper.areChannelsBypassingDnd()); verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any()); resetZenModeHelper(); // delete channels - mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId()); + mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel.getId()); assertTrue(mHelper.areChannelsBypassingDnd()); // channel2 can still bypass DND verify(mMockZenModeHelper, never()).setNotificationPolicy(any()); resetZenModeHelper(); - mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId()); + mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel2.getId()); assertFalse(mHelper.areChannelsBypassingDnd()); verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any()); resetZenModeHelper(); @@ -1527,11 +1530,13 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testUpdateCanChannelsBypassDnd() throws Exception { + int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1; + // create notification channel that can't bypass dnd // expected result: areChannelsBypassingDnd = false // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW); - mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false); + mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false); assertFalse(mHelper.areChannelsBypassingDnd()); verify(mMockZenModeHelper, never()).setNotificationPolicy(any()); resetZenModeHelper(); @@ -1539,7 +1544,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { // update channel so it CAN bypass dnd: // expected result: areChannelsBypassingDnd = true channel.setBypassDnd(true); - mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true); + mHelper.updateNotificationChannel(PKG_N_MR1, uid, channel, true); assertTrue(mHelper.areChannelsBypassingDnd()); verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any()); resetZenModeHelper(); @@ -1547,7 +1552,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { // update channel so it can't bypass dnd: // expected result: areChannelsBypassingDnd = false channel.setBypassDnd(false); - mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true); + mHelper.updateNotificationChannel(PKG_N_MR1, uid, channel, true); assertFalse(mHelper.areChannelsBypassingDnd()); verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any()); resetZenModeHelper(); @@ -3333,6 +3338,17 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test + public void testDeleted_twice() throws Exception { + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager, mStatsEventBuilderFactory); + + mHelper.createNotificationChannel( + PKG_P, UID_P, createNotificationChannel("id", "id", 2), true, false); + assertTrue(mHelper.deleteNotificationChannel(PKG_P, UID_P, "id")); + assertFalse(mHelper.deleteNotificationChannel(PKG_P, UID_P, "id")); + } + + @Test public void testDeleted_recentTime() throws Exception { mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, mAppOpsManager, mStatsEventBuilderFactory); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java index 38466ebaa0cf..32a4774ca4f2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java @@ -270,9 +270,16 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase { @Test public void testOnReportFullyDrawn() { + // Create an invisible event that should be cancelled after the next event starts. + onActivityLaunched(mTrampolineActivity); + mTrampolineActivity.mVisibleRequested = false; + mActivityOptions = ActivityOptions.makeBasic(); mActivityOptions.setSourceInfo(SourceInfo.TYPE_LAUNCHER, SystemClock.uptimeMillis() - 10); - onActivityLaunched(mTopActivity); + onIntentStarted(mTopActivity.intent); + notifyActivityLaunched(START_SUCCESS, mTopActivity); + verifyAsync(mLaunchObserver).onActivityLaunched(eqProto(mTopActivity), anyInt()); + verifyAsync(mLaunchObserver).onActivityLaunchCancelled(eqProto(mTrampolineActivity)); // The activity reports fully drawn before windows drawn, then the fully drawn event will // be pending (see {@link WindowingModeTransitionInfo#pendingFullyDrawn}). @@ -287,6 +294,10 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase { verifyAsync(mLaunchObserver).onReportFullyDrawn(eqProto(mTopActivity), anyLong()); verifyOnActivityLaunchFinished(mTopActivity); verifyNoMoreInteractions(mLaunchObserver); + + final ActivityMetricsLogger.TransitionInfoSnapshot fullyDrawnInfo = mActivityMetricsLogger + .logAppTransitionReportedDrawn(mTopActivity, false /* restoredFromBundle */); + assertWithMessage("Invisible event must be dropped").that(fullyDrawnInfo).isNull(); } private void onActivityLaunchedTrampoline() { @@ -480,6 +491,7 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase { @Test public void testConsecutiveLaunchWithDifferentWindowingMode() { mTopActivity.setWindowingMode(WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW); + mTrampolineActivity.mVisibleRequested = true; onActivityLaunched(mTrampolineActivity); mActivityMetricsLogger.notifyActivityLaunching(mTopActivity.intent, mTrampolineActivity /* caller */, mTrampolineActivity.getUid()); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java index 2558259370d2..741f33f8aca7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java @@ -18,6 +18,8 @@ package com.android.server.wm; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; +import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; +import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; @@ -407,16 +409,16 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { } @Test - public void testSupportsMultiWindow_activityMinWidthHeight_smallerThanSupport() { + public void testSupportsMultiWindow_landscape_checkActivityMinWidth() { // This is smaller than the min dimensions device support in multi window, // the activity will be supported in multi window final float density = mContext.getResources().getDisplayMetrics().density; - final int supportedDimensions = (int) ((mAtm.mLargeScreenSmallestScreenWidthDp - 1) + final int supportedWidth = (int) (mAtm.mLargeScreenSmallestScreenWidthDp * mAtm.mMinPercentageMultiWindowSupportWidth * density); final ActivityInfo.WindowLayout windowLayout = new ActivityInfo.WindowLayout(0, 0, 0, 0, 0, - /* minWidth= */supportedDimensions, - /* minHeight= */supportedDimensions); + /* minWidth= */ supportedWidth, + /* minHeight= */ 0); final ActivityRecord activity = new ActivityBuilder(mAtm) .setCreateTask(true) .setWindowLayout(windowLayout) @@ -425,15 +427,48 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { final Task task = activity.getTask(); final TaskDisplayArea tda = task.getDisplayArea(); tda.getConfiguration().smallestScreenWidthDp = mAtm.mLargeScreenSmallestScreenWidthDp - 1; + tda.getConfiguration().screenWidthDp = mAtm.mLargeScreenSmallestScreenWidthDp - 1; + tda.getConfiguration().orientation = ORIENTATION_LANDSCAPE; - // Always check the activity min width/height. - mAtm.mSupportsNonResizableMultiWindow = 1; + assertFalse(activity.supportsMultiWindow()); + assertFalse(task.supportsMultiWindow()); + + tda.getConfiguration().screenWidthDp = (int) Math.ceil( + mAtm.mLargeScreenSmallestScreenWidthDp + / mAtm.mMinPercentageMultiWindowSupportWidth); assertTrue(activity.supportsMultiWindow()); assertTrue(task.supportsMultiWindow()); + } - // The default config is relying on the screen size. Check for small screen - mAtm.mSupportsNonResizableMultiWindow = 0; + @Test + public void testSupportsMultiWindow_portrait_checkActivityMinHeight() { + // This is smaller than the min dimensions device support in multi window, + // the activity will be supported in multi window + final float density = mContext.getResources().getDisplayMetrics().density; + final int supportedHeight = (int) (mAtm.mLargeScreenSmallestScreenWidthDp + * mAtm.mMinPercentageMultiWindowSupportHeight * density); + final ActivityInfo.WindowLayout windowLayout = + new ActivityInfo.WindowLayout(0, 0, 0, 0, 0, + /* minWidth= */ 0, + /* minHeight= */ supportedHeight); + final ActivityRecord activity = new ActivityBuilder(mAtm) + .setCreateTask(true) + .setWindowLayout(windowLayout) + .setResizeMode(RESIZE_MODE_RESIZEABLE) + .build(); + final Task task = activity.getTask(); + final TaskDisplayArea tda = task.getDisplayArea(); + tda.getConfiguration().smallestScreenWidthDp = mAtm.mLargeScreenSmallestScreenWidthDp - 1; + tda.getConfiguration().screenHeightDp = mAtm.mLargeScreenSmallestScreenWidthDp - 1; + tda.getConfiguration().orientation = ORIENTATION_PORTRAIT; + + assertFalse(activity.supportsMultiWindow()); + assertFalse(task.supportsMultiWindow()); + + tda.getConfiguration().screenHeightDp = (int) Math.ceil( + mAtm.mLargeScreenSmallestScreenWidthDp + / mAtm.mMinPercentageMultiWindowSupportHeight); assertTrue(activity.supportsMultiWindow()); assertTrue(task.supportsMultiWindow()); diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java index 39a59c9e5064..03944172db7c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java @@ -255,7 +255,6 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { mController.setDeferredCancel(true /* deferred */, false /* screenshot */); mController.cancelAnimationWithScreenshot(false /* screenshot */); verify(mMockRunner).onAnimationCanceled(null /* taskSnapshot */); - assertNull(mController.mRecentScreenshotAnimator); // Simulate the app transition finishing mController.mAppTransitionListener.onAppTransitionStartingLocked(false, 0, 0, 0); @@ -271,7 +270,8 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { assertEquals(activity.getTask().getTopVisibleActivity(), activity); assertEquals(activity.findMainWindow(), win1); - mController.addAnimation(activity.getTask(), false /* isRecentTaskInvisible */); + RecentsAnimationController.TaskAnimationAdapter adapter = mController.addAnimation( + activity.getTask(), false /* isRecentTaskInvisible */); assertTrue(mController.isAnimatingTask(activity.getTask())); spyOn(mWm.mTaskSnapshotController); @@ -282,14 +282,9 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { mController.setDeferredCancel(true /* deferred */, true /* screenshot */); mController.cancelAnimationWithScreenshot(true /* screenshot */); verify(mMockRunner).onAnimationCanceled(mMockTaskSnapshot /* taskSnapshot */); - assertNotNull(mController.mRecentScreenshotAnimator); - assertTrue(mController.mRecentScreenshotAnimator.isAnimating()); - - // Assume IRecentsAnimationController#cleanupScreenshot called to finish screenshot - // animation. - spyOn(mController.mRecentScreenshotAnimator.mAnimatable); - mController.mRecentScreenshotAnimator.cancelAnimation(); - verify(mController.mRecentScreenshotAnimator.mAnimatable).onAnimationLeashLost(any()); + + // Continue the animation (simulating a call to cleanupScreenshot()) + mController.continueDeferredCancelAnimation(); verify(mAnimationCallbacks).onAnimationFinished(REORDER_KEEP_IN_PLACE, false); } @@ -655,6 +650,59 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { assertFalse(win1.mHasSurface); } + @Test + public void testCancelForRotation_ReorderToTop() throws Exception { + mWm.setRecentsAnimationController(mController); + final ActivityRecord activity = createActivityRecord(mDefaultDisplay); + final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1"); + activity.addWindow(win1); + + mController.addAnimation(activity.getTask(), false /* isRecentTaskInvisible */); + mController.setWillFinishToHome(true); + mController.cancelAnimationForDisplayChange(); + + verify(mMockRunner).onAnimationCanceled(any()); + verify(mAnimationCallbacks).onAnimationFinished(REORDER_MOVE_TO_TOP, false); + } + + @Test + public void testCancelForRotation_ReorderToOriginalPosition() throws Exception { + mWm.setRecentsAnimationController(mController); + final ActivityRecord activity = createActivityRecord(mDefaultDisplay); + final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1"); + activity.addWindow(win1); + + mController.addAnimation(activity.getTask(), false /* isRecentTaskInvisible */); + mController.setWillFinishToHome(false); + mController.cancelAnimationForDisplayChange(); + + verify(mMockRunner).onAnimationCanceled(any()); + verify(mAnimationCallbacks).onAnimationFinished(REORDER_MOVE_TO_ORIGINAL_POSITION, false); + } + + @Test + public void testCancelForStartHome() throws Exception { + mWm.setRecentsAnimationController(mController); + final ActivityRecord activity = createActivityRecord(mDefaultDisplay); + final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1"); + activity.addWindow(win1); + + RecentsAnimationController.TaskAnimationAdapter adapter = mController.addAnimation( + activity.getTask(), false /* isRecentTaskInvisible */); + mController.setWillFinishToHome(true); + + // Verify cancel is called with a snapshot and that we've created an overlay + spyOn(mWm.mTaskSnapshotController); + doReturn(mMockTaskSnapshot).when(mWm.mTaskSnapshotController).getSnapshot(anyInt(), + anyInt(), eq(false) /* restoreFromDisk */, eq(false) /* isLowResolution */); + mController.cancelAnimationForHomeStart(); + verify(mMockRunner).onAnimationCanceled(any()); + + // Continue the animation (simulating a call to cleanupScreenshot()) + mController.continueDeferredCancelAnimation(); + verify(mAnimationCallbacks).onAnimationFinished(REORDER_MOVE_TO_TOP, false); + } + private ActivityRecord createHomeActivity() { final ActivityRecord homeActivity = new ActivityBuilder(mWm.mAtmService) .setParentTask(mRootHomeTask) diff --git a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java index 20b987de9aa1..e1696924dd3d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java @@ -24,9 +24,11 @@ import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import android.os.Parcel; import android.platform.test.annotations.Presubmit; import android.view.Display.Mode; import android.view.DisplayInfo; +import android.view.WindowManager.LayoutParams; import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; @@ -50,6 +52,16 @@ public class RefreshRatePolicyTest extends WindowTestsBase { private RefreshRatePolicy mPolicy; private HighRefreshRateDenylist mDenylist = mock(HighRefreshRateDenylist.class); + // Parcel and Unparcel the LayoutParams in the window state to test the path the object + // travels from the app's process to system server + void parcelLayoutParams(WindowState window) { + Parcel parcel = Parcel.obtain(); + window.mAttrs.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + window.mAttrs.copyFrom(new LayoutParams(parcel)); + parcel.recycle(); + } + @Before public void setUp() { DisplayInfo di = new DisplayInfo(mDisplayInfo); @@ -69,6 +81,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { final WindowState cameraUsingWindow = createWindow(null, TYPE_BASE_APPLICATION, "cameraUsingWindow"); cameraUsingWindow.mAttrs.packageName = "com.android.test"; + parcelLayoutParams(cameraUsingWindow); assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow)); assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE); assertEquals(0, mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE); @@ -86,6 +99,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { final WindowState denylistedWindow = createWindow(null, TYPE_BASE_APPLICATION, "denylistedWindow"); denylistedWindow.mAttrs.packageName = "com.android.test"; + parcelLayoutParams(denylistedWindow); when(mDenylist.isDenylisted("com.android.test")).thenReturn(true); assertEquals(0, mPolicy.getPreferredModeId(denylistedWindow)); assertEquals(60, mPolicy.getPreferredRefreshRate(denylistedWindow), FLOAT_TOLERANCE); @@ -97,6 +111,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { "overrideWindow"); overrideWindow.mAttrs.packageName = "com.android.test"; overrideWindow.mAttrs.preferredDisplayModeId = LOW_MODE_ID; + parcelLayoutParams(overrideWindow); when(mDenylist.isDenylisted("com.android.test")).thenReturn(true); assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow)); assertEquals(60, mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE); @@ -108,6 +123,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { "overrideWindow"); overrideWindow.mAttrs.packageName = "com.android.test"; overrideWindow.mAttrs.preferredDisplayModeId = LOW_MODE_ID; + parcelLayoutParams(overrideWindow); mPolicy.addNonHighRefreshRatePackage("com.android.test"); assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow)); assertEquals(0, mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE); @@ -120,6 +136,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { "overrideWindow"); overrideWindow.mAttrs.packageName = "com.android.test"; overrideWindow.mAttrs.preferredDisplayModeId = LOW_MODE_ID; + parcelLayoutParams(overrideWindow); overrideWindow.mActivityRecord.mSurfaceAnimator.startAnimation( overrideWindow.getPendingTransaction(), mock(AnimationAdapter.class), false /* hidden */, ANIMATION_TYPE_APP_TRANSITION); @@ -134,6 +151,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { final WindowState cameraUsingWindow = createWindow(null, TYPE_BASE_APPLICATION, "cameraUsingWindow"); cameraUsingWindow.mAttrs.packageName = "com.android.test"; + parcelLayoutParams(cameraUsingWindow); mPolicy.addNonHighRefreshRatePackage("com.android.test"); assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow)); @@ -152,6 +170,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { public void testAppMaxRefreshRate() { final WindowState window = createWindow(null, TYPE_BASE_APPLICATION, "window"); window.mAttrs.preferredMaxDisplayRefreshRate = 60f; + parcelLayoutParams(window); assertEquals(0, mPolicy.getPreferredModeId(window)); assertEquals(0, mPolicy.getPreferredRefreshRate(window), FLOAT_TOLERANCE); assertEquals(60, mPolicy.getPreferredMaxRefreshRate(window), FLOAT_TOLERANCE); diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java index 42ef08630500..a8e17534e6ed 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java @@ -484,7 +484,8 @@ public class SystemServicesTestRule implements TestRule { mSupportsFreeformWindowManagement = true; mSupportsPictureInPicture = true; mDevEnableNonResizableMultiWindow = false; - mMinPercentageMultiWindowSupportWidth = 0.3f; + mMinPercentageMultiWindowSupportHeight = 0.3f; + mMinPercentageMultiWindowSupportWidth = 0.5f; mLargeScreenSmallestScreenWidthDp = 600; mSupportsNonResizableMultiWindow = 0; mRespectsActivityMinWidthHeightMultiWindow = 0; diff --git a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java index 16a2d8d88e39..6606fb0f482c 100644 --- a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java +++ b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java @@ -182,15 +182,28 @@ final class TranslationManagerServiceImpl extends + "translation state for token=" + token + " taskId=" + taskId); return; } + int translationActivityUid = -1; try { + IBinder activityToken = taskTopActivityTokens.getActivityToken(); taskTopActivityTokens.getApplicationThread().updateUiTranslationState( - taskTopActivityTokens.getActivityToken(), state, sourceSpec, targetSpec, + activityToken, state, sourceSpec, targetSpec, viewIds, uiTranslationSpec); mLastActivityTokens = new WeakReference<>(taskTopActivityTokens); + ComponentName componentName = + mActivityTaskManagerInternal.getActivityName(activityToken); + try { + if (componentName != null) { + translationActivityUid = + getContext().getPackageManager().getApplicationInfoAsUser( + componentName.getPackageName(), 0, getUserId()).uid; + } + } catch (PackageManager.NameNotFoundException e) { + Slog.d(TAG, "Cannot find package for" + componentName); + } } catch (RemoteException e) { Slog.w(TAG, "Update UiTranslationState fail: " + e); } - invokeCallbacks(state, sourceSpec, targetSpec); + invokeCallbacks(state, sourceSpec, targetSpec, translationActivityUid); } @GuardedBy("mLock") @@ -216,7 +229,8 @@ final class TranslationManagerServiceImpl extends } private void invokeCallbacks( - int state, TranslationSpec sourceSpec, TranslationSpec targetSpec) { + int state, TranslationSpec sourceSpec, TranslationSpec targetSpec, + int translationActivityUid) { Bundle res = new Bundle(); res.putInt(EXTRA_STATE, state); // TODO(177500482): Store the locale pair so it can be sent for RESUME events. @@ -229,6 +243,14 @@ final class TranslationManagerServiceImpl extends LocalServices.getService(InputMethodManagerInternal.class) .getEnabledInputMethodListAsUser(mUserId); mCallbacks.broadcast((callback, uid) -> { + // callback to the application that is translated if registered. + if ((int) uid == translationActivityUid) { + try { + callback.sendResult(res); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to invoke UiTranslationStateCallback: " + e); + } + } // Code here is non-optimal since it's temporary.. boolean isIme = false; for (InputMethodInfo inputMethod : enabledInputMethods) { diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 128602d5acbd..1b8492722c10 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -2226,7 +2226,14 @@ public class UsageStatsService extends SystemService implements } @Override - public long getLastTimeAnyComponentUsed(String packageName) { + public long getLastTimeAnyComponentUsed(String packageName, String callingPackage) { + if (!hasPermissions( + callingPackage, android.Manifest.permission.INTERACT_ACROSS_USERS)) { + throw new SecurityException("Caller doesn't have INTERACT_ACROSS_USERS permission"); + } + if (!hasPermission(callingPackage)) { + throw new SecurityException("Don't have permission to query usage stats"); + } synchronized (mLock) { // Truncate the returned milliseconds to the boundary of the last day before exact // time for privacy reasons. diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java index eac21b492f10..5183e5b8e246 100644 --- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java +++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java @@ -863,7 +863,12 @@ public class SoundTriggerService extends SystemService { } private void enforceCallingPermission(String permission) { - PermissionUtil.checkPermissionForPreflight(mContext, mOriginatorIdentity, permission); + if (PermissionUtil.checkPermissionForPreflight(mContext, mOriginatorIdentity, + permission) != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException( + "Identity " + mOriginatorIdentity + " does not have permission " + + permission); + } } private void enforceDetectionPermissions(ComponentName detectionService) { diff --git a/telephony/java/android/telephony/data/QosBearerFilter.java b/telephony/java/android/telephony/data/QosBearerFilter.java index 5642549d7313..54930d0266b7 100644 --- a/telephony/java/android/telephony/data/QosBearerFilter.java +++ b/telephony/java/android/telephony/data/QosBearerFilter.java @@ -57,6 +57,12 @@ public final class QosBearerFilter implements Parcelable { public static final int QOS_PROTOCOL_UDP = android.hardware.radio.V1_6.QosProtocol.UDP; public static final int QOS_PROTOCOL_ESP = android.hardware.radio.V1_6.QosProtocol.ESP; public static final int QOS_PROTOCOL_AH = android.hardware.radio.V1_6.QosProtocol.AH; + public static final int QOS_MIN_PORT = android.hardware.radio.V1_6.QosPortRange.MIN; + /** + * Hardcoded inplace of android.hardware.radio.V1_6.QosPortRange.MAX as it + * returns -1 due to uint16_t to int conversion in java. (TODO: Fix the HAL) + */ + public static final int QOS_MAX_PORT = 65535; // android.hardware.radio.V1_6.QosPortRange.MIN; @QosProtocol private int protocol; @@ -229,6 +235,12 @@ public final class QosBearerFilter implements Parcelable { return end; } + public boolean isValid() { + return start >= QOS_MIN_PORT && start <= QOS_MAX_PORT + && end >= QOS_MIN_PORT && end <= QOS_MAX_PORT + && start <= end; + } + @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(start); diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java index 530003d6350a..91121187a19a 100644 --- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java +++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java @@ -331,7 +331,7 @@ public final class RcsContactUceCapability implements Parcelable { return null; } for (RcsContactPresenceTuple tuple : mPresenceTuples) { - if (tuple.getServiceId().equals(serviceId)) { + if (tuple.getServiceId() != null && tuple.getServiceId().equals(serviceId)) { return tuple; } } diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp index c679d0487629..c563e06ab528 100644 --- a/tests/StagedInstallTest/Android.bp +++ b/tests/StagedInstallTest/Android.bp @@ -52,6 +52,7 @@ java_test_host { data: [ ":com.android.apex.apkrollback.test_v1", ":com.android.apex.cts.shim.v2_prebuilt", + ":StagedInstallTestApexV2_WrongSha", ":TestAppAv1", ], test_suites: ["general-tests"], diff --git a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java index e633c87d7fbb..6a62304f9af7 100644 --- a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java +++ b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java @@ -179,6 +179,26 @@ public class StagedInstallInternalTest { assertThat(info.isStagedSessionFailed()).isTrue(); } + @Test + public void testApexActivationFailureIsCapturedInSession_Commit() throws Exception { + int sessionId = Install.single(TestApp.Apex1).setStaged().commit(); + assertSessionReady(sessionId); + storeSessionId(sessionId); + } + + @Test + public void testApexActivationFailureIsCapturedInSession_Verify() throws Exception { + int sessionId = retrieveLastSessionId(); + assertSessionFailedWithMessage(sessionId, "has unexpected SHA512 hash"); + } + + private static void assertSessionFailedWithMessage(int sessionId, String msg) { + assertSessionState(sessionId, (session) -> { + assertThat(session.isStagedSessionFailed()).isTrue(); + assertThat(session.getStagedSessionErrorMessage()).contains(msg); + }); + } + private static void assertSessionReady(int sessionId) { assertSessionState(sessionId, (session) -> assertThat(session.isStagedSessionReady()).isTrue()); diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java index ccd63f94de54..5d7fdd183dec 100644 --- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java +++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java @@ -56,6 +56,7 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test { @Rule public AbandonSessionsRule mHostTestRule = new AbandonSessionsRule(this); private static final String SHIM_V2 = "com.android.apex.cts.shim.v2.apex"; + private static final String APEX_WRONG_SHA = "com.android.apex.cts.shim.v2_wrong_sha.apex"; private static final String APK_A = "TestAppAv1.apk"; private static final String APK_IN_APEX_TESTAPEX_NAME = "com.android.apex.apkrollback.test"; @@ -322,6 +323,27 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test { runPhase("testFailStagedSessionIfStagingDirectoryDeleted_Verify"); } + @Test + public void testApexActivationFailureIsCapturedInSession() throws Exception { + // We initiate staging a normal apex update which passes pre-reboot verification. + // Then we replace the valid apex waiting in /data/app-staging with something + // that cannot be activated and reboot. The apex should fail to activate, which + // is what we want for this test. + runPhase("testApexActivationFailureIsCapturedInSession_Commit"); + final String sessionId = getDevice().executeShellCommand( + "pm get-stagedsessions --only-ready --only-parent --only-sessionid").trim(); + assertThat(sessionId).isNotEmpty(); + // Now replace the valid staged apex with something invalid + getDevice().enableAdbRoot(); + getDevice().executeShellCommand("rm /data/app-staging/session_" + sessionId + "/*"); + final File invalidApexFile = mHostUtils.getTestFile(APEX_WRONG_SHA); + getDevice().pushFile(invalidApexFile, + "/data/app-staging/session_" + sessionId + "/base.apex"); + getDevice().reboot(); + + runPhase("testApexActivationFailureIsCapturedInSession_Verify"); + } + private List<String> getStagingDirectories() throws DeviceNotAvailableException { String baseDir = "/data/app-staging"; try { diff --git a/tests/utils/testutils/java/com/android/internal/util/test/FsUtil.java b/tests/utils/testutils/java/com/android/internal/util/test/FsUtil.java new file mode 100644 index 000000000000..e65661298b7c --- /dev/null +++ b/tests/utils/testutils/java/com/android/internal/util/test/FsUtil.java @@ -0,0 +1,40 @@ +/* + * 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.util.test; + +import java.io.File; + +public class FsUtil { + + /** + * Deletes all files under a given directory. Deliberately ignores errors, on the assumption + * that test cleanup is only supposed to be best-effort. + * + * @param dir directory to clear its contents + */ + public static void deleteContents(File dir) { + File[] files = dir.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + deleteContents(file); + } + file.delete(); + } + } + } +} diff --git a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java index 4ce78aa4d8c1..dc338ae0fdc7 100644 --- a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java +++ b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java @@ -20,6 +20,8 @@ import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -70,6 +72,14 @@ public class VcnGatewayConnectionConfigTest { public static final String GATEWAY_CONNECTION_NAME_PREFIX = "gatewayConnectionName-"; private static int sGatewayConnectionConfigCount = 0; + private static VcnGatewayConnectionConfig buildTestConfig( + String gatewayConnectionName, IkeTunnelConnectionParams tunnelConnectionParams) { + return buildTestConfigWithExposedCaps( + new VcnGatewayConnectionConfig.Builder( + gatewayConnectionName, tunnelConnectionParams), + EXPOSED_CAPS); + } + // Public for use in VcnGatewayConnectionTest public static VcnGatewayConnectionConfig buildTestConfig() { return buildTestConfigWithExposedCaps(EXPOSED_CAPS); @@ -83,10 +93,9 @@ public class VcnGatewayConnectionConfigTest { TUNNEL_CONNECTION_PARAMS); } - // Public for use in VcnGatewayConnectionTest - public static VcnGatewayConnectionConfig buildTestConfigWithExposedCaps(int... exposedCaps) { - final VcnGatewayConnectionConfig.Builder builder = - newBuilder().setRetryIntervalsMillis(RETRY_INTERVALS_MS).setMaxMtu(MAX_MTU); + private static VcnGatewayConnectionConfig buildTestConfigWithExposedCaps( + VcnGatewayConnectionConfig.Builder builder, int... exposedCaps) { + builder.setRetryIntervalsMillis(RETRY_INTERVALS_MS).setMaxMtu(MAX_MTU); for (int caps : exposedCaps) { builder.addExposedCapability(caps); @@ -95,6 +104,11 @@ public class VcnGatewayConnectionConfigTest { return builder.build(); } + // Public for use in VcnGatewayConnectionTest + public static VcnGatewayConnectionConfig buildTestConfigWithExposedCaps(int... exposedCaps) { + return buildTestConfigWithExposedCaps(newBuilder(), exposedCaps); + } + @Test public void testBuilderRequiresNonNullGatewayConnectionName() { try { @@ -193,4 +207,46 @@ public class VcnGatewayConnectionConfigTest { assertEquals(config, new VcnGatewayConnectionConfig(config.toPersistableBundle())); } + + private static IkeTunnelConnectionParams buildTunnelConnectionParams(String ikePsk) { + final IkeSessionParams ikeParams = + IkeSessionParamsUtilsTest.createBuilderMinimum() + .setAuthPsk(ikePsk.getBytes()) + .build(); + return TunnelConnectionParamsUtilsTest.buildTestParams(ikeParams); + } + + @Test + public void testTunnelConnectionParamsEquals() throws Exception { + final String connectionName = "testTunnelConnectionParamsEquals.connectionName"; + final String psk = "testTunnelConnectionParamsEquals.psk"; + + final IkeTunnelConnectionParams tunnelParams = buildTunnelConnectionParams(psk); + final VcnGatewayConnectionConfig config = buildTestConfig(connectionName, tunnelParams); + + final IkeTunnelConnectionParams anotherTunnelParams = buildTunnelConnectionParams(psk); + final VcnGatewayConnectionConfig anotherConfig = + buildTestConfig(connectionName, anotherTunnelParams); + + assertNotSame(tunnelParams, anotherTunnelParams); + assertEquals(tunnelParams, anotherTunnelParams); + assertEquals(config, anotherConfig); + } + + @Test + public void testTunnelConnectionParamsNotEquals() throws Exception { + final String connectionName = "testTunnelConnectionParamsNotEquals.connectionName"; + + final IkeTunnelConnectionParams tunnelParams = + buildTunnelConnectionParams("testTunnelConnectionParamsNotEquals.pskA"); + final VcnGatewayConnectionConfig config = buildTestConfig(connectionName, tunnelParams); + + final IkeTunnelConnectionParams anotherTunnelParams = + buildTunnelConnectionParams("testTunnelConnectionParamsNotEquals.pskB"); + final VcnGatewayConnectionConfig anotherConfig = + buildTestConfig(connectionName, anotherTunnelParams); + + assertNotEquals(tunnelParams, anotherTunnelParams); + assertNotEquals(config, anotherConfig); + } } diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java index a88f112f4502..69407657b3c4 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java @@ -16,10 +16,16 @@ package com.android.server.vcn; +import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -33,16 +39,20 @@ import org.junit.runner.RunWith; @SmallTest public class VcnGatewayConnectionRetryTimeoutStateTest extends VcnGatewayConnectionTestBase { private long mFirstRetryInterval; + private VcnNetworkAgent mNetworkAgent; @Before public void setUp() throws Exception { super.setUp(); mFirstRetryInterval = mConfig.getRetryIntervalsMillis()[0]; + mNetworkAgent = mock(VcnNetworkAgent.class); mGatewayConnection.setUnderlyingNetwork(TEST_UNDERLYING_NETWORK_RECORD_1); mGatewayConnection.transitionTo(mGatewayConnection.mRetryTimeoutState); mTestLooper.dispatchAll(); + + mGatewayConnection.setNetworkAgent(mNetworkAgent); } @Test @@ -54,6 +64,9 @@ public class VcnGatewayConnectionRetryTimeoutStateTest extends VcnGatewayConnect assertEquals(mGatewayConnection.mConnectingState, mGatewayConnection.getCurrentState()); verifyRetryTimeoutAlarmAndGetCallback(mFirstRetryInterval, true /* expectCanceled */); + + assertNotNull(mGatewayConnection.getNetworkAgent()); + verify(mNetworkAgent, never()).unregister(); } @Test @@ -65,6 +78,9 @@ public class VcnGatewayConnectionRetryTimeoutStateTest extends VcnGatewayConnect assertEquals(mGatewayConnection.mRetryTimeoutState, mGatewayConnection.getCurrentState()); verifyRetryTimeoutAlarmAndGetCallback(mFirstRetryInterval, false /* expectCanceled */); + + assertNotNull(mGatewayConnection.getNetworkAgent()); + verify(mNetworkAgent, never()).unregister(); } @Test @@ -76,6 +92,9 @@ public class VcnGatewayConnectionRetryTimeoutStateTest extends VcnGatewayConnect assertEquals(mGatewayConnection.mDisconnectedState, mGatewayConnection.getCurrentState()); verifyRetryTimeoutAlarmAndGetCallback(mFirstRetryInterval, true /* expectCanceled */); + + assertNull(mGatewayConnection.getNetworkAgent()); + verify(mNetworkAgent).unregister(); } @Test @@ -93,6 +112,9 @@ public class VcnGatewayConnectionRetryTimeoutStateTest extends VcnGatewayConnect assertEquals(mGatewayConnection.mConnectingState, mGatewayConnection.getCurrentState()); verifyRetryTimeoutAlarmAndGetCallback(mFirstRetryInterval, true /* expectCanceled */); + + assertNotNull(mGatewayConnection.getNetworkAgent()); + verify(mNetworkAgent, never()).unregister(); } @Test @@ -108,6 +130,9 @@ public class VcnGatewayConnectionRetryTimeoutStateTest extends VcnGatewayConnect assertNull(mGatewayConnection.getCurrentState()); assertTrue(mGatewayConnection.isQuitting()); + + assertNull(mGatewayConnection.getNetworkAgent()); + verify(mNetworkAgent).unregister(); } @Test @@ -117,5 +142,8 @@ public class VcnGatewayConnectionRetryTimeoutStateTest extends VcnGatewayConnect assertEquals(mGatewayConnection.mDisconnectedState, mGatewayConnection.getCurrentState()); assertFalse(mGatewayConnection.isQuitting()); + + assertNull(mGatewayConnection.getNetworkAgent()); + verify(mNetworkAgent).unregister(); } } diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java index a4f95e03e9bd..83610e0b7a67 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java @@ -24,8 +24,12 @@ 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 com.android.server.vcn.VcnGatewayConnection.VcnIkeSession; +import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent; + import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Matchers.eq; @@ -191,4 +195,23 @@ public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase { verify(mDisconnectRequestAlarm).cancel(); } + + @Test + public void testQuittingCleansUpPersistentState() { + final VcnIkeSession vcnIkeSession = mock(VcnIkeSession.class); + final VcnNetworkAgent vcnNetworkAgent = mock(VcnNetworkAgent.class); + + mGatewayConnection.setIkeSession(vcnIkeSession); + mGatewayConnection.setNetworkAgent(vcnNetworkAgent); + + mGatewayConnection.quitNow(); + mTestLooper.dispatchAll(); + + assertNull(mGatewayConnection.getIkeSession()); + verify(vcnIkeSession).kill(); + assertNull(mGatewayConnection.getNetworkAgent()); + verify(vcnNetworkAgent).unregister(); + + verifyWakeLockReleased(); + } } diff --git a/tools/fonts/fontchain_linter.py b/tools/fonts/fontchain_linter.py index 1266ccee4df5..e181c62c67e5 100755 --- a/tools/fonts/fontchain_linter.py +++ b/tools/fonts/fontchain_linter.py @@ -117,13 +117,14 @@ def get_emoji_map(font): reverse_cmap = {glyph: code for code, glyph in emoji_map.items() if not contains_pua(code) } # Add variation sequences - vs_dict = get_variation_sequences_cmap(font).uvsDict - for vs in vs_dict: - for base, glyph in vs_dict[vs]: - if glyph is None: - emoji_map[(base, vs)] = emoji_map[base] - else: - emoji_map[(base, vs)] = glyph + vs_cmap = get_variation_sequences_cmap(font) + if vs_cmap: + for vs in vs_cmap.uvsDict: + for base, glyph in vs_cmap.uvsDict[vs]: + if glyph is None: + emoji_map[(base, vs)] = emoji_map[base] + else: + emoji_map[(base, vs)] = glyph # Add GSUB rules ttfont = open_font(font) @@ -310,17 +311,12 @@ def parse_fonts_xml(fonts_xml_path): def check_emoji_coverage(all_emoji, equivalent_emoji): - emoji_font = get_emoji_font() - check_emoji_font_coverage(emoji_font, all_emoji, equivalent_emoji) + emoji_fonts = get_emoji_fonts() + check_emoji_font_coverage(emoji_fonts, all_emoji, equivalent_emoji) -def get_emoji_font(): - emoji_fonts = [ - record.font for record in _all_fonts - if 'Zsye' in record.scripts] - assert len(emoji_fonts) == 1, 'There are %d emoji fonts.' % len(emoji_fonts) - return emoji_fonts[0] - +def get_emoji_fonts(): + return [ record.font for record in _all_fonts if 'Zsye' in record.scripts ] def is_pua(x): return 0xE000 <= x <= 0xF8FF or 0xF0000 <= x <= 0xFFFFD or 0x100000 <= x <= 0x10FFFD @@ -331,58 +327,71 @@ def contains_pua(sequence): else: return is_pua(sequence) +def get_psname(ttf): + return str(next(x for x in ttf['name'].names + if x.platformID == 3 and x.platEncID == 1 and x.nameID == 6)) def check_emoji_compat(): - ttf = open_font(get_emoji_font()) - meta = ttf['meta'] - assert meta, 'Compat font must have meta table' - assert 'Emji' in meta.data, 'meta table should have \'Emji\' data.' + for emoji_font in get_emoji_fonts(): + ttf = open_font(emoji_font) + psname = get_psname(ttf) + + # If the font file is NotoColorEmoji, it must be Compat font. + if psname == 'NotoColorEmoji': + meta = ttf['meta'] + assert meta, 'Compat font must have meta table' + assert 'Emji' in meta.data, 'meta table should have \'Emji\' data.' -def check_emoji_font_coverage(emoji_font, all_emoji, equivalent_emoji): - coverage = get_emoji_map(emoji_font) +def check_emoji_font_coverage(emoji_fonts, all_emoji, equivalent_emoji): + coverages = [] + for emoji_font in emoji_fonts: + coverages.append(get_emoji_map(emoji_font)) errors = [] for sequence in all_emoji: - if not sequence in coverage: - errors.append('%s is not supported in the emoji font.' % printable(sequence)) + if all([sequence not in coverage for coverage in coverages]): + errors.append('%s is not supported in the emoji font.' % printable(sequence)) - for sequence in coverage: - if sequence in {0x0000, 0x000D, 0x0020}: - # The font needs to support a few extra characters, which is OK - continue + for coverage in coverages: + for sequence in coverage: + if sequence in {0x0000, 0x000D, 0x0020}: + # The font needs to support a few extra characters, which is OK + continue - if contains_pua(sequence): - # The font needs to have some PUA for EmojiCompat library. - continue + if contains_pua(sequence): + # The font needs to have some PUA for EmojiCompat library. + continue - if sequence not in all_emoji: - errors.append('%s support unexpected in the emoji font.' % printable(sequence)) + if sequence not in all_emoji: + errors.append('%s support unexpected in the emoji font.' % printable(sequence)) for first, second in equivalent_emoji.items(): - if first not in coverage or second not in coverage: - continue # sequence will be reported missing - if coverage[first] != coverage[second]: - errors.append('%s and %s should map to the same glyph.' % ( - printable(first), - printable(second))) - - for glyph in set(coverage.values()): - maps_to_glyph = [ - seq for seq in coverage if coverage[seq] == glyph and not contains_pua(seq) ] - if len(maps_to_glyph) > 1: - # There are more than one sequences mapping to the same glyph. We - # need to make sure they were expected to be equivalent. - equivalent_seqs = set() - for seq in maps_to_glyph: - equivalent_seq = seq - while equivalent_seq in equivalent_emoji: - equivalent_seq = equivalent_emoji[equivalent_seq] - equivalent_seqs.add(equivalent_seq) - if len(equivalent_seqs) != 1: - errors.append('The sequences %s should not result in the same glyph %s' % ( - printable(equivalent_seqs), - glyph)) + for coverage in coverages: + if first not in coverage or second not in coverage: + continue # sequence will be reported missing + if coverage[first] != coverage[second]: + errors.append('%s and %s should map to the same glyph.' % ( + printable(first), + printable(second))) + + for coverage in coverages: + for glyph in set(coverage.values()): + maps_to_glyph = [ + seq for seq in coverage if coverage[seq] == glyph and not contains_pua(seq) ] + if len(maps_to_glyph) > 1: + # There are more than one sequences mapping to the same glyph. We + # need to make sure they were expected to be equivalent. + equivalent_seqs = set() + for seq in maps_to_glyph: + equivalent_seq = seq + while equivalent_seq in equivalent_emoji: + equivalent_seq = equivalent_emoji[equivalent_seq] + equivalent_seqs.add(equivalent_seq) + if len(equivalent_seqs) != 1: + errors.append('The sequences %s should not result in the same glyph %s' % ( + printable(equivalent_seqs), + glyph)) assert not errors, '%d emoji font errors:\n%s\n%d emoji font coverage errors' % (len(errors), '\n'.join(errors), len(errors)) |